Skip to content

Releases

0.11.4 — Final release: Windows lease read retry

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 21:40
1ae8144

v0.11.4 — Final release: Windows lease read retry

Final release. This supersedes 0.11.3 as the last planned release of opencode-goal-plugin; it carries one bug fix found after 0.11.3 shipped. OpenCode ships a built-in /goal as of v2.2.1; on 2.2.1 and later use the built-in command unless you need this plugin's independent verifier, limits, agent tools or multi-goal sequences. The plugin keeps working on OpenCode 1 and OpenCode 2 and receives bug and security fixes only. With both installed the plugin takes over /goal; set commandName to keep both (see the README).

Install: "plugins": ["opencode-goal-plugin@0.11.4"] (OpenCode 2) or "plugin": [...] plus a goal command entry (OpenCode 1). npm. Versions below 0.11.4 are deprecated on npm in favour of this one.

Changes

  • On Windows, retry a claim read that fails with EPERM, EACCES or EBUSY with the same 10 ms to 160 ms backoff as claim renames and unlinks. Windows keeps a directory entry for a claim another handle still holds open after it was unlinked and refuses to open it until that handle closes, so two plugin instances racing to reclaim a stale lease could end with the loser failing on a permission error instead of reporting the lease as contended (seen once on windows-latest CI, test/persistence-lease.test.js "simultaneous stale observers cannot both acquire the replacement lease"). The test now names the loser's error when it fails.

Everything else is as in v0.11.3.

0.11.3 — Final release: ledger recovery, verifier integrity, maintenance mode

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 20:54
169f4b2

v0.11.3 — Final release: ledger recovery, verifier integrity, maintenance mode

Superseded by v0.11.4, which adds one Windows lease fix; use that version.

Final planned release. OpenCode ships a built-in /goal as of v2.2.1; on 2.2.1 and later use the built-in command unless you need this plugin's independent verifier, limits, agent tools or multi-goal sequences. The plugin keeps working on OpenCode 1 and OpenCode 2 and receives bug and security fixes only. With both installed the plugin takes over /goal; set commandName to keep both (see the README).

Install: "plugins": ["opencode-goal-plugin@0.11.3"] (OpenCode 2) or "plugin": [...] plus a goal command entry (OpenCode 1). npm. Verified on OpenCode 1.17.15, 2.0.16, 2.0.26 and 2.2.2.

Changes

  • Stop ledger recovery from bringing back replaced goals. Replacing a goal with /goal <objective>, goal_set or /goal sequence left no terminal ledger event, so after a truncated, corrupt or wrong-version state.json the old goal came back as a paused goal in /goal list. Replacements now record a replaced event, which recovery treats like completed and cleared. Ledgers written before this change keep the old behavior.
  • Start a new ledger line when the last one was torn. A crash mid-append left a line without a newline, and the next event was appended onto it, so both were skipped as malformed and a later cleared or completed event could be lost.
  • Report a ledger append as durable only when every byte was written. A short write used to count as success; the append now finishes the write or reports failure.
  • Quarantine an invalid state.json as state.json.corrupt.* whenever it fails to load. It was kept only when the ledger rebuilt at least one goal; otherwise the next save overwrote it and the data was lost.
  • On Windows, retry removing the persistence lease claim on release when the unlink fails with EPERM, EACCES or EBUSY, with the same 10 ms to 160 ms backoff as the 0.11.2 rename retry. One such failure left the instance's own claim behind, and because the owner process is always alive to itself, a same-process replacement after an OpenCode 2 location reload stayed passive until OpenCode restarted. A claim that stays locked past the retries still fails the release as before; other platforms are unchanged.
  • Only affects users who set auditorOptions.failurePolicy: "approve": a completion verifier whose prompt or permissions differ from the plugin's own goal-verify definition on OpenCode 2, or a verifier child session linked to a different parent session, was treated as an operational failure and auto-approved. These integrity failures now always reject; an unavailable API, missing child-session ID, provider error or timeout still follows the configured policy.
  • Give the built-in completion verifier the whole completion claim, up to the 8000-character claim limit. It was cut to the last 1000 characters, so a structured goal_complete claim lost its summary and early criteria before the verifier saw it.
  • Keep the recorded reason when a goal that is already stopped sees a later provider error, abort or rejected permission. A goal the assistant marked [goal:blocked] was relabelled paused with provider error, user interrupted or permission rejected when, for example, the turn the user spent resolving the blocker failed, so /goal status lost the blocker. User pauses and audit rejections were overwritten the same way.
  • On OpenCode 2.2, find a goal session's existing child sessions again. 2.2 returns session.list as a page ({ data, cursor }), which the bridge did not unwrap, so noContinueWhileChildrenActive only saw children created while the current plugin instance was running and missed any that started before a reload. Earlier 2.0 hosts have no session.list in the plugin context and are unchanged.
  • On OpenCode 2, release the /goal registration the plugin re-asserts over a shadowing config command when the plugin is unloaded, and skip the re-assertion if the plugin was unloaded while it was checking. Real hosts already scope plugin registrations to the plugin, so this only matters for embedders.
  • Docs: on OpenCode 2 a file: plugin entry that points at src/goal-plugin.js is rejected (configured plugin path must be a directory) and, on 2.2.1 and later, the built-in /goal answers instead, so the README's local-development section and the demo now give the OpenCode 2 routes (.opencode/plugins/<file>.js or a packed tarball) next to the OpenCode 1 file: form. Restructure the README's first screen around the maintenance status, why the plugin existed and its engineering highlights, and correct the CI claim: Node 18–24 runs on Linux, with macOS and Windows covering the filesystem-sensitive tests. Retire the feature-request issue template and add maintenance notices to CONTRIBUTING and SECURITY.
  • Docs: add a maintenance-status note. OpenCode 2.2.1 ships a built-in /goal; with default options this plugin takes over the command and the built-in does not run, and setting commandName keeps both (verified on a live 2.2.2 host). Record OpenCode 2.0.26 and 2.2.2 as verified hosts alongside 2.0.16.
  • Docs: correct several claims that no longer matched the code. OpenCode 2 exposes 9 tools (not 11), the token budget is the peak context size including cache tokens, audit children are deleted on hosts with session.remove, per-session state lives under state.json.sessions/, the upgrade notes described 0.11.0 instead of the current release, budgetWrapupRatio applies to the token budget only, and /goal stop clears rather than pauses.
  • Correct the comment on the lease liveness check, and the 0.11.1 entry's reasoning: signal 0 is only an existence check under Node and OpenCode's embedded Bun, including on Windows (verified on windows-latest for #81), so it never terminated the OpenCode service. Skipping it for the host's own process stays as a harmless shortcut.

0.11.0 — OpenCode 2 support, authoritative live leases, fail-closed verifier switching

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 20:54

v0.11.0 — OpenCode 2 support, authoritative live leases, fail-closed verifier switching

Released on 2026-09-30. Release notes backfilled on 2026-10-30 from CHANGELOG.md.

  • Normalize directory separators with a linear scan, preventing adversarial location strings from causing regular-expression backtracking.

  • Keep live persistence owners authoritative regardless of claim age. On OpenCode 2 location reloads, explicitly dispose the previous same-process plugin instance before initializing its replacement; do not steal a live claim on a timer.

  • Fail closed when an OpenCode 2 agent switch fails or the completion verifier's identity/permissions differ from the owned definition. Revoke previously confirmed audit readiness on config conflicts, wait for the child execution before reading its verdict, and map child removal when the host exposes it.

  • Make Windows-path case assertions platform-aware while preserving POSIX location isolation.

  • Make the release contracts pass under npm 12 on machines whose ~/.npmrc
    sets allow-scripts: npm run re-exports that entry as environment config,
    which npm 12 rejects with EALLOWSCRIPTS when the child install also passes
    --ignore-scripts, so the type, packed-host, and packed-tool contracts now
    strip script-policy npm_config_* keys from the environment they hand to
    child npm. The same three scripts also normalize npm 12's pack --json
    output (keyed by package name instead of a bare array): the packed-host and
    packed-tool contracts accepted only the array shape and failed at the
    install step, and the type contract crashed in its final success log even
    after both tsc passes because it still indexed the raw result. All three
    contracts now pass locally (type contract passed (NodeNext + Bundler; opencode-goal-plugin-0.11.0.tgz), packed host contract passed,
    packed tool contract passed … 11 tools).

  • Extend the live OpenCode 2.0.16 verification of the OpenCode 2 adapter and
    record it in docs/compatibility.md: command ownership over a legacy config
    command.goal entry on a cold boot (the plugin's framed control result is
    the admitted turn and the config template text never reaches the model), a
    full goal run to completion through goal_complete on a live provider, the
    auto-continue loop (two <goal_continuation> prompts with a live
    <progress_budget> countdown before the talk-only stall gate paused the
    goal), the session-title status indicator, agent registration with system
    prompts and translated permission rules, and the plugin-options precedence
    rule for a package listed in both user-level and project config.

  • Add OpenCode 2 support. The default export now carries a setup entrypoint next to server: OpenCode 1 keeps reading id + server (the V1 hook map), OpenCode 2 reads id + setup and ignores server, so one package serves both lines and engines.opencode widens from >=1.17.15 <2 to >=1.17.15. The new src/v2-bridge.js adapts OpenCode 2's plugin context onto the existing V1 hook contract instead of forking the workflow, so the goal core (state machine, persistence lease, budgets, ledger, tool surface) is unchanged: session.hook("prompt") drives chat.message, two session.hook("context") registrations drive chat.params and the system block, session.hook("compaction") drives experimental.session.compacting, tool.hook("execute.before") keeps the throw-to-block contract, tool.transform/agent.transform replace the tool map and config hook (Zod v4 passes through as Standard Schema, V1 agent permission/tool maps translate to ordered V2 rules with both spellings of renamed actions), command.transform registers /goal and submits the routed control result as the prompt itself, and event.subscribe() normalizes the V2 stream back to the V1 event shapes (session.execution.succeeded → session.idle, …failed → session.error, …interrupted → abort, session.compaction.ended → session.compacted, session.step.ended → message.updated, session.agent/model.selected → session.updated). Because V2 messages carry no parentID, it is derived from transcript order and from the last admitted prompt; because session.create has no parentID field, the completion auditor's child records the parent link in session metadata; V2 step failures are not treated as terminal (V2 retries them) and terminal errors come from session.execution.failed; V2 has no client.app.log, so advisory diagnostics use the existing console fallback; and V2 has no post-compaction auto-continue, so experimental.compaction.autocontinue needs no replacement. test/v2-bridge.test.js pins every mapping, the session-client contract, and an end-to-end /goal set command turn that creates a goal instead of being read as user input.

  • Register the slash command so OpenCode 2's config ordering cannot shadow it. OpenCode 2 registers config command/commands entries after user plugins, which would let a legacy command.goal entry override the plugin's handler; the bridge re-asserts its registration after activation (retriggered by command.updated/config.updated) and warns if a foreign definition still owns the name. A config command entry is now required only on OpenCode 1 — OpenCode 2 users should drop it.

  • Verify OpenCode 2.0.16 against a real host: plugin load to state: active through both a package spec and a local .opencode/plugins/*.js entry, the /goal command listed by GET /api/command, and the native goal/goal-verify agents present in GET /api/agent. docs/compatibility.md now records the supported surface, the full hook mapping, the divergences above, and the current validation boundaries. A configured plugin directory that contains a package.json is resolved by name@version into OpenCode's npm cache, so a local checkout loads only through .opencode/plugins/<file>.js.

  • On OpenCode 2, stop exposing the V1 tool aliases get_goal and set_goal, which duplicate goal_status and goal_set. Two spellings of one operation led a model to invent get_goal_status right after a goal was set. get_goal_history, update_goal and clear_goal have no canonical twin and stay; OpenCode 1 is unchanged.

  • Invalidate pending completion approvals when the objective changes, and give auditors isolated goal snapshots so an old verdict cannot complete a newly edited goal.

  • Apply the planning-only agent hold to every work command, including add, sequence, resume and focus, and to goal creation/resume tools. Preserve routed first-turn protection when the host reports its agent after the command hook.

  • Reject contradictory completion check results, invalid exit codes, excessive per-criterion evidence and structured evidence that exceeds the completion budget.

  • Return structured failures from canonical goal creation when validation fails, including invalid budgets, while preserving legacy tool messages.

  • Honor the configured SDK shape in the built-in completion verifier's create, prompt, timeout abort and cleanup calls.

  • Fix persistence lease acquisition on filesystems that cap timestamps at 2038. New compatibility guards use a representable timestamp, existing 2100 guards remain valid, and expiring guards fail closed.

  • Keep ordinary chat available when goal leases encounter unsupported hard links (including ENOSYS), unsafe lease paths, or an unusable guard timestamp. Goal controls return persistence_unavailable with recovery guidance; migration failures release the session lease before entering passive mode.

0.11.2 — Windows rename retry, zod security bump

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 20:54
867b97f

v0.11.2 — Windows rename retry, zod security bump

Released on 2026-10-29. Release notes backfilled on 2026-10-30 from CHANGELOG.md.

  • On Windows, retry the atomic rename behind goal state and persistence lease saves when it fails with EPERM, EACCES or EBUSY, waiting 10 ms and doubling up to 160 ms (about 0.3 s at most). Windows refuses to rename over a file another process has open, such as antivirus, an indexer or anything reading state.json, and one such failure on the save before an auto-continue paused the goal with continuation claim persistence failed until a manual /goal resume. In a soak that made 3% of state renames fail this way, this cut paused goals from 8 to 0. A lock that outlasts the retries still fails closed as before; other platforms are unchanged.
  • Bump the pinned zod dependency from 4.6.5 to 4.6.7 for GHSA-mrhx-c7xc-m3w5: earlier versions can exhaust memory while validating oversized constrained collections (#88).

0.11.1 — OpenCode 2 Code Mode tool hint, lease liveness check, setup teardown

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 20:54
89b0d2a

v0.11.1 — OpenCode 2 Code Mode tool hint, lease liveness check, setup teardown

Released on 2026-10-18. Release notes backfilled on 2026-10-30 from CHANGELOG.md.

  • On OpenCode 2, tell the model where the goal tools live. OpenCode 2's Code Mode offers plugin tools only inside the execute tool (as tools.goal_status() and so on), while the plugin's prompts name the tools bare, so some models called goal_status directly and reported the goal tools unavailable (#85). When a request offers execute and no direct goal tool, the system prompt now gets a one-line note pointing the model at execute and the Code Mode catalog. Verified on live OpenCode 2.0.16 and 2.0.31 hosts, with the package loaded from global config as in the report: the tools were always registered in the catalog.
  • Never send a liveness signal to the host's own process when checking a persistence lease owner. On Windows, runtimes that emulate POSIX signals may treat kill(pid, 0) as a real termination, which matches reports of the OpenCode service dying silently with the plugin installed (#81).
  • On OpenCode 2, tear down everything a partially failed setup already started (event subscription, timers, hook registrations, and the goal core with its persistence lease) instead of leaking it on every location boot.
  • On Windows, treat / and \ as the same separator when matching a location, so a reload with a differently spelled path retires the previous instance instead of running beside it.
  • Fix completion audits always failing on OpenCode 2.0.26. That host appends a browser deny rule to every agent, and the verifier ownership check compared permissions by exact JSON, so it rejected the plugin's own goal-verify agent and every completion was rejected. The check now accepts extra host-added deny rules, which only narrow access, and still rejects any changed, missing, reordered, allow or ask rule. Verified against live 2.0.16 and 2.0.26 hosts, including the foreign-verifier rejection mode.
  • When the auditor's prompt fails and no verdict reached the transcript, report auditor prompt failed: <reason> instead of the misleading "no single clear final-line verdict".

0.10.0 — Plan-guard and title fixes, cost cap, literal flags, agent authority, pinned installs

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 07 Sep 04:37
dfefe47

v0.10.0 — Plan-guard and title fixes, cost cap, literal flags, agent authority, pinned installs

Two defects reproduced against live OpenCode 1.18.25 and 1.18.29 are fixed, two contributions from forks are ported with credit, agent tools gain an authority setting, and the install docs now explain why an unpinned plugin never updates.

Fixes

Plan-mode guard fails open on a session's first command

OpenCode runs command.execute.before before any chat hook for the turn, and its Session record carries no agent field, so the 0.9.0 "session record fallback" could never learn the agent for a /goal <objective> sent as a fresh session's first turn. The goal started live and the routed text told the model to start working. Reproduced over the HTTP command API with agent: "plan" (the path opencode run --agent plan uses too).

The routed turn does carry the agent. chat.message now re-evaluates the planning-only restriction for the goal that command created and, when the agent is restricted, holds the goal (plan agent active, budget preserved), rewrites the turn as a read-only control turn, and blocks tools for it. A completion marker on that turn does not complete the held goal. Pinned by a new mutation-contract entry.

Stale ▶ in the session title after completion

With sessionTitleStatus, completion archived the goal and the title sync returned early, leaving the last running line on the session until /goal clear. A completed goal now renders as ✅ ship the release · 3 turns · 2m · 45k; /goal clear still restores your original title.

Ported from forks

  • Cost cap — maxCostUsd plugin option and --max-cost per-goal flag. The goal pauses with the usual wrap-up prompt once the cumulative API cost OpenCode reports reaches the cap (max cost reached ($5.00)). /goal status shows Cost budget: $spent/$cap, the continuation budget carries cost_remaining_usd, the near-limit warning fires within 10% of the cap, and goal_set/set_goal accept maxCostUsd. An unknown provider cost never trips the cap; one response may overshoot. Idea and first implementation by @NiklasTR.
  • Fenced literal flags — a ```fence``` in /goal arguments is objective text verbatim: /goal run ```pytest --maxfail=1``` and fix failures no longer rejects with Unsupported flag: --maxfail. Ported from @NiklasTR.

New option

  • agentGoalAuthority — "full" (default, unchanged) or "status". In "status" mode the agent tools may complete, block, pause, resume, and create a goal when none is live, but goal_set/set_goal refuse to replace an active goal (an agent_authority failure envelope on the canonical tool), update_goal refuses objective changes, and clear_goal refuses to clear — a model can no longer rewrite the objective you gave it. Prompted by @felores's fork.

Install docs: pin your version

OpenCode resolves an unpinned "opencode-goal-plugin" entry to @latest once, installs it under ~/.cache/opencode/packages/opencode-goal-plugin@latest/, and never re-resolves while that directory exists. Anyone who followed the old README is still on whichever version they first installed. The README now pins the version ("opencode-goal-plugin@0.10.0"), documents the upgrade path (bump the pin, or delete the cached directory), mentions opencode plugin <name>@<version>, and npx opencode-goal-plugin warns when the unpinned cache lags the package. npm install was never required and is gone from the instructions.

Also

  • zod 4.4.3 → 4.5.4; CodeQL action v4.37.9.
  • OpenCode 1.18.29 added to the compatibility table from a deterministic-provider canary against a real opencode serve process.
  • ledgerFilePath documented; file:// checkouts noted to need node_modules.

Upgrading

Set "plugin": ["opencode-goal-plugin@0.10.0"] and restart OpenCode. If you had an unpinned entry, also delete ~/.cache/opencode/packages/opencode-goal-plugin* (or run npx opencode-goal-plugin@0.10.0 to see whether a stale copy is cached).

0.9.0 — Plan-mode safety and a live status indicator

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 29 Aug 18:31
66dac65

v0.9.0 — Plan-mode safety and a live status indicator

Both features in this release were verified against a live OpenCode 1.18.25 TUI, not unit tests alone.

Plan-mode safety

A goal set while a planning-only agent is active is now recorded but held instead of starting.

Auto-continue already paused when a session switched to Plan mid-goal. This closes the creation path: previously /goal <objective> typed in Plan mode created a live goal and ran the loop before any idle occurred, and the routed command text told the model to start working.

A held goal:

  • records stopReason: plan agent active and keeps its full budget
  • sends zero auto-continues
  • is announced through a read-only control turn that tells the model not to begin work

Run /goal resume after switching to an executing agent to start it.

The active agent is read from the host's execution context, falling back to the session record. That fallback is what makes the restriction work in practice: OpenCode runs command.execute.before before chat.message/chat.params, so the context is empty for the first command in a session — exactly the case a freshly opened Plan-mode session hits.

New options

Option Default Controls
restrictedAgents ["plan"] Agent names treated as planning-only (case-insensitive). [] releases the restriction.
allowGoalExecutionFromPlan false Allow creation and auto-continue while a restricted agent is active.

The default-on behavior is pinned by the mutation contract.

Scope

The restriction stops the goal loop. It cannot stop a model acting on the single routed command turn, because OpenCode's command.execute.before does not fully intercept command text. A held goal's routed text explicitly instructs the model not to begin work, but a non-compliant model may still act once. Build-mode behavior is unchanged.

Session-title status indicator (opt-in)

Set sessionTitleStatus: true to mirror live goal status into the OpenCode session title, which the TUI renders persistently:

▶ ship the release · 3/10 · 2m · 45k/200k

Status icon, objective, auto-continues used / limit, elapsed, and context tokens / budget. ▶ running, ⏸ paused, ⛔ blocked — blocked outranks paused because it needs you, not just a resume.

  • Off by default; it overwrites a user-visible field.
  • The original title is captured before the first overwrite and restored by /goal clear.
  • An unchanged render skips the API call, so read-only commands cost nothing.
  • Refreshes on commands and on idle/compaction/interruption — never on the message.updated events that stream during a turn, keeping API round-trips out of the response path.
  • Status lines written by a previous process are recognized as the plugin's own, so a restart followed by /goal clear cannot promote stale goal status to the session's permanent title.
  • Failures log at debug level and never interrupt the goal loop.

No TUI plugin entrypoint, no @opentui dependencies, no build step.

Compatibility

OpenCode 1.18.25 added to the tested matrix, backed by a real run: the goal command and native goal agent register, session-sharded persistence works, a Plan-mode goal is held with zero auto-continues, and evidence-gated completion closes cleanly with [goal:evidence] + [goal:complete].

The >=1.17.15 <2 engine range already covered it, so no pin change.

OpenCode 2 is documented as unsupported and untested — not known-broken — with a concrete checklist of what a supported claim would require. This plugin is server-only, so its configuration lives entirely in opencode.json on any OpenCode line.

Verification

npm run release:check → exit 0

  • 414 tests
  • mutation contract 68/68 critical mutants killed
  • behavior benchmark score 100
  • type contract (NodeNext + Bundler), command hook smoke, packed host contract, packed tool contract (11 tools)
  • npm audit --omit=dev --audit-level=high → 0 vulnerabilities

Artifact reproducibility: the local pack, the CI workflow artifact, and the published registry tarball are byte-identical — shasum 1294a0aa1120f669b8e159fa782aee14aa2da47a, 24 files, 479,273 bytes unpacked.

Install

npm install opencode-goal-plugin@0.9.0

Full changelog: v0.8.2...v0.9.0

0.8.2 — Compaction guard hardening

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 20:54
3814c8b

v0.8.2 — Compaction guard hardening

Released on 2026-08-21. Release notes backfilled on 2026-10-30 from CHANGELOG.md.

  • Harden the post-compaction goal continuation guard introduced in
    #58. Building on
    the epoch-guard groundwork contributed by
    @harryzhou2000, the stalled-compaction
    circuit breaker no longer misfires on two conditions that OpenCode produces in
    practice:
    • A re-delivered session.compacted event no longer counts as a second
      compaction. Real OpenCode compaction events carry only a sessionID (no
      identity field), so identity-based deduplication could never fire against a
      live host; a duplicate host delivery could therefore trip the two-strike
      breaker and abort the session. Re-deliveries are now recognized by the
      absence of any message activity since the previous compaction.
    • A [goal:complete] or [goal:blocked] reported on the assistant turn that
      a compaction retains as its continuation source is now honored instead of
      being suppressed, so a finished goal is archived rather than driven for one
      more redundant continuation.
  • Remove a productive-turn detection branch that inspected message parts on the
    message.updated event. That event never carries parts (they arrive on
    message.part.updated, which the plugin does not observe), so the check was
    inert; the stalled-compaction breaker resets on assistant output-token
    progress, which a tool-using turn also produces.

0.8.1 — Post-compaction auto-continue fix

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 20:54
36879d7

v0.8.1 — Post-compaction auto-continue fix

Released on 2026-08-07. Release notes backfilled on 2026-10-30 from CHANGELOG.md.

  • Fix goal auto-continue stalling after session compaction: a continuation
    claim for a pre-compaction source turn could match the still-visible tail
    assistant message after compaction and suppress the post-compaction
    continuation until the user nudged the goal. The claim is now invalidated on
    session.compacted, so the loop resumes on the next idle. Contributed by
    @harryzhou2000 in
    #58.
  • Update the bundled zod dependency from 4.1.8 to 4.4.3.

0.8.0 — noInterruptOnUserMessage and noContinueWhileChildrenActive options

Choose a tag to compare

@william-ricchiuti william-ricchiuti released this 30 Oct 20:54
2a0b9bb

v0.8.0 — noInterruptOnUserMessage and noContinueWhileChildrenActive options

Released on 2026-08-06. Release notes backfilled on 2026-10-30 from CHANGELOG.md.

Both new options in this release were contributed by
@harryzhou2000 in
#53.

  • Add noInterruptOnUserMessage plugin option. When true, a new human message steers an active goal — the loop keeps running and the message is included in the next continuation — instead of pausing it with stopReason: "user intervention". The pause-on-intervention default is unchanged.
  • Add noContinueWhileChildrenActive plugin option. When true, auto-continue is deferred while the session has active child sessions (subagents, background tasks), so the goal loop does not prompt the orchestrator over work a child is already doing; the goal stays running and continues on a later idle once the children finish. A child counts as active only while the host reports a non-idle status for it. Each deferral episode records a deferred history event and a status line so /goal status distinguishes "waiting on a subagent" from a hung loop. A deferred goal is re-driven by the child's own idle event, since a parent that is already idle emits no event of its own while a child runs. Hosts that cannot report children/status, and sessions with more concurrent children than the plugin can track, fail open and log once per plugin instance.