core: improve directory validation error messages to help users fix invalid directory names

This commit is contained in:
Dax Raad
2025-10-09 22:40:23 -04:00
parent 096710a8cc
commit 9b52d33889
2 changed files with 25 additions and 17 deletions

View File

@@ -10,6 +10,8 @@ export function FormatError(input: unknown) {
`Config file at ${input.data.path} is not valid JSON(C)` + (input.data.message ? `: ${input.data.message}` : "")
)
}
if (Config.DirectoryError.isInstance(input))
return `Directory "${input.data.dir}" in ${input.data.path} is not valid. Did you mean "${input.data.suggestion}"?`
if (Config.InvalidError.isInstance(input))
return [
`Config file at ${input.data.path} is invalid` + (input.data.message ? `: ${input.data.message}` : ""),

View File

@@ -62,7 +62,7 @@ export namespace Config {
]
for (const dir of directories) {
await assertValid(dir).catch(() => {})
await assertValid(dir)
installDependencies(dir)
result.command = mergeDeep(result.command ?? {}, await loadCommand(dir))
result.agent = mergeDeep(result.agent, await loadAgent(dir))
@@ -120,23 +120,20 @@ export namespace Config {
}
})
const INVALID_DIRS = new Bun.Glob(`{${["agents", "commands", "plugins", "tools"].join(",")}}/`)
async function assertValid(dir: string) {
const ALLOWED_DIRS = new Set(["agent", "command", "mode", "plugin", "tool", "themes"])
const UNEXPECTED_DIR_GLOB = new Bun.Glob("*/")
for await (const item of UNEXPECTED_DIR_GLOB.scan({
absolute: true,
followSymlinks: true,
dot: true,
cwd: dir,
onlyFiles: false,
})) {
const dirname = path.basename(item)
if (!ALLOWED_DIRS.has(dirname)) {
throw new InvalidError({
path: dir,
message: `Unexpected directory "${dirname}" found in "${dir}". Only ${ALLOWED_DIRS.values().toArray().join(", ")} directories are allowed.`,
})
}
const invalid = await Array.fromAsync(
INVALID_DIRS.scan({
onlyFiles: false,
cwd: dir,
}),
)
for (const item of invalid) {
throw new DirectoryError({
path: dir,
dir: item,
suggestion: item.substring(0, item.length - 1),
})
}
}
@@ -714,6 +711,15 @@ export namespace Config {
}),
)
export const DirectoryError = NamedError.create(
"ConfigDirectoryError",
z.object({
path: z.string(),
dir: z.string(),
suggestion: z.string(),
}),
)
export const InvalidError = NamedError.create(
"ConfigInvalidError",
z.object({