@startanaicompany/crm 1.0.1 → 1.0.2

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.
Files changed (3) hide show
  1. package/README.md +59 -25
  2. package/index.js +16 -6
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -8,44 +8,61 @@ AI-first CRM CLI (`saac_crm`) — manage leads, API keys, and user accounts from
8
8
  npm install -g @startanaicompany/crm
9
9
  ```
10
10
 
11
- ## First-Time Setup
11
+ ---
12
+
13
+ ## 🤖 AI Agent Quick Start (zero-auth, no human needed)
14
+
15
+ Agents bootstrap themselves with a single command — **no credentials required**:
12
16
 
13
17
  ```bash
14
- # 1. Point at your CRM deployment
18
+ # Step 1: create your own API key (no auth needed)
15
19
  saac_crm config set --url https://your-crm.example.com
20
+ saac_crm keys create --name my-agent
21
+ # → returns crm_xxxxxxxxxxxx — store this as your API key
16
22
 
17
- # 2. Register your workspace and create the first admin key
18
- # (prompts for deployment admin password)
19
- saac_crm register --workspace mycompany --name "main-admin-key"
20
-
21
- # 3. Save the returned key as default (or use SAAC_CRM_API_KEY env)
22
- saac_crm config set --api-key crm_xxxxxxxxxxxx
23
- # OR
23
+ # Step 2: set the key and start managing leads
24
24
  export SAAC_CRM_API_KEY=crm_xxxxxxxxxxxx
25
+ saac_crm leads create --name "Jane Smith" --email "jane@example.com"
26
+ saac_crm leads list
25
27
  ```
26
28
 
27
29
  > **Auth priority**: `--api-key` flag > `SAAC_CRM_API_KEY` env var > config file (`~/.saac_crm/config.json`)
28
30
 
29
- ## Commands
31
+ > ⚠️ **Agents: never call `saac_crm register`** — that command is for one-time operator setup only (requires deployment password). Your entry point is always `keys create --name`.
30
32
 
31
- ### Workspace Registration
33
+ ---
34
+
35
+ ## 👤 Operator Setup (one-time, human)
36
+
37
+ This is done once per deployment — **not by agents**:
32
38
 
33
39
  ```bash
34
- # Register workspace + create first admin key (all-in-one)
35
- saac_crm register --workspace mycompany --name "admin-key"
40
+ # 1. Point at your deployment
41
+ saac_crm config set --url https://your-crm.example.com
36
42
 
37
- # Check current workspace slug (public no auth needed)
38
- curl https://your-crm.example.com/api/v1/workspace
43
+ # 2. Register workspace + create admin key (prompts for workspace slug and password)
44
+ saac_crm register --name "main-admin-key"
45
+ # → prompts: Workspace slug (e.g. mycompany):
46
+ # → prompts: Deployment admin password:
47
+ # → returns crm_xxx admin key — store securely
48
+
49
+ # 3. Save admin key and create first human user account
50
+ saac_crm config set --api-key crm_xxx_admin_key
51
+ saac_crm users create --email admin@example.com --name "Admin" --role admin
39
52
  ```
40
53
 
54
+ ---
55
+
56
+ ## Commands
57
+
41
58
  ### API Keys
42
59
 
43
60
  ```bash
44
- # Create an agent key (no auth required)
61
+ # Create agent key — ZERO AUTH, no prior setup needed
45
62
  saac_crm keys create --name "my-agent"
46
63
 
47
- # Create an admin scope key (requires deployment password + workspace slug)
48
- saac_crm keys create --name "admin-agent" --scope admin \
64
+ # Create admin scope key (operator only — requires deployment password + workspace slug)
65
+ saac_crm keys create --name "admin-key" --scope admin \
49
66
  --workspace mycompany --admin-password <deployment-password>
50
67
 
51
68
  # List all keys (metadata only — full key never shown again)
@@ -83,7 +100,8 @@ saac_crm leads history <id>
83
100
  ### Users (requires admin scope key)
84
101
 
85
102
  ```bash
86
- # Create a human user account
103
+ # Create a human user account (both commands are equivalent)
104
+ saac_crm users create --email admin@example.com --name "Admin User" --role admin
87
105
  saac_crm users register --email admin@example.com --name "Admin User" --role admin
88
106
 
89
107
  # List users
@@ -96,6 +114,23 @@ saac_crm users update <id> --role viewer
96
114
  saac_crm users deactivate <id>
97
115
  ```
98
116
 
117
+ ### Human Login
118
+
119
+ ```bash
120
+ # Log in as admin/viewer — saves JWT to config for dashboard access
121
+ saac_crm login --workspace mycompany --email admin@example.com
122
+ # → prompts for password, saves JWT to ~/.saac_crm/config.json
123
+ ```
124
+
125
+ ### Workspace Registration (operator only)
126
+
127
+ ```bash
128
+ # First-time setup — registers workspace slug + creates admin key
129
+ # Prompts for --workspace and --admin-password if not provided
130
+ saac_crm register --name "main-admin-key"
131
+ saac_crm register --name "main-admin-key" --workspace mycompany --admin-password <pw>
132
+ ```
133
+
99
134
  ### Configuration
100
135
 
101
136
  ```bash
@@ -111,11 +146,10 @@ saac_crm config get
111
146
  --url <url> Override API base URL for this command
112
147
  ```
113
148
 
114
- ## Human Login
149
+ ## Architecture
115
150
 
116
- Humans log in via the web UI at the deployment URL. Login requires:
117
- 1. **Workspace slug** (e.g. `mycompany`)
118
- 2. **Email**
119
- 3. **Password**
151
+ This is a **single-tenant** system: one workspace slug per deployment, registered once by an operator.
120
152
 
121
- User accounts are created by an AI agent using an admin scope key via `saac_crm users register`.
153
+ - **Agents** self-service `keys create` manage leads
154
+ - **Operators** → `register` once → `users create` → human accounts
155
+ - **Humans** → `login` → web dashboard at your deployment URL
package/index.js CHANGED
@@ -99,7 +99,7 @@ const program = new Command();
99
99
  program
100
100
  .name('saac_crm')
101
101
  .description('AI-first CRM CLI — manage leads and API keys')
102
- .version('1.0.1')
102
+ .version('1.0.2')
103
103
  .option('--api-key <key>', 'API key (overrides SAAC_CRM_API_KEY env and config)')
104
104
  .option('--url <url>', 'API base URL (overrides config)');
105
105
 
@@ -115,9 +115,14 @@ configCmd
115
115
  .option('--url <url>', 'CRM API base URL (e.g. https://yourapp.example.com)')
116
116
  .option('--api-key <key>', 'Default API key to use')
117
117
  .action((opts) => {
118
+ // NOTE: commander.js may consume --url and --api-key at the parent program level
119
+ // if they share the same option names. Always fall back to program.opts().
120
+ const globalOpts = program.opts();
118
121
  const cfg = loadConfig();
119
- if (opts.url) cfg.apiUrl = opts.url;
120
- if (opts.apiKey) cfg.apiKey = opts.apiKey;
122
+ const urlValue = opts.url || globalOpts.url;
123
+ const apiKeyValue = opts.apiKey || globalOpts.apiKey;
124
+ if (urlValue) cfg.apiUrl = urlValue;
125
+ if (apiKeyValue) cfg.apiKey = apiKeyValue;
121
126
  saveConfig(cfg);
122
127
  console.log('Configuration saved to', CONFIG_FILE);
123
128
  printJSON(cfg);
@@ -317,7 +322,7 @@ leadsCmd
317
322
  };
318
323
  try {
319
324
  const res = await client.post('/leads', body, { headers });
320
- printJSON(res.data.data);
325
+ printJSON(res.data);
321
326
  } catch (err) {
322
327
  handleError(err);
323
328
  }
@@ -330,15 +335,20 @@ leadsCmd
330
335
  .option('--email <email>', 'Filter by email (partial match)')
331
336
  .option('--company <company>', 'Filter by company (partial match)')
332
337
  .option('--tag <tag>', 'Filter by tag — repeatable, AND logic', (v, prev) => prev.concat([v]), [])
338
+ .option('--api-key-id <id>', 'Filter by the API key ID that created the lead')
339
+ .option('--self', 'Filter leads created by the current API key (shorthand for --api-key-id self)')
333
340
  .option('--page <n>', 'Page number', '1')
334
341
  .option('--per-page <n>', 'Results per page', '20')
335
342
  .action(async (opts) => {
336
343
  const globalOpts = program.opts();
337
344
  const client = getClient(globalOpts);
345
+ // --self is a shorthand for --api-key-id self
346
+ const apiKeyIdFilter = opts.self ? 'self' : opts.apiKeyId;
338
347
  const params = {
339
348
  ...(opts.status && { status: opts.status }),
340
349
  ...(opts.email && { email: opts.email }),
341
350
  ...(opts.company && { company: opts.company }),
351
+ ...(apiKeyIdFilter && { api_key_id: apiKeyIdFilter }),
342
352
  page: opts.page,
343
353
  per_page: opts.perPage
344
354
  };
@@ -361,7 +371,7 @@ leadsCmd
361
371
  const client = getClient(globalOpts);
362
372
  try {
363
373
  const res = await client.get(`/leads/${id}`);
364
- printJSON(res.data.data);
374
+ printJSON(res.data);
365
375
  } catch (err) {
366
376
  handleError(err);
367
377
  }
@@ -399,7 +409,7 @@ leadsCmd
399
409
  };
400
410
  try {
401
411
  const res = await client.put(`/leads/${id}`, body);
402
- printJSON(res.data.data);
412
+ printJSON(res.data);
403
413
  } catch (err) {
404
414
  handleError(err);
405
415
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@startanaicompany/crm",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "AI-first CRM CLI — manage leads and API keys from the terminal",
5
5
  "main": "index.js",
6
6
  "bin": {