@lotics/cli 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -5
- package/dist/src/cli.js +84 -12
- package/dist/src/client.d.ts +1 -0
- package/dist/src/client.js +2 -1
- package/dist/src/config.d.ts +1 -0
- package/dist/src/config.js +11 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -23,17 +23,34 @@ npm install -g @lotics/cli@latest
|
|
|
23
23
|
|
|
24
24
|
The CLI checks for updates once per day and prompts when a new version is available.
|
|
25
25
|
|
|
26
|
-
##
|
|
26
|
+
## Authentication
|
|
27
|
+
|
|
28
|
+
**`lotics signup`** — Creates a new Lotics account, organization, workspace, and API key in one step. Prints email and auto-generated password for web app login.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
lotics signup # interactive prompts
|
|
32
|
+
lotics signup --email a@b.com --name "Agent" # non-interactive
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**`lotics auth`** — Saves an existing API key directly (e.g. one created in the Lotics web app).
|
|
27
36
|
|
|
28
37
|
```bash
|
|
29
|
-
#
|
|
30
|
-
lotics auth
|
|
38
|
+
lotics auth # interactive prompt
|
|
39
|
+
lotics auth ltk_... # non-interactive
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
API key is saved to `~/.lotics/config.json`. Run `lotics logout` to remove saved credentials.
|
|
43
|
+
|
|
44
|
+
Auth priority: `--api-key` flag > `LOTICS_API_KEY` env > `~/.lotics/config.json`.
|
|
31
45
|
|
|
32
|
-
|
|
46
|
+
## CLI
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Discover tools
|
|
33
50
|
lotics tools # list tools by category with descriptions
|
|
34
51
|
lotics tools query_records # show full description + input schema
|
|
35
52
|
|
|
36
|
-
#
|
|
53
|
+
# Execute
|
|
37
54
|
lotics run query_tables '{}'
|
|
38
55
|
lotics run query_records '{"table_id":"tbl_...","field_keys":["name"]}'
|
|
39
56
|
|
package/dist/src/cli.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import readline from "node:readline";
|
|
5
|
-
import { LoticsClient } from "./client.js";
|
|
6
|
-
import { resolveAuth, loadConfig, saveConfig, deleteConfig,
|
|
5
|
+
import { LoticsClient, API_BASE_URL } from "./client.js";
|
|
6
|
+
import { resolveAuth, loadConfig, saveConfig, deleteConfig, checkForUpdate } from "./config.js";
|
|
7
7
|
import { VERSION } from "./version.js";
|
|
8
8
|
function printHelp() {
|
|
9
9
|
console.log(`Lotics CLI v${VERSION} — AI agent interface for Lotics
|
|
@@ -14,8 +14,22 @@ Lotics is an AI-powered operations platform. Through this CLI you can:
|
|
|
14
14
|
- Build and run automations (event-driven workflows)
|
|
15
15
|
- Create and manage apps, knowledge docs, and files
|
|
16
16
|
|
|
17
|
+
AUTHENTICATION
|
|
18
|
+
lotics signup Create account, org, workspace, and API key
|
|
19
|
+
lotics auth [api_key] Save an existing API key (e.g. from the web app)
|
|
20
|
+
lotics whoami Show the email of the current account
|
|
21
|
+
lotics logout Remove saved credentials
|
|
22
|
+
|
|
23
|
+
Signup flags:
|
|
24
|
+
--email <email> Email (required; prompted if omitted)
|
|
25
|
+
--name <name> Display name (defaults to email prefix)
|
|
26
|
+
|
|
27
|
+
Signup prints email and auto-generated password for web app login.
|
|
28
|
+
Use lotics whoami to check the current account email.
|
|
29
|
+
Auth priority: --api-key flag > LOTICS_API_KEY env > saved config.
|
|
30
|
+
|
|
17
31
|
USAGE
|
|
18
|
-
1. lotics
|
|
32
|
+
1. lotics signup Create account and get API key
|
|
19
33
|
2. lotics tools List available tools by category
|
|
20
34
|
3. lotics tools <name> Show tool description and full input schema
|
|
21
35
|
4. lotics run <tool> '<json>' Execute a tool with JSON arguments
|
|
@@ -25,8 +39,6 @@ USAGE
|
|
|
25
39
|
Query tools return IDs used as arguments to other tools.
|
|
26
40
|
|
|
27
41
|
COMMANDS
|
|
28
|
-
lotics auth Save API key (interactive)
|
|
29
|
-
lotics logout Remove saved credentials
|
|
30
42
|
lotics tools List all available tools
|
|
31
43
|
lotics tools <name> Show tool description and input schema
|
|
32
44
|
lotics run <tool> '<json>' Execute a tool
|
|
@@ -41,9 +53,6 @@ FLAGS
|
|
|
41
53
|
--api-key <key> API key (overrides saved config and LOTICS_API_KEY)
|
|
42
54
|
--version Show version
|
|
43
55
|
|
|
44
|
-
For non-interactive use, set LOTICS_API_KEY in the environment
|
|
45
|
-
instead of running lotics auth.
|
|
46
|
-
|
|
47
56
|
OUTPUT
|
|
48
57
|
Default output is a human-readable text summary. Use --json to get
|
|
49
58
|
structured JSON for programmatic use. Errors print to stderr and
|
|
@@ -73,6 +82,8 @@ function parseArgs(argv) {
|
|
|
73
82
|
output: undefined,
|
|
74
83
|
as: undefined,
|
|
75
84
|
apiKey: undefined,
|
|
85
|
+
email: undefined,
|
|
86
|
+
name: undefined,
|
|
76
87
|
version: false,
|
|
77
88
|
help: false,
|
|
78
89
|
};
|
|
@@ -100,6 +111,12 @@ function parseArgs(argv) {
|
|
|
100
111
|
case "--api-key":
|
|
101
112
|
flags.apiKey = argv[++i];
|
|
102
113
|
break;
|
|
114
|
+
case "--email":
|
|
115
|
+
flags.email = argv[++i];
|
|
116
|
+
break;
|
|
117
|
+
case "--name":
|
|
118
|
+
flags.name = argv[++i];
|
|
119
|
+
break;
|
|
103
120
|
case "--version":
|
|
104
121
|
case "-v":
|
|
105
122
|
flags.version = true;
|
|
@@ -147,8 +164,48 @@ function prompt(question) {
|
|
|
147
164
|
});
|
|
148
165
|
});
|
|
149
166
|
}
|
|
150
|
-
async function
|
|
151
|
-
const
|
|
167
|
+
async function publicPost(path, body) {
|
|
168
|
+
const response = await fetch(`${API_BASE_URL}${path}`, {
|
|
169
|
+
method: "POST",
|
|
170
|
+
headers: { "Content-Type": "application/json" },
|
|
171
|
+
body: JSON.stringify(body),
|
|
172
|
+
});
|
|
173
|
+
const data = await response.json();
|
|
174
|
+
return { ok: response.ok, status: response.status, data };
|
|
175
|
+
}
|
|
176
|
+
async function handleSignup(flags) {
|
|
177
|
+
const email = flags.email ?? (process.stdin.isTTY ? await prompt("Email: ") : "");
|
|
178
|
+
if (!email) {
|
|
179
|
+
console.error("Email is required. Use --email or run interactively.");
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
const name = flags.name ?? (process.stdin.isTTY ? await prompt("Name (enter to use email): ") : undefined);
|
|
183
|
+
const body = { email };
|
|
184
|
+
if (name)
|
|
185
|
+
body.name = name;
|
|
186
|
+
const { ok, status, data } = await publicPost("/v1/cli/signup", body);
|
|
187
|
+
if (!ok) {
|
|
188
|
+
if (status === 409) {
|
|
189
|
+
console.error("An account with this email already exists. Use: lotics auth");
|
|
190
|
+
}
|
|
191
|
+
else if (status === 429) {
|
|
192
|
+
console.error("Too many signup attempts. Try again later.");
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
console.error(`Signup failed: ${data.message ?? JSON.stringify(data)}`);
|
|
196
|
+
}
|
|
197
|
+
process.exit(1);
|
|
198
|
+
}
|
|
199
|
+
const existing = loadConfig() ?? {};
|
|
200
|
+
saveConfig({ ...existing, api_key: data.api_key, email: data.email });
|
|
201
|
+
console.error(`Account created. You can now use the CLI.`);
|
|
202
|
+
console.error(` Email: ${data.email}`);
|
|
203
|
+
console.error(` Password: ${data.password}`);
|
|
204
|
+
console.error(`\nUse these credentials to log into the Lotics web app.`);
|
|
205
|
+
console.error(`Run "lotics whoami" to check the current account email.`);
|
|
206
|
+
}
|
|
207
|
+
async function handleAuth(providedKey) {
|
|
208
|
+
const apiKey = providedKey ?? await prompt("Enter your API key: ");
|
|
152
209
|
if (!apiKey) {
|
|
153
210
|
console.error("No API key provided.");
|
|
154
211
|
process.exit(1);
|
|
@@ -164,7 +221,7 @@ async function handleAuth() {
|
|
|
164
221
|
}
|
|
165
222
|
const existing = loadConfig() ?? {};
|
|
166
223
|
saveConfig({ ...existing, api_key: apiKey });
|
|
167
|
-
console.error(
|
|
224
|
+
console.error("Authenticated.");
|
|
168
225
|
}
|
|
169
226
|
function requireClient(flags) {
|
|
170
227
|
const auth = resolveAuth(flags);
|
|
@@ -207,8 +264,23 @@ async function main() {
|
|
|
207
264
|
return;
|
|
208
265
|
}
|
|
209
266
|
// --- Commands that don't require auth ---
|
|
267
|
+
if (command === "signup") {
|
|
268
|
+
await handleSignup(flags);
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
210
271
|
if (command === "auth") {
|
|
211
|
-
await handleAuth();
|
|
272
|
+
await handleAuth(subcommand ?? flags.apiKey);
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
if (command === "whoami") {
|
|
276
|
+
const config = loadConfig();
|
|
277
|
+
if (config?.email) {
|
|
278
|
+
console.log(config.email);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
console.error("Not signed up. Run: lotics signup");
|
|
282
|
+
process.exit(1);
|
|
283
|
+
}
|
|
212
284
|
return;
|
|
213
285
|
}
|
|
214
286
|
if (command === "logout") {
|
package/dist/src/client.d.ts
CHANGED
package/dist/src/client.js
CHANGED
|
@@ -21,12 +21,13 @@ function getMimeType(filename) {
|
|
|
21
21
|
const ext = path.extname(filename).toLowerCase();
|
|
22
22
|
return MIME_MAP[ext] ?? "application/octet-stream";
|
|
23
23
|
}
|
|
24
|
+
export const API_BASE_URL = process.env.LOTICS_API_URL ?? "https://api.lotics.ai";
|
|
24
25
|
export class LoticsClient {
|
|
25
26
|
apiKey;
|
|
26
27
|
baseUrl;
|
|
27
28
|
constructor(options) {
|
|
28
29
|
this.apiKey = options.apiKey;
|
|
29
|
-
this.baseUrl =
|
|
30
|
+
this.baseUrl = API_BASE_URL;
|
|
30
31
|
}
|
|
31
32
|
async throwResponseError(response) {
|
|
32
33
|
const text = await response.text();
|
package/dist/src/config.d.ts
CHANGED
package/dist/src/config.js
CHANGED
|
@@ -70,7 +70,18 @@ async function fetchLatestVersion() {
|
|
|
70
70
|
clearTimeout(timeout);
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
|
+
function isNewerVersion(latest, current) {
|
|
74
|
+
const [lMaj, lMin, lPat] = latest.split(".").map(Number);
|
|
75
|
+
const [cMaj, cMin, cPat] = current.split(".").map(Number);
|
|
76
|
+
if (lMaj !== cMaj)
|
|
77
|
+
return lMaj > cMaj;
|
|
78
|
+
if (lMin !== cMin)
|
|
79
|
+
return lMin > cMin;
|
|
80
|
+
return lPat > cPat;
|
|
81
|
+
}
|
|
73
82
|
function printUpdateWarning(current, latest) {
|
|
83
|
+
if (!isNewerVersion(latest, current))
|
|
84
|
+
return;
|
|
74
85
|
console.error(`\nUpdate available: ${current} → ${latest}`);
|
|
75
86
|
console.error(`Run: npm i -g @lotics/cli\n`);
|
|
76
87
|
}
|