Local Rules Reference
The complete active macOS rules that can affect capture, requests, validation, status, or replacement.
This reference describes executable local behavior in the macOS input method. Model prompt instructions are identified separately. Local Swift code has no rule that classifies a Latin fragment as English or Pinyin.
Capture rules
- An explicit non-empty selection overrides automatic capture.
- Convert uses the current paragraph, excluding boundary newlines.
- Polish and Explain use the sentence around the caret; delimiters are
。!?.!?and newline. - Terminal, Ghostty, VS Code, and VS Code Insiders prefer the local typing buffer. Other hosts use document capture first and the buffer as fallback.
- Outer whitespace is preserved for automatic capture.
- Markdown heading, quote, list, numbered-list, and task-box prefixes are excluded from automatic Convert request text and preserved in the host.
- Empty capture reports
nothingToConvert.
Typing-buffer rules
- Ordinary printable keystrokes append to a buffer tied to the current text client. Normal Backspace removes the last buffered character.
- Client changes, pointer input outside the action menu, newline, navigation or focus keys, Command/Control editing commands, Option-Backspace, untrackable keys, deactivation, completion, and unchanged completion clear the buffer.
- A buffer generation mismatch prevents replacement and reports
textChanged.
Accepted-paragraph rules
- A verified paragraph replacement records its start location and accepted text for that host client.
- If the paragraph still begins with the accepted text, only newly appended content is requested. Up to 100 preceding characters are read-only context.
- If the prefix no longer matches, the complete paragraph body is requested.
Protected-content rules
- Code spans/fences, URLs, email addresses, paths, Markdown link targets, recognized key patterns, private-key blocks, and labelled secret values are replaced by local placeholders before the request.
- Labelled secrets own the remainder of their line.
- Overlapping candidates are resolved by location, longest range, then priority.
- Restoration requires every target placeholder exactly once.
- Secret candidates show the privacy lock; other protected objects do not.
Model-output boundary
- Complete leading
<think>,<analysis>, or<reasoning>blocks are removed only when non-empty response text remains. - Incomplete, embedded, or remaining reasoning markup rejects the response.
- Empty sanitized output rejects the response.
Convert validator
| Failure identifier | Failing variable |
|---|---|
empty | Output contains no non-whitespace text |
contextEnvelopeLeak | Internal context or target markers appear in output |
metaExplanation | Reasoning markup remains |
lineBreakMismatch | Newline count changed |
markdownPrefixMismatch | Per-line Markdown structural prefix changed |
protectedTokenMismatch | Protected token, line, order, or boundary changed |
Convert has no local Pinyin likelihood, Latin prefix, English-word, or code paragraph rejection.
Polish validator
Polish uses empty, metaExplanation, lineBreakMismatch,
markdownPrefixMismatch, and protectedTokenMismatch. It additionally uses
informationAnchorMismatch when the ordered sequence of number-like anchors
changes. A local postprocessor changes a comma before Han text from , to ,.
Explain performs protected-content restoration but does not write to the host.
Request and retry rules
- Empty Convert and Polish input returns locally without a request.
- Convert sends one request with temperature 0 and a 1,024-token output limit.
- A structurally invalid first Convert result gets one repair request.
- An identical first Convert result gets one aggressive retry. Recognized Mini/Lite routes use Pro when available; an unavailable Pro route falls back to the selected model.
- A structurally valid identical final result returns normally and becomes
unchangedat replacement time. - Polish gets one repair request after a validation failure.
- Explain sends one request with a 300-token output limit.
- Requests use a 45-second timeout. Missing or expired credentials, non-success
HTTP status, decode failures, unsafe reasoning markup, empty response, or
failed final structural validation becomes
actionFailed.
Application exceptions
- Selection-or-caret replacement clients:
com.tencent.xinWeChat,com.microsoft.VSCode,com.microsoft.VSCodeInsiders. - Typed-buffer-preferred clients:
com.apple.Terminal,com.mitchellh.ghostty,com.microsoft.VSCode,com.microsoft.VSCodeInsiders. - Xcode has no bundle-specific exception.
Replacement rules
- The source range or buffer generation must still match the capture snapshot.
- Identical replacement reports
unchangedwithout insertion. - Normal hosts receive committed range replacement.
- Selection-or-caret clients receive insertion into the exact selection, or a synthetic Backspace batch when the caret is still at the target end.
- Synthetic replacement is client/generation-bound and times out after two seconds.
- Readable resulting text is verified. Mismatch reports
replacementFailed; unreadable resulting text recordsreplacementSentwithout claiming read-back verification. - No replacement path creates marked composition.
Trigger and status rules
- Caps Lock maps to F20 only while UnimeType is selected and the setting is on.
- Plain Caps Lock runs Convert. Option + Caps Lock opens the action menu when enabled. Option + Return runs Convert when enabled. Repeats are ignored.
- One action may be in flight.
- Silent states:
processing,completed,replacementSent. - Visible abnormal states:
unchanged,nothingToConvert,requestInFlight,textChanged,selectionRequired,replacementFailed,actionFailed,setupRequired,cancelled.
Model prompt rules, not local decisions
The configured prompt asks the model to convert plausible enabled-language input, preserve clear English and protected structure, use context for ambiguous Pinyin, and return only the target. These instructions influence the model's answer, but local Swift code does not use them to classify or block the input.