diff --git a/packages/opencode/src/session/instruction.ts b/packages/opencode/src/session/instruction.ts index 86f73d0fd238..72ae4fe2c748 100644 --- a/packages/opencode/src/session/instruction.ts +++ b/packages/opencode/src/session/instruction.ts @@ -92,6 +92,13 @@ export namespace InstructionPrompt { } } + const rules = await Glob.scan(".opencode/rules/*.{md,mdc}", { + cwd: Instance.directory, + absolute: true, + include: "file", + }).catch(() => []) + rules.forEach((p) => paths.add(path.resolve(p))) + if (config.instructions) { for (let instruction of config.instructions) { if (instruction.startsWith("https://") || instruction.startsWith("http://")) continue diff --git a/packages/opencode/test/session/instruction.test.ts b/packages/opencode/test/session/instruction.test.ts index e0bf94a9500d..a6569266d44f 100644 --- a/packages/opencode/test/session/instruction.test.ts +++ b/packages/opencode/test/session/instruction.test.ts @@ -168,3 +168,18 @@ describe("InstructionPrompt.systemPaths OPENCODE_CONFIG_DIR", () => { } }) }) + +test("loads .opencode/rules/project-rule.md as a system path", async () => { + await using tmp = await tmpdir({ + init: async (dir) => { + await Bun.write(path.join(dir, ".opencode", "rules", "project-rule.md"), "# Project Rule\nDo not break things.") + }, + }) + await Instance.provide({ + directory: tmp.path, + fn: async () => { + const paths = await InstructionPrompt.systemPaths() + expect(paths.has(path.join(tmp.path, ".opencode", "rules", "project-rule.md"))).toBe(true) + }, + }) +})