From b99565959bb7a094e339802076d6ad6fd7d7f83c Mon Sep 17 00:00:00 2001 From: Aiden Cline <63023139+rekram1-node@users.noreply.github.com> Date: Wed, 2 Jul 2025 22:27:04 -0500 Subject: [PATCH] feat: configurable instructions (#624) --- packages/opencode/config.schema.json | 7 +++++++ packages/opencode/src/config/config.ts | 4 ++++ packages/opencode/src/session/system.ts | 15 +++++++++++++++ packages/opencode/src/util/filesystem.ts | 24 ++++++++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/packages/opencode/config.schema.json b/packages/opencode/config.schema.json index 6ee406c0..35dfd6f1 100644 --- a/packages/opencode/config.schema.json +++ b/packages/opencode/config.schema.json @@ -297,6 +297,13 @@ }, "description": "MCP (Model Context Protocol) server configurations" }, + "instructions": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional instruction files or patterns to include" + }, "experimental": { "type": "object", "properties": { diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index cf2f3479..eb67778e 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -176,6 +176,10 @@ export namespace Config { .record(z.string(), Mcp) .optional() .describe("MCP (Model Context Protocol) server configurations"), + instructions: z + .array(z.string()) + .optional() + .describe("Additional instruction files or patterns to include"), experimental: z .object({ hook: z diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts index 1c77824b..722964ea 100644 --- a/packages/opencode/src/session/system.ts +++ b/packages/opencode/src/session/system.ts @@ -2,6 +2,7 @@ import { App } from "../app/app" import { Ripgrep } from "../file/ripgrep" import { Global } from "../global" import { Filesystem } from "../util/filesystem" +import { Config } from "../config/config" import path from "path" import os from "os" @@ -55,8 +56,10 @@ export namespace SystemPrompt { "CLAUDE.md", "CONTEXT.md", // deprecated ] + export async function custom() { const { cwd, root } = App.info().path + const config = await Config.get() const found = [] for (const item of CUSTOM_FILES) { const matches = await Filesystem.findUp(item, cwd, root) @@ -72,6 +75,18 @@ export namespace SystemPrompt { .text() .catch(() => ""), ) + + if (config.instructions) { + for (const instruction of config.instructions) { + try { + const matches = await Filesystem.globUp(instruction, cwd, root) + found.push(...matches.map((x) => Bun.file(x).text())) + } catch { + continue // Skip invalid glob patterns + } + } + } + return Promise.all(found).then((result) => result.filter(Boolean)) } diff --git a/packages/opencode/src/util/filesystem.ts b/packages/opencode/src/util/filesystem.ts index bddc4025..c4fd163c 100644 --- a/packages/opencode/src/util/filesystem.ts +++ b/packages/opencode/src/util/filesystem.ts @@ -15,4 +15,28 @@ export namespace Filesystem { } return result } + + export async function globUp(pattern: string, start: string, stop?: string) { + let current = start + const result = [] + while (true) { + try { + const glob = new Bun.Glob(pattern) + for await (const match of glob.scan({ + cwd: current, + onlyFiles: true, + dot: true, + })) { + result.push(join(current, match)) + } + } catch { + // Skip invalid glob patterns + } + if (stop === current) break + const parent = dirname(current) + if (parent === current) break + current = parent + } + return result + } }