macOS (this repo) | Windows
macOS menu bar utility that logs committed on-screen text (including CJK after IME confirm — not keycodes), clipboard copy, and ⌘V paste. Writes daily local UTF-8 .log files. Nothing is uploaded.
- Typing — Branch A (native apps): AX value diffs; under Chinese IME, Latin is held and resolved against full Latin tokens still in the field (keeps
test/zhong, drops pinyin scraps). Idle does not flush held Latin while Chinese IME is active. Branch B (Cursor / VS Code–based): unreliable Monaco textareas ignored; under Chinese IME, key-fallback is off and chat text is captured after send (Enter / ⌘Enter). Branch B rules do not apply to Finder/Notes/企微. - Copy / paste — Watches the pasteboard and global ⌘V; a copy followed quickly by the same paste merges into
copy_paste - Line buffering — Flush after N seconds idle (default 3, configurable). Enter does not start a new log line (IME confirm often uses Enter).
- Menu bar — Pause / resume, open today’s log, settings (directory, retention, truncation, launch at login)
- Privacy-friendly — Data stays on disk; typing in password / secure fields is not recorded
- macOS 14+
- Accessibility permission (text capture + global paste hotkey)
git clone https://github.com/wizizm/irecorder.git
cd irecorder
./scripts/package-app.shThe script will:
swift build -c release- Produce
dist/iRecorder.app - Install to
/Applications/iRecorder.appand open it
Package only (skip /Applications):
IRECORDER_SKIP_INSTALL=1 ./scripts/package-app.shThe build uses ad-hoc signing. After every reinstall, re-check System Settings → Privacy & Security → Accessibility for iRecorder (path should be
/Applications/iRecorder.app).
- Click the orange iR menu bar icon
- If Accessibility is inactive: Open Settings from the menu or Settings pane, then enable iRecorder
- Quit and relaunch the app (macOS often does not apply the grant until process restart)
- Default log directory:
~/Documents/iRecorder/
Once capture starts, today’s log should soon contain a session_started line.
One file per day: YYYY-MM-DD.log
2026-07-15T16:12:03+08:00 type Safari 你好世界
2026-07-15T16:12:10+08:00 copy_paste Finder→Notes clipboard text
2026-07-15T16:12:20+08:00 copy Safari only copied
2026-07-15T16:12:25+08:00 paste Notes pasted later
| Column | Meaning |
|---|---|
| Time | ISO 8601 |
| Kind | type / copy / paste / copy_paste |
| App | Frontmost app; cross-app paste looks like A→B |
| Payload | Original text. type escapes newline / tab / \ as \n / \t / \\ (one physical line). copy / paste / copy_paste keep real newlines and tabs so you can copy the payload out with original formatting (a record may span multiple lines). |
- Copy / paste beyond the configured size is truncated with
[truncated](default 100 KB;0= no truncate). Typing is never truncated. - The app’s own log content is not re-captured (avoids escape blow-up when a log is open in Console)
- AX echo after paste is not logged again as
type
| Setting | Notes |
|---|---|
| Log directory | Default ~/Documents/iRecorder |
| Retention days | 0 = never auto-delete |
| Copy / paste truncate | KB; 0 = unlimited |
| Type-line idle | 1–60 seconds |
| Launch at login | Needs a real .app (more reliable under Applications) |
| Open today’s log hotkey | Global shortcut (default ⇧⌘L); requires Accessibility |
- Some custom-drawn UIs / games still cannot be typed-captured; Cursor chat Chinese is logged after send (Enter), not while composing; Cursor code-editor Chinese mid-typing is unsupported
- Typing in password / Secure fields is skipped; if text is already on the clipboard, copy / paste may still be logged
- Ad-hoc signature is not notarized; Gatekeeper may warn — grant Accessibility manually
swift test # core library unit tests
swift run iRecorder # run the executable (login item etc. limited without a full .app)| Target | Role |
|---|---|
IRecorderCore |
Diff, buffering, formatting, file I/O, settings (tested) |
iRecorder |
AX / pasteboard / ⌘V, menu bar & settings UI, .app packaging |
Sources/
IRecorderCore/ # pure logic
iRecorder/ # app + capture + UI
Tests/
IRecorderCoreTests/
scripts/
package-app.sh # release build → dist/ → /Applications
Resources/ # AppIcon.icns, MenuBarIcon.png
iRecorder does not collect or upload any data. Logs are written only to the directory you choose. Accessibility is used solely to read committed on-screen text and observe the paste hotkey.