Use the In-App Editor
CUST/OS includes a full-screen text editor inside the plugin. It is how you author skills, edit custos.yaml, and write automation files without leaving ATAK.
Open the editor
Tap the Editor icon in the NavBar. The chat panel hides and the editor takes the full panel width.
You can also open the editor automatically on a script error: when a tool fails, the chat panel shows a [Debug] link that opens the editor with the failing file loaded and the error highlighted.
What you can edit
The file tree on the left shows three roots:
/sdcard/atak/custos/skills/-- every shipped and user skill/sdcard/atak/custos/config/--custos.yamland any future config files/sdcard/atak/custos/automations/-- automation.luafiles
Supported file types:
.lua-- Lua source with syntax highlighting, auto-formatted on save.md-- Markdown (used for SKILL.md), auto-formatted on save.yaml/.yml-- YAML (used for custos.yaml), auto-formatted and parse-validated on save
Tabs
Each opened file gets its own tab at the top. Tap a tab to switch. The "X" on a tab closes it. Unsaved changes are preserved when you switch tabs but are NOT preserved if you close the editor panel.
Find / search
Use the search bar above the editor to find text in the current file. The match count appears next to the input. Enter / Shift+Enter jumps between matches.
Save
Tap Save (or File > Save):
- The buffer is auto-formatted (Lua, YAML, and Markdown each have their own formatter).
- For
custos.yamlspecifically, the formatted text is parsed to verify it is valid. A parse error stops the write, shows a toast with the error, and leaves the last known-good config in place. - For any other file, the formatted text is written to disk and CUST/OS picks up the change.
There is no Accept/Reject diff gate on operator saves — the diff-review flow is reserved for agent-initiated file writes, which go through the approval gate separately.
Hot-reload behavior
Different file types reload differently, but in every case no plugin restart is required:
| File | What happens on save |
|---|---|
*.lua under skills/ |
Skills reload, keyword index rebuilds, tools immediately callable |
SKILL.md |
Same as above |
*.lua under automations/ |
Automations reload, schedules and event listeners recalculate |
custos.yaml |
Config reloads -- providers, hooks, and sandbox settings refresh |
Debug mode
When a tool fails during chat, the chat row has a [Debug] link. Tapping it:
- Opens the editor
- Loads the failing
.luafile - Scrolls to the error line
- Shows the error message and stack trace in the bottom debug bar
Fix the script, save, and re-issue the original chat message. The hot-reload picks up your fix immediately.
Editing custos.yaml
The editor treats custos.yaml as special: it reformats the file and then parses it with the same YAML parser the runtime uses. A parse error short-circuits the write with a toast, so a malformed config can never overwrite the last known-good one.
Toolbar layout
The editor toolbar is arranged left-to-right:
[filename] [File] [View] [Find] [Run]
Below the toolbar is the tab bar:
[+ | tab1 | tab2 | ...]
The + button creates a new scratch file. File and View are dropdown menus. Find opens the in-file search bar. Run executes the active tab.
File and View menus
- File > Open -- opens the file tree browser
- File > Save -- formats, validates (for
custos.yaml), and writes the file - File > Delete -- deletes the current file (with confirmation)
- View > Show Console -- toggles the console pane below the editor
- View > Half Screen / View > Full Screen -- toggles between half-width (side-by-side with the map) and full-width mode
Scratchpad files
The + button creates a new scratch file in /sdcard/atak/custos/scratch/. Scratch files are regular .lua files -- you can save them, close them, and reopen them later. They do not need a SKILL.md and are never loaded as skills.
Use scratch files for one-off experiments, test scripts, or quick calculations.
Running code
The Run button executes the active tab:
- Scratch files run as raw Lua. The script executes top-to-bottom and the return value appears in the console. All registered tool functions are pre-loaded as globals, so you can call any skill's tools directly (e.g.,
return focus_map({lat=41.63, lon=-93.85})). - Skill
.luafiles prompt you for JSON arguments, then call the tool function exactly as the agent would invoke it.
If the console is not visible, hitting Run opens it automatically.
Console
Open the console with View > Show Console or by hitting Run. The console shows:
- Return values in green
- console.log output in white
- Errors in red
- Timing -- execution duration in milliseconds
The console is resizable and clears on each new Run.
Drag-to-insert
Long-press a .lua tab and drag it into the editor area. A function call snippet drops at the cursor with parameter placeholders pre-filled from the tool's annotations. For example, dragging focus_map.lua inserts:
focus_map({lat = 0, lon = 0})
Useful when writing scratch files that compose multiple tools.
Limits
- No multi-file refactor -- you cannot rename a tool across files in one shot.
- No VCS integration -- pair with
adb pullif you want to commit changes. - No undo across saves -- undo within a session works; once you save and accept, the diff is gone.
- No external editor sync -- files pushed from a workstation overwrite unsaved editor state.