OMC version 5.2.1
OMC 5 requires macOS 14.6 or later. For older macOS versions, use OMC 4.x.
OMC 5.2.1 is a point release on top of 5.2. It carries one security fix: the embedded Python bytecode cache no longer lives in world-writable /tmp - along with a find bar for RichText and Chat documents, a richer Chat element, an indeterminate linear progress bar, a test suite for AppletBuilder itself, two new documents written for AI agents, and an embedded Python refreshed to 3.14.7.
Security
The Python bytecode cache moved off world-writable /tmp
Every OMC applet with an embedded Python interpreter used to run with PYTHONPYCACHEPREFIX set to the compile-time literal /tmp/Pyc. On macOS /tmp is world-writable: its sticky bit stops one user from deleting or renaming another user's entries, but not from creating new ones. CPython validates a cached .pyc only against the mtime and size of its .py source, and an applet bundle is world-readable, so both of those are trivially reproducible by anyone with a local account.
This fix lives in Abracode.framework, so an applet picks it up when it is rebuilt against 5.2.1. If you ship applets with embedded Python, rebuild them with AppletBuilder 5.2.1. You may also want to remove any stale /tmp/Pyc left behind on machines you control.
A second, smaller instance of the same class is fixed in AppletBuilder: five hardcoded /tmp paths in its own scripts moved to ${TMPDIR:-/tmp}, including a world-writable path used for the converted help cache.
Highlights
Find in ActionUI RichText and Chat documents
Both the RichText and Chat elements gained a find bar and a programmatic search channel.
"showFindBar"(Boolean) puts a Cmd-F find bar over the element. Cmd-G and Shift-Cmd-G step forward and back, Escape closes, and the bar's menu toggles case-sensitive, whole-word, diacritic-insensitive, and regular-expression matching. It defaults tofalseonRichTextandtrueonChat, so every existing Chat document gains it.states["search"]lets the host drive the search instead. A non-empty string highlights that term - and, when the find bar is enabled, shows it in the bar without stealing focus. An empty string clears. The value is re-delivered on every states change, so a repeated identical value is ignored, which lets a reader dismiss the bar without it reopening.
In Chat the search spans the whole conversation: Cmd-G walks hits across messages, opening folded thought and tool cards that contain one and scrolling the hit into view, and the menu can widen the scope to thoughts and tool calls. Markdown bodies are searched as rendered text, so a styled **fox** is found by typing "fox". Deleted, streaming and still-running items are skipped until they settle.
ActionUI ProgressView: an indeterminate linear bar
ProgressView used to infer its shape purely from data - a value present meant a bar, absent meant a spinner - which left an indeterminate linear bar unreachable. A new "progressViewStyle" property takes "automatic" (the default, preserving the old behavior), "linear" (always a bar, determinate or not) or "circular" (a spinner or ring gauge).
AppletBuilder tests itself
AppletBuilder now ships its own omctest suite under Distribution/Tests/, 299 checks across four files, with a reference in Distribution/Tests/README.md:
Two new documents written for AI agents
-
omc_applet_catalog.mdis a classified inventory of the public first-party applets - 18 repositories undergithub.com/abra-code- written for an agent that is about to build a new applet. The skill teaches the format; the catalog tells you which existing app to copy from. It covers where the applets live and what is tracked versus added at build time, which applets are legacy Interface Builder nibs and therefore not agent-editable, a "I am building X, clone Y" quick-pick table, applet families, a technique cookbook mapping each UI and scripting pattern to the applet that demonstrates it, a full matrix, known gaps, and a suggested reading order. -
nib_to_actionui_migration.mdis an 11-step guide to porting a nib-based applet to ActionUI, each step with a verification gate before moving on: assessing the source, reusing the nib'stag=values as ActionUI ids, value-representation traps, layout verified withappletbuilder preview --screenshot, replacing editable combo boxes (ActionUI has no native equivalent - the guide pairs aTextFieldwith a companion dropdown at1000 + the field's id, and weighs a menu-stylePickeragainst aMenufor the dropdown itself), drag and drop onto a text field, manifest and command wiring verified withappletbuilder validate, shell-quoting the assembled command, building JSON from shell, tests, and the final hand-off to a human. It ends in a symptom index.The skill previously told agents that nibs "cannot be worked on," with no path forward. It now points at this guide: if the ask is to replace the nib rather than maintain it, that port is an agent-doable job.
Both documents ship inside AppletBuilder.app/Contents/Resources/Documentation/ as well as in the repo.
New in the ActionUI Chat element
The bundled Chat component moved from ChatView 0.5.6 to 0.6.2, which brings more than the find feature:
ChatImageItemnow carries sender, time, delivery state and reactions the way a file item does, groups into sender runs, shows the sender name, and has animageAddedevent that upserts by id.- Captions on photos and files. A new
captionfield onChatImageItemandChatFiletakes Markdown and is searchable as a body. A captioned photo becomes a full bubble, and photo and file bubbles gain "Reply" alongside "React". - Reactions on file and voice items, previously message-only, over a shared badge and menu implementation.
- A reaction badge now reserves space above a reacted bubble instead of stealing it from the gap above, the pill styling is flattened, and the macOS context menu's reaction entry is a labeled "React" menu rather than an unlabeled control group.
The underlying ActionUI RichText component moved from 0.1.1 to 0.2.3. Besides the search engine behind the find bars, that range adds regular-expression matching and fixes a TextKit 2 bug where highlight changes did not repaint until the next scroll.
Build hygiene
Development junk is swept before codesigning
Junk present at codesigning time is sealed into CodeResources and cannot be removed afterward without invalidating the signature. Both bundles are now swept immediately before their own signing step:
update_appletbuilder.shsweepsAppletBuilder.app, a fully regenerated build product, so its list also includes.gitand.svn.clean_build_junk()inlib.build.shsweeps a user's applet duringapplet_build(), since an OMC applet's.appbundle is the project. There.gitis deliberately preserved and only reported, and reported quietly, so a versioned applet does not pop an error window on every build.
The sweep covers Finder droppings, __pycache__ and .pyc, .pytest_cache, editor and agent scratch directories, and thin_distribution.sh leftovers. It matches symlinks as well as real files, uses case-insensitive matching so thumbs.db is caught on a case-insensitive volume, and resolves a symlinked bundle path to its physical path first, because find will not descend into a symlinked start path. Counts are reported as a before/after delta rather than a pre-scan, because rm and find -delete swallow errors - a failed sweep used to print green. A surviving item now halts the script.
For scale: there were 26 .claude directories inside .app bundles under the development tree when this was written.
AppletBuilder keeps Python's bytecode cache out of its own bundle
AppletBuilder imports three in-bundle Python packages plus its shipped standard library, and nothing redirected the cache, so Python wrote __pycache__ directories next to each of them. A single appletbuilder validate wrote 14 of them into AppletBuilder.app, and opening Help added four more; each one breaks the signed bundle's seal. Most were invisible, because Contents/Library/Python and Contents/Library/mistune are gitignored wholesale - only 2 of the 14 ever showed up in git status.
lib.common.sh now exports a PYTHONPYCACHEPREFIX default pointing outside the bundle, sourced by every AppletBuilder process including the appletbuilder agent CLI. An inherited value is never overwritten, so the engine's per-uid prefix and omctest's per-run scratch both still win.
Embedded Python 3.14.7
The embedded Python distribution shipped in AppletBuilder - and copied into every new Python applet - moves from 3.14.6 to 3.14.7.
Compatibility notes
- The bytecode-cache fix changes where an applet's
.pycfiles are written, from a single shared/tmp/Pycto a per-user directory under/var/folders/. Anything that read or cleaned/tmp/Pycneeds updating. Documentation and the skill now useexport PYTHONPYCACHEPREFIX="$TMPDIR/Pyc"in their pip-install snippets instead of the old/tmp/Pyc. Chatgains the find bar by default ("showFindBar"istrue). Set it tofalseif you do not want Cmd-F bound inside a chat view.ProgressViewdocuments that omit"progressViewStyle"are unaffected -"automatic"is exactly the previous behavior.OMCTEST_API_VERSIONis unchanged at 6. Suites written for 5.2 run as-is.
Documentation and skill
- New
Documentation/omc_applet_catalog.mdandDocumentation/nib_to_actionui_migration.md, both also bundled in AppletBuilder. - The skill's reference table points at both, and its NIB paragraph now offers the migration path instead of a dead end.
omc_python_scripting_guide.md,omctest_guide.md,SKILL.mdand the skill's core content all describe the new per-userPYTHONPYCACHEPREFIXlocation, explicitly noting that it is not$TMPDIR.- Schema and documentation refresh for
Chat,RichTextandProgressView. - New
Distribution/Tests/README.md, the reference for AppletBuilder's own suite.
In this distribution
- AppletBuilder.app - OMC applet development studio.
- OnMyCommandCM.plugin - contextual menu plugin for use with Shortcuts.app; commands load from
~/Library/Preferences/com.abracode.OnMyCommandCMPrefs.plist. - OMCService.service - macOS service template for standalone OMC-based system services.
- Skill/ - the OMC AI agent skill (three flavors) plus its installer.
- Scripts/ -
codesign_applet.sh,install_contextual_menu_plugin.sh,thin_distribution.sh,OMCApplet.entitlements, and the examplecom.abracode.OnMyCommandCMPrefs.plist.
See the main OMC README at https://github.com/abra-code/OMC/ for full documentation on commands, runtime context, dialogs, and services.