Skip to content

feat(plugin): add shutdown hook#16769

Open
RKelln wants to merge 3 commits intoanomalyco:devfrom
RKelln:feat/plugin-shutdown-hook
Open

feat(plugin): add shutdown hook#16769
RKelln wants to merge 3 commits intoanomalyco:devfrom
RKelln:feat/plugin-shutdown-hook

Conversation

@RKelln
Copy link

@RKelln RKelln commented Mar 9, 2026

Issue for this PR

Closes #10524
Related: #10003

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Plugins currently have no way to run cleanup when OpenCode exits. If a plugin manages a long-lived child process (like a database server), Ctrl+C kills it mid-write and corrupts data.

This adds a "shutdown" hook to the Hooks interface. The hook is called during Instance.disposeAll() — the existing shutdown path that both the TUI (worker.ts) and bootstrap.ts already invoke on exit. The implementation registers a dispose callback on the Instance.state() call in Plugin, which iterates the loaded hooks and calls each plugin's shutdown() sequentially. Each hook invocation is wrapped in .catch() so one failing plugin doesn't prevent others from cleaning up.

I also added "shutdown" to the Exclude list on the trigger() type parameter since shutdown takes no input/output args and shouldn't be callable via trigger().

How did you verify your code works?

  • Added two tests in test/plugin/shutdown.test.ts:
    1. Verifies a plugin's shutdown hook is called when Instance.dispose() runs (writes a marker file)
    2. Verifies that a throwing shutdown hook does not prevent subsequent hooks from running (the second test actually caught a bug — the original implementation had no per-hook error handling)
  • All 16 plugin tests pass (bun test test/plugin/ — 14 existing + 2 new)
  • Full typecheck passes across all 13 workspace packages via the pre-push hook (turbo typecheck)

Screenshots / recordings

N/A — no UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Adds a `shutdown` hook to the Hooks interface that is called during
Instance dispose. Plugins can use this to gracefully clean up background
processes (e.g. stop a Dolt SQL server) before OpenCode exits.

The hook is invoked via the dispose callback registered on
Plugin.state(), which is triggered by Instance.disposeAll() on the
existing TUI and bootstrap shutdown paths.

Closes anomalyco#10524

Generated-by: github-copilot/claude-sonnet-4.6
@github-actions github-actions bot added needs:compliance This means the issue will auto-close after 2 hours. and removed needs:compliance This means the issue will auto-close after 2 hours. labels Mar 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

@github-actions github-actions bot added the needs:compliance This means the issue will auto-close after 2 hours. label Mar 9, 2026
@RKelln
Copy link
Author

RKelln commented Mar 9, 2026

Opus written fix, working on local testing and review still, will update when I have.

OK tested locally (TUI only), works with my beads shutdown plugin.

Added docs

Adds two tests for the shutdown hook:
- Verifies shutdown is called during Instance.dispose()
- Verifies a throwing shutdown hook does not prevent others from running

The second test caught a real bug: the dispose callback had no per-hook
error handling, so one failing plugin would skip all subsequent shutdown
hooks. Fixed by adding .catch() around each hook invocation.

Generated-by: github-copilot/claude-opus-4.6
@github-actions github-actions bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Mar 9, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Add shutdown hook to the Events reference list and add an Examples
section showing how to use it for background process cleanup.

Generated-by: claude-opus-4.6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature Request: Plugin shutdown hook for graceful cleanup

1 participant