tweak: adjust instructions resolving logic

adjust-instructions-logic
Aiden Cline 2026-02-01 12:05:53 -06:00
parent 94baf1f721
commit f2e1dbda16
2 changed files with 106 additions and 17 deletions

View File

@ -16,17 +16,6 @@ const FILES = [
"CONTEXT.md", // deprecated
]
function globalFiles() {
const files = [path.join(Global.Path.config, "AGENTS.md")]
if (!Flag.OPENCODE_DISABLE_CLAUDE_CODE_PROMPT) {
files.push(path.join(os.homedir(), ".claude", "CLAUDE.md"))
}
if (Flag.OPENCODE_CONFIG_DIR) {
files.push(path.join(Flag.OPENCODE_CONFIG_DIR, "AGENTS.md"))
}
return files
}
async function resolveRelative(instruction: string): Promise<string[]> {
if (!Flag.OPENCODE_DISABLE_PROJECT_CONFIG) {
return Filesystem.globUp(instruction, Instance.directory, Instance.worktree).catch(() => [])
@ -81,18 +70,27 @@ export namespace InstructionPrompt {
}
}
for (const file of globalFiles()) {
if (await Bun.file(file).exists()) {
paths.add(path.resolve(file))
break
}
const agentsmd: string[] = []
if (Flag.OPENCODE_CONFIG_DIR) agentsmd.push(path.join(Flag.OPENCODE_CONFIG_DIR, "AGENTS.md"))
agentsmd.push(path.join(Global.Path.config, "AGENTS.md"))
const found: string[] = []
for (const file of agentsmd) {
if (await Bun.file(file).exists()) found.push(path.resolve(file))
}
if (found.length === 0 && !Flag.OPENCODE_DISABLE_CLAUDE_CODE_PROMPT) {
const claude = path.join(Global.Path.home, ".claude", "CLAUDE.md")
if (await Bun.file(claude).exists()) found.push(path.resolve(claude))
}
found.forEach((file) => paths.add(file))
if (config.instructions) {
for (let instruction of config.instructions) {
if (instruction.startsWith("https://") || instruction.startsWith("http://")) continue
if (instruction.startsWith("~/")) {
instruction = path.join(os.homedir(), instruction.slice(2))
instruction = path.join(Global.Path.home, instruction.slice(2))
}
const matches = path.isAbsolute(instruction)
? await Array.fromAsync(

View File

@ -1,9 +1,19 @@
import { describe, expect, test } from "bun:test"
import fs from "fs/promises"
import path from "path"
import { Global } from "../../src/global"
import { InstructionPrompt } from "../../src/session/instruction"
import { Instance } from "../../src/project/instance"
import { tmpdir } from "../fixture/fixture"
const restore = (key: string, value: string | undefined) => {
if (value === undefined) {
delete process.env[key]
return
}
process.env[key] = value
}
describe("InstructionPrompt.resolve", () => {
test("returns empty when AGENTS.md is at project root (already in systemPaths)", async () => {
await using tmp = await tmpdir({
@ -48,3 +58,84 @@ describe("InstructionPrompt.resolve", () => {
})
})
})
describe("InstructionPrompt.systemPaths", () => {
test("includes config and global AGENTS, skips CLAUDE when agents exist", async () => {
const homeValue = process.env["OPENCODE_TEST_HOME"]
const configValue = process.env["OPENCODE_CONFIG_DIR"]
const disableValue = process.env["OPENCODE_DISABLE_CLAUDE_CODE_PROMPT"]
await using config = await tmpdir()
await using home = await tmpdir()
await using project = await tmpdir()
try {
process.env["OPENCODE_CONFIG_DIR"] = config.path
process.env["OPENCODE_TEST_HOME"] = home.path
delete process.env["OPENCODE_DISABLE_CLAUDE_CODE_PROMPT"]
const configAgent = path.join(config.path, "AGENTS.md")
const globalAgent = path.join(Global.Path.config, "AGENTS.md")
const claudeAgent = path.join(Global.Path.home, ".claude", "CLAUDE.md")
await fs.mkdir(path.dirname(globalAgent), { recursive: true })
await fs.mkdir(path.dirname(claudeAgent), { recursive: true })
await Bun.write(configAgent, "# Config")
await Bun.write(globalAgent, "# Global")
await Bun.write(claudeAgent, "# Claude")
await Instance.provide({
directory: project.path,
fn: async () => {
const system = await InstructionPrompt.systemPaths()
expect(system.has(path.resolve(configAgent))).toBe(true)
expect(system.has(path.resolve(globalAgent))).toBe(true)
expect(system.has(path.resolve(claudeAgent))).toBe(false)
},
})
} finally {
await fs.rm(path.join(Global.Path.config, "AGENTS.md"), { force: true })
restore("OPENCODE_TEST_HOME", homeValue)
restore("OPENCODE_CONFIG_DIR", configValue)
restore("OPENCODE_DISABLE_CLAUDE_CODE_PROMPT", disableValue)
}
})
test("uses CLAUDE when no agents exist", async () => {
const homeValue = process.env["OPENCODE_TEST_HOME"]
const configValue = process.env["OPENCODE_CONFIG_DIR"]
const disableValue = process.env["OPENCODE_DISABLE_CLAUDE_CODE_PROMPT"]
await using config = await tmpdir()
await using home = await tmpdir()
await using project = await tmpdir()
try {
process.env["OPENCODE_CONFIG_DIR"] = config.path
process.env["OPENCODE_TEST_HOME"] = home.path
delete process.env["OPENCODE_DISABLE_CLAUDE_CODE_PROMPT"]
const globalAgent = path.join(Global.Path.config, "AGENTS.md")
const claudeAgent = path.join(Global.Path.home, ".claude", "CLAUDE.md")
await fs.rm(globalAgent, { force: true })
await fs.mkdir(path.dirname(claudeAgent), { recursive: true })
await Bun.write(claudeAgent, "# Claude")
await Instance.provide({
directory: project.path,
fn: async () => {
const system = await InstructionPrompt.systemPaths()
expect(system.has(path.resolve(globalAgent))).toBe(false)
expect(system.has(path.resolve(claudeAgent))).toBe(true)
},
})
} finally {
await fs.rm(path.join(Global.Path.config, "AGENTS.md"), { force: true })
restore("OPENCODE_TEST_HOME", homeValue)
restore("OPENCODE_CONFIG_DIR", configValue)
restore("OPENCODE_DISABLE_CLAUDE_CODE_PROMPT", disableValue)
}
})
})