|
@@ -395,27 +395,52 @@ export namespace Config {
|
|
|
})
|
|
})
|
|
|
export type PermissionRule = z.infer<typeof PermissionRule>
|
|
export type PermissionRule = z.infer<typeof PermissionRule>
|
|
|
|
|
|
|
|
|
|
+ // Capture original key order before zod reorders, then rebuild in original order
|
|
|
|
|
+ const permissionPreprocess = (val: unknown) => {
|
|
|
|
|
+ if (typeof val === "object" && val !== null && !Array.isArray(val)) {
|
|
|
|
|
+ return { __originalKeys: Object.keys(val), ...val }
|
|
|
|
|
+ }
|
|
|
|
|
+ return val
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const permissionTransform = (x: unknown): Record<string, PermissionRule> => {
|
|
|
|
|
+ if (typeof x === "string") return { "*": x as PermissionAction }
|
|
|
|
|
+ const obj = x as { __originalKeys?: string[] } & Record<string, unknown>
|
|
|
|
|
+ const { __originalKeys, ...rest } = obj
|
|
|
|
|
+ if (!__originalKeys) return rest as Record<string, PermissionRule>
|
|
|
|
|
+ const result: Record<string, PermissionRule> = {}
|
|
|
|
|
+ for (const key of __originalKeys) {
|
|
|
|
|
+ if (key in rest) result[key] = rest[key] as PermissionRule
|
|
|
|
|
+ }
|
|
|
|
|
+ return result
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
export const Permission = z
|
|
export const Permission = z
|
|
|
- .object({
|
|
|
|
|
- read: PermissionRule.optional(),
|
|
|
|
|
- edit: PermissionRule.optional(),
|
|
|
|
|
- glob: PermissionRule.optional(),
|
|
|
|
|
- grep: PermissionRule.optional(),
|
|
|
|
|
- list: PermissionRule.optional(),
|
|
|
|
|
- bash: PermissionRule.optional(),
|
|
|
|
|
- task: PermissionRule.optional(),
|
|
|
|
|
- external_directory: PermissionRule.optional(),
|
|
|
|
|
- todowrite: PermissionAction.optional(),
|
|
|
|
|
- todoread: PermissionAction.optional(),
|
|
|
|
|
- webfetch: PermissionAction.optional(),
|
|
|
|
|
- websearch: PermissionAction.optional(),
|
|
|
|
|
- codesearch: PermissionAction.optional(),
|
|
|
|
|
- lsp: PermissionRule.optional(),
|
|
|
|
|
- doom_loop: PermissionAction.optional(),
|
|
|
|
|
- })
|
|
|
|
|
- .catchall(PermissionRule)
|
|
|
|
|
- .or(PermissionAction)
|
|
|
|
|
- .transform((x) => (typeof x === "string" ? { "*": x } : x))
|
|
|
|
|
|
|
+ .preprocess(
|
|
|
|
|
+ permissionPreprocess,
|
|
|
|
|
+ z
|
|
|
|
|
+ .object({
|
|
|
|
|
+ __originalKeys: z.string().array().optional(),
|
|
|
|
|
+ read: PermissionRule.optional(),
|
|
|
|
|
+ edit: PermissionRule.optional(),
|
|
|
|
|
+ glob: PermissionRule.optional(),
|
|
|
|
|
+ grep: PermissionRule.optional(),
|
|
|
|
|
+ list: PermissionRule.optional(),
|
|
|
|
|
+ bash: PermissionRule.optional(),
|
|
|
|
|
+ task: PermissionRule.optional(),
|
|
|
|
|
+ external_directory: PermissionRule.optional(),
|
|
|
|
|
+ todowrite: PermissionAction.optional(),
|
|
|
|
|
+ todoread: PermissionAction.optional(),
|
|
|
|
|
+ webfetch: PermissionAction.optional(),
|
|
|
|
|
+ websearch: PermissionAction.optional(),
|
|
|
|
|
+ codesearch: PermissionAction.optional(),
|
|
|
|
|
+ lsp: PermissionRule.optional(),
|
|
|
|
|
+ doom_loop: PermissionAction.optional(),
|
|
|
|
|
+ })
|
|
|
|
|
+ .catchall(PermissionRule)
|
|
|
|
|
+ .or(PermissionAction),
|
|
|
|
|
+ )
|
|
|
|
|
+ .transform(permissionTransform)
|
|
|
.meta({
|
|
.meta({
|
|
|
ref: "PermissionConfig",
|
|
ref: "PermissionConfig",
|
|
|
})
|
|
})
|