refactor(agent-presets): keep the user-root segment out of the package API

`USER_PRESET_DIR` was exported with no production consumer — only the new test
read it, and a test that imports the implementation constant cannot catch that
constant being wrong. It stays module-internal, and the test spells the segment
it expects.
This commit is contained in:
Yichen Jiang
2026-08-12 11:36:24 +08:00
parent dfa2d91dcb
commit 2646da8d56
3 changed files with 13 additions and 7 deletions

View File

@@ -33,6 +33,10 @@ export const COMPOSITION_FILE = 'agent.cordis.yml'
* the installed app can resolve; where a person's own presets go is the same * the installed app can resolve; where a person's own presets go is the same
* place in every deployment that does not say otherwise, so a launcher that * place in every deployment that does not say otherwise, so a launcher that
* forgets to configure one still finds them. * forgets to configure one still finds them.
*
* Package-internal on purpose: no consumer outside this package addresses the
* directory by name, and a test that imported it could not catch this value
* being wrong — the expected segment is spelled out where it is asserted.
*/ */
export const USER_PRESET_DIR = '.agent-presets' export const USER_PRESET_DIR = '.agent-presets'

View File

@@ -50,7 +50,7 @@ export const AgentPresetSettingsSchema: z<AgentPresetSettings> = z.object({
default: z.string(), default: z.string(),
}) })
export { COMPOSITION_FILE, discoverPresets, scanRoot, USER_PRESET_DIR } from './discovery.ts' export { COMPOSITION_FILE, discoverPresets, scanRoot } from './discovery.ts'
export { export {
METADATA_FILE, readPresetMetadata, renderPresetMetadata, type PresetMetadata, METADATA_FILE, readPresetMetadata, renderPresetMetadata, type PresetMetadata,
} from './metadata.ts' } from './metadata.ts'

View File

@@ -19,10 +19,12 @@ import { Context } from '@deepseek-ai/cordis'
import Loader from '@deepseek-ai/cordis-plugin-loader' import Loader from '@deepseek-ai/cordis-plugin-loader'
import Include from '@deepseek-ai/cordis-plugin-include' import Include from '@deepseek-ai/cordis-plugin-include'
import { afterEach, beforeEach, describe, expect, it } from 'vitest' import { afterEach, beforeEach, describe, expect, it } from 'vitest'
import AgentPresets, { COMPOSITION_FILE, USER_PRESET_DIR, type Config } from '@deepseek-ai/dsh-agent-presets' import AgentPresets, { COMPOSITION_FILE, type Config } from '@deepseek-ai/dsh-agent-presets'
const FIXTURES = join(dirname(fileURLToPath(import.meta.url)), 'fixtures') const FIXTURES = join(dirname(fileURLToPath(import.meta.url)), 'fixtures')
const SYSTEM_ROOT = join(FIXTURES, 'system') const SYSTEM_ROOT = join(FIXTURES, 'system')
/** Spelled out rather than imported: the convention is what these tests assert. */
const USER_ROOT_SEGMENT = '.agent-presets'
const VALID = '- id: tool-alpha\n name: ../../plugins/contribute.js\n config:\n tool: alpha\n' const VALID = '- id: tool-alpha\n name: ../../plugins/contribute.js\n config:\n tool: alpha\n'
let home: string let home: string
@@ -56,8 +58,8 @@ async function roster(config: Partial<Config> = {}): Promise<Context> {
/** Hand-place a preset directory under the harness home's preset root. */ /** Hand-place a preset directory under the harness home's preset root. */
async function seedHomePreset(id: string): Promise<void> { async function seedHomePreset(id: string): Promise<void> {
await mkdir(join(home, USER_PRESET_DIR, id), { recursive: true }) await mkdir(join(home, USER_ROOT_SEGMENT, id), { recursive: true })
await writeFile(join(home, USER_PRESET_DIR, id, COMPOSITION_FILE), VALID) await writeFile(join(home, USER_ROOT_SEGMENT, id, COMPOSITION_FILE), VALID)
} }
describe('the harness-home preset root', () => { describe('the harness-home preset root', () => {
@@ -79,7 +81,7 @@ describe('the harness-home preset root', () => {
expect(listed.find(preset => preset.id === 'mine')).toMatchObject({ trust: 'user' }) expect(listed.find(preset => preset.id === 'mine')).toMatchObject({ trust: 'user' })
expect((await ctx.agentPresets.resolve('mine')).path) expect((await ctx.agentPresets.resolve('mine')).path)
.toBe(join(home, USER_PRESET_DIR, 'mine', COMPOSITION_FILE)) .toBe(join(home, USER_ROOT_SEGMENT, 'mine', COMPOSITION_FILE))
}) })
it('makes a roster with only a system root authorable, and receives the copy', async () => { it('makes a roster with only a system root authorable, and receives the copy', async () => {
@@ -88,7 +90,7 @@ describe('the harness-home preset root', () => {
expect(ctx.agentPresets.authorable).toBe(true) expect(ctx.agentPresets.authorable).toBe(true)
await ctx.agentPresets.copy('standard', 'copied') await ctx.agentPresets.copy('standard', 'copied')
expect(existsSync(join(home, USER_PRESET_DIR, 'copied', COMPOSITION_FILE))).toBe(true) expect(existsSync(join(home, USER_ROOT_SEGMENT, 'copied', COMPOSITION_FILE))).toBe(true)
}) })
it('sorts after every configured root, so a shipped id still shadows a home directory', async () => { it('sorts after every configured root, so a shipped id still shadows a home directory', async () => {
@@ -124,6 +126,6 @@ describe('the harness-home preset root', () => {
await ctx.agentPresets.copy('standard', 'copied') await ctx.agentPresets.copy('standard', 'copied')
expect(existsSync(join(explicit, 'copied', COMPOSITION_FILE))).toBe(true) expect(existsSync(join(explicit, 'copied', COMPOSITION_FILE))).toBe(true)
expect(existsSync(join(home, USER_PRESET_DIR, 'copied'))).toBe(false) expect(existsSync(join(home, USER_ROOT_SEGMENT, 'copied'))).toBe(false)
}) })
}) })