Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
직접 명령은 검토 Prompt를 거치지 않습니다. 실행하기 전에 소스를 확인하세요.
npx skills add https://github.com/tomevault-io/skills-registry --skill omc명령은 한 줄로 유지됩니다. 복사하기 전에 가로로 스크롤해 전체 내용을 확인하세요.
로컬 사본을 원하시나요? SkillsMP에서 현재 제공할 수 있는 파일을 다운로드하세요.
SOC 직업 분류 기준
SKILL.md 표시 중
| name | omc |
| description | > Use when this capability is needed. |
OMC (OnMyCommand) is a macOS low-code app builder engine. OMC applets are GUI .app bundles, with optional macOS Services menu items. Each applet combines a declarative command manifest (Command.plist) with shell scripts, Python scripts, or AppleScript files that implement the actions.
The OMC engine (Abracode.framework) handles app runtime, input routing, UI presentation, and script execution. A developer writes only the application-specific logic.
User should start a new applet using AppletBuilder (Distribution/AppletBuilder.app) — it creates the correct bundle structure, installs the framework, and generates the initial Command.plist and starter scripts.
MyApp.app/
├── Contents/
│ ├── Frameworks/
│ │ └── Abracode.framework ← OMC engine (copied from AppletBuilder template)
│ ├── MacOS/
│ │ └── MyApp ← executable (renamed copy of OMC binary)
│ ├── Resources/
│ │ ├── Base.lproj/
│ │ │ ├── MainMenu.nib ← app menu (from template; do not remove)
│ │ │ └── MyDialog.json ← optional ActionUI JSON dialog
│ │ ├── Scripts/
│ │ │ ├── lib.myapp.sh ← shared library: tool paths + control IDs
│ │ │ └── MyApp.*.sh / *.py ← action handler scripts
│ │ └── Command.plist ← command definitions
│ └── Info.plist
The command manifest lives at Contents/Resources/Command.plist (XML/binary plist) or Contents/Resources/Command.json (JSON). OMC reads either, preferring Command.json when both are present; AppletBuilder creates new applets with Command.json. The two formats are structurally identical — the same keys, value types, and VERSION == 2 rule apply (a JSON number 2 for VERSION, JSON true/false for booleans). This guide shows plist XML, but every example maps directly to JSON.
Root structure (plist):
<?xml version="1.0" encoding="UTF-8"?>
<plist version="1.0">
<dict>
<key>COMMAND_LIST</key>
<array>
<!-- one <dict> per command -->
</array>
<key>VERSION</key>
<integer>2</integer>
</dict>
</plist>
Root structure (JSON equivalent):
{
"COMMAND_LIST": [
{ }
],
"VERSION": 2
}
| Key | Type | Notes |
|---|---|---|
NAME | string | Human-readable label. Required. Shared across a command group. |
COMMAND_ID | string | Dot-notation ID (e.g. MyApp.results.selected). Required for subcommands. On the main command either omit it or set it explicitly to <NAME>.main (or bare main) — both are equivalent. The main command is also addressable for chaining by <NAME>.main, main, or the legacy internal top!. Its script filename follows the convention <NAME>.main.<ext>. |
EXECUTION_MODE | string | How the command runs. Default: exe_script_file or exe_shell_script if COMMAND is set. |
ACTIVATION_MODE | string | What context information the command expects. Default: act_always. |
<dict>
<key>NAME</key>
<string>MyApp</string>
<key>EXECUTION_MODE</key>
<string>exe_script_file</string>
<key>ACTIVATION_MODE</key>
<string>act_file_or_folder</string>
</dict>
Script files live in Contents/Resources/Scripts/. The filename maps directly to a COMMAND_ID:
| Script file | Handles COMMAND_ID |
|---|---|
MyApp.main.sh | the main command (no COMMAND_ID, or COMMAND_ID = MyApp.main) — MyApp is the NAME |
MyApp.results.selected.py | MyApp.results.selected |
MyApp.settings.save.sh | MyApp.settings.save |
lib.myapp.sh | (shared library — sourced by other scripts, not a command handler) |
OMC resolves the interpreter from the extension: .sh / .bash / .zsh → corresponding shell, .py → Python, .applescript → AppleScript, .js → JSC.
No shebang line is needed. OMC supplies the interpreter path automatically.
For Python applets, the embedded Python at Contents/Library/Python/bin/python3 is used when present — no system Python dependency. When a bundle has embedded Python, OMC exports — for every handler, shell or Python — PATH (prepended with the interpreter's bin/), PYTHONPYCACHEPREFIX=/tmp/Pyc, and PYTHONPATH (prepended with Contents/Library/Packages/ when it exists). Install third-party modules into Contents/Library/Packages/ (e.g. python3 -m pip install --target .../Contents/Library/Packages pkg) rather than the runtime's own site-packages: the Packages/ dir survives a Python runtime upgrade/rebuild, whereas Contents/Library/Python/ is replaced wholesale. See docs/omc_python_scripting_guide.md.
OMC exports these variables into every script's environment:
| Variable | Description |
|---|---|
$OMC_APP_BUNDLE_PATH | Full path to the running applet's .app bundle |
$OMC_OMC_SUPPORT_PATH | Path to OMC's support directory — all runtime tools live here |
$OMC_CURRENT_COMMAND_GUID | GUID of the current command invocation (pass to omc_next_command) |
$OMC_OBJ_PATH | Path of the file/folder that triggered the command (drag & drop / open panel / service) |
| Variable | Description |
|---|---|
$OMC_ACTIONUI_WINDOW_UUID | Window UUID for ActionUI dialog scripts |
$OMC_NIB_DLG_GUID | Window UUID for NIB dialog scripts |
| Variable | Description |
|---|---|
$OMC_ACTIONUI_VIEW_<N>_VALUE | Current value of ActionUI element with id N |
$OMC_NIB_DIALOG_CONTROL_<N>_VALUE | Value of NIB control with tag N |
$OMC_NIB_TABLE_<N>_COLUMN_<M>_VALUE | Selected row value from NIB table tag N, column M (1-based; column 0 = all columns tab-joined) |
Set when a script runs as the handler for an actionID or valueChangeActionID:
| Variable | Description |
|---|---|
$OMC_ACTIONUI_TRIGGER_VIEW_ID | id of the element that fired the action |
$OMC_ACTIONUI_TRIGGER_VIEW_PART_ID | Part ID (e.g. column index for Table) |
$OMC_ACTIONUI_TRIGGER_CONTEXT | JSON string with full trigger context |
All tools are at $OMC_OMC_SUPPORT_PATH/. Source a shared library at the top of every script:
source "${OMC_APP_BUNDLE_PATH}/Contents/Resources/Scripts/lib.myapp.sh"
Set up aliases once in lib.myapp.sh:
dialog_tool="$OMC_OMC_SUPPORT_PATH/omc_dialog_control"
next_cmd="$OMC_OMC_SUPPORT_PATH/omc_next_command"
# Set text value
"$dialog_tool" "$window_uuid" <id> "value"
# ActionUI: set rich content
"$dialog_tool" "$window_uuid" <id> markdown "# Hello"
"$dialog_tool" "$window_uuid" <id> html "<p>Hello</p>"
# Enable / disable a control
"$dialog_tool" "$window_uuid" <id> omc_enable
"$dialog_tool" "$window_uuid" <id> omc_disable
# Show / hide a control
"$dialog_tool" "$window_uuid" <id> omc_show
"$dialog_tool" "$window_uuid" <id> omc_hide
# Set window title
"$dialog_tool" "$window_uuid" omc_window "My Window Title"
# Feed a table from stdin (tab-separated; each line is a row)
printf "Label1\t/data/1\nLabel2\t/data/2\n" | \
"$dialog_tool" <tableID> omc_table_set_rows_from_stdin
<tableID> omc_select_row 3
<tableID> omc_select_row_with_content
<tableID> omc_select_row_with_content 1
<tableID> omc_deselect
<> omc_set_property
<> omc_set_property
omc_window \
omc_present_alert
<parentID> \
omc_insert_element
<elementID> omc_remove_element
Button spec for alerts: "title:role:actionID" — role is cancel, destructive, or empty for default.
"$next_cmd" "$OMC_CURRENT_COMMAND_GUID" "MyApp.next.step"
Schedules MyApp.next.step to run after the current script exits. The chained script runs in a fresh environment with the same window context.
To chain back to the applet's main command, target it by <NAME>.main (e.g. MyApp.main), bare main, or the legacy top! — all three resolve to the main command whether it was declared with no COMMAND_ID or with an explicit <NAME>.main / main id. The same aliases work in NEXT_COMMAND_ID.
docs/<tool>--help.md)| Tool | Purpose | Typical call |
|---|---|---|
alert | Modal alert; choice returned via exit code (0=OK, 1=Cancel) | alert --level caution --ok "Go" --cancel "Cancel" "Sure?" |
pasteboard | Cross-script key-value store; prefix keys with app name + window UUID | pasteboard my_key set "v" / pasteboard my_key get |
notify | macOS notification | notify --title "MyApp" "Done." |
plister | Plist read/write (for complex edits: plutil -convert json → edit → xml1) | plister get value "$plist" /COMMAND_LIST/0/NAME |
Each of these caused a real applet failure for an AI agent. The full
explanations, workaround tables, a script test harness, and a debug-logging
recipe are in docs/omc_agent_tips_and_troubleshooting.md — read it when any
of these bites or when behavior can't be explained from the code.
.sh scripts run under /bin/sh = macOS bash 3.2 in POSIX mode. There
is no bash 4/5 on macOS. Process substitution (done < <(cmd)),
mapfile, declare -A, and ${var,,} are fatal parse errors that kill
the script mid-file with no UI feedback. Validate with sh -n, never
bash -n — bash -n passes scripts that die under OMC.INIT_SUBCOMMAND_ID (runs before the window
appears). A non-blocking window's main command script runs at an
unpredictable time — keep it exit 0.LoadableView can't be targeted by
omc_dialog_control. Populate them in their viewDidLoadActionID handler
from state files; have init write its readiness file last (atomic mv)
and let handlers poll for it.omc_dialog_control <id> "text") replaces the rows with one string, it does not move the selection.
To select programmatically use the dedicated verbs: omc_select_row <0-based index>, omc_select_row_with_content <text> [1-based column] (omit column or
0 = match any column; selects the first match), or omc_deselect to clear.
These work on Table and List, fire no actionID, and leave the rows untouched; read the
result back via $OMC_ACTIONUI_VIEW_<id>_VALUE. Feed rows via
omc_table_set_rows_from_stdin; extra tab-separated fields beyond the declared columns
act as hidden columns (read via $OMC_ACTIONUI_TABLE_<ID>_COLUMN_<N>_VALUE).dbg() logger to /tmp (gated on a flag file), log
$OMC_ACTIONUI_TRIGGER_VIEW_ID/_PART_ID/_CONTEXT in every handler, ask
the user to perform the UI operation once, read the log back. Don't guess.Set via EXECUTION_MODE in a command dictionary.
| Mode | Description | Use when |
|---|---|---|
exe_script_file | Runs matching script from Scripts/; async; full env vars | Primary mode for all applets — every handler |
exe_script_file_with_output_window | Like above; stdout shown in an output window | Debugging; long-running tasks |
exe_shell_script | Inline COMMAND string; __SPECIAL_WORDS__ substituted; async | Contextual menu one-liners |
Other modes exist for special cases — exe_shell_script_with_output_window, exe_system, exe_applescript[_with_output_window], exe_terminal, exe_iterm — see docs/omc_command_reference.md.
The main command (no COMMAND_ID) attaches ACTIONUI_WINDOW or NIB_DIALOG and opens the window on launch.
Set via ACTIVATION_MODE. Controls when the command is visible in contextual menus.
| Mode | Activates when |
|---|---|
act_always | Always (use for applet launcher commands and subcommands) |
act_file | A file is selected / right-clicked |
act_folder | A folder is selected / right-clicked |
act_file_or_folder | Either a file or folder is selected |
act_file_or_folder_not_finder_window | File or folder (not just a Finder background click) |
act_selected_text | Text is selected in any application |
Attach a dialog to a command by adding one of these keys to the command dict:
<key>ACTIONUI_WINDOW</key>
<dict>
<key>JSON_NAME</key>
<string>MainWindow</string> <!-- filename without .json, in Base.lproj/ -->
<key>INIT_SUBCOMMAND_ID</key>
<string>MyApp.main.init</string> <!-- fires when window loads; populate tables here -->
<key>WINDOW_DID_ACTIVATE_SUBCOMMAND_ID</key>
<string>MyApp.main.activated</string>
<key>WINDOW_DID_DEACTIVATE_SUBCOMMAND_ID</key>
<string>MyApp.main.deactivated</string>
</dict>
The JSON file Contents/Resources/Base.lproj/MainWindow.json defines the UI (see ActionUI skill).
Same shape with NIB_NAME instead of JSON_NAME, plus IS_BLOCKING (false = modeless), END_OK_SUBCOMMAND_ID, END_CANCEL_SUBCOMMAND_ID. See docs/Nib-Guide.md.
INIT_SUBCOMMAND_ID fires when the window opens — use it to populate initial data. END_OK_SUBCOMMAND_ID / END_CANCEL_SUBCOMMAND_ID fire on confirm / cancel (these and IS_BLOCKING work for ACTIONUI_WINDOW too).
| Key | Type | Description |
|---|---|---|
NEXT_COMMAND_ID | string | Static: always chains to this command after execution |
END_NOTIFICATION | dict | Shows a completion alert (TITLE, MESSAGE strings) |
PROGRESS | dict | Progress bar dialog (TITLE, MODE: steps/counter/indeterminate) |
INPUT_DIALOG | dict | Prompts for user input before running (TYPE: text/password/popup/combo) |
SUBMENU_NAME | string | Groups this command under a submenu in contextual menus |
CATEGORIES | array | Filter categories for OMC's command list UI |
These are invoked automatically without being declared in COMMAND_LIST:
| COMMAND_ID | When |
|---|---|
app.will.launch | Before the app is fully launched |
app.did.launch | After launch completes |
app.did.activate | App comes to the foreground |
app.did.deactivate | App loses focus |
app.will.terminate | App is about to quit — use to clean up background processes |
OMC applets have two dialog paradigms. Most new applets should use ActionUI JSON.
A JSON file in Contents/Resources/Base.lproj/ defines the UI using the ActionUI framework. Connect it to a command via ACTIONUI_WINDOW in Command.plist:
<key>ACTIONUI_WINDOW</key>
<dict>
<key>JSON_NAME</key><string>MainWindow</string>
<key>INIT_SUBCOMMAND_ID</key><string>MyApp.main.init</string>
</dict>
For ActionUI JSON format (element types, properties, layout patterns) — read the ActionUI skill. The OMC-specific concerns are:
actionID property value on buttons/pickers/etc. is the COMMAND_ID of the handler script that runs on clickvalueChangeActionID fires as the value changes (e.g., every keystroke in a TextField)$OMC_ACTIONUI_WINDOW_UUID$OMC_ACTIONUI_VIEW_<id>_VALUEINIT_SUBCOMMAND_ID fires when the window loads — populate tables, pickers, and initial state hereInit script pattern:
# MyApp.main.init.sh
source "${OMC_APP_BUNDLE_PATH}/Contents/Resources/Scripts/lib.myapp.sh"
# Populate a picker (element id=20)
"$dialog_tool" "$OMC_ACTIONUI_WINDOW_UUID" 20 \
omc_set_property "options" '["Option A","Option B","Option C"]'
# Enable a button that starts disabled (element id=10)
"$dialog_tool" "$OMC_ACTIONUI_WINDOW_UUID" 10 omc_enable
Nib (Interface Builder) dialogs predate ActionUI. .nib files can only be edited in Xcode, so agents cannot work on them directly. When maintaining an existing NIB applet: the window UUID is $OMC_NIB_DLG_GUID, control values arrive as $OMC_NIB_DIALOG_CONTROL_<tag>_VALUE, and the dialog attaches via a NIB_DIALOG dict in the command manifest. Full reference: docs/Nib-Guide.md and docs/omc_controls_user_defined_runtime_attributes.md.
AppletBuilder (Distribution/AppletBuilder.app) is the tool for creating and
maintaining applets. Humans use its GUI; AI agents drive the same operations from
the command line via the bundled appletbuilder CLI — create from a template,
validate, prettify/preview ActionUI, and rebuild — running the same underlying
code as the GUI.
Distribution/AppletBuilder.app/Contents/Resources/Agents/appletbuilder <command> [args]
Progress and validation detail go to stderr; capturable results (a created
applet's path, prettified JSON, a screenshot path, listings) go to stdout.
Exit codes: 0 ok · 2 warnings · 1 errors.
| Command | Does |
|---|---|
| `create (--template <name | path> | --clone <App.app>) --name --dest [--bundle-id ] [--python] [--icon <name |
validate <App.app | Command.json | UI.json | script> | Auto-detects the target and runs the matching validator(s). For a bundle: Info.plist + command manifest (Layer 1/2) + every script + every ActionUI JSON. |
build <App.app> [--identity <id>] [--thin arm64|x86_64] [--warnings-as-errors] [--update-python] [--force] | Full validation, then refresh framework/executable (newer version auto-copies; --force re-copies even when unchanged), thin, and codesign. Halts before signing on validation errors. Independently, a working embedded Python is left untouched unless --update-python is given; a missing/broken runtime is always installed. Replacing the runtime wipes anything pip-installed into its site-packages — install deps into Contents/Library/Packages (on PYTHONPATH) so they survive. |
prettify <file.json> [--stdout] | Reformat JSON in place (or to stdout). |
preview <UI.json> [--screenshot <out.png>] | Render an ActionUI view to a PNG (read it to inspect the layout); a MainMenu.json menu-bar doc prints a text summary instead. Needs a GUI session. |
list-templates / list-icons | Names for --template / --icon. |
Example — create a Python applet, then validate and build it:
AB="Distribution/AppletBuilder.app/Contents/Resources/Agents/appletbuilder"
NEWAPP=$("$AB" create --template "ActionUI Window" --name MyApp --dest ~/Desktop --python --icon Bolt)
"$AB" validate "$NEWAPP"
"$AB" build "$NEWAPP" --thin arm64
Full reference: Distribution/AppletBuilder.app/Contents/Resources/Agents/README.md.
| Template | Use when |
|---|---|
Empty | Minimal bundle; no dialog |
ActionUI Window | ActionUI JSON dialog (recommended for OMC 5.0+) |
ActionUI Web | ActionUI dialog with embedded WebView |
Nib Window | NIB (Interface Builder) dialog |
Nib Web | NIB dialog with embedded WebView |
The Name also becomes the executable name and script prefix. New applets are
created with a Command.json manifest. Humans can do the same from the GUI's New
Applet panel.
Edit the bundle's files directly:
Contents/Resources/Command.json (or Command.plist — OMC reads either, preferring Command.json when both exist)Contents/Resources/Scripts/*Contents/Resources/Base.lproj/*.json (ActionUI) or *.nib (NIB — edit in Xcode)After editing, run appletbuilder validate <App.app> to catch problems.
Applets are signed for local execution; editing bundle resources (scripts, ActionUI JSONs, Command.json) does not stop the app from launching during development — macOS (as of 26) does not block resource-modified locally-signed apps. Re-sign — appletbuilder build <App.app>, the Build button in AppletBuilder's Build & Run pane, or Scripts/codesign_applet.sh — after changing binaries/frameworks, before distributing, or if the OS refuses to launch the app.
For full GUI-navigation help (Project Editor tabs, Commands editor, UI Files Validate/Preview/Prettify buttons, etc.), see docs/appletbuilder_user_guide.md.
Define tool paths and control IDs once in lib.myapp.sh and source it from every handler. This is the standard pattern in every OMC applet.
# lib.myapp.sh
dialog_tool="$OMC_OMC_SUPPORT_PATH/omc_dialog_control"
next_cmd="$OMC_OMC_SUPPORT_PATH/omc_next_command"
alert_tool="$OMC_OMC_SUPPORT_PATH/alert"
pasteboard_tool="$OMC_OMC_SUPPORT_PATH/pasteboard"
notify_tool="$OMC_OMC_SUPPORT_PATH/notify"
# Works for both ActionUI and NIB windows
window_uuid="${OMC_ACTIONUI_WINDOW_UUID:-$OMC_NIB_DLG_GUID}"
cmd_guid="$OMC_CURRENT_COMMAND_GUID"
# Control IDs — match id values in ActionUI JSON or tag values in NIB
STATUS_LABEL_ID=100
RESULTS_TABLE_ID=101
SAVE_BTN_ID=110
# Helper functions
set_value() { "$dialog_tool" "$window_uuid" "$1" "$2"; }
set_enabled() {
if [ "$2" = "1" ]; then
"$dialog_tool" "$window_uuid" "$1" omc_enable
else
"$dialog_tool" "$window_uuid" "$1" omc_disable
fi
}
Each handler sources the library immediately:
source "${OMC_APP_BUNDLE_PATH}/Contents/Resources/Scripts/lib.myapp.sh"
Per-window state — keyed to window UUID; lost when the window closes:
key="myapp_selection_${window_uuid}"
"$pasteboard_tool" "$key" set "$selected_path"
selected_path=$("$pasteboard_tool" "$key" get)
Persistent preferences — survive app restarts; use defaults:
/usr/bin/defaults write com.example.myapp LastUsedPath "$path"
saved=$(/usr/bin/defaults read com.example.myapp LastUsedPath 2>/dev/null)
Temporary files — for processing within a single command:
tmp=$(/usr/bin/mktemp)
# ... write to $tmp, read from $tmp ...
/bin/rm -f "$tmp"
ActionUI Table and List elements receive rows via omc_table_set_rows_from_stdin. Each row is tab-separated; fields map to columns in order.
# Two-column table (display name + data path)
{
while IFS= read -r filepath; do
name=$(/usr/bin/basename "$filepath")
printf "%s\t%s\n" "$name" "$filepath"
done < "$file_list"
} | "$dialog_tool" "$window_uuid" "$RESULTS_TABLE_ID" omc_table_set_rows_from_stdin
The number of tab-separated fields per row must match the widths array length in the ActionUI JSON. The actionID on the Table fires when the user selects a row; read the selected value via $OMC_ACTIONUI_VIEW_<id>_VALUE.
When a Table's actionID fires, the selected value is in $OMC_ACTIONUI_VIEW_<id>_VALUE. For multi-column tables, the trigger context identifies which column was used:
# In MyApp.results.selected.sh
source "${OMC_APP_BUNDLE_PATH}/Contents/Resources/Scripts/lib.myapp.sh"
selected_path="$OMC_ACTIONUI_VIEW_101_VALUE"
if [ -z "$selected_path" ]; then
set_enabled "$OPEN_BTN_ID" 0
exit 0
fi
# Save selection and enable action buttons
key="myapp_selection_${window_uuid}"
"$pasteboard_tool" "$key" set "$selected_path"
set_enabled "$OPEN_BTN_ID" 1
set_enabled "$REMOVE_BTN_ID" 1
Use omc_next_command when one script needs to trigger another after finishing — for example, chaining an init sequence or refreshing the UI after a background operation completes:
# Trigger refresh after processing
"$next_cmd" "$cmd_guid" "MyApp.results.loaded"
The chained command runs in its own script invocation with the same window context. Chain depth is not limited, but avoid circular chains.
For static always-chain (every execution), use NEXT_COMMAND_ID in Command.plist instead.
A common pattern — enable action buttons only when something is selected:
has_selection=0
if [ -n "$OMC_ACTIONUI_VIEW_101_VALUE" ]; then
has_selection=1
fi
set_enabled "$OPEN_BTN_ID" "$has_selection"
set_enabled "$REMOVE_BTN_ID" "$has_selection"
set_enabled "$REVEAL_BTN_ID" "$has_selection"
Control-click (or right-click + hold Ctrl) when triggering a command to see stdout in a window, without permanently setting EXECUTION_MODE to exe_script_file_with_output_window.
Dump the full environment from any script:
/usr/bin/printenv | /usr/bin/sort
After creating or editing a command manifest, validate it before building. The verifier handles both formats — Command.plist and Command.json — transparently (by extension):
python3 Skill/scripts/validate_command_plist.py <App.app | Command.plist | Command.json>
Pass the applet bundle (.app / .omc) rather than the bare file to also run bundle cross-checks (Layer 2); for a bundle the verifier resolves the command file itself, preferring Command.json when both exist (as OMC does): every exe_script_file command has a matching Scripts/<COMMAND_ID>.*, the ACTIONUI_WINDOW JSON / NIB_DIALOG nib resources exist, and subcommand IDs (INIT_SUBCOMMAND_ID, END_OK_SUBCOMMAND_ID, NEXT_COMMAND_ID, …) resolve.
Exit codes: 0 clean · 2 warnings only · 1 errors ([INFO] lines are advisory and never affect the exit code). Fix every [ERROR] before building; investigate each [WARNING] (usually a typo, a wrong value type, or a key with no effect in its context); [INFO] lines are just FYI.
Common findings:
DEFAULT_LOCATION / DEFAULT_FILE_NAME must be an array; a bare string is silently ignored by the engine.EXECUTION_MODE alias — use the modern name (exe_popen → exe_shell_script).VERSION not 2 — the engine loads nothing unless the root VERSION is 2.CUSTOM_* without WINDOW_TYPE=custom; OUTPUT_WINDOW_SETTINGS / PROGRESS without a popen / *_with_output_window mode; INPUT_MENU without a popup/combo INPUT_TYPE).COMMAND_ID (INIT_SUBCOMMAND_ID, NEXT_COMMAND_ID, …) or a JSON_NAME / NIB_NAME resource doesn't exist in the bundle. These are errors.COMMAND and no matching script file. This is a valid, common pattern when the command presents a dialog (its subcommands do the work) or chains via NEXT_COMMAND_ID, so it is only flagged at [INFO] level — and not at all when a dialog/chain is present. If the command was meant to run a script, the info note also catches a typo'd COMMAND_ID.The verifier's key knowledge lives in Skill/scripts/schemas/ (Command.json plus one file per sub-dictionary). Read the relevant schema when unsure about a key name, type, or allowed values. This is the same verifier AppletBuilder runs on Build and on the Commands tab Validate button.
Full OMC reference is in the docs/ folder (also bundled in AppletBuilder.app/Contents/Resources/Documentation/):
| File | Contents |
|---|---|
docs/omc_agent_tips_and_troubleshooting.md | For AI agents: sh-vs-bash fatal syntax, script test harness, init/LoadableView lifecycle, table & picker runtime semantics, debug-logging workflow, pre-flight checklist — with real failure case studies |
docs/building_omc_applet.md | Step-by-step applet creation guide with all details |
docs/appletbuilder_user_guide.md | UI navigation reference for the AppletBuilder GUI app (for human users) |
docs/omc_command_reference.md | Complete Command.plist key reference — all execution modes, dialog keys, output window settings, progress dialogs, input dialogs, services |
docs/omc_runtime_context_reference.md | Every $OMC_* environment variable and __SPECIAL_WORD__ substitution |
docs/omc_scripting_guide.md | Shell script patterns: reading controls, updating UI, tables, state, debugging |
docs/omc_python_scripting_guide.md | Python handlers: env (PATH/PYTHONPATH/Packages), equivalents of all shell patterns, installing deps into Contents/Library/Packages, and thinning the embedded Python (the thin_applet_python.sh plan/apply workflow) |
docs/omc_dialog_control--help.md | Full omc_dialog_control command reference with all operations |
docs/omc_next_command--help.md | omc_next_command reference |
docs/alert--help.md | alert tool reference with all flags |
docs/pasteboard--help.md | pasteboard tool reference |
docs/notify--help.md | notify tool reference |
docs/plister--help.md | plister plist tool reference |
When you need the exact keys for NIB_DIALOG, the complete list of omc_dialog_control operations, or the full env-var table, read the relevant docs/ file directly.
For ActionUI JSON UI (element types, properties, validation, patterns): read the ActionUI skill (../ActionUI/Skill/SKILL.md). The OMC skill only covers how ActionUI connects to OMC — the JSON format itself is entirely in the ActionUI skill.
Generated by Skill/build_skill.py — edit Skill/master/content/.md, not this file.*
Source: abra-code/OMC — distributed by TomeVault.
docs/omc_services_reference.mdmacOS Services integration via NSServices in Info.plist |
docs/Nib-Guide.md | Nib dialog creation: editing in Xcode, control classes, connecting to OMC |
docs/omc_controls_user_defined_runtime_attributes.md | All OMC control classes in Nibs and their settable properties |
docs/MenuBar-Guide.md | Menu bar JSON (MainMenu.json) in 5.1 applets: actionID command wiring, the autoPopulate Commands menu, deletion via replacing, Open Recent — the base array-root format is in the ActionUI skill (ActionUI-MenuBar-JSON-Guide.md) |