Skip to content

Instantly share code, notes, and snippets.

@ahosker
Last active January 29, 2026 08:19
Show Gist options
  • Select an option

  • Save ahosker/267f375a65378bcb9a867fd9a195db1e to your computer and use it in GitHub Desktop.

Select an option

Save ahosker/267f375a65378bcb9a867fd9a195db1e to your computer and use it in GitHub Desktop.
OpenCode Plugins: Terminal Bell

.env Protection

A simple OpenCode Plugin to block access to .env files.

How to Install?

On Linux, save env-protection.ts to ~/.config/opencode/plugin/env-protection.ts.

env-protection.ts

import type { Plugin } from "@opencode-ai/plugin"

export const EnvProtection = async ({ client, $ }) => {
  return {
    tool: {
      execute: {
        before: async (input, output) => {
          if (input.tool === "read" && output.args.filePath.includes(".env")) {
            throw new Error("Do not read .env files");
          }
        },
      },
    },
  };
};

Credit

lkhari

dkarter ~Advanced Version

Terminal Bell

A simple OpenCode plugin to ring the terminal bell once a request is complete.

How to Install?

On Linux, save terminal-bell.ts to ~/.config/opencode/plugin/terminal-bell.ts.

terminal-bell.ts

import type { Plugin } from "@opencode-ai/plugin"

export const TerminalBell: Plugin = async ({ project, client, $, directory, worktree }) => {
  return {
    event: async ({ event }) => {
      if (event.type === "session.idle") {
        console.log("Session went idle")
        await Bun.write(Bun.stdout, "\x07")
      }
    }
  }
}

VS Code

If you are using VSCode & SSH, you need to enable terminalBell in the settings, in a project that will be .vscode/settings.json the settings file can be as simple as:

{
    "accessibility.signals.terminalBell": {
        "sound": "on",
        "announcement": "auto",
    }
}

Credit

CarlosGtrz

@silentjay
Copy link

Here's an version of terminal bell for people on terminal emulators that don't support an audible terminal bell like alacritty

import type { Plugin } from "@opencode-ai/plugin"

export const TerminalBell: Plugin = async ({ project, client, $, directory, worktree }) => {
  return {
    event: async ({ event }) => {
      if (event.type === "session.idle") {
        // Play a system sound (audible bell)
        try {
          await $`paplay /usr/share/sounds/freedesktop/stereo/bell.oga`
        } catch (err) {
          console.warn("Failed to play audible bell:", err)
        }
      }
    }
  }
}

@starhound
Copy link

Use PowerShell for fine audio control.

import { type Plugin } from "@opencode-ai/plugin"

export const ChimePlugin: Plugin = async ({ $ }) => {
  return {
    event: async ({ event }) => {
      // session.idle is the only event we care about for "completion"
      if (event.type === "session.idle") {
        // This PowerShell command plays two distinct beeps
        // 800Hz for 100ms, then 1000Hz for 100ms
        await $`powershell.exe -c "[console]::beep(800, 100); [console]::beep(1000, 100)"`
          .quiet()
          .nothrow();
      }
    },
  };
};

@philharmonie
Copy link

For MacOS:

import type { Plugin } from "@opencode-ai/plugin";

export const TerminalBell: Plugin = async ({
  project,
  client,
  $,
  directory,
  worktree,
}) => {
  return {
    event: async ({ event }) => {
      if (event.type === "session.idle") {
        try {
          await $`afplay /System/Library/Sounds/Glass.aiff`;
        } catch (err) {
          console.warn("Failed to play audible bell:", err);
        }
      }
    },
  };
};

@Sleepful
Copy link

      if (event.type === "session.idle") {
        await Bun.write(Bun.stdout, "\x07")
        try {
          await $`afplay /System/Library/Sounds/Ping.aiff`;
        } catch (err) {
          console.warn("Failed to play audible bell:", err);
        }
      }

This is nice, gets the terminal bell (I have sound off, but I like to use the indication in tmux). Also Ping.aiff is louder it seems.

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