@lotics / cli
用于AI代理与Lotics交互的CLI和SDK。
Lotics是一个人工智能运营平台。通过这个命令行,你可以:
- 管理表、记录和视图(带有类型化字段的结构化数据)
- 从模板生成文档(Excel, Word, PDF, Email)
- 构建和运行自动化-时间表,webhook,应用程序工作流;检查执行和版本历史记录
- 管理工作空间——邀请成员、管理群组、共享资源、转移所有权、浏览已连接的帐户(OAuth附件仅限web)
- 创建和管理应用程序、知识文档和文件
能力指导
lotics docs 列出了这个CLI的引用,包含在其中——模型引用和每一个
文档下面-文档总是描述二进制答案。 lotics docs <area> 打印一个
(lotics docs reference). 每个答案都以一页纸为限,所以一份长长的文件会交出它的章节列表
和 lotics docs <area>/<section>. 一个CLI副本缺少的页面——一个服务器随后添加的页面
一个错误可以引用-从服务器读取,并且 lotics docs [<area>] --grep <text> 搜索
引用服务器提供的服务;两者都使用这台机器的凭证。自定义代码应用程序的SDK参考
船内 @lotics/app-sdk,在应用程序自己的 node_modules.
从代理那里驱动命令行?开始 AGENTS.md (node_modules/@lotics/cli/AGENTS.md)
——哪个表面能回答哪个问题,每个命令都适用的惯例,以及陷阱。
每个命令契约,标志,退出代码和陷阱都在
文档/ cli_reference.md; lotics --help 是始终当前的动词列表。
该平台的主要表面都有专门的使用指南
包裹(可在 node_modules/@lotics/cli/docs/*.md 一旦安装):
docs/getting_started.md-一个工作空间容纳什么和一个页面 为每个职位开放。docs/first_build.md-一个调用一个调用构建的整个工作空间:哪些应用程序,每一行的处理,检查拒绝了什么。docs/building_an_app.md-构建一个端到端应用程序:一个应用程序 表述成一棵树,用set_app,或者一个自定义代码的应用程序@lotics/app-sdk. 在启动应用程序之前先读一遍。docs/document_templates.md-生成成品文件 (PDF, Excel, Word, email)通过填写可重复使用的模板:五种模板类型 创建→生成→链的生命周期,以及标记能力。docs/migration.md-当一个版本改变了CLI时该怎么办 写入磁盘;当磁盘上的某些内容不再与CLI所做的匹配时,读取一次。docs/knowledge_docs.md- AI的规则手册层:编写 特工猜不透的程序和政策,谁能看懂文件,还有 搜索-读取检索代理只使用它们需要的行。docs/app_architecture.md-一个工厂被分成应用程序,而且docs/working_in_a_workspace.md-每个工作一旦存在的手段。
用两个命令启动
安装CLI并创建一个帐户;然后使用以下工具构建帐户的工作空间:
curl -fsSL https://lotics.ai/install.sh | bash
lotics auth signup [email protected]
安装程序下载一个编译后的可执行文件——没有Node.js,没有npm:每个应用程序都部署在上面 激流的。Node 18+仅适用于定制代码应用程序,该应用程序构建在这台机器上进行部署。
描述你的工作空间
表和应用程序由两种工具编写,在CLI和MCP上都是一样的。 set_tables 需要
{ "tables": [...] } -总是一个列表,全部或没有-每个表都是一个由别名键控的文档:它的字段
(通过别名键入)、选项、链接、视图以及如何识别一行。链接通过id或
由 ref 的另一个表的相同的调用,和状态 multi;一个双向链路状态 pair 在
两个表。表由其文档的RFC 7396合并补丁编辑,其中 null 删除。
set_app 每次调用一个应用程序: { "body": <the App tree> } 要创建,树表示应用程序的 name; { "app_id": …, "nodes": { "<address>": <patch> } } 更改一个节点(应用程序自己的道具通过更改) body). 两者都创建when
没有给定id并在给定id时进行编辑 dry_run 不写支票。每个答案都说明了权限
允许和删除写入。
新的工作空间:一个 set_tables 调用表(每个表最多有50,200个第一行,一次调用),然后调用每个表 set_app 呼叫,然后修复。
lotics docs reference # the keys, with a worked example
lotics run set_tables @tables.json # every table of the workspace, in one call
lotics app apply orders.app.json --check # set_app as a dry run: everything wrong, nothing written
lotics app apply orders.app.json # set_app: creates the app, or edits the one the file records
答案指出了一个应用程序未声明的处理,它的行需要;中没有写入任何内容 树给你。更改文件并再次应用;再次应用较早的树是撤消表更改 数据写入会保留。
另一个方向: lotics app pull <app_id> 将应用程序的树写入文件。
安装
curl -fsSL https://lotics.ai/install.sh | bash # macOS, Linux, WSL — no Node.js needed
npm install -g @lotics/cli # or, if you already have Node 18+
irm https://lotics.ai/install.ps1 | iex # Windows PowerShell — no Node.js needed
更新
lotics upgrade 就地更新此CLI,运行该副本来自哪个安装程序。通过
手动:重新运行您使用的安装程序; npm install -g @lotics/cli@latest 更新NPM
安装。
当有新版本可用时,CLI每天检查一次更新,并在stderr上打印一个说明,命名正确的安装程序。
身份验证
两种凭证,你持有哪一种决定了什么 logout 所做的。 auth signup / auth login 给这台机器一台 登录 -它代表你,承担你的任何角色,你可以在设置→安全→查看和撤销 按键和终端;它会在90天后失效,每使用一次就会过期。 auth api-key 保存一个 API密匙 发出管理员命令。管理员在设置中创建的键有自己的名称和访问权限,可以访问每个应用程序和表,也可以只访问键上选择的那些;为一个人创建的密钥具有这个人的访问权限,当这个人被删除时,它就停止工作了。这两种类型通常存在于服务器和其他人的机器上,只有管理员才能撤销它。 lotics auth whoami 打印这台机器持有的类型-从保存的配置文件,或者从配置文件没有说明的服务器。
当凭证停止工作时,拒绝说明它已失效的三种方式中的哪一种-“…已被撤销。”/“……过期了。”/“……属于一个在本组织不再活跃的成员。”-和它的 hint 列出补救措施: lotics auth login <email> 对于终端登录,请管理员为API密钥提供新密钥。如果一个凭证的记录中没有说明它是两者中的哪一个,则该凭证将同时得到两者。服务器根本无法识别的密钥得到一个通用的答案,这是故意的:无法识别的密钥从被拒绝中学不到任何东西。
lotics auth signup -一步创建新的Lotics帐户、组织、工作空间和API密钥。发送一个神奇的链接电子邮件,这样你就可以访问web应用程序。
lotics auth signup # interactive prompts
lotics auth signup [email protected] --name "Agent" # non-interactive
lotics auth login -在已经存在的帐户中签名,在新机器上或将另一个组织添加到持有密钥的组织(您选择的组织变为活动)。 它不会等你。 它打印要打开的页面(也通过邮件发送给您)和页面必须显示的代码,然后退出。如果被要求登录,检查代码,按确认键,然后运行您想要运行的任何操作:下一个需要凭据的命令在执行自己的工作之前收集密钥。
lotics auth login [email protected] # prints the page + code, exits — nothing to keep open
# …press Confirm in the browser…
lotics auth whoami # picks up the key, then answers
lotics auth login [email protected] --wait # one command instead: holds the terminal until Confirm
lotics auth login [email protected] --local # pins this directory to that org (implies --wait)
在按下确认键之前运行的命令将重新命名页面和代码并退出1;请求的有效期为15分钟,之后的下一个命令要求再次请求。重新运行 auth login 总是安全的——它会替换请求,所以只有最新的代码才是有效的。
lotics auth web -发送一个神奇的链接电子邮件访问web应用程序(需要事先注册)。如果帐户的电子邮件地址从未被确认过,并且它持有密码,那么使用链接登录将删除该密码;该命令是这样说的,并指明了位置 忘记了密码 设置一个新的。
lotics auth web
lotics auth api-key -保存API密钥(例如在Lotics web应用程序中创建的密钥)。密钥属于一个组织,所以这个 将该组织注册为配置文件 -每org运行一次。注册第二个键添加配置文件;它不会覆盖第一个。
lotics auth api-key # interactive prompt
lotics auth api-key ltk_... # registers the key's org as a profile (now active)
运行 lotics auth logout [<name|id>] 要删除配置文件(默认为活动组织),或 lotics auth logout --all 擦店。在固定目录中,裸表单将删除 销,而不是配置文件-命名要删除其凭据的组织。保存的配置文件 auth login / auth signup 是一个 登录,注销也会在服务器端撤销它。一个被 auth api-key 是一个管理员颁发的密钥,其他机器也可以持有,所以它只会从这台机器上删除,并保持活跃,直到管理员在设置→API密钥下撤销它。在记录类型之前保存的配置文件没有说明任何信息,因此只有当答案是登录时,才会询问服务器并撤销凭证。
组织
每个保存的API密钥属于一个组织。注册一个密钥每org一次,然后自由切换-没有重新粘贴:
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-insensitive
的组织 id 是身份;该名称是密钥保存的标签,它是你的-在应用程序中重命名组织永远不会移动它,因此脚本范围继续运行。 lotics auth whoami 学习新名称并记录在标签旁边;都解决了,而且 lotics org 打印 label (server: name) 虽然他们不同。匹配两个保存的组织的名称被拒绝而不是猜测;使用id。
并行工作(工作树)
将一个目录固定到它自己的/workspace,所以是全局的 org use 其他地方从不打扰它。大头针是一个指针——键仍然来自全局存储,所以没有什么需要粘贴的:
cd my-worktree
lotics org use acme --local # writes ./.lotics/config.json { active_org }
lotics workspace select wks_... # records the workspace in the local pin
每个工作树独立解析;在另一个shell中切换全局默认值不会影响固定的工作树。 .lotics/ 应该被忽略。
解析工作区的每个命令在执行之前都会命名其目标 lotics → Starters / Equipment & Projects 在 stderr,因此stdout对管道保持干净。这两部分都是name,因为该行的存在是为了在破坏性写入之前读取;在任何命令第一次列出工作空间时,工作空间的名称将缓存在其id旁边,在此之前,该行将打印id并表示还不知道该名称。如果目录或环境中没有任何内容选择org,并且它来自机器范围的默认值,则该行表示org并打印 --local 命令来固定——默认是另一个shell可以在您的两个命令之间移动。 lotics auth whoami 根据要求报告相同的决议,包括哪个来源获胜。
解决优先级
--api-key flag > LOTICS_API_KEY env > LOTICS_ORG env (name|id)
> local .lotics/config.json > app manifest workspace → its saved profile
> global active profile
LOTICS_WORKSPACE (或 --workspace <id> / -w)覆盖任何级别的工作空间。对于临时或CI使用,设置 LOTICS_API_KEY 而不是保存任何东西。
LOTICS_ORG 在任何命令运行之前解析一次。 与未保存的凭据匹配的值拒绝一个句子中的每个动词——不需要凭据的读、写和检查——并且拒绝列出该机器持有的组织,因此无需另一个命令即可回答。即使键以另一种方式到达,它也会拒绝:限定命令范围的变量在此期间不得未读 LOTICS_API_KEY 将写入发送到其他地方。当变量解析并提供键时,键决定组织,命令就这样说。组织保留保存它的名称:服务器端重命名永远不会移动它,新名称也会解析,并且 lotics org 当它们不同时打印。
在自定义代码应用的目录中, lotics app deploy 当没有显式选择凭证时,从目录派生凭证:清单命名应用程序的工作空间,当只有一个保存的配置文件拥有该工作空间时,使用该配置文件-永远不会咨询机器范围的默认值。一个显式的标志、env var或目录pin仍然占上风,而一个组织的配置文件记住了不同的工作空间,它就会被忽略为宣布的默认值。
诊断
每个请求都标识CLI (user-agent: lotics-cli/<version> node/<v> <platform>),并将生成它的命令命名为(x-lotics-cli-command: app.apply),因此服务器日志中的故障可以追溯到产生该故障的动词和版本。两个头文件都不带参数:命令链在任何id、path、 @file,或JSON有效负载。它还列出了旧的CLI不能做的事情(x-lotics-cli-capabilities: docs-fallback),因此服务器以如下格式进行响应:错误将页面命名为 lotics docs <path> 的命令行 docs-fallback,以及 lotics run docs '{"path":"<path>"}' 对任何其他人。
LOTICS_TELEMETRY=1 另外记录会话。 默认为关闭。在shell配置文件中而不是每个命令中设置它—每个调用都是它自己的进程。当设置:
- 请求携带一个会话id,由每个命令共享——在代理控制下,它采用控制自己的会话id,否则它会在30分钟空闲后转过来(
~/.lotics/session.json)。 - 每次调用都将一条记录追加到
~/.lotics/telemetry-<host>.ndjson-命令、退出代码、执行时间,以及在出现故障时打印的消息。CLI与每个Lotics对话一个线轴,因此针对一个实例的记录只发送给该实例。批处理是在以后对同一主机运行时发送的;失败的发送将被重新尝试,而不会被静默丢弃。
争论有助于 哈希 和一个 形状 (records[].data.name:string),没有其他内容——没有值、没有文件内容、没有记录数据。散列是关键:连续出现两次具有相同散列的失败意味着错误消息没有告诉您足够的信息来修复调用。
不设置,不存储任何内容,不发送任何内容,也不创建假脱机文件。
报告问题
lotics report '{"goal":"rename a view","actual":"no command does it","wanted":"lotics run set_tables"}'
lotics report @report.json # a long one, from a file
cat report.json | lotics report - # or from stdin — `-` is required, see below
lotics report # the frame, and what is worth reporting
这就是上面记录的通道 不能 秀。他们捕获的所有东西都挂在 命令失败了,这遗漏了两件最有价值的事情:一是不成功的能力 存在(没有运行任何命令,因此没有记录任何内容)和执行错误操作的命令退出0 事情。同样值得发送的还有:一个错误的消息没有告诉你如何修复它,以及任何类似的事情 使创作速度比应有的慢。
报告是一个框架,而不是一个段落。 日志可以重建你 跑;没有什么可以 重建你 想要,两者之间的差距就是报告。
| 场 | ||
|---|---|---|
goal | 要求 | 你想要完成的事情 |
actual | 要求 | 结果呢? |
expected | 你所期望的-这和 actual 是缺陷吗? | |
tried | 你已经试过了,还有上面写的 | |
wanted | 什么能让你解脱 |
没有严重程度或类别可选。
从stdin中读取需要显式的 -. 与 - 裸形式总是打印框架和a
吹笛的要等多久就等多久。
如果 LOTICS_TELEMETRY=1 设置后,会话中的命令会自动附加—不要重新键入
他们。无论遥测是否开启,它都会运行(调用它是被动记录的同意)
需要一个选择),帖子立即,并告诉你,如果它没有着陆。
不要粘贴记录、文件内容或凭证。
工作区
工作区位于活动组织内。如果组织有多个工具,请在运行工具之前选择:
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" --timezone America/New_York --currency USD
# create a new workspace (admin only); without the flags it
# takes the org's oldest workspace's zone and currency
lotics workspace settings --currency USD --timezone America/New_York
# change the current workspace's name/currency/zone
lotics workspace delete wks_... --yes # delete a workspace (admin only; soft delete, recoverable)
单一工作空间组织在第一次使用时自动选择。每次选择都会被记住,所以切换回你离开的地方。
命令行界面
# Discover tools
lotics tools # list tools by category with descriptions
lotics tools query_records # show full description + input schema
# Execute
lotics run get_workspace '{"kind":"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 set_knowledge @args.json
cat args.json | lotics run set_knowledge - # the trailing - reads stdin
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_document '{"..."}'
lotics download <file_id> -o ./reports/
# What is in the store, newest first — one page, with the command for the next one
lotics file list --limit 50
# CI / non-interactive (key inline)
LOTICS_API_KEY=ltk_... lotics run get_workspace '{}'
# One-off against a saved org/workspace, no switching
LOTICS_ORG=acme LOTICS_WORKSPACE=wks_... lotics run get_workspace '{}'
知识文档
在工作空间的知识文档之上的文件原生表面——人工智能的规则手册层。主体是一个Markdown文件: create/update 从文件系统中读取它, get 把它写回来。看到 docs/knowledge_docs.md 对于模型。
lotics knowledge list # catalog: id, name, description (--json)
lotics knowledge create --name "Shipping tariffs" \
--description "HS-coded rates; searchable by lane and code" \
--from ./tariffs.md # or --content '<inline>'; prints the new id
lotics knowledge get kdc_... -o ./tariffs.md # body → file (omit -o for stdout; --json = full doc)
lotics knowledge update kdc_... --from ./tariffs.md # send only what changed (--name / --description too)
lotics knowledge rm kdc_... [kdc_...] # delete; sharing and history are kept
lotics knowledge list --deleted # deleted docs you can restore
lotics knowledge restore kdc_... [kdc_...] # bring them back, all or none
create / update 是工具吗? set_knowledge (没有 knowledge_doc_id 创建一个文档(一个补丁),并将正文内联发送;服务器对内容文件(和文件)进行生成和版本链 update Diffs +在内部解决并发性(不需要传递令牌)。 get 是一个内容读取路径,为服务器端身体补水。
自定义代码的应用
# Your own project depending on @lotics/app-sdk (React 19); `npm run build` writes a static dist/ with index.html
lotics app create "Sales Desk" --custom . # registers the app, links this directory by package.json#lotics
lotics app deploy -m "Add quote drawer" # build + upload a new version of the live app
lotics app pull # in the project: bring it up to the live version (refused while it has edits)
# What the app reads and writes is bound on the app, and each change mints a version:
lotics run set_app_queries '{"app_id":"app_...","queries":{"openInvoices":{...}}}'
lotics run set_workflow '{"source":"on({ type: \"app\", app_id: \"app_...\", alias: \"issueInvoice\" });\n..."}'
# Running an app's alias is a TOOL call, like every other tool. Exits non-zero
# when the RUN failed, not only when the call did.
lotics run run_app_query '{"app_id":"app_abc","alias":"openInvoices","params":{}}'
lotics run run_app_workflow '{"app_id":"app_abc","alias":"issueInvoice","inputs":{...}}'
lotics run run_app_workflow '{...}' --print-created # the records it created + a cleanup plan
该应用程序的SDK参考是 node_modules/@lotics/app-sdk/AGENTS.md 一旦项目安装它。 lotics tools <name> 打印任何工具的输入。
SDK
import { LoticsClient } from "@lotics/cli";
const client = new LoticsClient({ apiKey: "ltk_..." });
const { result } = await client.execute("get_workspace", {});
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");