Plugin
Tulis plugin Anda sendiri untuk memperluas Dropstone.
Plugin memungkinkan Anda memperluas Dropstone dengan menghubungkan ke berbagai peristiwa dan menyesuaikan perilaku. Anda dapat membuat plugin untuk menambahkan fitur baru, mengintegrasikan dengan layanan eksternal, atau memodifikasi perilaku default Dropstone.
Gunakan plugin
Ada dua cara untuk memuat plugin.
Dari file lokal
Tempatkan file JavaScript atau TypeScript di direktori plugin.
.dropstone/plugins/- Plugin tingkat proyek~/.config/dropstone/plugins/- Plugin global
File di direktori ini secara otomatis dimuat saat startup.
Dari npm
Tentukan paket npm di file konfigurasi Anda.
{
"$schema": "https://dropstone.io/schema/config.json",
"plugin": ["@my-org/internal-plugin", "dropstone-notify-on-idle"]
}
Paket npm reguler dan scoped didukung.
Cara plugin diinstal
Plugin npm diinstal secara otomatis menggunakan Bun saat startup. Paket dan dependensinya di-cache di ~/.cache/dropstone/node_modules/.
Plugin lokal dimuat langsung dari direktori plugin. Untuk menggunakan paket eksternal, Anda harus membuat package.json dalam direktori konfigurasi Anda (lihat Dependencies), atau publikasikan plugin ke npm dan tambahkan ke konfigurasi Anda.
Urutan pemuatan
Plugin dimuat dari semua sumber dan semua hook berjalan secara berurutan. Urutan pemuatan adalah:
- Konfigurasi global (
~/.config/dropstone/dropstone.json) - Konfigurasi proyek (
dropstone.json) - Direktori plugin global (
~/.config/dropstone/plugins/) - Direktori plugin proyek (
.dropstone/plugins/)
Paket npm duplikat dengan nama dan versi yang sama dimuat sekali. Namun, plugin lokal dan plugin npm dengan nama serupa keduanya dimuat secara terpisah.
Buat plugin
Plugin adalah modul JavaScript/TypeScript yang mengekspor satu atau lebih fungsi plugin. Setiap fungsi menerima objek konteks dan mengembalikan objek hooks.
Dependencies
Plugin lokal dan alat kustom dapat menggunakan paket npm eksternal. Tambahkan package.json ke direktori konfigurasi Anda dengan dependensi yang Anda butuhkan.
{
"dependencies": {
"shescape": "^2.1.0"
}
}
Dropstone menjalankan bun install saat startup untuk menginstal ini. Plugin dan alat Anda kemudian dapat mengimpornya.
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)
}
},
}
}
Struktur dasar
export const MyPlugin = async ({ project, client, $, directory, worktree }) => {
console.log("Plugin initialized!")
return {
// Hook implementations go here
}
}
Fungsi plugin menerima:
project: Informasi proyek saat ini.directory: Direktori kerja saat ini.worktree: Jalur git worktree.client: Klien Dropstone SDK untuk berinteraksi dengan agen.$: Shell API Bun untuk menjalankan perintah.
Dukungan TypeScript
Untuk plugin TypeScript, Anda dapat mengimpor tipe dari paket plugin:
import type { Plugin } from "@blankline/dropstone-plugin"
export const MyPlugin: Plugin = async ({ project, client, $, directory, worktree }) => {
return {
// Type-safe hook implementations
}
}
Peristiwa
Plugin dapat berlangganan peristiwa seperti yang terlihat di bawah di bagian Contoh. Berikut adalah daftar peristiwa yang berbeda yang tersedia.
Peristiwa Perintah
command.executed
Peristiwa File
file.editedfile.watcher.updated
Peristiwa Instalasi
installation.updated
Peristiwa LSP
lsp.client.diagnosticslsp.updated
Peristiwa Pesan
message.part.removedmessage.part.updatedmessage.removedmessage.updated
Peristiwa Izin
permission.askedpermission.replied
Peristiwa Server
server.connected
Peristiwa Sesi
session.createdsession.compactedsession.deletedsession.diffsession.errorsession.idlesession.statussession.updated
Peristiwa Todo
todo.updated
Peristiwa Shell
shell.env
Peristiwa Alat
tool.execute.aftertool.execute.before
Contoh
Berikut adalah beberapa contoh plugin yang dapat Anda gunakan untuk memperluas dropstone.
Kirim notifikasi
Kirim notifikasi ketika peristiwa tertentu terjadi:
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 "dropstone"'`
}
},
}
}
Kami menggunakan osascript untuk menjalankan AppleScript di macOS. Di sini kami menggunakannya untuk mengirim notifikasi.
Perlindungan .env
Cegah dropstone dari membaca file .env:
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")
}
},
}
}
Injeksi variabel lingkungan
Injeksi variabel lingkungan ke semua eksekusi shell (alat AI dan terminal pengguna):
export const InjectEnvPlugin = async () => {
return {
"shell.env": async (input, output) => {
output.env.MY_API_KEY = "secret"
output.env.PROJECT_ROOT = input.cwd
},
}
}
Alat kustom
Plugin juga dapat menambahkan alat kustom ke dropstone:
import { type Plugin, tool } from "@blankline/dropstone-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})`
},
}),
},
}
}
Helper tool membuat alat kustom yang dapat dipanggil dropstone. Ini mengambil fungsi skema Zod dan mengembalikan definisi alat dengan:
description: Apa yang dilakukan alatargs: Skema Zod untuk argumen alatexecute: Fungsi yang berjalan ketika alat dipanggil
Alat kustom Anda akan tersedia untuk dropstone bersama dengan alat bawaan.
Note:
Jika alat plugin menggunakan nama yang sama dengan alat bawaan, alat plugin memiliki prioritas.
Logging
Gunakan client.app.log() alih-alih console.log untuk logging terstruktur:
export const MyPlugin = async ({ client }) => {
await client.app.log({
body: {
service: "my-plugin",
level: "info",
message: "Plugin initialized",
extra: { foo: "bar" },
},
})
}
Level: debug, info, warn, error. Lihat referensi SDK untuk detail.
Hook pemadatan
Sesuaikan konteks yang disertakan ketika sesi dipadatkan:
import type { Plugin } from "@blankline/dropstone-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
`)
},
}
}
Hook experimental.session.compacting diaktifkan sebelum LLM menghasilkan ringkasan kelanjutan. Gunakan untuk menyuntikkan konteks khusus domain yang akan dilewatkan oleh prompt pemadatan default.
Anda juga dapat mengganti prompt pemadatan sepenuhnya dengan mengatur output.prompt:
import type { Plugin } from "@blankline/dropstone-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 long-running coding session.
Summarize:
1. The current task and its status
2. Which files are being modified
3. Any blockers or open questions
4. The next steps to complete the work
Format as a structured prompt the next session can use to resume work.
`
},
}
}
Ketika output.prompt diatur, itu sepenuhnya menggantikan prompt pemadatan default. Array output.context diabaikan dalam hal ini.