Pretype — ваш Mac дописывает предложения за вас
текст, который существует до того, как вы его напечатали.
Редактор кода дописывает строки за вас. Pretype делает то же со всем, что вы печатаете на Mac.
Тёмную половину печатаете вы — серую печатает модель на вашем собственном чипе.
Лучший интерфейс — невидимый — он живёт у вашей каретки.
Серый текст — это идея целиком, но не приложение целиком. Всё, что ниже, — та же локальная модель у той же каретки, на клавишах, где уже лежат ваши пальцы.
- Tab
Исправляет опечатку
Словарь macOS, всплывающий над словом, — на том языке, который он читает вокруг каретки. Esc убирает подсказку, и про то же слово он больше не спросит.
- Tab
Пишет эмодзи словами
macOS уже знает все имена Unicode, поэтому тысячи шорткодов предлагаются в той же плашке — без единой таблицы в комплекте.
- ⌥Tab
Переписывает корявое
Грамматика и формулировка правятся на месте, вашей же интонацией, — или только что набранное слово, если ничего не выделено. Всегда сначала показывает, никогда не применяет за вашей спиной.
- ⌥⇧Tab
Пишет ответ целиком
Перед пустым полем чата он читает переписку на экране и набрасывает следующее сообщение одним серым текстом. По желанию, OCR на самом Mac и только по этому аккорду.
- сам
Запоминает ваши слова
Имена, сленг, фраза, которую вы печатаете десять раз в день, — из модели вашего собственного письма, собранной на этом Mac, отвечающей раньше, чем стартует LLM. Очистить или выключить можно в любой момент.
- сам
Знает, когда молчать
Никогда в терминалах и менеджерах паролей, никогда при защищённом вводе macOS. В приложении, где вы его всё время игнорируете, он перестаёт предлагать — и говорит об этом в меню, с кнопкой «продолжить».
Tab работает здесь. И в любом другом текстовом поле вашего Mac — без плагина под каждое приложение.
Это всё ещё ваши слова. Просто уже напечатанные.
Установите
Перетащите в «Программы». Без аккаунта и мастера настройки — иконка в строке меню, один запрос Универсального доступа и модель, скачанная один раз (≈2 ГБ).
Печатайте
Пишите как обычно. Ghost-текст появляется у каретки, подстроенный под шрифт самого поля. Не угадал? Просто печатайте дальше.
Tab
Tab берёт слово, ⇧Tab — предложение. То, что заберёт следующий Tab, на тон темнее. Когда подсказки нет, Tab — это просто Tab.
Дополнение, исправления и ответы измерены каждое на своём бенчмарке — а модель по умолчанию подбирается под память вашего Mac. Можно просто не думать об этом.
Призрачный текст, который завершает Tab. Одиннадцать моделей на одних и тех же отложенных предложениях, с ранжированием по любому языку, на котором вы действительно пишете.
Выделенный текст, починенный на месте. Этот аккорд работает не на выбранной вами модели, а на её instruct-родственнике — поэтому здесь шесть строк-родственников, и каждая говорит, каким моделям она достаётся.
Целое сообщение, написанное по переписке на экране. Те же шесть родственников, что и у исправления, — и почти обратный порядок.
Размер точки — память в RAM (полая — встроена в macOS) · покрытие — доля случаев с ответом · ± — язык против среднего модели по 17 языкам
Точность первого слова, молчание — промах; сопоставленные ячейки (OpenSubtitles · Tatoeba · Leipzig) · ячейки по языкам тонкие (±5–10 пп) — сравнивайте модели внутри языка, а не числа между языками · 07.2026
Усы — 95% интервал · красная риска — как часто модель переписывает строку, в которой и так всё было верно (170 чистых контролей) · предложено — доля строк, где модель вообще что-то предложила · размер точки — память в RAM
Одна настоящая опечатка на строку, 17 языков, через реальный пайплайн приложения — гейт минимальной правки уже учтён в числах. Верное исправление, сформулированное иначе, считается промахом, так что практическая польза выше этой планки. В ячейке одного языка 30 строк — читайте усы, а не число. Тиры E4B 8-bit и 6-bit работают на 6-битном родственнике, которого прогон не покрыл; строка 4-bit — его измеренный минимум. Apple Intelligence в этом прогоне нет · 07.2026
Усы — 95% интервал · ответила — доля случаев, где модель вообще написала черновик · размер точки — память в RAM · ± — язык против итога модели по 19 языкам
Черновик считается годным, если он на языке переписки и не пересказывает экран, — это нижняя граница пригодности, а не оценка качества; близость к эталону оказалась слишком шумной. 19 языков, по 30 переписок, поэтому ячейки языков широкие — читайте усы. Apple Intelligence в этом прогоне нет · 07.2026
Каждая настройка знает свою измеренную цену.
Три панели — отображение, модель, персонализация. Наведите на любой контрол — Pretype покажет, что он улучшает и чего стоит, по реальным замерам.
Inline-текст или плавающая панель, клавиша принятия, яркость ghost-текста с живым предпросмотром — и отключение для отдельных приложений.
Измеренная карта всего каталога: точность вверх, скорость вправо, размер пузыря — память. Смена модели в один клик.
Персона и стилевые подсказки для каждого приложения задают тон и формулировки. Всё это остаётся на вашем Mac.
Ваши слова принадлежат вам.
Не верьте приватности на слово — весь путь ввода — это три файла. Прочитайте их, прежде чем доверять.
/// Fallback for apps whose focus
/// notifications never fire (some
/// Electron builds): ask the system-
/// wide element who has focus now.
static func
systemFocusedTextElement()
-> AXUIElement? {
let sys =
AXUIElementCreateSystemWide()
guard CopyAttributeValue(sys,
kAXFocusedUIElementAttribute,
&ref) == .success
else { return nil }
return isEditableTextElement(el)
? el : nil
} /// CGEvent tap on key-down events.
/// The handler returns `true` to
/// swallow the event — used to eat
/// Tab while a suggestion is shown.
final class KeyTap {
func start() {
let mask = CGEventMask(
1 << CGEventType
.keyDown.rawValue)
tapPort = CGEvent.tapCreate(
tap: .cgSessionEventTap,
place: .headInsertEventTap,
options: .defaultTap,
eventsOfInterest: mask,
...)
}
} /// Inserts text by posting synthetic
/// keyboard events — the most app-
/// agnostic path (AppKit, Electron,
/// web views, terminals alike).
enum TextInjector {
/// Tags our synthetic events so
/// the key tap ignores them.
static let magicTag: Int64 =
0x5052_5459 // "PRTY"
static func insert(_ t: String) {
for c in utf16Chunks(t.utf16) {
post(chunk: c, keyDown: true)
post(chunk: c, keyDown: false)
}
}
}