kenso 0.0.0-stage → 0.1.7
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 +74 -2
- package/dist/kenso.js +12220 -0
- package/dist/operations.json +1 -0
- package/docs/README.md +74 -0
- package/docs/agents.md +124 -0
- package/docs/auth.md +108 -0
- package/docs/batch.md +152 -0
- package/docs/crm.md +111 -0
- package/docs/leads.md +214 -0
- package/docs/output-and-errors.md +154 -0
- package/docs/reference.md +31729 -0
- package/docs/studio.md +113 -0
- package/package.json +46 -4
- package/skill/kenso-cli/SKILL.md +141 -0
package/docs/studio.md
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Studio (beta)
|
|
2
|
+
|
|
3
|
+
Studio templates are the pages, docs and other assets Kenso builds for each account or lead. The `kenso studio` commands let you edit a template as a folder of files on your machine, check it, preview it, and fill it for many accounts or leads at once. They are beta: they need the `studio` feature flag on your workspace. Help and `kenso describe` hide them until your workspace has it; `--all-commands` shows them.
|
|
4
|
+
|
|
5
|
+
| Command | What it does |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `studio pull <templateId> --dir <dir>` | Write a template version's files to a folder |
|
|
8
|
+
| `studio push <templateId> --dir <dir>` | Save the folder's files to the template's draft and print the validation |
|
|
9
|
+
| `studio validate <templateId> --dir <dir>` | Validate the folder against the template without saving |
|
|
10
|
+
| `studio preview <templateId>` | Render a version for up to 3 accounts and print the preview links |
|
|
11
|
+
| `studio fill <templateId>` | Fill the template for many accounts or campaign leads, estimate first |
|
|
12
|
+
|
|
13
|
+
Find template ids with the generated commands:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
kenso asset-templates list
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Edit a template locally
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
kenso studio pull 12 --dir ./my-template
|
|
23
|
+
kenso studio validate 12 --dir ./my-template
|
|
24
|
+
kenso studio push 12 --dir ./my-template
|
|
25
|
+
kenso studio preview 12 --dir ./my-template --account-ids 501,502
|
|
26
|
+
kenso studio push 12 --dir ./my-template --publish
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### pull
|
|
30
|
+
|
|
31
|
+
`pull` writes every file of the version under `--dir`: text files from the answer, binaries downloaded from signed links and checked against their SHA-256. It overwrites files with the same path and leaves other files in the folder alone. It checks every path before it writes anything, and refuses one that would land outside `--dir` (`unsafe_path`).
|
|
32
|
+
|
|
33
|
+
`--template-version` picks the version: `draft`, `latest` (the latest published) or a version id. The default is the draft, else the latest published version. (The flag is not `--version`, which prints the CLI version.)
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
kenso studio pull 12 --dir ./v3 --template-version 345
|
|
37
|
+
kenso studio pull 12 --dir ./my-template --dry-run
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
It prints `{templateId, versionId, files, dir}`. `--dry-run` lists the paths and writes nothing.
|
|
41
|
+
|
|
42
|
+
### push
|
|
43
|
+
|
|
44
|
+
`push` reads `--dir`, skipping dotfiles, dot folders and `node_modules`.
|
|
45
|
+
|
|
46
|
+
- A text file (valid UTF-8, no NUL byte, under 1 MB) goes inline.
|
|
47
|
+
- Any other file is uploaded through a signed upload URL first, 4 at a time, up to 5 MB each. A larger file is refused before any call.
|
|
48
|
+
- One push then saves the files into the draft and prints `{templateId, versionId, versionNumber, validation, changed, deleted}`.
|
|
49
|
+
|
|
50
|
+
Files that are in the draft but not in the folder stay, unless you pass `--delete-missing`. `--message` describes the change (default "Pushed with the Kenso CLI"). With `--publish`, the new version is published when validation passes, and the output adds `published`.
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
kenso studio push 12 --dir ./my-template --message "New hero copy"
|
|
54
|
+
kenso studio push 12 --dir ./my-template --delete-missing --publish
|
|
55
|
+
kenso studio push 12 --dir ./my-template --dry-run
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
When validation finds errors, the draft is still saved: the result prints, then the error `validation_failed` (exit 2) with the first problem as its `hint`. When publishing fails after a good push, the push result still prints and the error says which version was saved. `--dry-run` lists what would be sent and calls nothing.
|
|
59
|
+
|
|
60
|
+
### validate
|
|
61
|
+
|
|
62
|
+
`validate` reads the folder the same way and checks the files laid over the draft, as a push would, without saving them. Binaries are uploaded so they can be checked. `--delete-missing` validates exactly the folder's files. It prints the validation and exits 2 when there are errors.
|
|
63
|
+
|
|
64
|
+
### preview
|
|
65
|
+
|
|
66
|
+
`preview` renders a saved version, not your local files: the draft, else the latest published version, or `--version-id`. It takes up to a minute per account.
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
kenso studio preview 12
|
|
70
|
+
kenso studio preview 12 --account-ids 501,502,503 --mode render
|
|
71
|
+
kenso studio preview 12 --sample samples/acme.json
|
|
72
|
+
kenso studio preview 12 --mode interact --interact @steps.json
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
- `--account-ids` takes up to 3 ids. Without it, Kenso picks the 3 most recently touched accounts, else the template's samples.
|
|
76
|
+
- `--mode` is `render` (default) or `interact`. `--interact` takes the click, type and wait steps as JSON, `@file` or `-` (up to 20).
|
|
77
|
+
- With `--dir`, the CLI compares your folder to the version it renders and warns on stderr when they differ, naming the push command to run first.
|
|
78
|
+
|
|
79
|
+
The output lists each preview's link, screenshots, console errors and link issues.
|
|
80
|
+
|
|
81
|
+
## Fill a template for many accounts or leads
|
|
82
|
+
|
|
83
|
+
`fill` creates pages for a list of accounts, or for the leads of a campaign. A fill is charged per page, so it always prices the work first.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
kenso studio fill 12 --accounts accounts.txt
|
|
87
|
+
kenso studio fill 12 --accounts accounts.csv --column accountId --yes --wait
|
|
88
|
+
kenso studio fill 12 --campaign 345 --contacts leads.csv --yes
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- **Ids** come from `--accounts <file>`, or from `--contacts <file>` with `--campaign <id>`; `-` reads stdin. A file holds one id per line, or a CSV or JSONL with an id column (`--column`, else `id`, else `contactId`). Repeated ids are filled once.
|
|
92
|
+
- **Without `--yes`** (or with `--estimate`) it prints the estimate and the apply command, and creates nothing. For a campaign, the estimate counts one page per lead; Kenso builds one page per company, so it is an upper bound.
|
|
93
|
+
- **With `--yes`** it creates one fill run per 500 ids, one after another.
|
|
94
|
+
- **With `--wait`** it follows each run every 5 seconds until it completes, fails or is cancelled. Without it, follow a run with `kenso asset-runs get --run-id <id>`.
|
|
95
|
+
|
|
96
|
+
The summary lists `runs: [{runId, state, rows}]`, and `results.csv` has one line per id with its page id and state.
|
|
97
|
+
|
|
98
|
+
**The same fill never runs twice.** Rebuilding a page charges again, so when you rerun a fill with the same file (the same bytes) and the same flags:
|
|
99
|
+
|
|
100
|
+
- an unfinished fill continues where it stopped;
|
|
101
|
+
- a finished fill where every id succeeded answers from that run and changes nothing;
|
|
102
|
+
- anything else is refused with `already_filled` (exit 7). To retry only the ids that failed, take them from the earlier run's `results.csv` into a new file and fill that file.
|
|
103
|
+
|
|
104
|
+
The guard compares the file and the flags, not the ids: the same ids in another file, or in another order, are filled and charged again. Keep one ids file per fill, and check `kenso runs list` before you fill ids from a new file.
|
|
105
|
+
|
|
106
|
+
## Other Studio commands
|
|
107
|
+
|
|
108
|
+
Everything else (create a template, list versions, restore a version, datasets, publish) is a generated command under `asset-templates`, `asset-runs` and `asset-template-datasets`:
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
kenso asset-templates --help --all-commands
|
|
112
|
+
kenso describe asset-templates
|
|
113
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kenso",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.7",
|
|
4
|
+
"description": "The Kenso CLI: bulk lead, CRM and Studio work for people and coding agents",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"kenso": "dist/kenso.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist/",
|
|
12
|
+
"docs/",
|
|
13
|
+
"skill/",
|
|
14
|
+
"README.md"
|
|
15
|
+
],
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=22"
|
|
18
|
+
},
|
|
19
|
+
"packageManager": "pnpm@11.15.0",
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/Ken-Technology/ken-backend.git",
|
|
23
|
+
"directory": "cli"
|
|
24
|
+
},
|
|
25
|
+
"homepage": "https://ken.so/cli",
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "node scripts/build.mjs",
|
|
28
|
+
"typecheck": "tsc --noEmit",
|
|
29
|
+
"lint": "eslint .",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:contract": "vitest run test/contract.test.ts --passWithNoTests",
|
|
32
|
+
"check:startup": "node scripts/check-startup.mjs",
|
|
33
|
+
"check:package": "node scripts/check-package.mjs"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"@types/jmespath": "0.15.2",
|
|
37
|
+
"@types/node": "22.20.5",
|
|
38
|
+
"csv-parse": "7.0.3",
|
|
39
|
+
"csv-stringify": "6.9.0",
|
|
40
|
+
"esbuild": "0.28.2",
|
|
41
|
+
"eslint": "10.12.0",
|
|
42
|
+
"jmespath": "0.16.0",
|
|
43
|
+
"typescript": "6.0.3",
|
|
44
|
+
"typescript-eslint": "8.71.1",
|
|
45
|
+
"vitest": "5.0.3"
|
|
46
|
+
},
|
|
47
|
+
"gitHead": "8ed729698e19d049751bf644c41dc81170648392"
|
|
48
|
+
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
---
|
|
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.
|
|
4
|
+
---
|
|
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:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
kenso describe
|
|
131
|
+
kenso describe campaigns
|
|
132
|
+
kenso describe campaigns update
|
|
133
|
+
kenso campaigns update --help
|
|
134
|
+
```
|
|
135
|
+
|
|
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`.
|