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);