mirror of
https://gitea.toothfairyai.com/ToothFairyAI/tf_code.git
synced 2026-03-30 13:54:01 +00:00
- Rename packages/opencode → packages/tfcode (directory only) - Rename bin/opencode → bin/tfcode (CLI binary) - Rename .opencode → .tfcode (config directory) - Update package.json name and bin field - Update config directory path references (.tfcode) - Keep internal code references as 'opencode' for easy upstream sync - Keep @opencode-ai/* workspace package names This minimal branding approach allows clean merges from upstream opencode repository while providing tfcode branding for users.
171 lines
5.8 KiB
TypeScript
171 lines
5.8 KiB
TypeScript
import { afterEach, beforeEach, describe, expect, test } from "bun:test"
|
|
import path from "path"
|
|
import { InstructionPrompt } from "../../src/session/instruction"
|
|
import { Instance } from "../../src/project/instance"
|
|
import { Global } from "../../src/global"
|
|
import { tmpdir } from "../fixture/fixture"
|
|
|
|
describe("InstructionPrompt.resolve", () => {
|
|
test("returns empty when AGENTS.md is at project root (already in systemPaths)", async () => {
|
|
await using tmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(path.join(dir, "AGENTS.md"), "# Root Instructions")
|
|
await Bun.write(path.join(dir, "src", "file.ts"), "const x = 1")
|
|
},
|
|
})
|
|
await Instance.provide({
|
|
directory: tmp.path,
|
|
fn: async () => {
|
|
const system = await InstructionPrompt.systemPaths()
|
|
expect(system.has(path.join(tmp.path, "AGENTS.md"))).toBe(true)
|
|
|
|
const results = await InstructionPrompt.resolve([], path.join(tmp.path, "src", "file.ts"), "test-message-1")
|
|
expect(results).toEqual([])
|
|
},
|
|
})
|
|
})
|
|
|
|
test("returns AGENTS.md from subdirectory (not in systemPaths)", async () => {
|
|
await using tmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(path.join(dir, "subdir", "AGENTS.md"), "# Subdir Instructions")
|
|
await Bun.write(path.join(dir, "subdir", "nested", "file.ts"), "const x = 1")
|
|
},
|
|
})
|
|
await Instance.provide({
|
|
directory: tmp.path,
|
|
fn: async () => {
|
|
const system = await InstructionPrompt.systemPaths()
|
|
expect(system.has(path.join(tmp.path, "subdir", "AGENTS.md"))).toBe(false)
|
|
|
|
const results = await InstructionPrompt.resolve(
|
|
[],
|
|
path.join(tmp.path, "subdir", "nested", "file.ts"),
|
|
"test-message-2",
|
|
)
|
|
expect(results.length).toBe(1)
|
|
expect(results[0].filepath).toBe(path.join(tmp.path, "subdir", "AGENTS.md"))
|
|
},
|
|
})
|
|
})
|
|
|
|
test("doesn't reload AGENTS.md when reading it directly", async () => {
|
|
await using tmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(path.join(dir, "subdir", "AGENTS.md"), "# Subdir Instructions")
|
|
await Bun.write(path.join(dir, "subdir", "nested", "file.ts"), "const x = 1")
|
|
},
|
|
})
|
|
await Instance.provide({
|
|
directory: tmp.path,
|
|
fn: async () => {
|
|
const filepath = path.join(tmp.path, "subdir", "AGENTS.md")
|
|
const system = await InstructionPrompt.systemPaths()
|
|
expect(system.has(filepath)).toBe(false)
|
|
|
|
const results = await InstructionPrompt.resolve([], filepath, "test-message-2")
|
|
expect(results).toEqual([])
|
|
},
|
|
})
|
|
})
|
|
})
|
|
|
|
describe("InstructionPrompt.systemPaths OPENCODE_CONFIG_DIR", () => {
|
|
let originalConfigDir: string | undefined
|
|
|
|
beforeEach(() => {
|
|
originalConfigDir = process.env["OPENCODE_CONFIG_DIR"]
|
|
})
|
|
|
|
afterEach(() => {
|
|
if (originalConfigDir === undefined) {
|
|
delete process.env["OPENCODE_CONFIG_DIR"]
|
|
} else {
|
|
process.env["OPENCODE_CONFIG_DIR"] = originalConfigDir
|
|
}
|
|
})
|
|
|
|
test("prefers OPENCODE_CONFIG_DIR AGENTS.md over global when both exist", async () => {
|
|
await using profileTmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(path.join(dir, "AGENTS.md"), "# Profile Instructions")
|
|
},
|
|
})
|
|
await using globalTmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(path.join(dir, "AGENTS.md"), "# Global Instructions")
|
|
},
|
|
})
|
|
await using projectTmp = await tmpdir()
|
|
|
|
process.env["OPENCODE_CONFIG_DIR"] = profileTmp.path
|
|
const originalGlobalConfig = Global.Path.config
|
|
;(Global.Path as { config: string }).config = globalTmp.path
|
|
|
|
try {
|
|
await Instance.provide({
|
|
directory: projectTmp.path,
|
|
fn: async () => {
|
|
const paths = await InstructionPrompt.systemPaths()
|
|
expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(true)
|
|
expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(false)
|
|
},
|
|
})
|
|
} finally {
|
|
;(Global.Path as { config: string }).config = originalGlobalConfig
|
|
}
|
|
})
|
|
|
|
test("falls back to global AGENTS.md when OPENCODE_CONFIG_DIR has no AGENTS.md", async () => {
|
|
await using profileTmp = await tmpdir()
|
|
await using globalTmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(path.join(dir, "AGENTS.md"), "# Global Instructions")
|
|
},
|
|
})
|
|
await using projectTmp = await tmpdir()
|
|
|
|
process.env["OPENCODE_CONFIG_DIR"] = profileTmp.path
|
|
const originalGlobalConfig = Global.Path.config
|
|
;(Global.Path as { config: string }).config = globalTmp.path
|
|
|
|
try {
|
|
await Instance.provide({
|
|
directory: projectTmp.path,
|
|
fn: async () => {
|
|
const paths = await InstructionPrompt.systemPaths()
|
|
expect(paths.has(path.join(profileTmp.path, "AGENTS.md"))).toBe(false)
|
|
expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true)
|
|
},
|
|
})
|
|
} finally {
|
|
;(Global.Path as { config: string }).config = originalGlobalConfig
|
|
}
|
|
})
|
|
|
|
test("uses global AGENTS.md when OPENCODE_CONFIG_DIR is not set", async () => {
|
|
await using globalTmp = await tmpdir({
|
|
init: async (dir) => {
|
|
await Bun.write(path.join(dir, "AGENTS.md"), "# Global Instructions")
|
|
},
|
|
})
|
|
await using projectTmp = await tmpdir()
|
|
|
|
delete process.env["OPENCODE_CONFIG_DIR"]
|
|
const originalGlobalConfig = Global.Path.config
|
|
;(Global.Path as { config: string }).config = globalTmp.path
|
|
|
|
try {
|
|
await Instance.provide({
|
|
directory: projectTmp.path,
|
|
fn: async () => {
|
|
const paths = await InstructionPrompt.systemPaths()
|
|
expect(paths.has(path.join(globalTmp.path, "AGENTS.md"))).toBe(true)
|
|
},
|
|
})
|
|
} finally {
|
|
;(Global.Path as { config: string }).config = originalGlobalConfig
|
|
}
|
|
})
|
|
})
|