Skip to content

Add Opencode hooks to nitro agent - #10366

Open
michaelstaib wants to merge 50 commits into
mainfrom
mst/opencode
Open

Add Opencode hooks to nitro agent#10366
michaelstaib wants to merge 50 commits into
mainfrom
mst/opencode

Conversation

@michaelstaib

Copy link
Copy Markdown
Member

No description provided.

The first-prompt announcement and idle-push-per-transition gate no longer
reserve reserved sentinel ids on the mail delivery ledger (session_deliveries
stays real-mail-only). Both are now atomically armed/claimed via two new
agent_sessions columns and IAgentSessionRegistry methods, so a Nitro-pushed
chat message can skip rearming without touching the ledger at all.
Nitro's push side is expected (hc-10-5n6.2) to prepend a reserved text
prefix to a delivered message instead of tagging it with metadata; the
generated shim now detects and strips that exact prefix from output.parts
(opencode delivers the model-bound message there, not input.parts) and
sets nitroPushed on the hook payload. Adds a generated-JavaScript
regression, executed under Node, guarding the output.parts requirement.
… command group

Wires the opencode hook handler landed in hc-10-nds.1 into a process
entry point: OpencodeHookExecutor mirrors ClaudeHookExecutor and
CodexHookExecutor's fail-open envelope (stdin/stdout JSON, 10s entry
timeout, NITRO_HOOK_SUPPRESS kill switch, neutral {} on every failure
except a schema mismatch, which reports to stderr with exit 1), and
the hidden `nitro agent hook opencode` command group adds the
session-created, chat-message, session-idle, and session-deleted
leaf commands the generated shim invokes.
Adds the opencode-server branch to ActorWakeDispatcher and
PingSessionExecutor: wake pushes the mail digest as a real prompt
(prefixed with the reserved nitro push marker so the shim recognizes
and skips it) via OpencodeServerClient.PushMessageAsync, guarded by
the session registry's idle-push claim so at most one push fires per
idle transition and mail during a nitro-pushed turn waits for the
next one; when there is nothing left to deliver, a health-only ping
via PushAsync's sibling verifies the endpoint instead of a blind ok.
Registers IOpencodeServerClient additively in
ServiceCollectionExtensions. Existing claude-peer and codex-thread
branches are untouched.

Ref: hc-10-5n6.2
Move the opencode idle-push claim so it only spends the session's
one-shot flag once the gate reservation is already held, instead of
before it: a busy gate or a dropped capacity slot no longer burns the
claim for nothing. Rearm the claim whenever an attempt did not
actually deliver (a terminal failure, an access-denied offer, or a
health-only ping that found no digest left to push), so a transport
failure or a benign mail-already-read race no longer strands the
session waiting on a human prompt. PingSessionExecutor now tags a
health-only ping's outcome with a dedicated detail constant so the
dispatcher can tell it apart from a delivered push. Name the opencode
switch arm explicitly instead of falling through a wildcard.

Covers: a busy session gate never spends the idle-push claim, an
outright transport failure rearms it, and a health-only ping (no
mail left to push) rearms it too.
…ation

DispatchTargetAsync could strand an OpencodeServer session's one-shot
idle-push claim when the dispatch was cancelled between a successful
ClaimIdlePushAsync and the outcome-based rearm (a lost lease renewal or
caller shutdown mid-transport). Track the claim with idlePushClaimed/
idlePushSettled flags and hand it back from the inner finally whenever
a claimed attempt never reached the existing outcome-based decision.
SessionDeliveryLedger's reserving INSERT is already conditioned on the
session row existing, so the FK-violation catch in
OpencodeHookHandler.ReserveAsync (and the SessionRemovedDuringDeliveryException
it fed) could never fire; a deleted session already reserves nothing via
the normal empty-result path. Also documents that dryRun has no effect
in this handler (opencode has no session-file side channel to skip).

Findings F1 and F6 from hc-10-nds.1's review comment.
…stract

Adds back ISessionDeliveryLedger.ReserveAsync(harness, sessionId, ...)
as an additive overload with its original byte-identical SQL, and
reverts ClaudeHookHandler/CodexHookHandler and their test doubles to
call it, so the opencode host-aware overload no longer touches the
shipped Claude/Codex paths beyond the additive abstraction.

Also makes IAgentSessionRegistry's Arm/Claim announcement and idle-push
members abstract instead of default no-ops, and implements them on the
fake registry and every test decorator, so an implementation that does
not support the markers fails to compile rather than silently doing
nothing.

Findings F4 and F5 from hc-10-nds.1's review comment.
Seeds a raw v12-shaped agent_sessions table, predating the
announcement_pending and idle_push_armed columns, and asserts
InitializeAsync adds both defaulted to 0 without losing the existing
row.

Finding F2 from hc-10-nds.1's review comment.
Adds a chat-message-pushed.json fixture with nitroPushed: true and a
test asserting OpencodeHookExecutor deserializes it onto
OpencodeHookPayload.NitroPushed.

Finding F7 from hc-10-nds.1's review comment.
OpencodeHookHandler.HandleSessionIdleAsync no longer calls
ClaimIdlePushAsync or reserves a gate-channel delivery: the dispatcher
already claims the flag after its own gate reservation and rearms it
on every non-delivering path, so an idle event that beats the daemon
no longer spends the one-shot claim with nothing pushed. The event now
only touches presence/heartbeat, since the shim discards its response
either way. OpencodeHookOutcome.IdleDelivery is removed as dead
plumbing along with it.

Per the hc-10-5n6.2 planner ruling (option A).
Four minors from the hc-10-5n6.2 review cycle 3:
- Split the two ActorWakeDispatcherTests exceeding the 5-Assert limit
  into separate push/suppress and offer/deliver tests.
- Classify 'idle-not-armed' as a transient offer reason in
  MailWakeDaemonRetryPolicy.IsTransientOffer, matching busy/
  capacity-dropped/access-denied.
- Deduplicate PingSessionExecutor.ExecuteOpencodeServerAsync against
  ExecuteAsync via a shared helper, keeping every branch's existing
  behavior byte-identical.
- Persist the opencode health-only ping detail only when it actually
  changed from the row's own last recorded state, instead of
  rewriting it on every idle poll.
ActorWakeDispatcher minted a fresh pingAttemptId for every dispatch but
never stamped it onto agent_sessions.last_ping_attempt, so the executor's
later WritePingResultAsync call (conditioned on that column) always
matched zero rows: no ping result was ever durably recorded via the wake
path, for any harness. Stamp the attempt through
IAgentSessionRegistry.TryClaimPingCooldownAsync right before invoking the
executor, mirroring the retired manual ping command's own sequence, so
the write actually lands.
Adds a regression proving ActorWakeDispatcher, wired to the real
PingSessionExecutor, durably stamps last_ping_attempt and writes
last_ping_result on the agent_sessions row - the gap the wake-path fix
closes.
Drops the persist-only-when-changed gate in PingSessionExecutor: the
prior TryClaimPingCooldownAsync claim already nulls last_ping_result
and last_ping_detail before every attempt, so skipping the write for a
repeated health-only outcome left the row NULL on alternate wakes
instead of restoring it. Every health-only ping now writes back like
any other attempt. Also corrects the ActorWakeDispatcher comment
describing TryClaimPingCooldownAsync's false-return condition to match
its actual predicate (row missing or last_ping_at ahead of now).
…tcome

Updates FakePingSessionExecutor and every PingSessionExecutorTests
ExecuteOpencodeServerAsync call for the dropped previousPingResult/
previousPingDetail parameters. Renames the skip-the-write test to
assert the row is rewritten to ok/health-only instead of left NULL.

Adds DispatchAsync_Should_PersistTheHealthOnlyResult_When_TheOpencodeSessionWakesTwice,
which drives the real PingSessionExecutor (not the scriptable fake)
through two ActorWakeDispatcher wakes and asserts last_ping_attempt/
last_ping_result/last_ping_detail persist as ok/health-only after
each. The executor's own mail store is wrapped to always report no
unread mail, deterministically reproducing the health-only race the
opencode branch exists for, while the dispatcher keeps the real mail
store for its own outstanding-mail gate.
… row

Assert the surviving row's identifying values after the v12-to-v13
upgrade instead of only summing the new default-0 columns, which
passed vacuously even when the row was dropped entirely. Also fix the
IDE1006 s_ prefix warning on OpencodeHooksInstallerServiceTests'
static LaunchDescriptor field.
Match the structural shape of the Claude Code status and uninstall
subsections, whose --scope and --output options and example
invocations sit under explicit ### Options and ### Examples headings.
Copilot AI lite review requested due to automatic review settings September 8, 2026 06:04
@github-actions github-actions Bot added the 📚 documentation This issue is about working on our documentation. label Sep 8, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

There are user-facing/help and in-code documentation mismatches (notably around Opencode session-idle behavior and exit-code semantics) that should be corrected before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR extends Nitro’s agent “hooks” system with an Opencode integration, including a generated Opencode plugin shim, new hook event handlers, and supporting workspace/notify plumbing so Nitro can announce actor identity, prepend unread-mail nudges, and push idle deliveries for Opencode sessions.

Changes:

  • Add nitro agent hooks opencode {install|status|uninstall} and nitro agent hook opencode <event> command trees, plus a generated nitro-hooks.js shim and sidecar tracking.
  • Extend the agent workspace database/schema and session registry to support the opencode harness, opencode-server endpoints, endpoint credentials, and durable per-session flags for announcements/idle push gating.
  • Add an Opencode server HTTP client and integrate Opencode sessions into the wake dispatcher/ping executor flow, with expanded test coverage and documentation.
File summaries
File Description
website/content/docs/nitro/cli/structure.yaml Adds docs nav entry for agent hooks.
website/content/docs/nitro/cli/agent-hooks.md Documents nitro agent hooks including Opencode.
src/Nitro/CommandLine/test/fixtures/hooks/opencode/session-idle.json Opencode hook payload fixture (idle).
src/Nitro/CommandLine/test/fixtures/hooks/opencode/session-deleted.json Opencode hook payload fixture (deleted).
src/Nitro/CommandLine/test/fixtures/hooks/opencode/session-created.json Opencode hook payload fixture (created).
src/Nitro/CommandLine/test/fixtures/hooks/opencode/malformed.json Malformed-payload fixture for fail-open behavior.
src/Nitro/CommandLine/test/fixtures/hooks/opencode/chat-message.json Opencode hook payload fixture (chat).
src/Nitro/CommandLine/test/fixtures/hooks/opencode/chat-message-pushed.json Fixture for Nitro-pushed chat message handling.
src/Nitro/CommandLine/test/CommandLine.Tests/Tui/Agents/FakeAgentSessionRegistry.cs Updates fake registry for new session APIs.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Workspace/AgentSessionRegistryTests.cs Tests storing Opencode endpoint + credential rules.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Workspace/AgentDatabaseTests.cs Adds upgrade tests for Opencode + new columns.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/PingSessionExecutorTests.cs Adds Opencode ping/push behavior tests.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/OpencodeServerClientTests.cs Tests Opencode server HTTP client behavior.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/NotifierTests.cs Wires opencode client into notify composition.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/MailWakeDaemonRetryPolicyTests.cs Extends transient-offer classification tests.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Notify/ActorWakeDispatcherTests.cs Adds Opencode idle-armed and persistence scenarios.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/SessionDeliveryLedgerTests.cs Adds generation/host-scoped reservation tests.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/OpencodeHooksInstallerServiceTests.cs Tests shim install/status/uninstall + JS regression.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/OpencodeHookHandlerTests.cs End-to-end handler tests against real workspace DB.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/OpencodeHookExecutorTests.cs Tests fail-open executor envelope and parsing.
src/Nitro/CommandLine/test/CommandLine.Tests/Services/Hook/ClaudeHookHandlerTests.cs Updates delegating fakes for new APIs.
src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/OpencodeHooksCommandTests.cs Tests agent hooks opencode CLI help/flow.
src/Nitro/CommandLine/test/CommandLine.Tests/Commands/Agent/OpencodeHookCommandTests.cs Tests agent hook opencode <event> wiring/output.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/SessionPingGateSchema.cs Adds opencode to session ping gate harness check.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/SessionDeliveryLedger.cs Adds host-scoped ReserveAsync(AgentSessionGeneration) overload.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/MailWakeSchema.cs Adds opencode to wake-target harness check.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/ISessionDeliveryLedger.cs Adds generation/host-aware reservation overload contract.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/IAgentSessionRegistry.cs Adds endpoint-secret start overload + idle/announce flag APIs.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/EndpointAddress.cs Adds Opencode server URL validator helper.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentSessionSchema.cs Extends sessions schema: opencode + secrets + flags.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentSessionRegistry.cs Stores Opencode endpoint secret + implements new flags.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentSessionRecord.cs Adds EndpointSecret to session record projection.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentSessionIdentitySchema.cs Extends identities harness check; adds rebuild helper.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentSessionHarness.cs Adds opencode harness constant.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentSessionEndpointKind.cs Adds opencode-server endpoint kind constant.
src/Nitro/CommandLine/src/CommandLine/Services/Workspace/AgentDatabase.cs Bumps schema to v13 and adds rebuild/upgrade steps.
src/Nitro/CommandLine/src/CommandLine/Services/Notify/PingSessionExecutor.cs Adds opencode transport; supports nullable digest flow.
src/Nitro/CommandLine/src/CommandLine/Services/Notify/PingAttemptReason.cs Documents opencode as supported transport.
src/Nitro/CommandLine/src/CommandLine/Services/Notify/OpencodeServerClient.cs Implements HTTP push + ping for opencode server.
src/Nitro/CommandLine/src/CommandLine/Services/Notify/MailWakeDaemonRetryPolicy.cs Treats idle-not-armed as transient offer.
src/Nitro/CommandLine/src/CommandLine/Services/Notify/IPingSessionExecutor.cs Adds ExecuteOpencodeServerAsync contract.
src/Nitro/CommandLine/src/CommandLine/Services/Notify/IOpencodeServerClient.cs Adds opencode server client interface.
src/Nitro/CommandLine/src/CommandLine/Services/Notify/ActorWakeDispatcher.cs Adds opencode endpoint support + idle-push claim logic.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodePathResolver.cs Resolves user/project opencode plugin paths.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHooksTemplate.cs Generates nitro-hooks.js shim for opencode.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHooksSidecarStore.cs Stores shim install metadata + hashes.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHooksInstallerService.cs Installs/updates/uninstalls shim with concurrency guards.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHookResponse.cs Defines shim response envelope.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHookProtocol.cs Defines reserved pushed-prompt prefix constant.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHookPayload.cs Defines shim payload contract + aliases.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHookOutcome.cs Defines handler output parts for injection.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHookJsonContext.cs Adds source-gen JSON context for payload/response.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHookHandler.cs Implements opencode lifecycle + announcement/digest behavior.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/OpencodeHookExecutor.cs Adds fail-open executor for opencode hook commands.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/IOpencodeHookHandler.cs Defines opencode hook handler interface.
src/Nitro/CommandLine/src/CommandLine/Services/Hook/ClaudeHookHandler.cs Removes unused using after refactor.
src/Nitro/CommandLine/src/CommandLine/Extensions/ServiceCollectionExtensions.cs Registers opencode services into DI graph.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Options/OpencodeHookInstallScopeOption.cs Adds --scope option for opencode hooks commands.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Opencode/UninstallOpencodeHooksCommand.cs Implements agent hooks opencode uninstall.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Opencode/StatusOpencodeHooksCommand.cs Implements agent hooks opencode status + warnings.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Opencode/OpencodeVersionWarning.cs Emits minimum-version warning in human output.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Opencode/OpencodeVersionResolver.cs Resolves opencode version via opencode --version.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Opencode/OpencodeHooksCommand.cs Adds agent hooks opencode command group.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Opencode/IOpencodeVersionResolver.cs Defines version resolver interface for warnings.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/Opencode/InstallOpencodeHooksCommand.cs Implements agent hooks opencode install.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hooks/HooksCommand.cs Registers opencode under agent hooks.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hook/OpencodeHookCommandExtensions.cs Wires opencode hook leaf actions through executor.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hook/Opencode/SessionIdleHookCommand.cs Adds agent hook opencode session-idle leaf command.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hook/Opencode/SessionDeletedHookCommand.cs Adds agent hook opencode session-deleted leaf command.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hook/Opencode/SessionCreatedHookCommand.cs Adds agent hook opencode session-created leaf command.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hook/Opencode/OpencodeHookCommand.cs Adds agent hook opencode command group.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hook/Opencode/ChatMessageHookCommand.cs Adds agent hook opencode chat-message leaf command.
src/Nitro/CommandLine/src/CommandLine/Commands/Agent/Hook/HookCommand.cs Registers opencode under agent hook.
Review details
  • Files reviewed: 73/73 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +12 to +16
public SessionIdleHookCommand() : base("session-idle")
{
Description = "Adapt opencode's session.idle event: reserve unread mail for idle delivery.";

this.SetOpencodeHookAction(
Comment on lines +121 to +124
// Always success: a hook adapter reports failure to opencode through its
// own JSON protocol (or silently, via the neutral response), never
// through the process exit code.
private const int ExitCode = 0;
}
},
"chat.message": async (input, output) => {
// OpenCode exposes the message actually delivered to the
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Nitro CLI E2E snapshots: no flow recordings changed vs main.

…per file

Pure move: extracts IOpencodeHooksInstallerService, OpencodeHooksInstallReport,
OpencodeHooksStatusReport, and OpencodeHooksUninstallReport into their own
files, matching the already-split Claude and Codex hook installer siblings.
Also carries the unused-using deletions already present in the working tree
(OpencodeHooksInstallerService.cs and the three Opencode hook command files).
…livery

The chat-message handler committed its one-shot claims before the shim had
a chance to append them, so any delivery failure lost the actor-name
announcement and the mail reservation permanently, with no retry path. The
generated shim now records whether its previous append landed and reports
that on the next chat message, unconditionally, so an absent flag means only
an older shim. The handler re-arms the announcement and releases the digest
reservation whenever a turn is reported undelivered, and a claim that fails
after the reservation committed is compensated.

A turn with nothing to append records success rather than clearing its
entry, so steady-state neutral turns cannot re-announce. Repeated delivery
failure retries on every message by design: nothing was appended, so nothing
is user visible, and it self-heals as soon as appending works.

Squashed from six review cycles; the intermediate commits contradicted the
final design and conflicted with the one-type-per-file splits.
… failure

Compensation in OpencodeHookHandler now threads the ids ReserveAsync
actually won out of BuildDigestAsync and releases exactly those,
instead of re-querying the unread inbox and releasing ids another
consumer already holds (a double-delivery). Compensation also runs
with CancellationToken.None so a cancelled turn still releases, and
swallows its own failures so the primary exception always propagates.
RunAsync_Should_PublishDataChangedEvent_When_WalGrowsAndStaysGrown
_LikeACheckpointBlockedByAConcurrentReader fails intermittently with
a bare ReadOneAsync timeout under heavy concurrent load, never a
wrong-type event.

Diagnosis: not a lost-first-change bug in SqliteDbWatcher. The
watcher captures its -wal size baseline and enables the underlying
FileSystemWatcher synchronously before RunAsync's Task is even
returned to the caller, so no test in this file can race that
start-up as the ticket's initial theory suggested; a probe-write
variant built to prove watcher liveness before the act step
confirmed this and, empirically, made full-suite flakiness worse by
adding another write whose own notification can straggle. The
remaining failures are file system event delivery running behind
under system-wide load, sometimes past the fixed windows this class
already budgets for it.

Decouple the settle wait from the production Debounce value into its
own wider SettleDelay, and widen TestTimeout, so a delayed
notification (arrange echo or the act step's own event) has more
room to land before the assertion runs. Both changes are shared by
every test through SettleAsync and ReadOneAsync, covering the
sibling tests with the same shape.
The prior SettleAsync did a single fixed 500ms delay then a single
drain, so a notification straggling in after that one drain (for
example the arrange step's own database write) could still land
after the act step and be misread as the act step's event, or a
negative-assertion test could see an event it shouldn't. Reproduced
this independently: 1 failure in 10 full-suite runs in
RunAsync_Should_IgnoreUnrelatedFile_InSameDirectory with the same
signature.

Replace the single delay-then-drain with a quiescence loop: keep
draining after each SettleDelay window until a full window passes
with nothing read, bounded by TestTimeout so a pathological machine
cannot hang the test. This is shared by every test through
SettleAsync, so it covers all sibling tests with the same shape,
including the ticket's WalGrowsAndStaysGrown flake.

Also trim the SettleDelay and TestTimeout XML docs to their contract
per AGENTS.md (no flake history or design justification in doc
comments), and rename the four static readonly TimeSpan fields in
this file to the s_ prefix the naming analyzer requires so
`dotnet format --verify-no-changes` is clean again.
Switches OpencodeServerClient.PushMessageAsync from the synchronous
session/{id}/message route to session/{id}/prompt_async. The sync
route awaits the entire model turn inside the request, so any turn
longer than PingPolicy.HardTimeout (20s) was recorded as Timeout even
though it was delivered, causing ActorWakeDispatcher to re-arm and
double-push. prompt_async takes the identical body, forks the run
server-side, and returns 204, which the existing IsSuccessStatusCode
check already treats as success.
Only the move path re-validated and upgraded the schema; a workspace
already at .git/nitro fell straight to "nothing to migrate" even when
its stamped version was behind CurrentVersion, leaving the connect
error's "Run `nitro agent init` to migrate it" advice a dead end for
--migrate. Read the stamped version first: upgrade in place and report
it when the version is not current, otherwise keep the existing
message unchanged.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

📚 documentation This issue is about working on our documentation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants