opencode-architect 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,329 @@
1
+ # OpenCode Architect One-Shot Examples
2
+
3
+ Reference examples for routing decisions. Each shows: request → analysis → agent selection → execution order.
4
+
5
+ ---
6
+
7
+ ## Example 1: Test Baselining Plugin
8
+
9
+ **User Request:**
10
+ > Scaffold a plugin with skill "test-baselining" and command "test-baseline" that takes args init|eval|update. Generalize from example files.
11
+
12
+ **Analysis:**
13
+ - Skill creation → `opencode-skill-creator`
14
+ - Command with argument handling → `opencode-command-crafter`
15
+ - npm package for distribution → `opencode-packager`
16
+
17
+ **Execution:**
18
+ 1. Parallel: `opencode-skill-creator` (SKILL.md + XML template)
19
+ 2. Parallel: `opencode-command-crafter` (command with `$1` placeholder)
20
+ 3. Sequential: `opencode-packager` (package.json + README)
21
+
22
+ ---
23
+
24
+ ## Example 2: MCP Server Integration
25
+
26
+ **User Request:**
27
+ > Add a custom MCP server "my-company-tools" with 5 tools. Scope tools so only the "build" agent can access "deploy-*" tools.
28
+
29
+ **Analysis:**
30
+ - MCP server configuration → `opencode-mcp-integrator`
31
+ - No skill/command/tool creation needed
32
+ - Tool scoping is MCP configuration, not custom tool building
33
+
34
+ **Execution:**
35
+ 1. Single: `opencode-mcp-integrator` - configure server in opencode.json with permission rules
36
+
37
+ **Config produced:**
38
+ ```json
39
+ {
40
+ "mcp": {
41
+ "my-company-tools": {
42
+ "command": "npx",
43
+ "args": ["-y", "@my-company/mcp-server"]
44
+ }
45
+ },
46
+ "permission": {
47
+ "tool": {
48
+ "deploy-*": "deny"
49
+ }
50
+ },
51
+ "agent": {
52
+ "build": {
53
+ "permission": {
54
+ "tool": {
55
+ "deploy-*": "allow"
56
+ }
57
+ }
58
+ }
59
+ }
60
+ }
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Example 3: Commit Message Validator Tool
66
+
67
+ **User Request:**
68
+ > Create a custom tool "validate-commit" that checks commit messages follow conventional commits format. It should work in the current git repo.
69
+
70
+ **Analysis:**
71
+ - Custom tool with schema + execute logic → `opencode-tool-builder`
72
+ - Not a skill (no SKILL.md)
73
+ - Not a command (needs to be callable by agents as a tool)
74
+ - Not MCP (local tool, not external server)
75
+
76
+ **Execution:**
77
+ 1. Single: `opencode-tool-builder` - create plugin with tool definition
78
+
79
+ **Tool structure:**
80
+ ```typescript
81
+ // .opencode/plugins/commit-validator.ts
82
+ import { tool } from "@opencode-ai/plugin"
83
+
84
+ export const CommitValidatorPlugin = async (ctx) => {
85
+ return {
86
+ tool: {
87
+ "validate-commit": tool({
88
+ description: "Validate commit message follows conventional commits",
89
+ args: {
90
+ message: tool.schema.string().describe("Commit message to validate")
91
+ },
92
+ async execute(args, context) {
93
+ const pattern = /^(feat|fix|docs|style|refactor|test|chore)(\(.+\))?:\s.+/
94
+ const valid = pattern.test(args.message)
95
+ return { valid, message: args.message }
96
+ }
97
+ })
98
+ }
99
+ }
100
+ }
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Example 4: Code Review Agent
106
+
107
+ **User Request:**
108
+ > Create a "pr-reviewer" agent that reviews pull requests. It should have access to github tools but not bash or write tools. Load the "git-release" skill automatically.
109
+
110
+ **Analysis:**
111
+ - Agent definition with permissions → `opencode-agent-designer`
112
+ - Needs specific tool allowlist/denylist
113
+ - Skill pre-loading configuration
114
+ - Not creating a skill, just referencing existing one
115
+
116
+ **Execution:**
117
+ 1. Single: `opencode-agent-designer` - create agent frontmatter
118
+
119
+ **Agent structure:**
120
+ ```markdown
121
+ ---
122
+ name: pr-reviewer
123
+ description: Review pull requests with security and quality focus
124
+ tools:
125
+ bash: false
126
+ write: false
127
+ edit: false
128
+ github: true
129
+ read: true
130
+ grep: true
131
+ glob: true
132
+ permission:
133
+ skill:
134
+ "git-release": "allow"
135
+ model: anthropic/claude-3.5-sonnet
136
+ ---
137
+
138
+ ## Role
139
+ Review PRs for code quality, security vulnerabilities, and test coverage.
140
+
141
+ ## Workflow
142
+ 1. Fetch PR diff using github tools
143
+ 2. Analyze changes for patterns and issues
144
+ 3. Provide structured feedback
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Example 5: Multi-Component Plugin Package
150
+
151
+ **User Request:**
152
+ > Create a distributable package "opencode-devtools" that includes: a skill "debug-workflow", a command "/debug" that loads the skill, and a plugin that auto-injects environment variables.
153
+
154
+ **Analysis:**
155
+ - Skill creation → `opencode-skill-creator`
156
+ - Command creation → `opencode-command-crafter`
157
+ - Plugin with hooks → `opencode-plugin-engineer`
158
+ - Package bundling → `opencode-packager`
159
+
160
+ **Execution:**
161
+ 1. Parallel: `opencode-skill-creator` (debug-workflow SKILL.md)
162
+ 2. Parallel: `opencode-command-crafter` (debug.md command)
163
+ 3. Parallel: `opencode-plugin-engineer` (env-inject plugin)
164
+ 4. Sequential: `opencode-packager` (package all into distributable)
165
+
166
+ **Package structure:**
167
+ ```
168
+ opencode-devtools/
169
+ ├── package.json
170
+ ├── .opencode/
171
+ │ ├── skills/debug-workflow/SKILL.md
172
+ │ ├── commands/debug.md
173
+ │ └── plugins/env-inject.ts
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Example 6: Local-Only Session Notification Plugin (plugin-engineer, NOT packager)
179
+
180
+ **User Request:**
181
+ > Create a plugin that sends a desktop notification when a session completes or errors. This is for my local machine only, not for publishing.
182
+
183
+ **Analysis:**
184
+ - Plugin with event hooks → `opencode-plugin-engineer`
185
+ - **NOT** packager because:
186
+ - No npm distribution needed
187
+ - No skills or commands to bundle
188
+ - Single local plugin file, not a package
189
+ - User explicitly said "local machine only"
190
+
191
+ **Execution:**
192
+ 1. Single: `opencode-plugin-engineer` - create local plugin with event hooks
193
+
194
+ **Plugin structure:**
195
+ ```typescript
196
+ // .opencode/plugins/session-notify.ts
197
+ import type { Plugin } from "@opencode-ai/plugin"
198
+
199
+ export const SessionNotifyPlugin: Plugin = async ({ $ }) => {
200
+ return {
201
+ "session.idle": async () => {
202
+ await $`osascript -e 'display notification "Session complete" with title "OpenCode"'`
203
+ },
204
+ "session.error": async ({ event }) => {
205
+ await $`osascript -e 'display notification "Session error" with title "OpenCode"'`
206
+ }
207
+ }
208
+ }
209
+ ```
210
+
211
+ **Key distinction:**
212
+ | Use `plugin-engineer` when... | Use `packager` when... |
213
+ | ------------------------------------ | ----------------------------------- |
214
+ | Local-only plugin | Local package for sharing |
215
+ | Event hooks / behavior modification | Bundling skills + commands as assets|
216
+ | Single `.ts`/`.js` file | Full package structure with package.json |
217
+ | No distribution intent | Intended for local file:// sharing |
218
+ | Injecting env vars, notifications | Combining multiple opencode artifacts |
219
+
220
+ ---
221
+
222
+ ## Example 7: Plugin with Embedded Static Instructions (plugin-engineer, NOT packager)
223
+
224
+ **User Request:**
225
+ > Create a customer support plugin that injects a "support-agent" prompt into sessions. The prompt should be embedded in the plugin file itself, not as separate files.
226
+
227
+ **Analysis:**
228
+ - Plugin that injects static content → `opencode-plugin-engineer`
229
+ - **NOT** packager because:
230
+ - Instructions are embedded as string literals in code
231
+ - No separate `.md` files to bundle
232
+ - Content is generated/managed programmatically within the plugin
233
+ - Not a distributable asset package
234
+
235
+ **Execution:**
236
+ 1. Single: `opencode-plugin-engineer` - create plugin with embedded prompt string
237
+
238
+ **Plugin structure:**
239
+ ```typescript
240
+ // .opencode/plugins/support-agent.ts
241
+ import type { Plugin } from "@opencode-ai/plugin"
242
+
243
+ const SUPPORT_AGENT_PROMPT = `
244
+ You are a customer support agent for Acme Corp.
245
+
246
+ ## Guidelines
247
+ - Be empathetic and professional
248
+ - Escalate technical issues to engineering
249
+ - Never share internal policies with customers
250
+
251
+ ## Response Format
252
+ 1. Acknowledge the issue
253
+ 2. Provide solution or next steps
254
+ 3. Offer additional help
255
+ `
256
+
257
+ export const SupportAgentPlugin: Plugin = async ({ client }) => {
258
+ return {
259
+ "session.created": async ({ event }) => {
260
+ await client.context.inject(SUPPORT_AGENT_PROMPT)
261
+ }
262
+ }
263
+ }
264
+ ```
265
+
266
+ **Key distinction from packager:**
267
+
268
+ | Use `plugin-engineer` when... | Use `packager` when... |
269
+ | ------------------------------------------------ | ---------------------------------- |
270
+ | Instructions embedded as string in code | Separate `.md` files as assets |
271
+ | Content generated programmatically | Static markdown files to distribute|
272
+ | Single file contains logic + content | Package structure with multiple files |
273
+ | Runtime-generated prompts | Pre-authored skill/command files |
274
+ | Agent definitions with inline prompts | Skill SKILL.md + command .md bundles |
275
+
276
+ **Real-world pattern (reference):**
277
+ ```typescript
278
+ // Agent with embedded prompt - NO separate .md files
279
+ export const agent: AgentConfig = {
280
+ name: "data-analyzer",
281
+ prompt: `
282
+ Analyze data files and produce reports.
283
+
284
+ ## Steps
285
+ 1. Read input files
286
+ 2. Parse and validate
287
+ 3. Generate summary statistics
288
+ `
289
+ }
290
+ ```
291
+
292
+ ---
293
+
294
+ ## Example 8: Extract Quality Baseline Pattern
295
+
296
+ **User Request:**
297
+ > I've built a quality baseline check in my project that runs lint, tests, and coverage on every commit. I want to extract this into a reusable skill I can use across all my projects.
298
+
299
+ **Analysis:**
300
+ - Extraction workflow: analyze existing pattern → generalize → package
301
+ - Existing pattern in .opencode/ → `opencode-extension-auditor`
302
+ - Generalize into skill → `opencode-skill-creator`
303
+ - Package for local sharing → `opencode-packager`
304
+
305
+ **Execution:**
306
+ 1. Sequential: `opencode-extension-auditor` (analyze what exists in .opencode/)
307
+ 2. Sequential: `opencode-skill-creator` (generalize into a skill)
308
+ 3. Ask: "Would you like to package this for local sharing across projects?"
309
+ 4. If yes, Sequential: `opencode-packager` (create distributable package)
310
+
311
+ ---
312
+
313
+ ## Example 9: Extract and Publish MCP Toolset
314
+
315
+ **User Request:**
316
+ > I created some MCP tools in my company's internal repo. I want to extract them, package them as a local package, and eventually publish to our org's npm.
317
+
318
+ **Analysis:**
319
+ - Extraction + packaging + publishing pipeline
320
+ - MCP tools already configured → audit the MCP setup
321
+ - Extract tools into a plugin package → `opencode-packager`
322
+ - Publish to org npm → `opencode-publisher`
323
+
324
+ **Execution:**
325
+ 1. Sequential: `opencode-extension-auditor` (analyze MCP server configuration and tools)
326
+ 2. Sequential: `opencode-plugin-engineer` (if MCP tools need refactoring into a proper plugin)
327
+ 3. Sequential: `opencode-packager` (package for local sharing first)
328
+ 4. Ask: "Package ready. Publish to npm?"
329
+ 5. If yes, Sequential: `opencode-publisher` (transform and publish)
@@ -0,0 +1,109 @@
1
+ TEMPLATE INSTRUCTIONS
2
+ ====================
3
+ Replace the following placeholders before use:
4
+
5
+ CLI NAME
6
+ "opencode-myextension" → your CLI command name (matches package.json bin field)
7
+
8
+ VERSION
9
+ "1.0.0" → initial version
10
+
11
+ COMMANDS
12
+ "install" → install subcommand
13
+ "uninstall" → uninstall subcommand
14
+ "status" → status subcommand
15
+
16
+ SCOPE
17
+ "local" → default scope when --scope not specified
18
+
19
+ ---
20
+ #!/usr/bin/env bun
21
+ import { parseArgs } from "node:util";
22
+ import { install, uninstall, status, type Scope } from "./src/installer.ts";
23
+
24
+ const VERSION = JSON.parse(
25
+ await Bun.file(`${import.meta.dirname}/../package.json`).text()
26
+ ).version;
27
+
28
+ function printHelp(): void {
29
+ console.log(`
30
+ opencode-myextension v${VERSION}
31
+
32
+ Commands:
33
+ install Install the myextension skill and command
34
+ uninstall Remove the myextension skill and command
35
+ status Check installation status
36
+
37
+ Options:
38
+ -s, --scope <scope> Installation scope: "local" or "global"
39
+ -f, --force Skip confirmation prompts
40
+ -h, --help Show this help message
41
+ -v, --version Show version
42
+
43
+ Examples:
44
+ opencode-myextension install
45
+ opencode-myextension install --scope global
46
+ opencode-myextension uninstall --scope local
47
+ opencode-myextension status
48
+ `);
49
+ }
50
+
51
+ async function main(): Promise<void> {
52
+ const { positionals, values } = parseArgs({
53
+ options: {
54
+ scope: { type: "string", short: "s" },
55
+ force: { type: "boolean", short: "f", default: false },
56
+ help: { type: "boolean", short: "h", default: false },
57
+ version: { type: "boolean", short: "v", default: false },
58
+ },
59
+ allowPositionals: true,
60
+ strict: true,
61
+ });
62
+
63
+ if (values.version) { console.log(`opencode-myextension v${VERSION}`); process.exit(0); }
64
+ if (values.help || positionals.length === 0) { printHelp(); process.exit(0); }
65
+
66
+ const command = positionals[0];
67
+ const scope: Scope | undefined = values.scope as Scope | undefined;
68
+ const force: boolean = values.force;
69
+
70
+ if (scope && scope !== "local" && scope !== "global") {
71
+ console.error(`Invalid scope: ${scope}. Must be "local" or "global".`);
72
+ process.exit(1);
73
+ }
74
+
75
+ try {
76
+ switch (command) {
77
+ case "install": {
78
+ const installScope = scope || "local";
79
+ const result = await install(installScope, process.cwd());
80
+ console.log(`Installed ${installScope}:`);
81
+ console.log(` Skill: ${result.skillPath}`);
82
+ console.log(` Command: ${result.commandPath}`);
83
+ if (result.migrated) console.log(` Migrated: opencode.json → .opencode/opencode.json`);
84
+ break;
85
+ }
86
+ case "uninstall": {
87
+ const uninstallScope = scope || "local";
88
+ const result = await uninstall(uninstallScope, process.cwd());
89
+ console.log(`Uninstalled ${uninstallScope}:`);
90
+ console.log(` Removed: ${result.removed.join(", ")}`);
91
+ break;
92
+ }
93
+ case "status": {
94
+ const result = await status(process.cwd());
95
+ console.log("Status:");
96
+ if (result.local) console.log(` Local: installed=${result.local.installed}, version=${result.local.version}`);
97
+ if (result.global) console.log(` Global: installed=${result.global.installed}, version=${result.global.version}`);
98
+ break;
99
+ }
100
+ default: console.error(`Unknown command: ${command}`); printHelp(); process.exit(1);
101
+ }
102
+ } catch (error) {
103
+ const message = error instanceof Error ? error.message : String(error);
104
+ console.error(`Error: ${message}`);
105
+ process.exit(1);
106
+ }
107
+ }
108
+
109
+ main();
@@ -0,0 +1,15 @@
1
+ TEMPLATE INSTRUCTIONS
2
+ ====================
3
+ Replace the following placeholders before use:
4
+
5
+ EXTENSION NAME
6
+ "myextension" → your extension identifier (e.g., "mytool")
7
+
8
+ SKILL NAME
9
+ "myextension" → must match the folder name in assets/skills/
10
+
11
+ COMMAND NAME
12
+ "my-command.md" → your command file name in assets/commands/
13
+
14
+ ---
15
+ export { default } from "./plugin.ts";