---
title: Plugins
description: Skriv dine egne plugins for at udvide OpenCode.
---

Plugins giver dig mulighed for at udvide OpenCode ved at tilslutte sig forskellige begivenheder og tilpasse adfærd. Du kan oprette plugins for at tilføje nye funktioner, integrere med eksterne tjenester eller ændre OpenCodes standardadfærd.

For eksempler, tjek [plugins](/docs/ecosystem#plugins) oprettet af fællesskabet.

---

## Brug af plugin

Der er to måder at indlæse plugins på.

---

### Fra lokale filer

Placer JavaScript- eller TypeScript-filer i plugin-mappen.

- `.opencode/plugins/` - Plugins på projektniveau
- `~/.config/opencode/plugins/` - Globale plugins

Filer i disse mapper indlæses automatisk ved opstart.

---

### Fra npm

Angiv npm-pakker i din konfigurationsfil.

```json title="opencode.json"
{
  "$schema": "https://opencode.ai/config.json",
  "plugin": ["opencode-helicone-session", "opencode-wakatime", "@my-org/custom-plugin"]
}
```

Både almindelige og omfangsrige npm-pakker understøttes.

Gennemse tilgængelige plugins i [ecosystem](/docs/ecosystem#plugins).

---

### Installation af plugins

**npm plugins** installeres automatisk ved hjælp af Bun ved opstart. Pakker og deres afhængigheder cachelagres i `~/.cache/opencode/node_modules/`.

**Lokale plugins** indlæses direkte fra plugin-biblioteket. For at bruge eksterne pakker skal du oprette en `package.json` i din konfigurationsmappe (se [Dependencies](#dependencies)), eller udgive pluginnet til npm og [add it to your config](/docs/config#plugins).

---

### Indlæsningsrækkefølge

Plugins indlæses fra alle kilder, og alle hooks kører i rækkefølge. Indlæsningsrækkefølgen er:

1. Global konfiguration (`~/.config/opencode/opencode.json`)
2. Projektkonfiguration (`opencode.json`)
3. Global plugin-mappe (`~/.config/opencode/plugins/`)
4. Projekt plugin bibliotek (`.opencode/plugins/`)

Dublerede npm-pakker med samme navn og version indlæses én gang. Et lokalt plugin og et npm plugin med lignende navne indlæses dog hver for sig.

---

## Oprettelse af plugin

Et plugin er et **JavaScript/TypeScript modul**, der eksporterer et eller flere plugin
funktioner. Hver funktion modtager et kontekstobjekt og returnerer et hooks-objekt.

---

### Afhængigheder

Lokale plugins og brugerdefinerede værktøjer kan bruge eksterne npm-pakker. Tilføj en `package.json` til din konfigurationsmappe med de afhængigheder, du har brug for.

```json title=".opencode/package.json"
{
  "dependencies": {
    "shescape": "^2.1.0"
  }
}
```

OpenCode kører `bun install` ved opstart for at installere disse. Dine plugins og værktøjer kan derefter importere dem.

```ts title=".opencode/plugins/my-plugin.ts"
import { escape } from "shescape"

export const MyPlugin = async (ctx) => {
  return {
    "tool.execute.before": async (input, output) => {
      if (input.tool === "bash") {
        output.args.command = escape(output.args.command)
      }
    },
  }
}
```

---

### Grundlæggende struktur

```js title=".opencode/plugins/example.js"
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
  console.log("Plugin initialized!")

  return {
    // Hook implementations go here
  }
}
```

Plugin-funktionen modtager:

- `project`: Den aktuelle projektinformation.
- `directory`: Den aktuelle arbejdsmappe.
- `worktree`: Git worktree-stien.
- `client`: En opencode SDK klient til interaktion med AI.
- `$`: Buns [shell API](https://bun.com/docs/runtime/shell) til udførelse af kommandoer.

---

### TypeScript-understøttelse

For TypeScript-plugins kan du importere typer fra plugin-pakken:

```ts title="my-plugin.ts" {1}
import type { Plugin } from "@opencode-ai/plugin"

export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
  return {
    // Type-safe hook implementations
  }
}
```

---

### Begivenheder

Plugins kan abonnere på begivenheder som vist nedenfor i afsnittet Eksempler. Her er en liste over de forskellige arrangementer.

#### Kommandohændelser

- `command.executed`

#### Filhændelser

- `file.edited`
- `file.watcher.updated`

#### Installationshændelser

- `installation.updated`

#### LSP-hændelser

- `lsp.client.diagnostics`
- `lsp.updated`

#### Beskedhændelser

- `message.part.removed`
- `message.part.updated`
- `message.removed`
- `message.updated`

#### Tilladelseshændelser

- `permission.asked`
- `permission.replied`

#### Serverhændelser

- `server.connected`

#### Sessionshændelser

- `session.created`
- `session.compacted`
- `session.deleted`
- `session.diff`
- `session.error`
- `session.idle`
- `session.status`
- `session.updated`

#### Shell-hændelser

- `shell.env`

#### Værktøjshændelser

- `tool.execute.after`
- `tool.execute.before`

#### TUI-hændelser

- `tui.prompt.append`
- `tui.command.execute`
- `tui.toast.show`

---

## Eksempler

Her er nogle eksempler på plugins, du kan bruge til at udvide opencode.

---

### Send meddelelser

Send meddelelser, når visse hændelser indtræffer:

```js title=".opencode/plugins/notification.js"
export const NotificationPlugin = async ({ project, client, $, directory, worktree }) => {
  return {
    event: async ({ event }) => {
      // Send notification on session completion
      if (event.type === "session.idle") {
        await $`osascript -e 'display notification "Session completed!" with title "opencode"'`
      }
    },
  }
}
```

Vi bruger `osascript` til at køre AppleScript på macOS. Her bruger vi det til at sende notifikationer.

:::note
Hvis du bruger OpenCode desktop-appen, kan den sende systemmeddelelser automatisk, når et svar er klar, eller når en session fejler.
:::

---

### .env-beskyttelse

Undgå opencode i at læse `.env` filer:

```javascript title=".opencode/plugins/env-protection.js"
export const EnvProtection = async ({ project, client, $, directory, worktree }) => {
  return {
    "tool.execute.before": async (input, output) => {
      if (input.tool === "read" && output.args.filePath.includes(".env")) {
        throw new Error("Do not read .env files")
      }
    },
  }
}
```

---

### Injicer miljøvariabler

Injicer miljøvariabler i al shell-udførelse (AI-værktøjer og brugerterminaler):

```javascript title=".opencode/plugins/inject-env.js"
export const InjectEnvPlugin = async () => {
  return {
    "shell.env": async (input, output) => {
      output.env.MY_API_KEY = "secret"
      output.env.PROJECT_ROOT = input.cwd
    },
  }
}
```

---

### Brugerdefinerede værktøjer

Plugins kan også tilføje brugerdefinerede værktøjer til opencode:

```ts title=".opencode/plugins/custom-tools.ts"
import { type Plugin, tool } from "@opencode-ai/plugin"

export const CustomToolsPlugin: Plugin = async (ctx) => {
  return {
    tool: {
      mytool: tool({
        description: "This is a custom tool",
        args: {
          foo: tool.schema.string(),
        },
        async execute(args, context) {
          const { directory, worktree } = context
          return `Hello ${args.foo} from ${directory} (worktree: ${worktree})`
        },
      }),
    },
  }
}
```

`tool`-hjælperen opretter et brugerdefineret værktøj, som opencode kan kalde. Det tager en Zod-skemafunktion og returnerer en værktøjsdefinition med:

- `description`: Hvad værktøjet gør
- `args`: Zod-skema for værktøjets argumenter
- `execute`: Funktion, der kører, når værktøjet kaldes

Dine tilpassede værktøjer vil være tilgængelige for opencode sammen med indbyggede værktøjer.

:::note
Hvis et plugin-værktøj bruger samme navn som et indbygget værktøj, har plugin-værktøjet forrang.
:::

---

### Logning

Brug `client.app.log()` i stedet for `console.log` til struktureret logning:

```ts title=".opencode/plugins/my-plugin.ts"
export const MyPlugin = async ({ client }) => {
  await client.app.log({
    body: {
      service: "my-plugin",
      level: "info",
      message: "Plugin initialized",
      extra: { foo: "bar" },
    },
  })
}
```

Niveauer: `debug`, `info`, `warn`, `error`. Se [SDK documentation](https://opencode.ai/docs/sdk) for detaljer.

---

### Komprimerings-hooks

Tilpas konteksten inkluderet, når en session komprimeres:

```ts title=".opencode/plugins/compaction.ts"
import type { Plugin } from "@opencode-ai/plugin"

export const CompactionPlugin: Plugin = async (ctx) => {
  return {
    "experimental.session.compacting": async (input, output) => {
      // Inject additional context into the compaction prompt
      output.context.push(`
## Custom Context

Include any state that should persist across compaction:
- Current task status
- Important decisions made
- Files being actively worked on
`)
    },
  }
}
```

`experimental.session.compacting` krogen affyres, før LLM genererer en fortsættelsesoversigt. Brug den til at injicere domænespecifik kontekst, som standardkomprimeringsprompten ville gå glip af.

Du kan også erstatte komprimeringsprompten helt ved at indstille `output.prompt`:

```ts title=".opencode/plugins/custom-compaction.ts"
import type { Plugin } from "@opencode-ai/plugin"

export const CustomCompactionPlugin: Plugin = async (ctx) => {
  return {
    "experimental.session.compacting": async (input, output) => {
      // Replace the entire compaction prompt
      output.prompt = `
You are generating a continuation prompt for a multi-agent swarm session.

Summarize:
1. The current task and its status
2. Which files are being modified and by whom
3. Any blockers or dependencies between agents
4. The next steps to complete the work

Format as a structured prompt that a new agent can use to resume work.
`
    },
  }
}
```

Når `output.prompt` er indstillet, erstatter den standardkompressionsprompten fuldstændigt. `output.context`-arrayet ignoreres i dette tilfælde.
