From a671a6dc3565aff7471dcceb24201896c4f8689a Mon Sep 17 00:00:00 2001 From: GRayHook Date: Wed, 17 Jun 2026 10:04:55 +0700 Subject: [PATCH] =?UTF-8?q?Phase=201:=20add=20trackSkill=20=E2=80=94=20ded?= =?UTF-8?q?upe=20tracked=20skills=20by=20name.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upsert merges sources without reordering the skills list per SPEC §6.1 dedupe and insertion-order rules. Co-authored-by: Cursor --- src/state.ts | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/state.ts b/src/state.ts index 03597b6..89d7bb0 100644 --- a/src/state.ts +++ b/src/state.ts @@ -86,3 +86,34 @@ export function createRuntimeFlags(): RuntimeFlags { autoCompactIntegration: "auto", }; } + +export interface TrackSkillInput { + name: string; + filePath: string; + baseDir: string; + source: SkillSource; + seenAt?: number; +} + +/** Upsert by name, merge sources, preserve insertion order (SPEC §6.1). */ +export function trackSkill(state: ExtensionState, input: TrackSkillInput): void { + const seenAt = input.seenAt ?? Date.now(); + const existing = state.skills.find((skill) => skill.name === input.name); + if (existing) { + existing.filePath = input.filePath; + existing.baseDir = input.baseDir; + existing.lastSeenAt = seenAt; + if (!existing.sources.includes(input.source)) { + existing.sources.push(input.source); + } + return; + } + state.skills.push({ + name: input.name, + filePath: input.filePath, + baseDir: input.baseDir, + firstSeenAt: seenAt, + lastSeenAt: seenAt, + sources: [input.source], + }); +}