@senso-ai/cli 0.12.0 → 0.14.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 +176 -423
- package/dist/cli.js +3970 -2606
- package/package.json +51 -24
package/README.md
CHANGED
|
@@ -1,490 +1,243 @@
|
|
|
1
1
|
# Senso CLI
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/AI-Template-SDK/senso-user-cli/actions/workflows/testing.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@senso-ai/cli)
|
|
5
|
+
[](https://www.npmjs.com/package/@senso-ai/cli)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
[](LICENSE)
|
|
4
8
|
|
|
5
|
-
|
|
9
|
+
> Infrastructure for the Agentic Web
|
|
6
10
|
|
|
7
|
-
|
|
11
|
+
The command-line interface for [Senso](https://docs.senso.ai). Search your
|
|
12
|
+
knowledge base, manage content, run the generation engine and read your GEO
|
|
13
|
+
analytics — from a terminal, a script, or an AI agent.
|
|
8
14
|
|
|
9
|
-
|
|
15
|
+
Built for **agents** (Claude Code, Gemini CLI, Codex) as much as for people:
|
|
16
|
+
stdout carries only the payload, `--output json` is available on every command,
|
|
17
|
+
and failures exit with a code that says what went wrong.
|
|
10
18
|
|
|
11
|
-
##
|
|
19
|
+
## Install
|
|
12
20
|
|
|
13
|
-
Requires **Node.js
|
|
21
|
+
Requires **Node.js 20.12 or newer**. Works on Linux, macOS and Windows.
|
|
14
22
|
|
|
15
23
|
```bash
|
|
16
24
|
npm install -g @senso-ai/cli
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Verify it works:
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
25
|
senso --version
|
|
23
26
|
```
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
>
|
|
27
|
-
> ```bash
|
|
28
|
-
> npx @senso-ai/cli --help
|
|
29
|
-
> ```
|
|
30
|
-
|
|
31
|
-
## Quick Start
|
|
32
|
-
|
|
33
|
-
### 1. Authenticate
|
|
34
|
-
|
|
35
|
-
Get an API key from [docs.senso.ai](https://docs.senso.ai), then:
|
|
28
|
+
Or without installing:
|
|
36
29
|
|
|
37
30
|
```bash
|
|
38
|
-
senso
|
|
31
|
+
npx @senso-ai/cli --help
|
|
39
32
|
```
|
|
40
33
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
Alternatively, set an environment variable (useful for CI and AI agents):
|
|
44
|
-
|
|
45
|
-
```bash
|
|
46
|
-
export SENSO_API_KEY=tgr_your_key_here
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 2. Search your knowledge base
|
|
34
|
+
## 60 seconds
|
|
50
35
|
|
|
51
36
|
```bash
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
### 3. List your content
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
senso content list
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
That's it. Every endpoint in the Senso Org API is available as a CLI command.
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## Platform Support
|
|
66
|
-
|
|
67
|
-
| Platform | Supported | Config Location |
|
|
68
|
-
|----------|-----------|-----------------|
|
|
69
|
-
| **Linux** | Node 18+ | `~/.config/senso/config.json` |
|
|
70
|
-
| **macOS** | Node 18+ | `~/Library/Preferences/senso/config.json` |
|
|
71
|
-
| **Windows** | Node 18+ | `%APPDATA%\senso\config.json` |
|
|
72
|
-
|
|
73
|
-
Config paths are handled automatically via XDG-compatible directories. The config file stores your API key, org info, and update check timestamps with owner-only permissions (`0600`).
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Usage with AI Agents
|
|
78
|
-
|
|
79
|
-
The CLI is designed as a first-class tool for AI LLM agents. Pass `--output json` to get structured output and `--quiet` to suppress banners:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
# Claude Code / Gemini CLI / Codex can call this directly
|
|
83
|
-
senso search "customer refund policy" --output json --quiet
|
|
84
|
-
|
|
85
|
-
# Pass API key inline (no config file needed)
|
|
86
|
-
senso search "billing FAQ" --api-key tgr_... --output json --quiet
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
### Auth Priority
|
|
90
|
-
|
|
91
|
-
The CLI resolves credentials in this order:
|
|
92
|
-
|
|
93
|
-
1. `--api-key` flag (highest priority)
|
|
94
|
-
2. `SENSO_API_KEY` environment variable
|
|
95
|
-
3. `~/.config/senso/config.json` stored key
|
|
96
|
-
4. Interactive prompt (first-run only)
|
|
97
|
-
|
|
98
|
-
For non-interactive use (CI, agents), set the env var or pass the flag.
|
|
99
|
-
|
|
100
|
-
---
|
|
101
|
-
|
|
102
|
-
## Commands
|
|
103
|
-
|
|
104
|
-
### Authentication
|
|
105
|
-
|
|
106
|
-
```
|
|
107
|
-
senso login Authenticate with Senso (interactive)
|
|
108
|
-
senso logout Remove stored credentials
|
|
109
|
-
senso whoami Show current org and auth status
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### Search
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
senso search <query> Semantic search with AI-generated answer + source chunks
|
|
116
|
-
senso search context <query> Chunks only (no AI answer, faster)
|
|
117
|
-
senso search content <query> Content IDs only (deduplicated)
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
Options: `--max-results <n>`
|
|
121
|
-
|
|
122
|
-
### Content
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
senso content list List all knowledge base items
|
|
126
|
-
senso content get <id> Get full content detail by ID
|
|
127
|
-
senso content versions <id> List version history for a content item
|
|
128
|
-
senso content delete <id> Delete content (knowledge base + external)
|
|
129
|
-
senso content unpublish <id> Unpublish and revert to draft
|
|
130
|
-
senso content verification List items in verification workflow
|
|
131
|
-
senso content verification-counts Counts by status + published-domain summaries
|
|
132
|
-
senso content reject <versionId> Reject a content version
|
|
133
|
-
senso content restore <versionId> Restore rejected version to draft
|
|
134
|
-
senso content owners <id> List owners of a content item
|
|
135
|
-
senso content set-owners <id> Replace owners (--user-ids)
|
|
136
|
-
senso content remove-owner <id> <userId> Remove a single owner
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
Options: `content list` supports `--limit`, `--offset`, `--search`, `--sort`. `content verification` supports `--limit`, `--offset`, `--search`, `--status`, `--substatus`. `content reject` supports `--reason`.
|
|
140
|
-
|
|
141
|
-
### Generated Content (GEO)
|
|
142
|
-
|
|
143
|
-
```
|
|
144
|
-
senso generated-content list List published or draft generated content (--status published|drafts)
|
|
145
|
-
senso generated-content get <id> Get a generated content item with its rendered body
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
Options: `generated-content list` supports `--status`, `--limit`, `--offset`, `--search`.
|
|
149
|
-
|
|
150
|
-
### Content Generation
|
|
151
|
-
|
|
152
|
-
```
|
|
153
|
-
senso generate settings Get generation settings
|
|
154
|
-
senso generate update-settings Update generation settings (--data)
|
|
155
|
-
senso generate sample Generate sample for a prompt; waits for async job by default (--prompt-id, --content-type-id, --no-wait)
|
|
156
|
-
senso generate run Trigger a content engine run (--prompt-ids)
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### Content Engine
|
|
160
|
-
|
|
161
|
-
```
|
|
162
|
-
senso engine publish Publish content to external destinations (--data)
|
|
163
|
-
senso engine draft Save content as draft for review (--data)
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
### Tracked Competitors & Sources
|
|
37
|
+
# 1. Authenticate. Get a key from https://docs.senso.ai
|
|
38
|
+
export SENSO_API_KEY=tgr_your_key_here # or run: senso login
|
|
167
39
|
|
|
168
|
-
|
|
169
|
-
senso
|
|
170
|
-
senso competitors add Add a competitor (--name, --url)
|
|
171
|
-
senso competitors suggest Get AI-generated competitor suggestions
|
|
172
|
-
senso competitors batch-add Add up to 50 competitors (--data)
|
|
173
|
-
senso competitors update <id> Update a competitor (--name, --url)
|
|
174
|
-
senso competitors delete <id> Remove a competitor
|
|
175
|
-
|
|
176
|
-
senso tracked-sources list List citation-classification rules
|
|
177
|
-
senso tracked-sources add Add a rule (--pattern, --match-type, --tier)
|
|
178
|
-
senso tracked-sources update <id> Replace a rule (--pattern, --match-type, --tier)
|
|
179
|
-
senso tracked-sources delete <id> Remove a rule
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Options: `tracked-sources add`/`update` support `--category`, `--label`, `--priority`; `update` also supports `--active`/`--no-active`. `--match-type` is one of `domain | host | path_prefix | exact_url`; `--tier` is one of `primary | tracked | secondary`.
|
|
40
|
+
# 2. Ask your knowledge base a question
|
|
41
|
+
senso search "what is our refund policy?"
|
|
183
42
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
```
|
|
187
|
-
senso ingest upload <files...> Upload files to knowledge base (up to 10)
|
|
188
|
-
senso ingest reprocess <contentId> <file> Re-ingest content with new file
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
### Brand Kit & Content Types
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
senso brand-kit get Get brand kit guidelines
|
|
195
|
-
senso brand-kit set Create or replace brand kit (--data)
|
|
196
|
-
|
|
197
|
-
senso content-types list List content types
|
|
198
|
-
senso content-types create Create a content type (--data)
|
|
199
|
-
senso content-types get <id> Get content type by ID
|
|
200
|
-
senso content-types update <id> Update a content type (--data)
|
|
201
|
-
senso content-types delete <id> Delete a content type
|
|
43
|
+
# 3. The same thing, for a program
|
|
44
|
+
senso search "what is our refund policy?" --output json | jq -r .answer
|
|
202
45
|
```
|
|
203
46
|
|
|
204
|
-
|
|
47
|
+
That third line is the point of this tool. There is no `--quiet` in it because
|
|
48
|
+
none is needed: stdout carries the payload and nothing else.
|
|
205
49
|
|
|
206
|
-
|
|
50
|
+
## Using it from an agent
|
|
207
51
|
|
|
208
|
-
|
|
209
|
-
senso prompts list List prompts (geo questions)
|
|
210
|
-
senso prompts create Create a prompt (--data)
|
|
211
|
-
senso prompts get <promptId> Get prompt with run history
|
|
212
|
-
senso prompts delete <promptId> Delete a prompt
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Options: `prompts list` supports `--limit`, `--offset`, `--search`, `--sort`.
|
|
216
|
-
|
|
217
|
-
### Analytics (GEO)
|
|
218
|
-
|
|
219
|
-
Read-only metrics for your own organization: how often the AI models name your brand, your share of every brand mention the models made, and which domains and pages get cited. Works with the organization API key from `senso login`.
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
senso analytics summary Headline metrics + previous window + deltas
|
|
223
|
-
senso analytics mentions Visibility time series (day or week buckets)
|
|
224
|
-
senso analytics citations Citation rates and shares, with the series
|
|
225
|
-
senso analytics domains Cited domains, ranked (coverage + share)
|
|
226
|
-
senso analytics pages Cited pages, with the prompts driving them
|
|
227
|
-
senso analytics prompts Per-prompt performance table
|
|
228
|
-
senso analytics prompt <promptId> One prompt: history + latest full answers
|
|
229
|
-
senso analytics answers Latest answer per prompt × model × location
|
|
230
|
-
senso analytics glossary Canonical definition of every metric
|
|
231
|
-
senso analytics filters Filter values that have data for this org
|
|
232
|
-
```
|
|
52
|
+
The whole contract, in one place.
|
|
233
53
|
|
|
234
|
-
|
|
54
|
+
**Streams.** stdout is the payload. Everything else — progress, warnings,
|
|
55
|
+
errors, the banner — goes to stderr. Redirecting stdout to a file gives you data
|
|
56
|
+
or an empty file, never a sentence you have to strip.
|
|
235
57
|
|
|
236
|
-
|
|
237
|
-
|---------|---------|
|
|
238
|
-
| all except `prompt <promptId>`, `glossary`, `filters` | `--from`, `--to`, `--models`, `--location`, `--prompt-type`, `--tag` |
|
|
239
|
-
| `mentions`, `citations` | `--group-by <day\|week>` |
|
|
240
|
-
| `domains` | `--tier`, `--domain-contains`, `--sort <citations\|coverage>`, `--limit`, `--offset` |
|
|
241
|
-
| `pages` | `--tier`, `--domain`, `--domain-contains`, `--url-contains`, `--sort <citations\|coverage>`, `--limit`, `--offset` |
|
|
242
|
-
| `prompts` | `--search`, `--sort <mention_rate\|share_of_voice\|citations\|answered\|text>`, `--order <asc\|desc>`, `--limit`, `--offset` |
|
|
243
|
-
| `prompt <promptId>` | `--from`, `--to`, `--models`, `--location`, `--no-include-answers` |
|
|
244
|
-
| `answers` | `--from`, `--to`, `--models`, `--location`, `--prompt-type`, `--tag`, `--mentioned <bool>`, `--cited <bool>`, `--citation-tier <primary\|tracked\|secondary>`, `--limit`, `--offset` |
|
|
58
|
+
**Formats.** Every command takes `--output`:
|
|
245
59
|
|
|
246
|
-
|
|
60
|
+
| Format | For | Notes |
|
|
61
|
+
| ------- | ------------------ | ----------------------------------------------- |
|
|
62
|
+
| `json` | scripts and agents | The API payload, unmodified. Implies `--quiet`. |
|
|
63
|
+
| `table` | reading a list | Aligned columns; long cells truncated. |
|
|
64
|
+
| `plain` | reading one thing | Complete and untruncated. The default. |
|
|
247
65
|
|
|
248
|
-
|
|
66
|
+
**Exit codes.** Branch on these rather than on message text.
|
|
249
67
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
### Industry Intelligence (partner key required)
|
|
260
|
-
|
|
261
|
-
```
|
|
262
|
-
senso industries list List industries visible to the partner
|
|
263
|
-
senso industries summary <industry> Industry overview over a time window
|
|
264
|
-
senso industries brand <industry> <brandName> One brand within an industry
|
|
265
|
-
senso industries domain <industry> <domainOrUrl> Domain/URL citation lookup
|
|
266
|
-
senso industries prompt-metrics <industry> Per-prompt industry metrics
|
|
267
|
-
senso industries glossary Competitive-intelligence metric glossary
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
These commands read partner-scoped endpoints and **require a partner API key**. The organization key stored by `senso login` is rejected with a 401/403 — pass a partner key with `--api-key <key>` or `SENSO_API_KEY`. For metrics about your own organization, use `senso analytics` instead.
|
|
271
|
-
|
|
272
|
-
Options: all except `list` and `glossary` support `--from`, `--to`, `--location`, `--models`; `prompt-metrics` also supports `--limit`, `--offset`; `list` supports `--search`. The `<industry>` argument accepts a UUID or a name (e.g. `"Automotive"`).
|
|
273
|
-
|
|
274
|
-
### Organization
|
|
275
|
-
|
|
276
|
-
```
|
|
277
|
-
senso org get Get organization details
|
|
278
|
-
senso org update Update organization details (--data)
|
|
279
|
-
|
|
280
|
-
senso users list List users
|
|
281
|
-
senso users add Add a user (--data)
|
|
282
|
-
senso users get <userId> Get user details
|
|
283
|
-
senso users update <userId> Update a user's role (--data)
|
|
284
|
-
senso users remove <userId> Remove a user
|
|
285
|
-
senso users set-current <userId> Set org as current for a user
|
|
286
|
-
|
|
287
|
-
senso api-keys list List API keys
|
|
288
|
-
senso api-keys create Create API key (--data)
|
|
289
|
-
senso api-keys get <keyId> Get API key details
|
|
290
|
-
senso api-keys update <keyId> Update API key (--data)
|
|
291
|
-
senso api-keys delete <keyId> Delete API key
|
|
292
|
-
senso api-keys revoke <keyId> Revoke API key
|
|
293
|
-
|
|
294
|
-
senso members list List organization members
|
|
295
|
-
```
|
|
296
|
-
|
|
297
|
-
Options: `users list` supports `--limit`, `--offset`. `api-keys list` supports `--limit`, `--offset`. `members list` supports `--limit`, `--offset`, `--search`, `--sort`.
|
|
298
|
-
|
|
299
|
-
### Run Configuration
|
|
300
|
-
|
|
301
|
-
```
|
|
302
|
-
senso run-config models Get configured AI models
|
|
303
|
-
senso run-config set-models Set AI models (--data)
|
|
304
|
-
senso run-config schedule Get run schedule (days of week)
|
|
305
|
-
senso run-config set-schedule Set run schedule (--data)
|
|
306
|
-
```
|
|
68
|
+
| Code | Meaning | What to do |
|
|
69
|
+
| ---- | ------------------------------ | -------------------- |
|
|
70
|
+
| 0 | Success | — |
|
|
71
|
+
| 1 | The API or the runtime refused | Read the message |
|
|
72
|
+
| 2 | Usage error | Fix the command line |
|
|
73
|
+
| 3 | Authentication | Fix the credential |
|
|
74
|
+
| 4 | Not found | Check the ID |
|
|
75
|
+
| 5 | Network failure or timeout | Retry |
|
|
307
76
|
|
|
308
|
-
|
|
77
|
+
**Errors are structured too.** Under `--output json`, a failure writes JSON to
|
|
78
|
+
stderr and leaves stdout empty:
|
|
309
79
|
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"error": {
|
|
83
|
+
"code": "unauthorized",
|
|
84
|
+
"message": "Authentication failed: the API key was rejected.",
|
|
85
|
+
"status": 401,
|
|
86
|
+
"hint": "Run `senso login` to store a new key, or check SENSO_API_KEY."
|
|
87
|
+
}
|
|
88
|
+
}
|
|
310
89
|
```
|
|
311
|
-
senso update Update to the latest version
|
|
312
|
-
senso --version Show current version
|
|
313
|
-
senso --help Show help
|
|
314
|
-
```
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## Global Options
|
|
319
90
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
| `--api-key <key>` | Override API key (or set `SENSO_API_KEY` env var) |
|
|
323
|
-
| `--base-url <url>` | Override API base URL (default: `https://apiv2.senso.ai/api/v1`) |
|
|
324
|
-
| `--output <format>` | Output format: `json`, `table`, or `plain` (default: `plain`) |
|
|
325
|
-
| `--quiet` | Suppress banners and non-essential output |
|
|
326
|
-
| `--no-update-check` | Skip version check (or set `SENSO_NO_UPDATE_CHECK=1`) |
|
|
327
|
-
| `-v, --version` | Show version |
|
|
328
|
-
| `-h, --help` | Show help |
|
|
91
|
+
`error.code` is stable. Messages may be reworded; codes are part of the
|
|
92
|
+
interface.
|
|
329
93
|
|
|
330
|
-
|
|
94
|
+
**Environment.**
|
|
331
95
|
|
|
332
|
-
|
|
96
|
+
| Variable | Purpose |
|
|
97
|
+
| ------------------------- | ------------------------------------------------------------ |
|
|
98
|
+
| `SENSO_API_KEY` | The API key, if you would rather not run `senso login` |
|
|
99
|
+
| `SENSO_BASE_URL` | Point at a different API |
|
|
100
|
+
| `SENSO_CONFIG_DIR` | Relocate the config file (per-project credentials, or tests) |
|
|
101
|
+
| `SENSO_DEBUG=1` | Log every request and its status to stderr, key redacted |
|
|
102
|
+
| `SENSO_NO_UPDATE_CHECK=1` | Never check npm for a newer version |
|
|
103
|
+
| `NO_COLOR` | Disable color (any value) |
|
|
333
104
|
|
|
334
|
-
**
|
|
105
|
+
**Teaching an agent to use Senso.** The official agent skills install in one
|
|
106
|
+
command:
|
|
335
107
|
|
|
108
|
+
```bash
|
|
109
|
+
senso skills install --all
|
|
336
110
|
```
|
|
337
|
-
$ senso search "mortgage rates"
|
|
338
111
|
|
|
339
|
-
|
|
112
|
+
## Commands
|
|
340
113
|
|
|
341
|
-
|
|
114
|
+
**[Full command reference →](docs/reference/commands.md)** — every command,
|
|
115
|
+
argument and flag, generated from the CLI itself.
|
|
116
|
+
|
|
117
|
+
| Group | What it does |
|
|
118
|
+
| ------------------------------------------------------------------------ | ------------------------------------------------------------------- |
|
|
119
|
+
| `login` `logout` `whoami` | Authentication and the current organization |
|
|
120
|
+
| `search` | Ask the knowledge base, with an AI answer, raw chunks, or streaming |
|
|
121
|
+
| `kb` `ingest` `content` | The knowledge base: upload, browse, organize, verify |
|
|
122
|
+
| `ctas` | Call-to-action cards on published pages |
|
|
123
|
+
| `generate` `engine` `generated-content` `destinations` `publish-records` | Generate content and publish it |
|
|
124
|
+
| `analytics` | GEO metrics for your own organization |
|
|
125
|
+
| `industries` | Competitive intelligence (needs a partner key) |
|
|
126
|
+
| `prompts` `questions` `competitors` `tracked-sources` | What gets monitored |
|
|
127
|
+
| `brand-kit` `content-types` `product-lines` `tags` | How content is shaped |
|
|
128
|
+
| `org` `users` `members` `roles` `permissions` `api-keys` `credits` | Organization administration |
|
|
129
|
+
| `run-config` | Which models run, and on which days |
|
|
130
|
+
| `skills` | Install the Senso agent skills |
|
|
131
|
+
| `update` | Update this CLI |
|
|
132
|
+
|
|
133
|
+
A few worth knowing about:
|
|
342
134
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
135
|
+
```bash
|
|
136
|
+
senso search "..." --output json # answer + sources, for a program
|
|
137
|
+
senso search stream "..." # tokens as they arrive
|
|
138
|
+
senso ingest upload ./policy.pdf # into the knowledge base
|
|
139
|
+
senso analytics summary # headline GEO metrics
|
|
140
|
+
senso analytics glossary # what every metric means
|
|
346
141
|
```
|
|
347
142
|
|
|
348
|
-
|
|
143
|
+
### Reading the analytics numbers
|
|
349
144
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
"results": [
|
|
355
|
-
{
|
|
356
|
-
"title": "Mortgage Rate Overview",
|
|
357
|
-
"chunk_text": "Fixed-rate mortgages currently average...",
|
|
358
|
-
"content_id": "cnt_abc123"
|
|
359
|
-
}
|
|
360
|
-
]
|
|
361
|
-
}
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
**Table** (for listing resources):
|
|
145
|
+
`senso analytics` reports how often AI models name your brand and which pages
|
|
146
|
+
they cite. The metrics are easy to misread, so
|
|
147
|
+
**[docs/analytics.md](docs/analytics.md)** states what each one divides by. The
|
|
148
|
+
short version:
|
|
365
149
|
|
|
366
|
-
|
|
367
|
-
|
|
150
|
+
- **Share of Voice** divides by mentions of _every_ brand the models named, not
|
|
151
|
+
just your tracked competitors.
|
|
152
|
+
- **Citation Rate** and **Coverage** divide by answers that carried at least one
|
|
153
|
+
citation. **Citation Share** divides by total citation instances. They are
|
|
154
|
+
different metrics on different denominators.
|
|
155
|
+
- A metric shown as `—` means _not measured_ — its denominator was zero. That is
|
|
156
|
+
not the same as 0%.
|
|
157
|
+
- `analytics answers` is a snapshot, not a window: narrowing the dates hides
|
|
158
|
+
results rather than returning older ones.
|
|
368
159
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
cnt_def456 Variable Rate Products draft
|
|
372
|
-
```
|
|
160
|
+
`senso analytics glossary` is the canonical definition of each metric, its
|
|
161
|
+
denominator and its gotcha, straight from the API.
|
|
373
162
|
|
|
374
|
-
|
|
163
|
+
## Configuration
|
|
375
164
|
|
|
376
|
-
|
|
165
|
+
`senso login` stores your key in a JSON file with owner-only permissions:
|
|
377
166
|
|
|
378
|
-
|
|
167
|
+
| Platform | Location |
|
|
168
|
+
| -------- | ----------------------------------------- |
|
|
169
|
+
| Linux | `~/.config/senso/config.json` |
|
|
170
|
+
| macOS | `~/Library/Preferences/senso/config.json` |
|
|
171
|
+
| Windows | `%APPDATA%\senso\Config\config.json` |
|
|
379
172
|
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
│ Update available! 0.1.0 → 0.2.0 │
|
|
384
|
-
│ │
|
|
385
|
-
│ Run senso update to update │
|
|
386
|
-
│ │
|
|
387
|
-
╰──────────────────────────────────────────────╯
|
|
388
|
-
```
|
|
173
|
+
Set `SENSO_CONFIG_DIR` to put it somewhere else. Credentials resolve in this
|
|
174
|
+
order: `--api-key`, then `SENSO_API_KEY`, then the config file. `senso login`
|
|
175
|
+
needs a terminal; in CI or an agent, set the environment variable.
|
|
389
176
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
To disable: `--no-update-check` or `export SENSO_NO_UPDATE_CHECK=1`.
|
|
393
|
-
|
|
394
|
-
---
|
|
177
|
+
The CLI checks npm for a newer version once a day and prints a notice on stderr.
|
|
178
|
+
`senso update` upgrades it; `SENSO_NO_UPDATE_CHECK=1` turns the check off.
|
|
395
179
|
|
|
396
180
|
## Development
|
|
397
181
|
|
|
398
182
|
```bash
|
|
399
|
-
#
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
# Install dependencies
|
|
404
|
-
npm install
|
|
405
|
-
|
|
406
|
-
# Run in dev mode (TypeScript directly via tsx)
|
|
407
|
-
npm run dev -- search "test query"
|
|
408
|
-
|
|
409
|
-
# Build (single ESM bundle via tsup)
|
|
410
|
-
npm run build
|
|
411
|
-
|
|
412
|
-
# Run the built version
|
|
413
|
-
node dist/cli.js --help
|
|
414
|
-
|
|
415
|
-
# Run tests
|
|
416
|
-
npm test
|
|
417
|
-
```
|
|
418
|
-
|
|
419
|
-
### Project Structure
|
|
420
|
-
|
|
421
|
-
```
|
|
422
|
-
src/
|
|
423
|
-
├── cli.ts # Entry point — arg parsing, command dispatch
|
|
424
|
-
├── commands/ # One file per command group
|
|
425
|
-
│ ├── auth.ts # login, logout, whoami
|
|
426
|
-
│ ├── search.ts # search, search context, search content
|
|
427
|
-
│ ├── content.ts # CRUD + versions + verification + owners
|
|
428
|
-
│ ├── generated-content.ts # GEO generated content (list, get)
|
|
429
|
-
│ ├── generate.ts # content generation settings + triggers
|
|
430
|
-
│ ├── engine.ts # publish, draft
|
|
431
|
-
│ ├── competitors.ts # tracked competitors CRUD + suggest
|
|
432
|
-
│ ├── tracked-sources.ts # citation-classification rules CRUD
|
|
433
|
-
│ ├── ingest.ts # upload, reprocess (with S3 upload)
|
|
434
|
-
│ ├── brand-kit.ts # get, set
|
|
435
|
-
│ ├── content-types.ts # CRUD
|
|
436
|
-
│ ├── prompts.ts # CRUD
|
|
437
|
-
│ ├── analytics.ts # org GEO analytics (summary, citations, prompts, …)
|
|
438
|
-
│ ├── industries.ts # partner-scoped competitive intelligence
|
|
439
|
-
│ ├── org.ts # get, update
|
|
440
|
-
│ ├── users.ts # CRUD + set-current
|
|
441
|
-
│ ├── api-keys.ts # CRUD + revoke
|
|
442
|
-
│ ├── members.ts # list
|
|
443
|
-
│ ├── run-config.ts # models, schedule
|
|
444
|
-
│ └── update.ts # self-update
|
|
445
|
-
├── lib/
|
|
446
|
-
│ ├── api-client.ts # HTTP wrapper (native fetch, X-API-Key auth)
|
|
447
|
-
│ ├── config.ts # Config read/write (~/.config/senso/)
|
|
448
|
-
│ ├── output.ts # json/table/plain formatting
|
|
449
|
-
│ └── version.ts # Reads version from package.json
|
|
450
|
-
└── utils/
|
|
451
|
-
├── logger.ts # Colored log helpers (picocolors)
|
|
452
|
-
├── branding.ts # ASCII logo, gradient banner, boxed panels
|
|
453
|
-
└── updater.ts # npm registry version check
|
|
183
|
+
nvm use # Node 22, per .nvmrc
|
|
184
|
+
npm ci
|
|
185
|
+
make all # everything CI runs
|
|
454
186
|
```
|
|
455
187
|
|
|
456
|
-
|
|
188
|
+
`make all` is the whole pipeline, and CI invokes the same targets in the same
|
|
189
|
+
order — a green `make all` and a green pipeline cannot mean different things.
|
|
457
190
|
|
|
458
|
-
|
|
|
459
|
-
|
|
460
|
-
|
|
|
461
|
-
|
|
|
462
|
-
|
|
|
463
|
-
|
|
|
464
|
-
|
|
|
465
|
-
|
|
|
466
|
-
|
|
|
467
|
-
| Config | env-paths (XDG-compatible) |
|
|
468
|
-
| HTTP | Native `fetch` |
|
|
191
|
+
| Stage | Command | What it checks |
|
|
192
|
+
| ---------- | ---------------- | --------------------------------------------------------- |
|
|
193
|
+
| Lint | `make lint` | ESLint (type-aware) and Prettier |
|
|
194
|
+
| Typecheck | `make typecheck` | `tsc --noEmit` over src, tests and scripts |
|
|
195
|
+
| Security | `make security` | `npm audit`, semgrep, and gitleaks over the full history |
|
|
196
|
+
| Unit | `make unit` | Unit, command and policy tests, behind a coverage gate |
|
|
197
|
+
| End-to-end | `make e2e` | The built bundle, as a subprocess, against a mock API |
|
|
198
|
+
| Build | `make build` | The tsup bundle |
|
|
199
|
+
| Smoke | `make smoke` | Packs the tarball, installs it clean, and runs the binary |
|
|
469
200
|
|
|
470
|
-
|
|
201
|
+
**No test touches the network.** `tests/setup.ts` installs an MSW server with
|
|
202
|
+
`onUnhandledRequest: 'error'`, so a request nobody mocked fails the test rather
|
|
203
|
+
than quietly reaching a real Senso API with whatever key is in your environment.
|
|
204
|
+
That is enforced mechanically, which is why CI needs no secrets and why pull
|
|
205
|
+
requests from forks run the full suite.
|
|
471
206
|
|
|
472
|
-
|
|
207
|
+
Run `make help` for every target.
|
|
473
208
|
|
|
474
|
-
|
|
475
|
-
# 1. Bump the version in package.json, commit, and create a git tag
|
|
476
|
-
npm version patch # 0.1.0 → 0.1.1 (bug fixes)
|
|
477
|
-
npm version minor # 0.1.0 → 0.2.0 (new features, backwards-compatible)
|
|
478
|
-
npm version major # 0.1.0 → 1.0.0 (breaking changes)
|
|
209
|
+
## Repository layout
|
|
479
210
|
|
|
480
|
-
# 2. Push the commit and tag — the tag triggers the publish workflow
|
|
481
|
-
git push --follow-tags
|
|
482
211
|
```
|
|
483
|
-
|
|
484
|
-
The
|
|
485
|
-
|
|
486
|
-
|
|
212
|
+
src/
|
|
213
|
+
cli.ts The bin entry — the only file that ends the process
|
|
214
|
+
program.ts createProgram(): builds the command tree, no side effects
|
|
215
|
+
commands/ One file per command group
|
|
216
|
+
lib/ api-client, config, errors, output, run-action
|
|
217
|
+
utils/ logger, branding, updater
|
|
218
|
+
tests/
|
|
219
|
+
unit/ Library modules, in isolation
|
|
220
|
+
commands/ Each command group, in-process, against a mock API
|
|
221
|
+
e2e/ The built bundle, as a subprocess
|
|
222
|
+
policy/ This repository's own rules
|
|
223
|
+
docs/ How it works, and the generated command reference
|
|
224
|
+
scripts/ Reference generator, smoke test, pre-commit checks
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Documentation
|
|
228
|
+
|
|
229
|
+
| Document | Read it when you want to know |
|
|
230
|
+
| -------------------------------------------------------- | -------------------------------------------------------------- |
|
|
231
|
+
| [docs/README.md](docs/README.md) | How this CLI works, in 60 seconds and then in depth |
|
|
232
|
+
| [docs/reference/commands.md](docs/reference/commands.md) | Every command and flag |
|
|
233
|
+
| [docs/configuration.md](docs/configuration.md) | Every environment variable and file it touches |
|
|
234
|
+
| [docs/architecture.md](docs/architecture.md) | What happens between argv and the API |
|
|
235
|
+
| [docs/analytics.md](docs/analytics.md) | What every GEO metric divides by, and how to not misread one |
|
|
236
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | How to make a change, and what a review will send back |
|
|
237
|
+
| [SECURITY.md](SECURITY.md) | What this tool holds, and what it does not do |
|
|
238
|
+
| [CHANGELOG.md](CHANGELOG.md) | What changed and when |
|
|
239
|
+
| [CLAUDE.md](CLAUDE.md) | Conventions, and the behaviors that look like bugs but are not |
|
|
487
240
|
|
|
488
241
|
## License
|
|
489
242
|
|
|
490
|
-
[AGPL-3.0](LICENSE)
|
|
243
|
+
[AGPL-3.0-or-later](LICENSE)
|