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.
0. Initialize the Eidos Skill
Section titled “0. Initialize the Eidos Skill”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:
eidos self skill initeidos self skill init --globalNo Node.js, npm, or npx is required. Use eidos self skill init --space <DIR> for another Space;
the command refuses to replace edited Skill files unless --force is explicit.
1. Read a bounded context
Section titled “1. Read a bounded context”eidos --json data query tracker.eidos Tasks \ --compact \ --fields Title,Status \ --limit 50--compact returns the file revision, compact schema, and logical rows. Pass --fields
to restrict returned columns, and --where to filter rows:
eidos --json data query tracker.eidos Tasks \ --compact \ --where '{"op":"ne","field":"Status","value":"done"}' \ --fields Title,Statusne is the Boolean complement of eq, so an empty Status also matches. Add an
is-not-null rule when empty values should be excluded.
2. Apply an exact change
Section titled “2. Apply an exact change”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"]}eidos --json data mutate tracker.eidos request.jsonAlternatively, use inline mutation flags directly:
eidos --json data mutate tracker.eidos \ --table Tasks \ --match '{"_id":"019..."}' \ --set '{"Status":"doing"}' \ --expected-revision 1revision / --expected-revision rejects stale work. The CLI validates the proposed final state before commit and returns the modified rows.
3. Validate the committed file
Section titled “3. Validate the committed file”eidos --json file validate tracker.eidos --level fullTreat a nonzero exit status at any step as a failed workflow. Do not continue from guessed or partially parsed output.
Agent-facing row and schema intent
Section titled “Agent-facing row and schema intent”For common schema changes, use the intent commands under schema 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:
eidos --json schema field add tracker.eidos \ --table Tasks --name Due --type date \ --expected-revision 1 --dry-run
eidos --json schema field add tracker.eidos \ --table Tasks --name Owners --type relation --target-table People \ --cardinality many --on-delete detach \ --expected-revision 2
eidos --json schema table update tracker.eidos Tasks \ --record-label Title --content-field Notes --dry-run
eidos --json schema field update tracker.eidos Estimate \ --table Tasks --type integer --dry-run
eidos --json schema field update tracker.eidos Owners \ --table Tasks --cardinality one --dry-runtable 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 asset commands and cannot be
converted. schema field update on a relation changes its target, cardinality,
or deletion policy. Field nullability is intentionally not exposed.
Use data mutate --key 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:
eidos --json data mutate tracker.eidos \ --table Tasks \ --key "External ID" \ --insert '[{"External ID":"task-1","Title":"Ship CLI","Status":"doing"}]' \ --expected-revision 3 \ --dry-runThe 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 data mutate --changes when a single atomic batch must mix creates, updates, and
deletes for one Table:
eidos --json data 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..."} ]'data 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 schema apply and schema view apply commands remain available when an Agent already owns the exact stable-ID mutation document.
Attachment automation
Section titled “Attachment automation”Do not copy a local file and hand-build the File-field JSON. The
data asset 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:
eidos --json data asset import tracker.eidos \ --table Tasks --row 019... --field Files \ --source /absolute/path/report.pdf \ --expected-revision 5Repeat --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 data asset attach with
--uri assets/name.ext to reference it without copying.
Remove exact entry IDs with data asset 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:
eidos --json data asset verify tracker.eidos --diagnostics-limit 100Broken 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.
Runtime Formula and Lookup
Section titled “Runtime Formula and Lookup”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.
eidos --json schema field preview tracker.eidos \ --table Tasks --name Total \ --formula '"Estimate" * 2' --type integerCreate or update a Formula with revision-checked Runtime preflight:
eidos --json schema field add tracker.eidos \ --table Tasks --name Total --type formula \ --formula '"Estimate" * 2' --result-type integer \ --expected-revision 4 --dry-run
eidos --json schema field update tracker.eidos Total \ --table Tasks --formula '"Estimate" + 1' --result-type integer \ --expected-revision 4Create a Lookup after its Relation and target Field exist:
eidos --json schema field add tracker.eidos \ --table Tasks --name OwnerScore --type lookup \ --relation-field Owners --target-field Score \ --aggregate sum --expected-revision 5schema 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. data query
automatically evaluates 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.
Lower-level operations
Section titled “Lower-level operations”Schema changes support dry-run execution against the real transaction path before commit.
eidos --json schema apply tracker.eidos \ --expected-revision 1 \ --op @schema-change.json \ --dry-runschema apply 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 dump output:
eidos --json schema 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" }]}JSONThe 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. schema view update supports explicit name, type,
query, layout, and position patches; schema view delete removes the stable View ID.