diff --git a/src/index.ts b/src/index.ts index 58ed041..a44c35e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,7 +1,35 @@ -import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; +import type { ExtensionAPI, Skill } from "@earendil-works/pi-coding-agent"; +import { detectSlashSkill } from "./detect.js"; +import { findRegisteredSkillByName, resolveRegisteredSkills } from "./skills-registry.js"; +import { createInitialState, trackSkill } from "./state.js"; export default function skillReinject(pi: ExtensionAPI): void { - pi.on("session_start", () => { - // Phase 0 shell — hooks wired in later phases + const state = createInitialState(); + let registeredSkills: Skill[] = []; + + pi.on("before_agent_start", async (event) => { + registeredSkills = event.systemPromptOptions.skills ?? registeredSkills; + }); + + pi.on("input", async (event, ctx) => { + if (event.source === "extension") { + return { action: "continue" }; + } + + const skillName = detectSlashSkill(event.text); + if (skillName) { + const skills = resolveRegisteredSkills(ctx.cwd, registeredSkills); + const skill = findRegisteredSkillByName(skills, skillName); + if (skill) { + trackSkill(state, { + name: skill.name, + filePath: skill.filePath, + baseDir: skill.baseDir, + source: "slash", + }); + } + } + + return { action: "continue" }; }); } diff --git a/src/skills-registry.ts b/src/skills-registry.ts new file mode 100644 index 0000000..2f2e3dc --- /dev/null +++ b/src/skills-registry.ts @@ -0,0 +1,27 @@ +import { getAgentDir, loadSkills, type Skill } from "@earendil-works/pi-coding-agent"; + +/** First match on name collision (SPEC §11). */ +export function findRegisteredSkillByName( + skills: readonly Skill[], + name: string, +): Skill | undefined { + return skills.find((skill) => skill.name === name); +} + +/** Mirror resourceLoader skill list when cache is empty (e.g. first user input). */ +export function loadRegisteredSkills(cwd: string): Skill[] { + return loadSkills({ + cwd, + agentDir: getAgentDir(), + skillPaths: [], + includeDefaults: true, + }).skills; +} + +/** Prefer live skills from before_agent_start; fall back to loadSkills (SPEC §6.2). */ +export function resolveRegisteredSkills(cwd: string, cached: readonly Skill[]): Skill[] { + if (cached.length > 0) { + return [...cached]; + } + return loadRegisteredSkills(cwd); +}