(skillName: string)
| 11 | * Updates both usage count and last used timestamp. |
| 12 | */ |
| 13 | export function recordSkillUsage(skillName: string): void { |
| 14 | const now = Date.now() |
| 15 | const lastWrite = lastWriteBySkill.get(skillName) |
| 16 | // The ranking algorithm uses a 7-day half-life, so sub-minute granularity |
| 17 | // is irrelevant. Bail out before saveGlobalConfig to avoid lock + file I/O. |
| 18 | if (lastWrite !== undefined && now - lastWrite < SKILL_USAGE_DEBOUNCE_MS) { |
| 19 | return |
| 20 | } |
| 21 | lastWriteBySkill.set(skillName, now) |
| 22 | saveGlobalConfig(current => { |
| 23 | const existing = current.skillUsage?.[skillName] |
| 24 | return { |
| 25 | ...current, |
| 26 | skillUsage: { |
| 27 | ...current.skillUsage, |
| 28 | [skillName]: { |
| 29 | usageCount: (existing?.usageCount ?? 0) + 1, |
| 30 | lastUsedAt: now, |
| 31 | }, |
| 32 | }, |
| 33 | } |
| 34 | }) |
| 35 | } |
| 36 | |
| 37 | /** |
| 38 | * Calculates a usage score for a skill based on frequency and recency. |
no test coverage detected