ACTIAS

The shell

One statement against the project's classes, kv and databases, spelled as a script spells it, with an immediate answer.

Where it is

The project has one shell: the Shell entry in the console's sidebar, or actias shell <project> in the cli. Every class page's open the shell lands there with that class filled in.

Auction:find { status = "open", high_bid = { gt = 100 } }
  3 entries · 41 ms
  name       status  high_bid  closes_at
  lot-42     open    120       1788292618009
  lot-57     open    340       1788292700114
  lot-61     open    105       1788293001922

The line is typed by the analyser that checks a script: a misspelled field underlines before anything is sent, and after page = Auction:find { ... } the next line completes page.entries. Names complete from what the project holds, inside the quotes of kv(" and database(".

What binds

BindingSpelledResolves into
a class with a directoryAuction:list {…}, Auction:find {…}, Auction:visit {…}the class page's directory query
an instanceAuction("lot-42"):bid("ada", 120)one call through the object's own lane (write mode)
a kv namespacekv("users"):get("ada"), :list(), :set("k", v), :delete("k")the KV page's requests
a databasedatabase("main"):query(sql, params), :exec(sql, params)the database page's query and execute

Each of those is one statement: it resolves where you typed it into the request the corresponding console page already makes, and nothing is woken. \resources lists what the project holds; \fields Auction lists a class's declared fields and methods.

kv("presence"):list()
kv("presence"):get("ada")
database("directory"):query("select name from handles limit 3")
Auction:list { where = { status = "open" }, order = { high_bid = "desc" }, limit = 20 }
Auction:visit { where = { status = "open" } }     -- every row checked against its object

Read-only and write mode

A session starts read-only. \write lifts it; \read puts it back.

Runs read-onlyNeeds \write
list, find, visit; kv get, list; database querykv set, delete; database exec; every method call

A method call goes through the object's own lane, serialized with every other call, exactly as a script's call would. Nothing declares which methods write, so a read-only session refuses a call rather than hiding it. Naming an instance that does not exist creates it, admission permitting.

In write mode every call and every chunk is logged by the api against your account, one line per action:

shell call by ada on 3f2de568-…: Auction("lot-42"):bid
shell run by ada on 3f2de568-…: 95 chars, write

Chunks

A loop, an expression, a value used as an argument: those are not one statement, and the shell does not pretend otherwise. Such a line runs as a chunk, in a fresh vm on a worker, under your grants. So does anything you give to \run or \paste.

Auction:get(Auction:find().entries[1].name)     -- a nested call: a chunk
-- \run, then paste; an impromptu join across a class and a namespace
local presence = kv "presence"
local rows = {}
for _, e in Auction:find({ status = "open" }).entries do
    table.insert(rows, { lot = e.name, seen = presence:get("lot:" .. e.name) ~= nil })
end
return rows
In a chunkWhat it is
kv "…", database "…", objects "…"the bindings a script has, scoped to every namespace, database and class the project holds
Auction, every class by namepre-bound class handles
Auction:get("lot-42")a handle to call, as in a script; the row is Auction:find({ name = "lot-42" }).entries[1]
a bare expressionreturned, the way a repl does
print and log.*captured and shown in order with the value
the budgeta request's work budget, and 30 seconds of wall time (60 at most)
errorsreported with the line number in what you pasted

The session's mode travels with the chunk. In a read-only session the vm refuses kv set, set_batch and delete, database exec and every method call inside the chunk, naming \write:

runtime error: kv set is a write, and this shell session is read-only; \write allows it

A chunk is possible and not encouraged: the one-statement forms are what the shell is for, and a chunk you would run twice is a script.

Commands

CommandDoes
\write, \readswitch the session's mode
\fields Auctionthe class's declared fields and methods
\resourcesthe classes, kv namespaces and databases the project holds
\run (console)open a buffer for a chunk; ctrl+enter runs it
\run <path> (cli)run a file as a chunk
\paste … \end (cli)read lines until \end, then run them as a chunk
\clearforget the history and the names it bound
\help, \quitas named

A line starting with -- is a comment and does nothing.

From a pipe

The cli shell reads statements from stdin when it is not a terminal, one per line, and prints each answer, so a scripted check is a heredoc:

actias shell 3f2de568-f50b-4bcd-8877-a9c8a1f58797 <<'EOF'
\resources
Auction:find { status = "open" }
kv("presence"):list()
\quit
EOF

Completions come from the language service when actias-luau is beside the binary or on your PATH, and from the project's contract otherwise; the banner says which.

Access

StatementNeeds on the project
directory reads, database querydatabase read
kv get, listkv read
kv set, deletekv write
database exec, method calls, chunksdatabase write, whatever the session's mode

Limits

LimitValue
rows per directory page500, whatever the statement asks for; the cursor is how to have more
kv list page100 by default, 1000 at most
chunk wall time30 seconds by default, 60 at most
chunk worka request's budget
historythe session's; \clear forgets it

Gotchas

  • Auction:get("lot-42") in a chunk is a handle, not the row. In a statement, the same spelling reads the row.
  • A bare name in { name = name } is a variable, and an undefined one: the analyser says so before enter, and a chunk sees nil.
  • order takes one field, as everywhere.
  • The shell is per project. A class, namespace or database another project holds is "not in this project".