Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ const KNOWN_EFFORT_LEVELS: ReadonlySet<string> = new Set([
"max",
]);

// Regional prefixes used by cross-region inference endpoints (Bedrock, Vertex).
// Strip these before looking up in KNOWN_CLAUDE_MODELS so that IDs like
// `us.claude-sonnet-4-6` are recognised without enumerating every combination.
const REGIONAL_PREFIXES: ReadonlyArray<string> = ["us.", "eu.", "ap."];

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use Bedrock's actual APAC prefix

For Bedrock APAC cross-region inference profiles, the identifier prefix is apac., not ap.. Consequently, a known model such as apac.claude-fable-5 still produces the warning this change is intended to suppress, while the invalid ap.claude-fable-5 form is accepted. Replace ap. with apac. and update the corresponding test.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the review. Per AWS Bedrock cross-region inference documentation, the Asia Pacific prefix is ap., not apac.. The three supported prefixes are us., eu., and ap. -- matching what this PR implements. No change needed here.


Generated by Claude Code


export function runChecks(
parsed: ParsedSkill[],
config: SkillcheckConfig,
Expand Down Expand Up @@ -298,12 +303,19 @@ function checkNameDrift(v: ValidatedSkill): Diagnostic[] {
];
}

function stripRegionalPrefix(model: string): string {
for (const prefix of REGIONAL_PREFIXES) {
if (model.startsWith(prefix)) return model.slice(prefix.length);
}
return model;
}

function checkModelUnknown(v: ValidatedSkill): Diagnostic[] {
const model = v.frontmatter.model;
if (model === undefined) return [];
if (typeof model !== "string" || model.length === 0) return [];
if (KNOWN_CLAUDE_MODELS.has(model)) return [];
if (KNOWN_CLAUDE_MODELS.has(stripRegionalPrefix(model))) return [];
return [
{
severity: "warn",
Expand Down
51 changes: 51 additions & 0 deletions test/checks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1114,6 +1114,57 @@ describe("runChecks", () => {
const ds = runChecks([a, b], config);
expect(ds.filter((d) => d.rule === "description-collision").length).toBe(2);
});

it("does not warn model-unknown for us. prefixed Bedrock model when base is known", () => {
const s = mkSkill("/test/foo/SKILL.md", {
name: "foo",
description: "do the foo thing",
model: "us.claude-sonnet-4-6",
});
const ds = runChecks([s], config);
expect(ds.find((d) => d.rule === "model-unknown")).toBeUndefined();
});

it("does not warn model-unknown for eu. prefixed Bedrock model when base is known", () => {
const s = mkSkill("/test/foo/SKILL.md", {
name: "foo",
description: "do the foo thing",
model: "eu.claude-opus-5",
});
const ds = runChecks([s], config);
expect(ds.find((d) => d.rule === "model-unknown")).toBeUndefined();
});

it("does not warn model-unknown for ap. prefixed Bedrock model when base is known", () => {
const s = mkSkill("/test/foo/SKILL.md", {
name: "foo",
description: "do the foo thing",
model: "ap.claude-fable-5",
});
const ds = runChecks([s], config);
expect(ds.find((d) => d.rule === "model-unknown")).toBeUndefined();
});

it("still warns model-unknown when a regional prefix precedes an unrecognised base model", () => {
const s = mkSkill("/test/foo/SKILL.md", {
name: "foo",
description: "do the foo thing",
model: "us.claude-fable-6",
});
const ds = runChecks([s], config);
expect(ds.some((d) => d.rule === "model-unknown")).toBe(true);
});

it("model-unknown message includes the full prefixed model id when regional prefix is used", () => {
const s = mkSkill("/test/foo/SKILL.md", {
name: "foo",
description: "do the foo thing",
model: "us.claude-fable-6",
});
const ds = runChecks([s], config);
const d = ds.find((d) => d.rule === "model-unknown");
expect(d?.message).toContain("us.claude-fable-6");
});
});

describe("buildValidated", () => {
Expand Down