Skip to content

Feature Request: Plugin shutdown hook for graceful cleanup #10524

Description

@ErcinDedeoglu

Summary

Add a shutdown/exit hook to the plugin system so plugins can perform cleanup operations before OpenCode exits.

Use Case

I'm developing opencode-sync, a plugin that syncs OpenCode data (sessions, messages, config, etc.) to a private GitHub repository.

The plugin needs to sync local changes to remote before exit to prevent data loss. Currently, there's no way for plugins to:

  1. Know when OpenCode is about to exit
  2. Perform async cleanup operations before process termination

Current Behavior

Looking at the source:

  • packages/plugin/src/index.ts - The Hooks interface only has event hook for Bus events
  • packages/opencode/src/cli/cmd/tui/thread.ts - Has onExit callback but it's internal, not exposed to plugins
  • Session events are Created, Updated, Deleted, Diff, Error - no shutdown event

When OpenCode exits (Ctrl+C, :q, etc.), plugins have no opportunity to run cleanup code.

Proposed Solution

Add a shutdown hook to the plugin Hooks interface:

export interface Hooks {
  event?(input: { event: Bus.Event }): void;
  shutdown?(): Promise<void>;  // New hook
}

The shutdown hook should:

  1. Be called before OpenCode terminates
  2. Support async operations (return Promise)
  3. Have a reasonable timeout (e.g., 5 seconds) to prevent hanging

Alternatives Considered

  1. Node.js process events (beforeExit, SIGINT, SIGTERM) - OpenCode intercepts signals before plugin handlers run
  2. Frequent background syncing - Works but can't guarantee final changes are synced
  3. File watching with debounce - Same limitation, final changes may be lost

Additional Context

This would enable plugins to:

  • Sync data to remote storage
  • Close database connections
  • Flush logs
  • Clean up temporary files
  • Save state

Thank you for considering this feature!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions