kenso 0.1.12 → 0.1.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kenso",
3
- "version": "0.1.12",
3
+ "version": "0.1.13",
4
4
  "description": "The Kenso CLI: bulk lead, CRM and Studio work for people and coding agents",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -44,5 +44,5 @@
44
44
  "typescript-eslint": "8.71.1",
45
45
  "vitest": "5.0.3"
46
46
  },
47
- "gitHead": "e3f99f0ad804362414f0a972e0b352fbae1a0f27"
47
+ "gitHead": "17d0c13aa63ee64e49baaa76ee99cc3246d045a1"
48
48
  }
@@ -1,141 +1,26 @@
1
1
  ---
2
2
  name: kenso-cli
3
- description: Use the Kenso CLI (kenso) for bulk lead, CRM and Studio work in a Kenso workspace from files - import, update, remove, pause or tag leads in campaigns, import accounts and people, fill Studio templates, or call any Kenso API operation from the shell. Prefer it over the Kenso MCP for anything over about 50 records.
3
+ description: The Kenso CLI (kenso) for work from a file or over about 50 records - import, update, remove, pause, tag or export leads, import CRM accounts and people, edit Studio templates as local files and fill them, run an API operation per file row. For one record or a question, use the Kenso MCP.
4
4
  ---
5
5
 
6
- # Kenso CLI
7
-
8
- `kenso` does bulk work in Kenso from files and prints JSON. Use it instead of the Kenso MCP when the work starts from a file or touches more than about 50 records: the rows stay on disk, and you read a short summary.
9
-
10
- ## Install and auth
11
-
12
- ```bash
13
- npm i -g kenso
14
- kenso doctor
15
- ```
16
-
17
- Needs Node 22+. Auth, in order of precedence:
18
-
19
- - `KENSO_API_KEY` in the environment (plus `KENSO_WORKSPACE_ID` when the key reaches several workspaces). Nothing else to do.
20
- - Or a saved key. The key is never a flag value; pipe it in. The person creates it in app.ken.so at Settings > Integrations > API keys.
21
-
22
- ```bash
23
- echo $KEY | kenso auth login --with-key
24
- kenso workspace list --q acme
25
- kenso workspace use 1234
26
- kenso auth status
27
- ```
28
-
29
- Never print, echo to the conversation, or write the key into a file in the repo. `kenso auth login` alone is browser login: it may answer `browser_login_unavailable`; then use `--with-key`. If it works, it prints a link: ask the person to open it.
30
-
31
- ## Golden rules
32
-
33
- 1. **stdout is data, stderr is everything else.** Piped output is JSON: one object, NDJSON for lists, one JSON summary for a batch. Errors are one JSON line on stderr: `{"error":{"code","message","field","hint","next","httpStatus","requestId"}}`.
34
- 2. **Plan, then apply.** A batch command (import, update, remove, tag, `--each`) only plans without `--yes`: run it with `--dry-run`, read the plan, then run the exact command in its `next` (the same command with `--yes`). Never pass both. A single `kenso <resource> <action>` write and `kenso api` send at once: run it with `--dry-run` to see the request, then without it.
35
- 3. **Pass files, not rows.** Never paste a CSV or a list of records into the conversation or a command line. Write a file and pass `--file path` (or `--ids path`).
36
- 4. **Read the summary, then failures only.** If `failed`, `notFound` and `invalid` are 0, you are done. Otherwise read only the problem rows: `grep -E '^[0-9]+,(failed|not_found|invalid),' <results> | head -50`, or `invalidRows`. Do not read the whole results file.
37
- 5. **Follow `next`.** An error with a known fix carries the exact command to run in `next`, and what to change in `hint`.
38
- 6. **Branch on the exit code:**
39
-
40
- | Exit | Meaning | Do |
41
- |---|---|---|
42
- | 0 | OK (skipped rows are not failures) | Report the summary |
43
- | 1 | Unexpected error | Rerun with `--verbose`, report |
44
- | 2 | Usage or validation error | Fix the flags or the file (see `field`, `hint`) |
45
- | 3 | No key, bad key, or 401/403 | Ask for a key or a permission; do not retry |
46
- | 4 | Not found | Check the id |
47
- | 5 | Some rows failed, not found or invalid | Read the failed rows only, fix, resend those |
48
- | 6 | Rate limited, or a lead limit (`limit_reached`) stopped the run | Wait, or ask the person to raise the limit, then rerun |
49
- | 7 | Conflict, or another process holds the run | Read `message`; run a `next` with `--force` only after the person agrees |
50
- | 8 | Server error after retries | Wait a minute, rerun the same command |
51
- | 130 | Interrupted | Run the `next`: `kenso runs resume <runId>` |
52
-
53
- ## Leads: import
54
-
55
- ```bash
56
- kenso contacts import --template
57
- kenso contacts import --campaign 812 --file leads.csv --dry-run
58
- kenso contacts import --campaign 812 --file leads.csv --yes
59
- ```
60
-
61
- - CSV with a header row, or JSONL. Known columns: `email`, `firstName`, `lastName`, `title`, `linkedInUrl`, `companyName`, `companyDomain` (common header spellings are matched). Every other column becomes a custom variable in snake_case (`Pain Point` fills `{{pain_point}}`).
62
- - Rename or drop columns: `--map '{"Pain": "customVariables.pain_point", "Notes": null}'`.
63
- - Blank cells are never sent; the literal `null` clears a custom variable.
64
- - The dry run checks every row locally (`invalid_email`, `missing_first_name`, `duplicate_in_file` ...), shows the column `mapping` and the credit estimate. Check the mapping before you apply.
65
- - Row statuses: `created`, `updated`, `skipped` (with `reason`: `duplicate`, `blocklisted`, `already_contacted` ...), `failed`, `invalid`. `notSendable` counts saved leads that cannot be emailed yet.
66
- - Up to 100,000 rows without per-row results: add `--server-import`.
67
-
68
- ## Leads: update and cleanup
69
-
70
- ```bash
71
- kenso contacts update --file edits.csv --match id --dry-run
72
- kenso contacts update --file edits.csv --match email --campaign 812 --yes
73
- kenso contacts remove --ids ids.txt --dry-run
74
- kenso contacts remove --where '{"campaignIds": [812], "q": "acme"}' --yes
75
- kenso contacts restore --run r_ab3dxk2q --yes
76
- kenso contacts pause --ids ids.txt --yes
77
- kenso contacts resume --ids ids.txt --yes
78
- kenso contacts tag --tag 31 --ids ids.txt --yes
79
- kenso contacts export --campaign 812 --out contacts.csv
80
- ```
81
-
82
- - `update`: match by an `id`/`contactId` column, or by email within `--campaign`. A missing column or blank cell leaves a field unchanged; `null` clears it.
83
- - `--ids` takes one id per line, or a CSV/JSONL with an `id` column, or `-` for stdin. Get ids with `kenso contacts list --campaign-id 812 --all -o ids > ids.txt`.
84
- - Removing more than 1,000 needs `--confirm <count>` (the dry run's `next` has it). The remove summary has `undo`: keep it.
85
-
86
- ## Runs and resume
87
-
88
- Every batch run has an id (`r_...`) and a folder with `results.csv` (one line per input row: `row,status,id,reason,error`), `invalid.csv`, `plan.json` and `run.json`. The summary prints their absolute paths.
89
-
90
- - Rerunning the same command on the same file continues an unfinished run (`"resumed":true`) or, when every row already succeeded, answers `"changed":0` and sends no writes. Writes match existing records, so a resend never duplicates.
91
- - `kenso runs list`, `kenso runs show <runId>`, `kenso runs resume <runId>`.
92
- - `--concurrency` (1-16, default 4) works on `contacts update`, `remove`, `restore`, `pause`, `resume`, `tag`, `untag`, `people import`, `accounts import` and `--each`. `contacts import` sends one chunk at a time per campaign and has no such flag. 429s and transient 5xx are retried for you. Do not add your own retry loop.
93
-
94
- ## CRM and Studio (beta)
95
-
96
- Need the `accounts` or `studio` flag. Same plan-then-apply rules.
97
-
98
- ```bash
99
- kenso accounts import --file accounts.csv --dry-run
100
- kenso people import --file people.csv --dry-run
101
- kenso studio pull 12 --dir ./tpl
102
- kenso studio push 12 --dir ./tpl
103
- kenso studio fill 12 --accounts ids.txt
104
- ```
105
-
106
- `accounts import` charges research per created account: show the person the estimate first. `studio fill` charges per page and refuses to rerun a fill of the same file with the same flags (exit 7), but the same ids in another file are charged again. Read `kenso docs crm` and `kenso docs studio` before using them.
107
-
108
- ## Workflows in plain steps (beta)
109
-
110
- Needs the `workflows` and `workflows_plain` flags. Your own model writes the workflow from the person's words, in plain steps or as custom JSON/code; Kenso only runs it, so writing costs no Kenso AI credits.
111
-
112
- ```bash
113
- kenso workflows brief > brief.json
114
- kenso workflows brief --types ai.qualify@1,logic.filter@1 --include stepTypes
115
- kenso workflows create --data @create.json --dry-run
116
- kenso workflows validate --workflow-id 42
117
- kenso workflow-builder test --workflow-id 42 --data @test.json
118
- kenso workflows publish --workflow-id 42
119
- ```
120
-
121
- - Start with `brief`: `authoring` (how plain steps become engine steps), `stepTypes`, `triggers`, `examples` and `workspace` (campaigns, Slack, secret names). `--workflow-id` returns the current definition to change; save it with `kenso workflows update --workflow-id 42 --data @update.json` and its `baseVersion`.
122
- - `create.json` is `{"definition": {...}}`, the definition with its `plain` block. Fix every issue `validate` names, test on one record (`{"record": {"type": "person", "id": 123}}`), then publish.
123
- - Never write a secret's value into a definition or the conversation: reference `{{secrets.NAME}}` and ask the person to add it in app.ken.so at Settings > Integrations > Secrets.
124
-
125
- ## Everything else
126
-
127
- Every API operation is a command: `kenso <resource> <action>` (`kenso campaigns list`, `kenso tags create --name VIP`). A write like that runs at once, without `--yes`: check it with `--dry-run` first. Look commands up instead of guessing flags:
6
+ 1. Every write runs first with `--dry-run`, never `--yes`; apply with the plan's `next`. `--yes` at once only to continue an interrupted run or apply what the person confirmed.
7
+ 2. Many rows are one command with the file as it is (`--file`, `--ids`, `--each`), never a command per row. Run kenso only: no python, awk or shell tests, not even on a file or variable.
8
+ 3. Errors are JSON on stderr: follow `next`. `--force` only with the person's OK.
9
+ 4. Ids are flags: `--campaign 812` on contacts import, update, export; `--campaign-id 812` on API commands (`contacts list`). `--workspace <id>`; by name `kenso workspace list --q acme`.
128
10
 
129
11
  ```bash
130
- kenso describe
131
- kenso describe campaigns
132
- kenso describe campaigns update
133
- kenso campaigns update --help
12
+ kenso contacts import --campaign 812 --file leads.csv --dry-run # skips leads already in; --map '{"Pain": "customVariables.pain_point", "Notes": null}'; over 200 MB --server-import
13
+ kenso contacts update --file edits.csv --match id --dry-run # also one contact; or --match email --campaign 812
14
+ kenso contacts remove --ids ids.txt --dry-run # same for pause, resume, restore, tag --tag 31; over 1,000 add --confirm <count>
15
+ kenso contacts remove --where '{"campaignIds": [812], "q": "acme"}' --dry-run # also pause, resume; the plan shows the matches: no search first
16
+ kenso contacts list --campaign-id 812 --all -o ids > ids.txt # tag and restore take --ids only: list the ids first
17
+ kenso contacts export --campaign 812 --out leads.csv # a segment: kenso contact-exports create --segment-id 55
18
+ kenso runs list # an interrupted run (terminal lost): find it, then kenso runs resume <runId>. A changed file is a new run
19
+ kenso accounts import --file accounts.csv --dry-run # companies; people (any file of people) go in with kenso people import --file people.csv
20
+ kenso studio push 12 --dir ./tpl # to preview local edits push first (draft only; live needs --publish), then studio preview 12
21
+ kenso studio fill 12 --accounts ids.txt --dry-run # or --campaign 10546 --contacts leads.csv
22
+ kenso campaigns update --campaign-id 812 --name Q4 --dry-run # any API operation; --each rows.csv for many
23
+ kenso mcp call list_skills
134
24
  ```
135
25
 
136
- - Lists print one page; `--all` streams every page, `--limit` and `--cursor` page by hand. `--fields a,b` and `--query '<JMESPath>'` shape output without `jq`.
137
- - Many records: `--each file.csv` runs a generated command once per row (row keys are flag or API names), with results and resume. It needs `--yes` or `--dry-run` unless it is a GET.
138
- - Beta commands are hidden from help until the workspace has the flag; `--all-commands` shows them.
139
- - Raw route: `kenso api GET /v1/me`, `kenso api POST /v1/tags --data @tag.json`. Writes through `kenso api` run without `--yes`, so be sure first.
140
- - MCP-only tools (such as skills): `kenso mcp tools`, `kenso mcp call skills --operation list`.
141
- - Offline docs: `kenso docs`, `kenso docs leads`.
26
+ `accounts import` charges per new account, `studio fill` per page (again for the same ids in another file): show the estimate first. `pinned_by_user`: with the person's OK, `--overwrite-pinned`. Workflows: `kenso workflows brief` first; secrets only as `{{secrets.NAME}}`. Key: `KENSO_API_KEY`, or any variable piped as the first command, no check or printenv (an empty key is refused): `printf '%s' "$KEY" | kenso auth login --with-key`; never in a flag, output or file. `kenso api` only when no command fits. Flags: `kenso <resource> <action> --help`. More: `kenso docs leads|batch|crm|studio`.