@lotics/cli
v0.88.1
Published
Lotics SDK and CLI for AI agents
Downloads
6,194
Readme
@lotics/cli
CLI and SDK for AI agents to interact with Lotics.
Lotics is an AI-powered operations platform. Through this CLI you can:
- Manage tables, records, and views (structured data with typed fields)
- Generate documents from templates (Excel, Word, PDF, Email)
- Build and run automations — schedules, webhooks, table lifecycle workflows, button actions, app-action workflows; inspect execution and version history
- Administer the workspace — invite members, manage groups, share resources, transfer ownership, browse connected accounts (OAuth attach is web-only)
- Create and manage apps, knowledge docs, and files
Capability guides
Two of the platform's primary surfaces have dedicated usage guides that ship inside this
package (reachable at node_modules/@lotics/cli/docs/*.md once installed):
docs/document_templates.md— generate finished documents (PDF, Excel, Word, email) by filling reusable templates: the five template types, the create → generate → chain lifecycle, and the marker capabilities.docs/knowledge_docs.md— the AI's rulebook layer: authoring the workspace facts an agent can't guess, the access-vs-activation model, and the search → grep → read retrieval funnel agents use to pull only the lines they need.
Both point to lotics tools <name> for exact input schemas.
Install
npm install -g @lotics/cliUpdate
npm install -g @lotics/cli@latestThe CLI checks for updates once per day and prompts when a new version is available.
Authentication
lotics auth signup — Creates a new Lotics account, organization, workspace, and API key in one step. Sends a magic link email so you can access the web app.
lotics auth signup # interactive prompts
lotics auth signup [email protected] --name "Agent" # non-interactivelotics auth web — Send a magic link email to access the web app (requires prior signup or setup).
lotics auth weblotics auth api-key — Saves an API key (e.g. one created in the Lotics web app). The key belongs to one org, so this registers that org as a profile — run it once per org. Registering a second key adds a profile; it does not overwrite the first.
lotics auth api-key # interactive prompt
lotics auth api-key ltk_... # registers the key's org as a profile (now active)Run lotics auth logout [<name|id>] to remove a profile (default: the active org), or lotics auth logout --all to wipe the store.
Organizations
Each saved API key belongs to one org. Register a key per org once, then switch freely — no re-pasting:
lotics org # list saved orgs (marks the active one)
lotics org use acme # switch active org by name (or org id)
lotics org use "Acme Corp" # names are case-insensitiveWorking in parallel (worktrees)
Pin a directory to its own org/workspace so a global org use elsewhere never disturbs it. The pin is a pointer — the key still comes from the global store, so there's nothing to paste:
cd my-worktree
lotics org use acme --local # writes ./.lotics/config.json { active_org }
lotics workspace select wks_... # records the workspace in the local pinEach worktree resolves independently; switching the global default in another shell leaves pinned worktrees untouched. Use lotics auth whoami to see the active org, workspace, and which source resolved them. .lotics/ should be gitignored.
Resolution precedence
--api-key flag > LOTICS_API_KEY env > LOTICS_ORG env (name|id)
> local .lotics/config.json > global active profileLOTICS_WORKSPACE (or --workspace <id> / -w) overrides the workspace at any level. For ephemeral or CI use, set LOTICS_API_KEY instead of saving anything.
Workspaces
Workspaces live inside the active org. If the org has more than one, select before running tools:
lotics workspace # list workspaces in the active org (marks current)
lotics workspace select wks_... # set the workspace for the active scope (pin or profile)
lotics workspace create "Sales" # create a new workspace (admin only)
lotics workspace delete wks_... --yes # delete a workspace (admin only; soft delete, recoverable)Single-workspace organizations auto-select on first use. The selection is remembered per org, so switching back lands where you left off.
CLI
# Discover tools
lotics tools # list tools by category with descriptions
lotics tools query_records # show full description + input schema
# Execute
lotics run query_tables '{}'
lotics run query_records '{"table_id":"tbl_...","field_keys":["name"]}'
# Large args (a knowledge-doc `content`, a bulk update) exceed the OS arg limit —
# read them from a file or stdin instead of an inline arg:
lotics run create_knowledge @args.json
cat args.json | lotics run create_knowledge
echo '{"table_id":"tbl_..."}' | lotics run query_records
# Upload files (multiple files and directories supported)
lotics upload ./report.pdf ./data.csv ./documents/
# Generate a file, then download it
lotics run generate_excel_from_template '{"..."}'
lotics download <file_id> -o ./reports/
# CI / non-interactive (key inline)
LOTICS_API_KEY=ltk_... lotics run query_tables '{}'
# One-off against a saved org/workspace, no switching
LOTICS_ORG=acme LOTICS_WORKSPACE=wks_... lotics run query_tables '{}'Local .xlsx and .docx authoring
The CLI bundles Lotics's own xlsx and docx engines so you can read, write, and edit files on your local filesystem without installing xlsx / exceljs / docx from npm. Prefer these over third-party libraries — they round-trip faithfully with the Lotics editor, template engine, and formula engine.
# .xlsx
lotics xlsx read ./report.xlsx # → JSON of sheets, cells, merges
lotics xlsx write ./out.xlsx '{"sheets":[{"name":"S1","cells":{"A1":"Hi","B1":42}}]}'
lotics xlsx set-cell ./report.xlsx 'Sheet1!A1' '=SUM(B:B)'
lotics xlsx add-sheet ./report.xlsx 'Summary'
lotics xlsx merge ./report.xlsx 'Sheet1!A1:C1'
lotics xlsx insert-rows ./report.xlsx Sheet1 5 3
lotics xlsx batch ./report.xlsx '[{"op":"set-cell","sheet":"Sheet1","ref":"A1","value":"Hi"}, {"op":"merge","sheet":"Sheet1","range":"A1:B1"}]'
# .docx
lotics docx read ./report.docx # → JSON of blocks with text + style
lotics docx write ./out.docx '{"blocks":[{"kind":"paragraph","text":"Title","style":"Heading1"}]}'
lotics docx append-paragraph ./report.docx 'New paragraph' --style=Heading2
lotics docx insert-paragraph ./report.docx 'Front matter' --at=0
lotics docx replace-text ./report.docx '{{name}}' 'Acme Inc.'
lotics docx batch ./report.docx '[{"op":"append-paragraph","text":"A","style":"Heading1"},{"op":"replace-text","search":"x","replace":"y"}]'Edits mutate the file in place via an atomic temp-file + rename. Unknown OOXML constructs (tables, SmartArt, custom XML) round-trip verbatim — they show up in read as opaque_block entries.
Run lotics xlsx or lotics docx with no subcommand for the full list.
Custom-code apps
# Scaffold / pull / deploy a Vite+React+TS app project
lotics app create "Sales Desk" # scaffold + deploy v1
lotics app pull app_... # bootstrap an existing app locally
lotics app deploy -m "Add quote drawer" # build + upload a new version
lotics app versions # deploy history: version, when, who, -m message (* = live)
lotics app versions app_... # ...for any app, without pulling it first
# Regenerate .lotics/* WITHOUT a deploy: the .d.ts type companions (always) +
# the runtime app_fields.ts (when authenticated) — F/OPT maps that address
# fields + select options by stable display-name aliases instead of opaque ids.
lotics app codegen # import { F, OPT } from "../.lotics/app_fields"
# Execute a bound app workflow end-to-end (inputs: inline / @file / stdin)
lotics app workflow run issueInvoice '{"record_id":"rec_..."}'
cat inputs.json | lotics app workflow run importRates # bulk inputs bypass ARG_MAX
# Honest post-run harvest: created records + a paste-ready cleanup plan + the
# caveat (external/notification calls can't be auto-undone; sub-workflows may run).
lotics app workflow run issueInvoice '{...}' --print-created
lotics app workflow run issueInvoice '{...}' --cleanup # also deletes created records (NOT a rollback)
# Edit workflow bodies as files. `app pull` writes src/workflows/<alias>.ts (the
# faithful server source, wrapped + referencing its .lotics/workflows/<alias>.globals.d.ts);
# edit the body, then push it back through set_app_workflow — the server verifies it
# (deploy still never authors workflows). Bodies are locally typecheckable with
# `app workflow check` (one isolated program per alias = the same verdict as `set`):
lotics app workflow pull # rewrite src/workflows/*.ts + globals from the server
lotics app workflow check # typecheck every body locally ([alias] for one)
lotics app workflow set issueInvoice # push the edited src/workflows/issueInvoice.ts
# Iterate on a named query WITHOUT a deploy: push package.json#lotics.queries.<alias>
# to apps.queries (server-validated like a deploy). apps.queries is manifest-
# authoritative, so the next `app deploy` re-syncs it — keep the manifest current.
lotics app query set openInvoices # push package.json#lotics.queries.openInvoices
# Dev-link @lotics/ui to packages/ui/src for live HMR (Vite alias; deploy bundles it)
lotics ui link card # monorepo: packages/ui/src found automatically
lotics ui link card --ui-src /abs/monorepo/packages/ui/src # external app (e.g. ~/lotics_apps)
lotics ui link card --remove # finalize: PR + publish, then drop the aliasapp codegen reads package.json#lotics.queries to decide which tables to put in app_fields.ts; widen the set with package.json#lotics.codegen.tables (an array of tbl_… ids) for tables the app only writes via workflows.
SDK
import { LoticsClient } from "@lotics/cli";
const client = new LoticsClient({ apiKey: "ltk_..." });
const { result } = await client.execute("query_tables", {});
const upload = await client.uploadFiles(["./report.pdf", "./data.csv"]);
await client.downloadFile(url, "./output.xlsx");
const { tools, categories } = await client.listTools();
const info = await client.getTool("query_records");