Files
promptkey/lib/UsageStats.ahk
T
Spark b102a4a206 feat(core): moteur PromptKey — bibliothèque .md, variables, injection, raccourcis
- PromptStore/Frontmatter : un prompt = un fichier Markdown, en-tête au
  sous-ensemble strict du document d'architecture (§7), écriture UTF-8
- VariableEngine : variables typées + automatiques (selection, clipboard,
  date, app, cursor), résolution et profils de destination
- Injector/ClipboardGuard : focus capturé/rendu, presse-papiers sauvegardé
  puis restauré conditionnellement, aucun envoi automatique par défaut
- Search : classement flou insensible aux accents, pondéré par l'usage
- UsageStats (usage.json), HotkeyManager (conflits signalés, jamais muets)
- Settings : config.ini + profils par IA (claude, chatgpt, qwen, terminal…)
- PromptKey.ahk : tray, instance unique, capture du contexte, surveillance
  de la bibliothèque, installation du pack au premier lancement
2026-10-11 10:17:30 -04:00

76 lines
2.4 KiB
AutoHotkey

; UsageStats.ahk — Compteurs d'usage et derniers choix de variables (architecture §15).
; Fichier usage.json à côté de la bibliothèque. Ne contient JAMAIS de valeurs 'password'
; ni le contenu des variables automatiques (sélection / presse-papiers).
class UsageStats {
Path := ""
Data := Map() ; id -> Map(count, last_used, last_values: Map)
__New(path) {
this.Path := path
this.Load()
}
Load() {
this.Data := Map()
if !FileExist(this.Path)
return
try {
raw := FileRead(this.Path, "UTF-8")
parsed := Json.Parse(raw)
if (parsed is Map)
this.Data := parsed
} catch as e {
Util.Log("usage.json illisible, reparti de zéro : " e.Message)
this.Data := Map()
}
}
Save() {
try {
f := FileOpen(this.Path, "w", "UTF-8")
f.Write(Json.Stringify(this.Data, 1))
f.Close()
} catch as e {
Util.Log("Écriture usage.json impossible : " e.Message)
}
}
RecordUse(id, manualValues := "") {
if !this.Data.Has(id)
this.Data[id] := Map("count", 0, "last_used", "", "last_values", Map())
entry := this.Data[id]
entry["count"] := (entry.Has("count") ? Integer(entry["count"]) : 0) + 1
entry["last_used"] := A_Now ; format AHK YYYYMMDDHH24MISS (comparaisons et DateDiff)
if (manualValues is Map) {
if !entry.Has("last_values") || !(entry["last_values"] is Map)
entry["last_values"] := Map()
lv := entry["last_values"]
for name, val in manualValues {
; Les mots de passe et les contextes ne sont jamais mémorisés (§10.4 / §15).
if (name = "password" || name = "selection" || name = "clipboard")
continue
lv[name] := String(val)
}
}
this.Save()
}
LastValues(id) {
if (this.Data.Has(id) && this.Data[id].Has("last_values") && (this.Data[id]["last_values"] is Map))
return this.Data[id]["last_values"]
return Map()
}
Count(id) {
if (this.Data.Has(id) && this.Data[id].Has("count"))
return Integer(this.Data[id]["count"])
return 0
}
Reset() {
this.Data := Map()
this.Save()
}
}