- 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
95 lines
3.9 KiB
AutoHotkey
95 lines
3.9 KiB
AutoHotkey
; Injector.ahk — SEUL module autorisé à toucher au focus, au presse-papiers et à la frappe
|
|
; simulée pour livrer un prompt (architecture §11.1). Aucun autre module n'appelle
|
|
; Send / A_Clipboard pour l'injection.
|
|
|
|
class Injector {
|
|
Guard := ClipboardGuard()
|
|
SettingsRef := ""
|
|
|
|
__New(settings) {
|
|
this.SettingsRef := settings
|
|
}
|
|
|
|
; options : Map { hwnd, method ("clipboard"|"sendtext"), sendAfter (0/1), sensitive (0/1), cursorFromEnd }
|
|
; Retourne Map { ok, method, error }
|
|
Deliver(text, options) {
|
|
st := this.SettingsRef
|
|
method := options.Has("method") && options["method"] != "" ? options["method"] : st.Method
|
|
hwnd := options.Has("hwnd") ? options["hwnd"] : 0
|
|
if (Trim(text) = "")
|
|
return Map("ok", false, "method", method, "error", "Texte vide : rien à injecter.")
|
|
if (hwnd && !WinExist("ahk_id " hwnd)) {
|
|
; Fenêtre disparue : copie de secours (§11.5).
|
|
A_Clipboard := text
|
|
TrayTip("La fenêtre d'origine a disparu — le prompt a été copié dans le presse-papiers.", "PromptKey")
|
|
return Map("ok", false, "method", method, "error", "Fenêtre cible disparue, prompt copié.")
|
|
}
|
|
|
|
if (method = "sendtext" && StrLen(text) > 4000) {
|
|
TrayTip("Prompt long (" StrLen(text) " caractères) : la frappe simulée sera lente.", "PromptKey")
|
|
}
|
|
|
|
; Rendre le focus à la fenêtre d'origine.
|
|
if (hwnd) {
|
|
try WinActivate("ahk_id " hwnd)
|
|
try {
|
|
if !WinWaitActive("ahk_id " hwnd, , 0.5) {
|
|
A_Clipboard := text
|
|
TrayTip("Impossible de réactiver la fenêtre cible — prompt copié dans le presse-papiers.", "PromptKey")
|
|
return Map("ok", false, "method", method, "error", "Réactivation de la fenêtre impossible.")
|
|
}
|
|
}
|
|
Sleep(60)
|
|
}
|
|
|
|
if (method = "sendtext") {
|
|
SendText(text)
|
|
} else {
|
|
this.Guard.Save()
|
|
this.Guard.InjectedText := text
|
|
A_Clipboard := text
|
|
if !ClipWait(0.5) {
|
|
this.Guard.RestoreIfUnchanged()
|
|
return Map("ok", false, "method", method, "error", "Presse-papiers non prêt.")
|
|
}
|
|
Send("^v")
|
|
Sleep(st.PasteDelayMs)
|
|
; Restauration (ou vidage) différée, conditionnelle (§11.3).
|
|
guard := this.Guard
|
|
sensitive := options.Has("sensitive") ? options["sensitive"] : 0
|
|
if sensitive
|
|
SetTimer(() => guard.WipeIfUnchanged(), -st.RestoreDelayMs)
|
|
else
|
|
SetTimer(() => guard.RestoreIfUnchanged(), -st.RestoreDelayMs)
|
|
}
|
|
|
|
; Marqueur {{cursor}} : replacer le curseur (§10.3).
|
|
if (options.Has("cursorFromEnd") && options["cursorFromEnd"] > 0) {
|
|
n := options["cursorFromEnd"]
|
|
Send("{Left " n "}")
|
|
}
|
|
|
|
; Envoi automatique : seulement si le profil le demande explicitement (§12.4, D5).
|
|
if (options.Has("sendAfter") && options["sendAfter"]) {
|
|
delay := st.SendAfterDelayMs
|
|
TrayTip("Envoi automatique dans " Round(delay / 1000, 1) " s — Échap pour annuler.", "PromptKey")
|
|
; Fenêtre d'annulation : on écoute Échap pendant le délai.
|
|
cancelled := false
|
|
endTime := A_TickCount + delay
|
|
while (A_TickCount < endTime) {
|
|
if GetKeyState("Escape", "P") {
|
|
cancelled := true
|
|
break
|
|
}
|
|
Sleep(25)
|
|
}
|
|
if (!cancelled)
|
|
Send("{Enter}")
|
|
else
|
|
TrayTip("Envoi annulé — le texte reste en place.", "PromptKey")
|
|
}
|
|
Util.Log("Injection OK (" method ", " StrLen(text) " caractères)")
|
|
return Map("ok", true, "method", method, "error", "")
|
|
}
|
|
}
|