Skip to content

Safe automation workflow

The reliable write sequence is context → apply → validate. It gives an Agent or script a bounded view, prevents writes based on stale data, and proves the committed file still satisfies the requested validation level.

Every automation command below passes --json explicitly. The default output is designed for people and is not a machine contract.

The standalone CLI bundles the Skill used by Agent workflows. Initialize it in the current Space/project, or install it for the current user and all projects:

Terminal window
eidos skills init
eidos skills init --global

No Node.js, npm, or npx is required. Use --space <DIR> for another Space; the command refuses to replace edited Skill files unless --force is explicit.

Terminal window
eidos --json context tracker.eidos Tasks \
--fields Title,Status \
--limit 50

context returns file revision, compact schema, and logical rows. Add --full only when stable IDs, system fields, settings, relations, and saved views are needed.

Filters use portable JSON and may reference fields by name or stable ID:

Terminal window
eidos --json context tracker.eidos Tasks \
--where '{"op":"ne","field":"Status","value":"done"}' \
--fields Title,Status

ne is the Boolean complement of eq, so an empty Status also matches. Add an is-not-null rule when empty values should be excluded.

Save a request as request.json or pass it on stdin:

{
"revision": "1",
"table": "Tasks",
"match": { "_id": "019..." },
"expect": 1,
"set": { "Status": "doing" },
"returning": ["Title", "Status"]
}
Terminal window
eidos --json apply tracker.eidos request.json

revision rejects stale work. expect prevents an unexpectedly broad update. The CLI validates the proposed final state before commit and returns the rows requested by returning.

Terminal window
eidos --json validate tracker.eidos --level full

Treat a nonzero exit status at any step as a failed workflow. Do not continue from guessed or partially parsed output.

For common schema changes, use the intent commands instead of assembling raw operation JSON. Table and Field references may be display names or stable IDs; the CLI resolves them before the revision-checked transaction:

Terminal window
eidos --json field add tracker.eidos \
--table Tasks --name Due --type date \
--expected-revision 1 --dry-run
eidos --json relation add tracker.eidos \
--table Tasks --name Owners --target-table People \
--cardinality many --on-delete detach \
--expected-revision 2
eidos --json table update tracker.eidos Tasks \
--record-label Title --content-field Notes --dry-run
eidos --json field update tracker.eidos Estimate \
--table Tasks --type integer --dry-run
eidos --json relation update tracker.eidos Owners \
--table Tasks --cardinality one --dry-run

table update covers name, settings, record label, Markdown content Field, position, and default-Table changes. field update covers name, settings, position, record-label selection, stored-type conversion, and atomic option renames. Conversion uses the editor’s recommended policies by default; review the dry-run classification and pass --confirm-lossy only for an intentional explicit-lossy commit. File Fields use attachment commands and cannot be converted. relation update changes a forward Relation’s target, cardinality, or deletion policy. Field nullability is intentionally not exposed.

Use rows upsert when a caller has a stable business key but not a Row ID. It accepts one object or an array, updates the single matching row, and creates a row when no match exists. The key must contain stored, non-null Fields and identify at most one existing row:

Terminal window
eidos --json rows upsert tracker.eidos \
--table Tasks \
--key "External ID" \
--values '[{"External ID":"task-1","Title":"Ship CLI","Status":"doing"}]' \
--expected-revision 3 \
--dry-run

The response includes a plan showing create or update for each input; dry-run Row IDs are ephemeral, so use the IDs returned by the committed apply. Remove --dry-run to commit the entire batch as one revision. Duplicate input keys and keys matching multiple existing rows are rejected without changing the File.

Use rows mutate when a single atomic batch must mix creates, updates, and deletes for one Table:

Terminal window
eidos --json rows mutate tracker.eidos \
--table Tasks \
--expected-revision 4 \
--changes '[
{"kind":"update","rowId":"019...","values":{"Status":"done"}},
{"kind":"create","clientKey":"new-task","values":{"External ID":"task-2","Title":"Document"}},
{"kind":"delete","rowId":"019..."}
]'

rows mutate reuses the Runtime RowChange contract and either applies every change or none. Use --dry-run to inspect the result without changing the revision. The lower-level rows add/update/delete, schema-apply, and view-apply commands remain available when an Agent already owns the exact stable-ID mutation document.

Do not copy a local file and hand-build the File-field JSON. The attachment import command stages the bytes in the managed assets/ folder, derives canonical metadata, updates the exact cell with a revision check, and cleans staged or visible files when the mutation fails:

Terminal window
eidos --json attachment import tracker.eidos \
--table Tasks --row 019... --field Files \
--source /absolute/path/report.pdf \
--expected-revision 5

Repeat --source for one atomic multi-file import. Use --replace only when the whole cell should be replaced. If a file already exists below the directory containing the .eidos file, use attachment attach with --uri assets/name.ext to reference it without copying.

Remove exact entry IDs with attachment detach --entry 019..., or explicitly use --all. Detach and replace retain physical files because other records may still reference them. Check local paths, byte counts, media types, symlinks, and unreferenced managed files with:

Terminal window
eidos --json attachment verify tracker.eidos --diagnostics-limit 100

Broken references make the command exit nonzero. Orphaned assets are warnings and are never deleted automatically. After stale-revision, reload the target row and re-plan instead of replaying the attachment mutation.

Use the canonical Runtime for derived Fields. Preview Formula source text before committing it; the result includes the inferred type, dependencies, diagnostics, and optional sample values:

Formula uses a fixed SQLite 3.45 scalar-expression subset. See Formula expressions for the exact function whitelist and syntax; do not send arbitrary SQL or invent function aliases.

Terminal window
eidos --json formula preview tracker.eidos \
--table Tasks --name Total \
--formula '"Estimate" * 2' --type integer

Create or update a Formula with revision-checked Runtime preflight:

Terminal window
eidos --json formula add tracker.eidos \
--table Tasks --name Total \
--formula '"Estimate" * 2' --type integer \
--expected-revision 4 --dry-run
eidos --json formula update tracker.eidos Total \
--table Tasks --formula '"Estimate" + 1' --type integer \
--expected-revision 4

Create a Lookup after its Relation and target Field exist:

Terminal window
eidos --json lookup add tracker.eidos \
--table Tasks --name OwnerScore \
--relation-field Owners --target-field Score \
--aggregate sum --expected-revision 5

table create may include Formula fields in its initial field array and uses the same Runtime preflight path. Relation and Lookup fields are added after their referenced schema exists.

Lookup aggregates are values, first, count, sum, average, min, and max; add --distinct when distinct values are required. query and context automatically evaluate Formula, Lookup, and inverse Relation Fields when a Table contains them, so derived Fields may be projected, filtered, and sorted. Derived Fields are read-only in row mutations. Runtime rejects invalid types, missing targets, stale plans, and dependency cycles before commit. Deleting Formula or Lookup is explicitly lossy: preview it first and pass --confirm-lossy only after confirming the impact.

Schema changes support dry-run execution against the real transaction path before commit.

Terminal window
eidos --json schema-apply tracker.eidos \
--expected-revision 1 \
--op @schema-change.json \
--dry-run

schema-apply also accepts Runtime schema batches and resolves Table and Field names in settings, position, record-label, conversion, option-rename, Relation, Formula, and Lookup operations. CLI invocations do not share Runtime mutation tokens, so committed changes have no cross-command undo; use authorized Eidos Lite/Graft history or a known-good File copy for recovery.

Create a Calendar View from the stable Table and date/datetime Field IDs in schema output:

Terminal window
eidos --json view-apply tracker.eidos - <<'JSON'
{
"expectedRevision": "2",
"changes": [{
"kind": "create-view",
"clientKey": "calendar",
"tableId": "019...",
"name": "Calendar",
"type": "calendar",
"query": {},
"layout": { "dateField": "019..." },
"position": "1"
}]
}
JSON

The CLI allocates the View ID and returns it under createdViews. View query and layout references use stable Field IDs; display names are not accepted in the persisted View document. update-view supports explicit name, type, query, layout, and position patches; delete-view removes the stable View ID.