-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathplugin.ts
More file actions
121 lines (113 loc) · 3.55 KB
/
Copy pathplugin.ts
File metadata and controls
121 lines (113 loc) · 3.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
* OpenCoder Plugin - Main plugin function
*
* This module exports the plugin function that follows the OpenCode plugin API.
* The plugin provides autonomous development agents for continuous codebase improvement.
*
* Note: Agents are installed via postinstall script since the plugin API
* does not currently support dynamic agent registration.
*/
import type { Hooks, Plugin, PluginInput } from "@opencode-ai/plugin"
/** Plugin metadata for logging */
const PLUGIN_NAME = "opencoder"
/**
* Creates lifecycle hooks for debugging and visibility.
*
* These hooks provide optional logging points for plugin activity.
* Set OPENCODER_DEBUG=1 environment variable to enable debug logging.
*
* @param ctx - Plugin context from OpenCode containing session information
* @returns Hooks object with lifecycle callbacks for `event`, `tool.execute.before`, and `tool.execute.after`
*
* @example
* // Enable debug logging by setting environment variable:
* // OPENCODER_DEBUG=1 opencode @opencoder
*
* @example
* // Debug output format for events:
* // [2026-01-19T12:00:00.000Z] [opencoder] Event received {
* // "directory": "/home/user/project",
* // "type": "session.created",
* // "properties": ["sessionId", "timestamp"]
* // }
*/
function createLifecycleHooks(ctx: PluginInput): Hooks {
const debug = process.env.OPENCODER_DEBUG === "1"
/**
* Logs a debug message with context when OPENCODER_DEBUG=1 is set.
*
* Messages are formatted with ISO timestamp and plugin name prefix,
* followed by the message and context data as pretty-printed JSON.
*
* @param message - The log message describing the event
* @param data - Optional additional context to include in the log output
* @returns void
*
* @example
* // Output when debug is enabled:
* // [2026-01-19T12:00:00.000Z] [opencoder] Tool executing {
* // "directory": "/home/user/project",
* // "tool": "bash",
* // "sessionID": "abc123"
* // }
*/
const log = (message: string, data?: Record<string, unknown>): void => {
if (debug) {
const timestamp = new Date().toISOString()
const prefix = `[${timestamp}] [${PLUGIN_NAME}]`
const context = { directory: ctx.directory, ...data }
console.log(prefix, message, JSON.stringify(context, null, 2))
}
}
return {
/**
* Called on OpenCode events (sessions, messages, etc.)
*/
event: async ({ event }) => {
log("Event received", {
type: event.type,
properties: Object.keys(event.properties),
})
},
/**
* Called before tool execution
*/
"tool.execute.before": async ({ tool, sessionID, callID }, output) => {
log("Tool executing", {
tool,
sessionID,
callID,
argsKeys: Object.keys(output.args || {}),
})
},
/**
* Called after tool execution completes
*/
"tool.execute.after": async ({ tool, sessionID, callID }, output) => {
log("Tool completed", {
tool,
sessionID,
callID,
title: output.title,
outputLength: output.output?.length ?? 0,
})
},
}
}
/**
* The OpenCoder plugin function.
*
* This plugin provides autonomous development agents:
* - opencoder: Main orchestrator that runs the continuous Plan-Build-Commit loop
* - opencoder-planner: Subagent that analyzes codebases and creates development plans
* - opencoder-builder: Subagent that executes tasks with precision
*
* Usage:
* opencode @opencoder
*
* @param ctx - Plugin context provided by OpenCode
* @returns Hooks object with lifecycle callbacks for debugging visibility
*/
export const OpenCoderPlugin: Plugin = async (ctx) => {
return createLifecycleHooks(ctx)
}