feat: assemble resource bundle tool aliases

This commit is contained in:
Codex
2026-06-02 08:50:21 +08:00
parent 83ab1df593
commit 9700d0600f
7 changed files with 90 additions and 8 deletions
+19
View File
@@ -96,6 +96,7 @@ export function validateResourceBundleRef(value: unknown): ResourceBundleRef | n
}
result.sparsePaths = record.sparsePaths as string[];
}
if (record.toolAliases !== undefined) result.toolAliases = validateResourceToolAliases(record.toolAliases);
if (record.submodules !== undefined && record.submodules !== false) throw new AgentRunError("schema-invalid", "resourceBundleRef.submodules can only be false in v0.1", { httpStatus: 400 });
if (record.lfs !== undefined && record.lfs !== false) throw new AgentRunError("schema-invalid", "resourceBundleRef.lfs can only be false in v0.1", { httpStatus: 400 });
if (record.submodules === false) result.submodules = false;
@@ -104,6 +105,24 @@ export function validateResourceBundleRef(value: unknown): ResourceBundleRef | n
return result;
}
function validateResourceToolAliases(value: unknown): NonNullable<ResourceBundleRef["toolAliases"]> {
if (!Array.isArray(value)) throw new AgentRunError("schema-invalid", "resourceBundleRef.toolAliases must be an array", { httpStatus: 400 });
if (value.length > 16) throw new AgentRunError("schema-invalid", "resourceBundleRef.toolAliases must contain at most 16 entries", { httpStatus: 400 });
const seen = new Set<string>();
return value.map((entry, index) => {
const record = asRecord(entry, `resourceBundleRef.toolAliases[${index}]`);
const name = requiredString(record, "name");
if (!/^[a-z][a-z0-9._-]{0,62}$/u.test(name)) throw new AgentRunError("schema-invalid", `resourceBundleRef.toolAliases[${index}].name must be a lowercase command name`, { httpStatus: 400 });
if (seen.has(name)) throw new AgentRunError("schema-invalid", `resourceBundleRef.toolAliases name ${name} is duplicated`, { httpStatus: 400 });
seen.add(name);
const aliasPath = requiredString(record, "path");
if (aliasPath.startsWith("/") || aliasPath.includes("..")) throw new AgentRunError("schema-invalid", `resourceBundleRef.toolAliases[${index}].path must stay within the checkout`, { httpStatus: 400 });
const kind = requiredString(record, "kind");
if (kind !== "node-script" && kind !== "bun-script" && kind !== "sh-script" && kind !== "executable") throw new AgentRunError("schema-invalid", `resourceBundleRef.toolAliases[${index}].kind is not supported in v0.1`, { httpStatus: 400, details: { allowedKinds: ["node-script", "bun-script", "sh-script", "executable"] } });
return { name, path: aliasPath, kind };
});
}
export function validateExecutionPolicy(record: JsonRecord): ExecutionPolicy {
const timeout = record.timeoutMs;
if (typeof timeout !== "number" || !Number.isFinite(timeout) || timeout <= 0) throw new AgentRunError("schema-invalid", "executionPolicy.timeoutMs must be a positive number", { httpStatus: 400 });