Карты API для AutoHotkey
Карты поиска API для скриптов AutoHotkey.
Заметки по оформлению документации для миграции с AHK
Эти заметки относятся к файлам в scripting/api/ahk/.
Организация файлов
ahk-migration.mdдолжен оставаться компактным центральным документом и оглавлением. В нем стоит описывать общий план, давать ссылки на тематические страницы и оставлять только небольшую сводную таблицу для быстрого обзора.- Подробные соответствия, примеры кода, рекомендации и ссылки для проверки выносите в отдельные тематические файлы, например
hotkeys.md,keyboard-mouse.md,windows.md,cv-pixels-images.md,runtime-state.md,clipboard.mdиdll-native.md. - Сохраняйте текущий формат тематических страниц: front matter, короткий абзац с областью применения,
## Quick Map, затем узкие разделы по конвертации, отдельные абзацы**Recommendation:**, а в конце## Verification Links. - Делите тематический файл дальше только тогда, когда его становится трудно просматривать. Например,
windows.mdпозже можно разбить наwindows/matching.md,windows/activation.mdиwindows/controls.md, если это понадобится. ahk-gaps.mdдолжен оставаться общим списком незакрытых вопросов между разными темами. Тематические страницы должны ссылаться на ID из этого файла, а не дублировать спорную или не до конца понятную семантику.
Сначала исследование
- Прежде чем писать или менять запись о миграции с AHK, сначала прочитайте родительскую карту навигации в
../AGENTS.md, а затем нужные тематические карты, на которые она ссылается. - Для каждого AHK API или технологии EyeAuras, упомянутых в руководстве по миграции, рядом должна быть ссылка на проверку по документации или исходникам. Лучше короткая таблица проверки, чем утверждения без источников.
- Перед добавлением примеров кода проверяйте реальные реализации. Не задавайте свойства, которые уже имеют правильное значение по умолчанию. Пример:
IHotkeyTracker.IsEnabledпо умолчанию равенtrue, поэтому в примерах не нужно устанавливать его явно, если до этого в примере он не был отключен.
Примеры скриптов на C#
- Прежде чем выбирать форму API EyeAuras, смотрите на реальный интерфейс и реализацию в исходниках, а не только на сгенерированную страницу в wiki. Предпочитайте самый прямой overload, который уже есть в коде.
- Например,
ISendInputScriptingApiсодержит overload-ы для клика мышью, которые принимают координаты иWinPointнапрямую, поэтому лучше использовать:
SendInput.MouseLeftClick(x, y);
SendInput.MouseLeftClick(point);
а не разбивать операцию на MouseMoveTo(...) и затем MouseLeftClick() при переводе AHK Click x, y.
- В примерах миграции предпочитайте зависимости, внедряемые через свойства, а не встроенные вызовы
GetService<T>().
ISendInputScriptingApi SendInput { get; init; }
- Используйте понятные имена свойств, соответствующие роли сервиса, например
SendInput,CV,Clipboard,WindowSelector. - Избегайте имен свойств, которые конфликтуют с распространенными пространствами имен или типами фреймворка. Например, лучше
IWindowListProvider WindowsProvider { get; init; }, а не свойство с именемWindows. - Для примеров с
IComputerVisionExperimentalScriptingApiиспользуйте имя свойстваCV. Это привычное сокращение в этой области и оно делает CV-примеры компактнее. - Для одного целевого окна обычно лучше
IWindowSelector.FindWindow(...), если отсутствие окна — нормальная ветка сценария. ИспользуйтеIWindowSelector.GetWindow(...)только когда отсутствие окна считается исключительной ситуацией. ИспользуйтеIWindowSelector.TargetWindowвместе сActiveWindow, если примеру нужно постоянное состояние селектора.IWindowMatcher.FindMatches(...)применяйте только тогда, когда примеру нужны все совпадения или когда поиск намеренно выполняется по переданному списку. - Соблюдайте соглашение по именованию API EyeAuras в примерах:
GetSomething(...)возвращает значение или выбрасывает исключение.FindSomething(...)может вернутьnull, если ничего не найдено.TryGetSomething(..., out value)возвращаетboolи записывает значение в параметрout. Если реализация не соответствует этому соглашению, укажите это явно, а не скрывайте разницу за примером сtry/catch.
- Для примеров с активацией окна перед описанием поведения таймаута или восстановления состояния проверяйте
WindowHandleExtensions.Activate(...)иUnsafeNative.ActivateWindow(...)по исходникам. - Используйте
GetService<T>()только тогда, когда цель примера — динамический поиск сервиса или обнаружение сервисов. - По умолчанию не добавляйте строки
usingс пространствами имен в примеры для руководства по миграции. В редакторе скриптов EyeAuras обычно автоматически подставляются основные пространства имен для scripting, input, CV и shared. - Упоминайте пространства имен только тогда, когда пример зависит от необычного внешнего типа или пакета и это действительно влияет на решение при миграции.
- Держите демонстрационные сниппеты короткими и по делу. Не заканчивайте каждый пример с подпиской строкой
cancellationToken.WaitHandle.WaitOne()только ради того, чтобы код продолжал работать. Если это лишь часть долгоживущего скрипта, лучше сказать об этом в тексте. - Для коротких примеров в документации предпочитайте легковесные подписки. Например, используйте
.SubscribeSafe(_ => SendInput.Text("hello")), если обработка ошибок не является основной темой примера.
Область миграции
- В пользовательских примерах предпочитайте стабильные API. Используйте
ISendInputScriptingApi, а не устаревшие нестабильные алиасы. - Примеры должны быть короткими и близкими по форме к AHK: одно примитивное поведение AHK — один эквивалент в EyeAuras.
- Для прямой миграции API сначала показывайте прямой эквивалент. Если в EyeAuras есть более удобная абстракция, упомяните ее уже после прямого соответствия как вариант переработки. Например, для AHK
DllCallсначала стоит показать C# P/Invoke (DllImport/typed signature), а затем при желании упомянуть существующий API из EyeAuras/PoeShared. - Не представляйте Actions, Triggers или Overlays как легкие API-эквиваленты для простых операций. Это stateful-объекты рантайма Aura Tree со своей конфигурацией, жизненным циклом, сериализацией и UI-аспектами. Для примеров миграции лучше использовать прямые script API, сервисы, extension methods или небольшие helper-ы. Упоминайте Actions/Triggers/Overlays только тогда, когда пользователь действительно строит настраиваемую ауру, либо когда этот компонент дает существенный предметный рантайм, а не просто тонкую обертку, например состояние image-search или ML pipeline.
- Для каждого соответствия добавляйте короткую оценку того, какой вариант лучше или удобнее для пользователя. Недостаточно просто сказать, что что-то технически возможно. Прямо отмечайте, когда перевод в EyeAuras получается неудобным, слишком низкоуровневым или лучше выражается через aura trigger/action, узел Behavior Tree, helper method или recipe.
- В разделах конвертации отделяйте код и объяснение от итоговой оценки. Вердикт выносите в отдельный абзац
**Recommendation:**после кода и необходимых пояснений. Он должен быть очень коротким: достаточно сказать, что миграция приемлемая, лучше реализуется в EyeAuras, выглядит неудобно или должна быть оформлена как helper/recipe. - Если в EyeAuras есть несколько разумных подходов, сначала показывайте путь по умолчанию — самый простой. Более управляемый вариант упоминайте отдельно. Например,
[Keybind]— это чистый вариант по умолчанию для простых горячих клавиш в скриптах, аIHotkeyTrackerс Rx-подписками лучше подходит, когда скрипту нужна регистрация во время выполнения, несколько хоткеев или собственная композиция observable-потоков. - Для переменных и состояния основная замена обычным AHK-переменным — это обычные локальные переменные, поля и объекты C#.
ScriptVariable<T>иIVariablesScriptingApiнужны для общего или постоянного состояния: между запусками одного и того же скрипта, между разными скриптами или между скриптом и инфраструктурой EyeAuras вне самого скрипта. - Не скрывайте неприятные места миграции. Например, ручной цикл
while (...) { Sleep(...) }для AHKKeyWaitдопустим, но неудобен; его стоит помечать как кандидата на helper или отдавать предпочтение более высокоуровневому паттерну EyeAuras, если такой есть. - Неопределенную или спорную семантику выносите в
ahk-gaps.md, а не подавайте ее как прямой эквивалент.