Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .opencode/command/commit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
commit and push

make sure it includes a prefix like
docs:
tui:
core:
ci:
ignore:
wip:
8 changes: 8 additions & 0 deletions .opencode/command/hello.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
description: hello world
---

hey there $ARGUMENTS

!`ls`
check out @README.md
31 changes: 11 additions & 20 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions logs/.496fc674ed58d31f8b883da41cc2adb4564aad58-audit.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"keep": {
"days": true,
"amount": 14
},
"auditLog": "/Users/adam/code/opencode/dev/logs/.496fc674ed58d31f8b883da41cc2adb4564aad58-audit.json",
"files": [
{
"date": 1755891797740,
"name": "/Users/adam/code/opencode/dev/logs/mcp-puppeteer-2025-08-22.log",
"hash": "dd9b1f2e98b661ba2f56b91dd9afbdb25e50adbdd52ed1b0eef1d2045235d17c"
}
],
"hashType": "sha256"
}
6 changes: 6 additions & 0 deletions logs/mcp-puppeteer-2025-08-22.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:43:17.765"}
{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:43:17.766"}
{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:46:45.539"}
{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:46:45.540"}
{"level":"info","message":"Starting MCP server","service":"mcp-puppeteer","timestamp":"2025-08-22 14:53:08.159"}
{"level":"info","message":"MCP server started successfully","service":"mcp-puppeteer","timestamp":"2025-08-22 14:53:08.160"}
5 changes: 1 addition & 4 deletions opencode.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
{
"$schema": "https://opencode.ai/config.json",

"mcp": {
"context7": {
"type": "remote",
"url": "https://mcp.context7.com/sse"
},
"weather": {
"type": "local",
"command": ["opencode", "x", "@h1deya/mcp-server-weather"]
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@
"tree-sitter-bash",
"web-tree-sitter"
],
"overrides": {
"zod": "3.25.76"
},
"patchedDependencies": {}
}
1 change: 1 addition & 0 deletions packages/opencode/script/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Config } from "../src/config/config"
import { zodToJsonSchema } from "zod-to-json-schema"

const file = process.argv[2]
console.log(file)

const result = zodToJsonSchema(Config.Info, {
/**
Expand Down
44 changes: 44 additions & 0 deletions packages/opencode/src/command/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import z from "zod"
import { App } from "../app/app"
import { Config } from "../config/config"

export namespace Command {
export const Info = z
.object({
name: z.string(),
description: z.string().optional(),
agent: z.string().optional(),
model: z.string().optional(),
template: z.string(),
})
.openapi({
ref: "Command",
})
export type Info = z.infer<typeof Info>

const state = App.state("command", async () => {
const cfg = await Config.get()

const result: Record<string, Info> = {}

for (const [name, command] of Object.entries(cfg.command ?? {})) {
result[name] = {
name,
agent: command.agent,
model: command.model,
description: command.description,
template: command.template,
}
}

return result
})

export async function get(name: string) {
return state().then((x) => x[name])
}

export async function list() {
return state().then((x) => Object.values(x))
}
}
35 changes: 35 additions & 0 deletions packages/opencode/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,32 @@ export namespace Config {
}
throw new InvalidError({ path: item }, { cause: parsed.error })
}

// Load command markdown files
result.command = result.command || {}
const markdownCommands = [
...(await Filesystem.globUp("command/*.md", Global.Path.config, Global.Path.config)),
...(await Filesystem.globUp(".opencode/command/*.md", app.path.cwd, app.path.root)),
]
for (const item of markdownCommands) {
const content = await Bun.file(item).text()
const md = matter(content)
if (!md.data) continue

const config = {
name: path.basename(item, ".md"),
...md.data,
template: md.content.trim(),
}
const parsed = Command.safeParse(config)
if (parsed.success) {
result.command = mergeDeep(result.command, {
[config.name]: parsed.data,
})
continue
}
throw new InvalidError({ path: item }, { cause: parsed.error })
}
// Migrate deprecated mode field to agent field
for (const [name, mode] of Object.entries(result.mode)) {
result.agent = mergeDeep(result.agent ?? {}, {
Expand Down Expand Up @@ -192,6 +218,14 @@ export namespace Config {
export const Permission = z.union([z.literal("ask"), z.literal("allow"), z.literal("deny")])
export type Permission = z.infer<typeof Permission>

export const Command = z.object({
template: z.string(),
description: z.string().optional(),
agent: z.string().optional(),
model: z.string().optional(),
})
export type Command = z.infer<typeof Command>

export const Agent = z
.object({
model: z.string().optional(),
Expand Down Expand Up @@ -305,6 +339,7 @@ export namespace Config {
theme: z.string().optional().describe("Theme name to use for the interface"),
keybinds: Keybinds.optional().describe("Custom keybind configurations"),
tui: TUI.optional().describe("TUI specific settings"),
command: z.record(z.string(), Command).optional(),
plugin: z.string().array().optional(),
snapshot: z.boolean().optional(),
share: z
Expand Down
4 changes: 2 additions & 2 deletions packages/opencode/src/provider/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export namespace Provider {
},
}
},
async opencode() {
async opencode(input) {
return {
autoload: true,
autoload: Object.keys(input.models).length > 0,
options: {},
}
},
Expand Down
Loading