@lotics/cli 0.1.0 → 0.2.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 CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  CLI and SDK for AI agents to interact with Lotics.
4
4
 
5
+ Lotics is an AI-powered operations platform. Through this CLI you can:
6
+
7
+ - Manage tables, records, and views (structured data with typed fields)
8
+ - Generate documents from templates (Excel, Word, PDF)
9
+ - Build and run automations (event-driven workflows)
10
+ - Create and manage apps, knowledge docs, and files
11
+
5
12
  ## Install
6
13
 
7
14
  ```bash
@@ -23,25 +30,22 @@ The CLI checks for updates once per day and prompts when a new version is availa
23
30
  lotics auth
24
31
 
25
32
  # 2. Discover tools
26
- lotics tools # list all tool names
27
- lotics tools query_records # show description + input schema
33
+ lotics tools # list tools by category with descriptions
34
+ lotics tools query_records # show full description + input schema
28
35
 
29
36
  # 3. Execute
30
37
  lotics run query_tables '{}'
31
38
  lotics run query_records '{"table_id":"tbl_...","field_keys":["name"]}'
32
- lotics run query_records --json '{"table_id":"tbl_..."}'
33
39
 
34
40
  # Pipe args via stdin
35
41
  echo '{"table_id":"tbl_..."}' | lotics run query_records
36
42
 
37
43
  # Upload a file
38
44
  lotics upload ./report.pdf
39
- lotics upload ./photo.jpg --as cover.jpg
40
45
 
41
46
  # Generate a file, then download it
42
- lotics run generate_excel_from_template '{"..."}' --json
43
- # {"file_id":"fil_...","url":"...","filename":"report.xlsx",...}
44
- lotics download fil_... -o ./reports/
47
+ lotics run generate_excel_from_template '{"..."}'
48
+ lotics download <file_id> -o ./reports/
45
49
 
46
50
  # CI / non-interactive
47
51
  LOTICS_API_KEY=ltk_... lotics run query_tables '{}'
@@ -52,14 +56,11 @@ LOTICS_API_KEY=ltk_... lotics run query_tables '{}'
52
56
  ```typescript
53
57
  import { LoticsClient } from "@lotics/cli";
54
58
 
55
- const client = new LoticsClient({
56
- apiKey: "ltk_...",
57
- baseUrl: "https://api.lotics.com",
58
- });
59
+ const client = new LoticsClient({ apiKey: "ltk_..." });
59
60
 
60
61
  const { result } = await client.execute("query_tables", {});
61
62
  const upload = await client.uploadFile("./report.pdf");
62
63
  await client.downloadFile(url, "./output.xlsx");
63
- const { tools } = await client.listTools();
64
+ const { tools, categories } = await client.listTools();
64
65
  const info = await client.getTool("query_records");
65
66
  ```
package/dist/src/cli.js CHANGED
@@ -6,37 +6,63 @@ import { VERSION } from "./version.js";
6
6
  function printHelp() {
7
7
  console.log(`Lotics CLI v${VERSION} — AI agent interface for Lotics
8
8
 
9
- Lotics is an AI-powered operations platform for structured data,
10
- document generation, automations, and knowledge management.
9
+ Lotics is an AI-powered operations platform. Through this CLI you can:
10
+ - Manage tables, records, and views (structured data with typed fields)
11
+ - Generate documents from templates (Excel, Word, PDF)
12
+ - Build and run automations (event-driven workflows)
13
+ - Create and manage apps, knowledge docs, and files
14
+
15
+ USAGE
16
+ 1. lotics auth Authenticate (saves key to ~/.lotics/config.json)
17
+ 2. lotics tools List available tools by category
18
+ 3. lotics tools <name> Show tool description and full input schema
19
+ 4. lotics run <tool> '<json>' Execute a tool with JSON arguments
20
+
21
+ Always inspect the schema (step 3) before calling a tool.
22
+ Tools are grouped by category (tables, records, views, etc.).
23
+ Query tools return IDs used as arguments to other tools.
11
24
 
12
25
  COMMANDS
13
- lotics auth Save API key (interactive)
14
- lotics logout Remove saved credentials
15
- lotics tools List all available tools
16
- lotics tools <name> Show tool description and input schema
17
- lotics run <tool> '<json>' Execute a tool
18
- lotics run <tool> --json Full JSON output instead of compact text
19
- lotics upload <file> Upload a local file
20
- lotics download <file_id> Download a file by ID
26
+ lotics auth Save API key (interactive)
27
+ lotics logout Remove saved credentials
28
+ lotics tools List all available tools
29
+ lotics tools <name> Show tool description and input schema
30
+ lotics run <tool> '<json>' Execute a tool
31
+ lotics upload <file> Upload a local file
32
+ lotics download <file_id> Download a file by ID
21
33
 
22
34
  FLAGS
23
- --json Full JSON output
35
+ --json Full JSON output (default is human-readable text)
24
36
  --timeout <ms> Timeout for tool execution (default: 60000)
25
37
  -o <path> Output dir for downloads
26
38
  --as <name> Override upload filename
27
- --api-key <key> API key (for CI/agents)
28
- --api-url <url> API URL override
39
+ --api-key <key> API key (overrides saved config and LOTICS_API_KEY)
29
40
  --version Show version
30
41
 
31
- WORKFLOW
32
- 1. lotics auth Authenticate once
33
- 2. lotics tools See what's available
34
- 3. lotics tools <name> Read the schema before calling
35
- 4. lotics run <tool> '<json>' Execute with correct args
42
+ For non-interactive use, set LOTICS_API_KEY in the environment
43
+ instead of running lotics auth.
44
+
45
+ OUTPUT
46
+ Default output is a human-readable text summary. Use --json to get
47
+ structured JSON for programmatic use. Errors print to stderr and
48
+ exit with code 1.
49
+
50
+ FILES
51
+ Some tools generate files and return { file_id, url, filename }.
52
+ Use lotics download to save locally:
53
+
54
+ lotics run generate_excel_from_template '{"..."}'
55
+ lotics download <file_id> -o ./output/
36
56
 
37
- ENVIRONMENT
38
- LOTICS_API_KEY API key (overrides saved config)
39
- LOTICS_API_URL API URL (overrides saved config)`);
57
+ Upload files before referencing them in tool args:
58
+
59
+ lotics upload ./data.csv
60
+ lotics run create_records '{"file_id":"fil_..."}'
61
+
62
+ STDIN
63
+ Pipe JSON arguments via stdin instead of inline:
64
+
65
+ echo '{"table_id":"tbl_..."}' | lotics run query_records`);
40
66
  }
41
67
  function parseArgs(argv) {
42
68
  const flags = {
@@ -45,7 +71,6 @@ function parseArgs(argv) {
45
71
  output: undefined,
46
72
  as: undefined,
47
73
  apiKey: undefined,
48
- apiUrl: undefined,
49
74
  version: false,
50
75
  help: false,
51
76
  };
@@ -72,9 +97,6 @@ function parseArgs(argv) {
72
97
  case "--api-key":
73
98
  flags.apiKey = argv[++i];
74
99
  break;
75
- case "--api-url":
76
- flags.apiUrl = argv[++i];
77
- break;
78
100
  case "--version":
79
101
  case "-v":
80
102
  flags.version = true;
@@ -119,15 +141,13 @@ function prompt(question) {
119
141
  });
120
142
  });
121
143
  }
122
- async function handleAuth(flags) {
144
+ async function handleAuth() {
123
145
  const apiKey = await prompt("Enter your API key: ");
124
146
  if (!apiKey) {
125
147
  console.error("No API key provided.");
126
148
  process.exit(1);
127
149
  }
128
- const apiUrlInput = flags.apiUrl ?? (await prompt("API URL (default: https://api.lotics.com): "));
129
- const apiUrl = apiUrlInput || "https://api.lotics.com";
130
- const client = new LoticsClient({ apiKey, baseUrl: apiUrl });
150
+ const client = new LoticsClient({ apiKey });
131
151
  try {
132
152
  await client.listTools();
133
153
  }
@@ -137,7 +157,7 @@ async function handleAuth(flags) {
137
157
  process.exit(1);
138
158
  }
139
159
  const existing = loadConfig() ?? {};
140
- saveConfig({ ...existing, api_key: apiKey, api_url: apiUrl });
160
+ saveConfig({ ...existing, api_key: apiKey });
141
161
  console.error(`Authenticated. Config saved to ${getConfigPath()}`);
142
162
  }
143
163
  function requireClient(flags) {
@@ -146,7 +166,7 @@ function requireClient(flags) {
146
166
  console.error('Not authenticated. Run "lotics auth" or set LOTICS_API_KEY.');
147
167
  process.exit(1);
148
168
  }
149
- return new LoticsClient({ apiKey: auth.apiKey, baseUrl: auth.apiUrl });
169
+ return new LoticsClient({ apiKey: auth.apiKey });
150
170
  }
151
171
  async function main() {
152
172
  const { command, subcommand, toolArgs, flags } = parseArgs(process.argv.slice(2));
@@ -160,7 +180,7 @@ async function main() {
160
180
  }
161
181
  // --- Commands that don't require auth ---
162
182
  if (command === "auth") {
163
- await handleAuth(flags);
183
+ await handleAuth();
164
184
  return;
165
185
  }
166
186
  if (command === "logout") {
@@ -198,9 +218,9 @@ async function main() {
198
218
  }
199
219
  else {
200
220
  const { categories } = await client.listTools();
201
- for (const [category, names] of Object.entries(categories)) {
202
- console.log(`\n${category}`);
203
- console.log(` ${names.join(" ")}`);
221
+ for (const [category, { description, tools }] of Object.entries(categories)) {
222
+ console.log(description ? `\n## ${category} — ${description}` : `\n## ${category}`);
223
+ console.log(` ${tools.join(", ")}`);
204
224
  }
205
225
  console.log("");
206
226
  }
@@ -264,7 +284,6 @@ main()
264
284
  const message = error instanceof Error ? error.message : String(error);
265
285
  if (message.includes("fetch failed") || message.includes("ECONNREFUSED")) {
266
286
  console.error("Could not connect to the Lotics API.");
267
- console.error('Check your API URL or run "lotics auth" to reconfigure.');
268
287
  }
269
288
  else if (message.includes("ENOENT")) {
270
289
  const pathMatch = message.match(/open '([^']+)'/);
@@ -1,6 +1,5 @@
1
1
  export interface LoticsClientOptions {
2
2
  apiKey: string;
3
- baseUrl?: string;
4
3
  }
5
4
  export interface ToolExecuteResult {
6
5
  result: unknown;
@@ -30,10 +29,11 @@ export declare class LoticsClient {
30
29
  private throwResponseError;
31
30
  private request;
32
31
  listTools(): Promise<{
33
- tools: Array<{
34
- name: string;
32
+ tools: string[];
33
+ categories: Record<string, {
34
+ description: string;
35
+ tools: string[];
35
36
  }>;
36
- categories: Record<string, string[]>;
37
37
  }>;
38
38
  getTool(name: string): Promise<ToolInfo>;
39
39
  execute(tool: string, args: Record<string, unknown>, options?: {
@@ -26,7 +26,7 @@ export class LoticsClient {
26
26
  baseUrl;
27
27
  constructor(options) {
28
28
  this.apiKey = options.apiKey;
29
- this.baseUrl = (options.baseUrl ?? "https://api.lotics.com").replace(/\/$/, "");
29
+ this.baseUrl = "https://api.lotics.ai";
30
30
  }
31
31
  async throwResponseError(response) {
32
32
  const text = await response.text();
@@ -1,6 +1,5 @@
1
1
  export interface LoticsConfig {
2
2
  api_key?: string;
3
- api_url?: string;
4
3
  last_update_check?: number;
5
4
  latest_version?: string;
6
5
  }
@@ -15,13 +14,11 @@ export declare function getConfigPath(): string;
15
14
  */
16
15
  export declare function checkForUpdate(currentVersion: string): void;
17
16
  /**
18
- * Resolve API key and URL from flags, env vars, or config file.
19
- * Priority: flag > env > config file > default.
17
+ * Resolve API key from flags, env vars, or config file.
18
+ * Priority: flag > env > config file.
20
19
  */
21
20
  export declare function resolveAuth(flags: {
22
21
  apiKey?: string;
23
- apiUrl?: string;
24
22
  }): {
25
23
  apiKey: string;
26
- apiUrl: string;
27
24
  } | null;
@@ -75,17 +75,13 @@ function printUpdateWarning(current, latest) {
75
75
  console.error(`Run: npm i -g @lotics/cli\n`);
76
76
  }
77
77
  /**
78
- * Resolve API key and URL from flags, env vars, or config file.
79
- * Priority: flag > env > config file > default.
78
+ * Resolve API key from flags, env vars, or config file.
79
+ * Priority: flag > env > config file.
80
80
  */
81
81
  export function resolveAuth(flags) {
82
82
  const config = loadConfig();
83
83
  const apiKey = flags.apiKey ?? process.env.LOTICS_API_KEY ?? config?.api_key;
84
84
  if (!apiKey)
85
85
  return null;
86
- const apiUrl = flags.apiUrl ??
87
- process.env.LOTICS_API_URL ??
88
- config?.api_url ??
89
- "https://api.lotics.com";
90
- return { apiKey, apiUrl };
86
+ return { apiKey };
91
87
  }
@@ -1 +1 @@
1
- export declare const VERSION = "0.1.0";
1
+ export declare const VERSION: string;
@@ -1 +1,6 @@
1
- export const VERSION = "0.1.0";
1
+ import { readFileSync } from "node:fs";
2
+ import { fileURLToPath } from "node:url";
3
+ import path from "node:path";
4
+ const pkgPath = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../package.json");
5
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
6
+ export const VERSION = pkg.version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lotics/cli",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Lotics SDK and CLI for AI agents",
5
5
  "type": "module",
6
6
  "bin": {