init claude-code
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { getGlobalConfig, saveGlobalConfig } from '../config.js'
|
||||
|
||||
const SKILL_USAGE_DEBOUNCE_MS = 60_000
|
||||
|
||||
// Process-lifetime debounce cache — avoids lock + read + parse on debounced
|
||||
// calls. Same pattern as lastConfigStatTime / globalConfigWriteCount in config.ts.
|
||||
const lastWriteBySkill = new Map<string, number>()
|
||||
|
||||
/**
|
||||
* Records a skill usage for ranking purposes.
|
||||
* Updates both usage count and last used timestamp.
|
||||
*/
|
||||
export function recordSkillUsage(skillName: string): void {
|
||||
const now = Date.now()
|
||||
const lastWrite = lastWriteBySkill.get(skillName)
|
||||
// The ranking algorithm uses a 7-day half-life, so sub-minute granularity
|
||||
// is irrelevant. Bail out before saveGlobalConfig to avoid lock + file I/O.
|
||||
if (lastWrite !== undefined && now - lastWrite < SKILL_USAGE_DEBOUNCE_MS) {
|
||||
return
|
||||
}
|
||||
lastWriteBySkill.set(skillName, now)
|
||||
saveGlobalConfig(current => {
|
||||
const existing = current.skillUsage?.[skillName]
|
||||
return {
|
||||
...current,
|
||||
skillUsage: {
|
||||
...current.skillUsage,
|
||||
[skillName]: {
|
||||
usageCount: (existing?.usageCount ?? 0) + 1,
|
||||
lastUsedAt: now,
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates a usage score for a skill based on frequency and recency.
|
||||
* Higher scores indicate more frequently and recently used skills.
|
||||
*
|
||||
* The score uses exponential decay with a half-life of 7 days,
|
||||
* meaning usage from 7 days ago is worth half as much as usage today.
|
||||
*/
|
||||
export function getSkillUsageScore(skillName: string): number {
|
||||
const config = getGlobalConfig()
|
||||
const usage = config.skillUsage?.[skillName]
|
||||
if (!usage) return 0
|
||||
|
||||
// Recency decay: halve score every 7 days
|
||||
const daysSinceUse = (Date.now() - usage.lastUsedAt) / (1000 * 60 * 60 * 24)
|
||||
const recencyFactor = Math.pow(0.5, daysSinceUse / 7)
|
||||
|
||||
// Minimum recency factor of 0.1 to avoid completely dropping old but heavily used skills
|
||||
return usage.usageCount * Math.max(recencyFactor, 0.1)
|
||||
}
|
||||
Reference in New Issue
Block a user