From 24fb0d38e5f35000f9cc555a81729faed19d0ffe Mon Sep 17 00:00:00 2001 From: Ramnique Singh <30795890+ramnique@users.noreply.github.com> Date: Fri, 10 Jul 2026 16:17:07 +0530 Subject: [PATCH] fix(x): skill catalog advertises the post-reorg path; legacy path stays an alias MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bundled-skill CATALOG_PREFIX still pointed at the deleted src/application/assistant/skills tree, so the system prompt and the loadSkill example advertised paths that no longer exist — while the real post-reorg path (src/runtime/assembly/skills) was NOT a resolvable alias, so a model referencing the actual source tree got 'Skill not found'. The new path is now canonical in the catalog and tool description; the old prefix is kept as a loadSkill alias because agent snapshots baked before the reorg still carry it. Regression test pins both. Co-Authored-By: Claude Fable 5 --- .../src/runtime/assembly/skills/index.test.ts | 16 ++++++++++++++-- .../core/src/runtime/assembly/skills/index.ts | 7 ++++++- .../x/packages/core/src/runtime/tools/catalog.ts | 2 +- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/apps/x/packages/core/src/runtime/assembly/skills/index.test.ts b/apps/x/packages/core/src/runtime/assembly/skills/index.test.ts index 71056630..5491bcb6 100644 --- a/apps/x/packages/core/src/runtime/assembly/skills/index.test.ts +++ b/apps/x/packages/core/src/runtime/assembly/skills/index.test.ts @@ -103,7 +103,7 @@ describe("skills index (disk skill merge layer)", () => { const skills = await loadSkillsIndex(); const resolved = skills.resolveSkill("meeting-prep"); - expect(resolved?.catalogPath).toBe("src/application/assistant/skills/meeting-prep/skill.ts"); + expect(resolved?.catalogPath).toBe("src/runtime/assembly/skills/meeting-prep/skill.ts"); expect(resolved?.content).not.toContain("DISK CONTENT MARKER"); const catalog = skills.buildSkillCatalog(); @@ -178,7 +178,7 @@ describe("capability activation boundary", () => { summary: "a genuine model-activated skill", content: "guidance", tools: ["file-readText"], - catalogPath: "src/application/assistant/skills/real-skill/skill.ts", + catalogPath: "src/runtime/assembly/skills/real-skill/skill.ts", }; const mixed = [model, eager]; @@ -199,6 +199,18 @@ describe("capability activation boundary", () => { expect(catalog).toContain(id); } }); + + it("resolves bundled skills by the advertised path and by the pre-reorg legacy path", async () => { + // The catalog advertises the post-reorg source path; agent snapshots baked + // before the move still reference the old application/assistant prefix. + // Both must resolve to the same skill. + const { resolveSkill } = await loadSkillsIndex(); + const advertised = resolveSkill("src/runtime/assembly/skills/meeting-prep/skill.ts"); + const legacy = resolveSkill("src/application/assistant/skills/meeting-prep/skill.ts"); + expect(advertised?.id).toBe("meeting-prep"); + expect(legacy?.id).toBe("meeting-prep"); + expect(legacy?.content).toBe(advertised?.content); + }); }); describe("availability (catalog visibility)", () => { diff --git a/apps/x/packages/core/src/runtime/assembly/skills/index.ts b/apps/x/packages/core/src/runtime/assembly/skills/index.ts index a1d35a9b..8d89697d 100644 --- a/apps/x/packages/core/src/runtime/assembly/skills/index.ts +++ b/apps/x/packages/core/src/runtime/assembly/skills/index.ts @@ -31,7 +31,10 @@ import appsSkill from "./apps/skill.js"; import slackSkill from "./slack/skill.js"; const CURRENT_DIR = path.dirname(fileURLToPath(import.meta.url)); -const CATALOG_PREFIX = "src/application/assistant/skills"; +const CATALOG_PREFIX = "src/runtime/assembly/skills"; +// Pre-reorg home of the bundled skills. Agent snapshots baked before the move +// carry loadSkill references under this prefix, so it stays a resolvable alias. +const LEGACY_CATALOG_PREFIX = "src/application/assistant/skills"; // console.log(liveNoteSkill); @@ -355,6 +358,8 @@ for (const entry of bundledEntries) { `skills/${entry.id}/skill.js`, `${CATALOG_PREFIX}/${entry.id}/skill.ts`, `${CATALOG_PREFIX}/${entry.id}/skill.js`, + `${LEGACY_CATALOG_PREFIX}/${entry.id}/skill.ts`, + `${LEGACY_CATALOG_PREFIX}/${entry.id}/skill.js`, absoluteTs, absoluteJs, ]; diff --git a/apps/x/packages/core/src/runtime/tools/catalog.ts b/apps/x/packages/core/src/runtime/tools/catalog.ts index 3a89d86e..dd5b97ea 100644 --- a/apps/x/packages/core/src/runtime/tools/catalog.ts +++ b/apps/x/packages/core/src/runtime/tools/catalog.ts @@ -39,7 +39,7 @@ export const BuiltinTools: z.infer = { loadSkill: { description: "Load a Rowboat skill definition into context by fetching its guidance string", inputSchema: z.object({ - skillName: z.string().describe("Skill identifier or path (e.g., 'workflow-run-ops' or 'src/application/assistant/skills/workflow-run-ops/skill.ts')"), + skillName: z.string().describe("Skill identifier or path (e.g., 'workflow-run-ops' or 'src/runtime/assembly/skills/workflow-run-ops/skill.ts')"), }), execute: async ({ skillName }: { skillName: string }) => { const resolved = resolveSkill(skillName);