callkaro-cli-unofficial 0.4.0 → 0.4.1

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 (2) hide show
  1. package/README.md +276 -264
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,264 +1,276 @@
1
- # cku
2
-
3
- An unofficial fork of the [CallKaro CLI](https://www.npmjs.com/package/@callkaro-official/cli). It installs as `cku`, so it sits alongside the official `ck` without either one overwriting the other.
4
-
5
- Manage voice agents, calls, phone numbers, batch campaigns, simulations and analytics from the terminal — plus the dashboard side, which the official CLI doesn't reach at all.
6
-
7
- ```
8
- cku agents list
9
- cku calls make --agent <id> --to <number> --test
10
- cku kpi tasks --severity "Very High" --column action_items
11
- cku accounts use tejas@acme.com
12
- ```
13
-
14
- ---
15
-
16
- ## Why this exists
17
-
18
- **It doesn't fight the official CLI for a name.** Both packages write to the same global `node_modules/.bin`. If both were called `ck`, whichever npm install ran last would silently take over. You'd type `ck`, get official behaviour, and get no signal anything had changed. `cku` cannot collide.
19
-
20
- **It holds several accounts at once.** The official CLI keeps one session. This one keeps a file per account, and can pin an account to a folder, so two agents working in two directories can't switch each other out from under themselves.
21
-
22
- **It reaches the dashboard API.** The official CLI only talks to `/cli/*`. That leaves the KPI board, the call analyzers, and the server's own model catalogue unreachable from a terminal — [`cku kpi`](#only-in-cku) is the whole of that surface.
23
-
24
- **It fixes three upstream bugs.** Details and evidence in [`docs/BUG-REPORT.md`](docs/BUG-REPORT.md).
25
-
26
- ---
27
-
28
- ## Install
29
-
30
- ```bash
31
- npm install --global callkaro-cli-unofficial
32
- ```
33
-
34
- Or, to work on it directly:
35
-
36
- ```bash
37
- git clone https://github.com/TejasLamba2006/callkaro-cli-unofficial
38
- cd callkaro-cli-unofficial
39
- npm install && npm run build && npm link
40
- ```
41
-
42
- Node 18 or newer.
43
-
44
- ---
45
-
46
- ## How it fits together
47
-
48
- ![Runtime flow: cku commands through the shared layer to the backend, config, and the skill pack](docs/images/runtime-flow.webp)
49
-
50
- Every arrow above is a real import or a real call, checked against the source. `api.ts` is the only thing that touches the network. `config.ts` is the only thing that reads a token, which is why every route to the backend goes through it. The ASCII version below says the same thing for the terminal:
51
-
52
- ```
53
- ┌─ cku ─────────────────────────────────────────────┐
54
- │ index.ts commander wiring, 44 subcommands │
55
- │ ↓ │
56
- │ commands/ agents, calls, numbers, batches, │
57
- │ sim, analytics, audits, skills │
58
- │ ↓ │
59
- │ lib/ api.ts, config.ts, agentUpdate.ts, │
60
- │ looseJson.ts, ui.ts, catalog.ts │
61
- └──────┬────────────────────────────────────────────┘
62
- ↓
63
- account resolution, highest precedence first
64
- │
65
- CK_TOKEN → CK_ACCOUNT → ./.cku.json → global → none
66
- │
67
- ↓
68
- backend.callkaro.ai
69
- /cli/* · 61 endpoints · Bearer ck_5b02…
70
- ```
71
-
72
- One thing worth knowing up front: the official CLI ships **compiled output only**. Its npm package has `dist/` and nothing else: no TypeScript, no tests, no build config, and it isn't in any public repo. So this is a reconstruction. The `/cli/*` contract was rebuilt from the published bundle, and the command surface matches v5.0.0 (the official CLI's commands, its `accounts` group renamed `monitor`, plus the `accounts` group and the dashboard-side `dashboard`, `kpi`, `analyzers` and `models` groups).
73
-
74
- The public API at `api.callkaro.ai` is a different thing entirely, with an `X-API-KEY` header and three documented endpoints. This CLI doesn't use it. [`docs/architecture.md`](docs/architecture.md) covers the boundaries, and [`docs/api.md`](docs/api.md) has the full endpoint inventory.
75
-
76
- ---
77
-
78
- ## Several accounts
79
-
80
- ```bash
81
- cku login # add an account
82
- cku accounts # list them, * marks the active one
83
- cku accounts use <email> # change the global default
84
- cku accounts remove <email> # forget one
85
- ```
86
-
87
- ### Pin an account to a folder
88
-
89
- If you're running more than one agent at a time, this is the part that matters.
90
-
91
- ```bash
92
- cd ~/work/bot-alpha && cku accounts bind alpha@acme.com
93
- cd ~/work/bot-beta && cku accounts bind beta@other.com
94
- ```
95
-
96
- `bind` writes a `.cku.json` into that directory containing just the account slug and no token, so it's safe to commit. Every `cku` command in that folder (and anything nested under it) uses that account, regardless of what the global default says.
97
-
98
- Why this matters: `cku accounts use` changes **shared** state. Two agents in two folders both calling it would overwrite each other, and whichever wrote last would silently redirect the other bot's commands to the wrong CallKaro account. No error, just wrong data. A bound folder never reads shared state at all, so that can't happen.
99
-
100
- ```
101
- cku accounts status
102
- ```
103
-
104
- tells you which account is in effect *and where the choice came from*: env var, this folder, or the global default. Worth running first when something looks off, since acting on the wrong account is the most damaging mistake available here.
105
-
106
- Override for a single command with `CK_ACCOUNT=<email> cku whoami`.
107
-
108
- ---
109
-
110
- ## Fixes over the official CLI
111
-
112
- Full write-ups, with line numbers and reproduction steps, in [`docs/BUG-REPORT.md`](docs/BUG-REPORT.md).
113
-
114
- **`agents update --set` silently deleted agent configuration.** Send a partial `voice_configuration` and the backend replaces the whole object, so nine keys, including the voice itself, were dropped, and the command reported success. The agent kept working; it just couldn't make calls. The fix already exists upstream as `deepMerge`, with a comment describing exactly this problem. Nothing ever called it.
115
-
116
- **`skills install` failed on every run on Windows.** `tar` was handed an absolute path, and `C:/Users/...` gets read as a `<host>:<path>` remote spec, so tar tried to connect to a machine named "C". Since the temp path always sits under a drive root, this never worked there. It's also the only way to install the skill pack, so an agent couldn't bootstrap itself on Windows. Linux and macOS were never affected; no drive letters, no colon in a path.
117
-
118
- **`agents export` can't always be re-imported.** For some agents the export response omits a field the CLI's own validator requires, so the round trip fails. That part needs a backend fix; a workaround is in the `callkaro-cli` skill.
119
-
120
- My own first port of this fix had a worse version of the same bug: I merged against the agent's default version, so updating any other version could swap its voice for the default's. That's fixed and covered by a test, and the details are in [`docs/official-fixes.md`](docs/official-fixes.md).
121
-
122
- ---
123
-
124
- ## Only in `cku`
125
-
126
- Commands and capabilities the official CLI does not have at all. Not bug fixes — surface area.
127
-
128
- ### The KPI manager and the pending-task board
129
-
130
- The official `ck` has **no KPI commands whatsoever**. This is the only way to reach the board from a terminal.
131
-
132
- ```bash
133
- cku kpi tasks --severity "Very High" --column action_items --since 7d
134
- cku kpi show "<taskId>" # cause, recommended fix, metric impact
135
- cku kpi create --cause "…" --fix "…" --severity High
136
- cku kpi move "<taskId>" in_progress
137
- cku kpi comment "<taskId>" "Fixed in v3"
138
- cku kpi assign "<taskId>" --to "Name" # or --to ai_fde
139
- cku kpi target --agent <id> --value 25
140
- cku kpi rca --agent <id> --since 2026-09-01 --until 2026-09-30
141
- ```
142
-
143
- There is **no delete** for a card — the board retires one by moving it to `rejected`, which is reversible. Only `description` is editable after creation; `cause`, fix and severity are fixed at create, so correcting one means creating a replacement.
144
-
145
- `GET /pending-tasks` returns every column including `done` and `rejected`, so a closed card is not a gone card. The list prints a **COLUMN** column for exactly that reason, and `--column` filters on it.
146
-
147
- ### The dashboard credential
148
-
149
- ```bash
150
- cku dashboard login # separate from `cku login`; the token lasts 24h, renewed silently
151
- cku dashboard whoami
152
- cku dashboard probe # which dashboard routes this token reaches
153
- ```
154
-
155
- The dashboard API needs a *different* token from `/cli/*` — they're not interchangeable, and each rejects the other with an opaque 401. This also unlocks `cku analyzers` and `cku models`. The dashboard token expires every 24h with no refresh endpoint, so `cku dashboard login` saves your password (plain text, mode 0600, alongside the tokens) and re-logs in for you when it lapses. Pass `--no-save-password` to keep it off disk and re-enter it daily; `cku dashboard logout` deletes it.
156
-
157
- ### Knowing which models are actually valid
158
-
159
- ```bash
160
- cku models # per slot, and which field each governs
161
- cku models --slot agent
162
- ```
163
-
164
- Models are scoped per slot and **the slots disagree**: `agent` has 44, `post-call` has 9 and excludes `gpt-4o` and `o4-mini`. So the same value is valid in `model` and refused in `postcallmodel`. Works with or without a dashboard session, and says which source it read.
165
-
166
- ### A catalogue that can't silently rot
167
-
168
- The provider tables, and now the model lists, are regenerated from the server rather than hand-copied:
169
-
170
- ```bash
171
- npm run catalog:sync # refresh from the bundle + the live server
172
- npm run catalog:check # fail if catalog.json disagrees with the snapshot
173
- ```
174
-
175
- `catalog:check` runs offline against a committed snapshot, so it works in CI with no credentials. On 1 October 2026 it caught shipped tables that listed withdrawn models *and* missed live ones in both directions. A wrong voice model otherwise persists silently and only surfaces as a broken call.
176
-
177
- ### Smaller things
178
-
179
- - `cku agents chat` — text chat with an agent's real prompt and tools, no phone call. Scriptable with `--say`, replayable with `--history`. Custom in-call functions run for real
180
- - `cku scheduled list|queued|get` — scheduled calls and the queue of what will actually dial (dashboard login)
181
- - `cku sim update` — edit a test case in place
182
- - `cku calls list --postcall dnc_requested=true --provider-type plivo --sid <sid>` — filters the official CLI doesn't expose
183
- - `cku calls logs` — grep/awk/sed over the raw call log, in-process, no subprocess and no shell
184
- - `cku accounts status` — reports which account is in effect **and where that choice came from**
185
- - Per-project binding, so parallel agents can't redirect each other
186
- - `secrets set` without the value on the command line
187
- - `--json` that stays unpaged for scripting, with human tables paged
188
-
189
- ---
190
-
191
- ## Staying current
192
-
193
- A daily workflow checks npm for a newer `@callkaro-official/cli` and, when it finds one, regenerates the provider catalogue and opens a PR onto the `official` branch. It never merges anything itself.
194
-
195
- | Branch | What's on it |
196
- |---|---|
197
- | `official` | Clean base. Changes only arrive through sync PRs. |
198
- | `main` | `official` plus your customizations. Your working branch. |
199
-
200
- To take an update: review the PR, merge into `official`, then merge `official` into `main`.
201
-
202
- Worth knowing what the sync does and doesn't do. It regenerates `src/data/catalog.json` — the provider tables and the per-slot LLM model lists — because those change when the dashboard changes. It does **not** port command code, because the official source isn't available, so that's maintained by hand. The PR lists which commands were added or removed so you know what to look at.
203
-
204
- Keep your customizations in as few files as you can. That diff is the one you have to resolve on every update.
205
-
206
- ---
207
-
208
- ## Development
209
-
210
- ```bash
211
- npm run build # tsc -> dist/, copy endpoints.json, chmod +x
212
- npm test # build, then node --test
213
- npm run test:only # tests without rebuilding
214
- npm run dev # build and run
215
- npm run catalog:sync # regenerate the catalogue: provider tables + per-slot LLM lists, from the server
216
- npm run catalog:check # fail if catalog.json disagrees with the server snapshot (offline)
217
- npm run catalog:check:live # same, against the live server (needs `cku dashboard login`)
218
- ```
219
-
220
- Single test file:
221
-
222
- ```bash
223
- node --test tests/agentUpdate.test.js
224
- ```
225
-
226
- 269 tests. No linter or formatter is configured.
227
-
228
- ### Layout
229
-
230
- `src/index.ts` is commander wiring and almost nothing else. Every command, flag and description is declared there. `src/commands/` holds one module per command group. `src/lib/` holds the shared layer, and that's where the rules worth knowing live:
231
-
232
- - **`api.ts`** is the only place that talks to the backend. Adding an endpoint means adding a method here, not a raw `fetch` in a command.
233
- - **`looseJson.ts`** has two parsers, chosen by where the text came from. Values from argv get a repair pass, because PowerShell strips quotes out of single-quoted arguments and `--set '{"name":"x"}'` arrives as `{name:x}`. Values from files or stdin are parsed strictly, since the shell never touched them and a real typo should be reported rather than guessed at.
234
- - **`agentUpdate.ts`** merges updates into objects the backend replaces wholesale, so a partial update doesn't drop its siblings.
235
- - **`ui.ts`** sets `process.exitCode` rather than calling `process.exit()`. On Windows, exiting while a fetch socket is still closing trips a libuv assertion that aborts with code 127 and a pile of C-level noise.
236
-
237
- ### Regenerating docs
238
-
239
- Both of these read from the code, so they can't drift:
240
-
241
- ```bash
242
- node scripts/gen-api-inventory.js # endpoint tables in docs/api.md
243
- node scripts/gen-cli-reference.js ../callkaro-skills/skills/callkaro-cli/REFERENCE.md
244
- ```
245
-
246
- ---
247
-
248
- ## Skills
249
-
250
- The CLI installs a skill pack for Claude Code and other coding agents, so an agent can drive `cku` without being told how.
251
-
252
- ```bash
253
- cku skills install --claude # this fork's pack
254
- cku skills install --claude --official # the upstream pack
255
- cku skills update # refresh every install
256
- ```
257
-
258
- Targets include `--cursor --copilot --gemini --windsurf --roo --opencode --cline --codex --all`, plus `--project` to install into a repo rather than your user account. Skills ship from GitHub, so a new one reaches users without a CLI release.
259
-
260
- ---
261
-
262
- ## License
263
-
264
- Apache-2.0, matching the upstream CLI.
1
+ # cku
2
+
3
+ An unofficial fork of the [CallKaro CLI](https://www.npmjs.com/package/@callkaro-official/cli). It installs as `cku`, so it sits alongside the official `ck` without either one overwriting the other.
4
+
5
+ Manage voice agents, calls, phone numbers, batch campaigns, simulations and analytics from the terminal — plus the dashboard side, which the official CLI doesn't reach at all.
6
+
7
+ ```
8
+ cku agents list
9
+ cku calls make --agent <id> --to <number> --test
10
+ cku kpi tasks --severity "Very High" --column action_items
11
+ cku accounts use tejas@acme.com
12
+ ```
13
+
14
+ ---
15
+
16
+ ## Why this exists
17
+
18
+ **It doesn't fight the official CLI for a name.** Both packages write to the same global `node_modules/.bin`. If both were called `ck`, whichever npm install ran last would silently take over. You'd type `ck`, get official behaviour, and get no signal anything had changed. `cku` cannot collide.
19
+
20
+ **It holds several accounts at once.** The official CLI keeps one session. This one keeps a file per account, and can pin an account to a folder, so two agents working in two directories can't switch each other out from under themselves.
21
+
22
+ **It reaches the dashboard API.** The official CLI only talks to `/cli/*`. That leaves the KPI board, the call analyzers, and the server's own model catalogue unreachable from a terminal — [`cku kpi`](#only-in-cku) is the whole of that surface.
23
+
24
+ **It fixes three upstream bugs.** Details and evidence in [`docs/BUG-REPORT.md`](docs/BUG-REPORT.md).
25
+
26
+ ---
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ npm install --global callkaro-cli-unofficial
32
+ ```
33
+
34
+ Or, to work on it directly:
35
+
36
+ ```bash
37
+ git clone https://github.com/TejasLamba2006/callkaro-cli-unofficial
38
+ cd callkaro-cli-unofficial
39
+ npm install && npm run build && npm link
40
+ ```
41
+
42
+ Node 18 or newer.
43
+
44
+ ### Let your agent install it
45
+
46
+ Paste this into Claude Code, Cursor, Codex or any coding agent. It installs the CLI and this fork's skill pack, then checks both.
47
+
48
+ ```text
49
+ Install the unofficial CallKaro CLI and its skills:
50
+ 1. Run: npm install --global callkaro-cli-unofficial (needs Node 18+)
51
+ 2. Run: cku skills install --claude (use --cursor, --codex, --gemini, --windsurf, --cline, --roo, --opencode, --copilot, or --all for other tools; add --project to install into this repo only). Do NOT pass --official.
52
+ 3. Verify: run `cku --version` and `cku skills dir` (add the same tool flag), and tell me what you installed.
53
+ 4. Do not log in or run any other command. Tell me to run `cku login` myself.
54
+ ```
55
+
56
+ ---
57
+
58
+ ## How it fits together
59
+
60
+ ![Runtime flow: cku commands through the shared layer to the backend, config, and the skill pack](docs/images/runtime-flow.webp)
61
+
62
+ Every arrow above is a real import or a real call, checked against the source. `api.ts` is the only thing that touches the network. `config.ts` is the only thing that reads a token, which is why every route to the backend goes through it. The ASCII version below says the same thing for the terminal:
63
+
64
+ ```
65
+ ┌─ cku ─────────────────────────────────────────────┐
66
+ │ index.ts commander wiring, 44 subcommands │
67
+ │ ↓ │
68
+ │ commands/ agents, calls, numbers, batches, │
69
+ │ sim, analytics, audits, skills │
70
+ │ ↓ │
71
+ │ lib/ api.ts, config.ts, agentUpdate.ts, │
72
+ │ looseJson.ts, ui.ts, catalog.ts │
73
+ └──────┬────────────────────────────────────────────┘
74
+ ↓
75
+ account resolution, highest precedence first
76
+ │
77
+ CK_TOKEN → CK_ACCOUNT → ./.cku.json → global → none
78
+ │
79
+ ↓
80
+ backend.callkaro.ai
81
+ /cli/* · 61 endpoints · Bearer ck_5b02…
82
+ ```
83
+
84
+ One thing worth knowing up front: the official CLI ships **compiled output only**. Its npm package has `dist/` and nothing else: no TypeScript, no tests, no build config, and it isn't in any public repo. So this is a reconstruction. The `/cli/*` contract was rebuilt from the published bundle, and the command surface matches v5.0.0 (the official CLI's commands, its `accounts` group renamed `monitor`, plus the `accounts` group and the dashboard-side `dashboard`, `kpi`, `analyzers` and `models` groups).
85
+
86
+ The public API at `api.callkaro.ai` is a different thing entirely, with an `X-API-KEY` header and three documented endpoints. This CLI doesn't use it. [`docs/architecture.md`](docs/architecture.md) covers the boundaries, and [`docs/api.md`](docs/api.md) has the full endpoint inventory.
87
+
88
+ ---
89
+
90
+ ## Several accounts
91
+
92
+ ```bash
93
+ cku login # add an account
94
+ cku accounts # list them, * marks the active one
95
+ cku accounts use <email> # change the global default
96
+ cku accounts remove <email> # forget one
97
+ ```
98
+
99
+ ### Pin an account to a folder
100
+
101
+ If you're running more than one agent at a time, this is the part that matters.
102
+
103
+ ```bash
104
+ cd ~/work/bot-alpha && cku accounts bind alpha@acme.com
105
+ cd ~/work/bot-beta && cku accounts bind beta@other.com
106
+ ```
107
+
108
+ `bind` writes a `.cku.json` into that directory containing just the account slug and no token, so it's safe to commit. Every `cku` command in that folder (and anything nested under it) uses that account, regardless of what the global default says.
109
+
110
+ Why this matters: `cku accounts use` changes **shared** state. Two agents in two folders both calling it would overwrite each other, and whichever wrote last would silently redirect the other bot's commands to the wrong CallKaro account. No error, just wrong data. A bound folder never reads shared state at all, so that can't happen.
111
+
112
+ ```
113
+ cku accounts status
114
+ ```
115
+
116
+ tells you which account is in effect *and where the choice came from*: env var, this folder, or the global default. Worth running first when something looks off, since acting on the wrong account is the most damaging mistake available here.
117
+
118
+ Override for a single command with `CK_ACCOUNT=<email> cku whoami`.
119
+
120
+ ---
121
+
122
+ ## Fixes over the official CLI
123
+
124
+ Full write-ups, with line numbers and reproduction steps, in [`docs/BUG-REPORT.md`](docs/BUG-REPORT.md).
125
+
126
+ **`agents update --set` silently deleted agent configuration.** Send a partial `voice_configuration` and the backend replaces the whole object, so nine keys, including the voice itself, were dropped, and the command reported success. The agent kept working; it just couldn't make calls. The fix already exists upstream as `deepMerge`, with a comment describing exactly this problem. Nothing ever called it.
127
+
128
+ **`skills install` failed on every run on Windows.** `tar` was handed an absolute path, and `C:/Users/...` gets read as a `<host>:<path>` remote spec, so tar tried to connect to a machine named "C". Since the temp path always sits under a drive root, this never worked there. It's also the only way to install the skill pack, so an agent couldn't bootstrap itself on Windows. Linux and macOS were never affected; no drive letters, no colon in a path.
129
+
130
+ **`agents export` can't always be re-imported.** For some agents the export response omits a field the CLI's own validator requires, so the round trip fails. That part needs a backend fix; a workaround is in the `callkaro-cli` skill.
131
+
132
+ My own first port of this fix had a worse version of the same bug: I merged against the agent's default version, so updating any other version could swap its voice for the default's. That's fixed and covered by a test, and the details are in [`docs/official-fixes.md`](docs/official-fixes.md).
133
+
134
+ ---
135
+
136
+ ## Only in `cku`
137
+
138
+ Commands and capabilities the official CLI does not have at all. Not bug fixes — surface area.
139
+
140
+ ### The KPI manager and the pending-task board
141
+
142
+ The official `ck` has **no KPI commands whatsoever**. This is the only way to reach the board from a terminal.
143
+
144
+ ```bash
145
+ cku kpi tasks --severity "Very High" --column action_items --since 7d
146
+ cku kpi show "<taskId>" # cause, recommended fix, metric impact
147
+ cku kpi create --cause "…" --fix "…" --severity High
148
+ cku kpi move "<taskId>" in_progress
149
+ cku kpi comment "<taskId>" "Fixed in v3"
150
+ cku kpi assign "<taskId>" --to "Name" # or --to ai_fde
151
+ cku kpi target --agent <id> --value 25
152
+ cku kpi rca --agent <id> --since 2026-09-01 --until 2026-09-30
153
+ ```
154
+
155
+ There is **no delete** for a card — the board retires one by moving it to `rejected`, which is reversible. Only `description` is editable after creation; `cause`, fix and severity are fixed at create, so correcting one means creating a replacement.
156
+
157
+ `GET /pending-tasks` returns every column including `done` and `rejected`, so a closed card is not a gone card. The list prints a **COLUMN** column for exactly that reason, and `--column` filters on it.
158
+
159
+ ### The dashboard credential
160
+
161
+ ```bash
162
+ cku dashboard login # separate from `cku login`; the token lasts 24h, renewed silently
163
+ cku dashboard whoami
164
+ cku dashboard probe # which dashboard routes this token reaches
165
+ ```
166
+
167
+ The dashboard API needs a *different* token from `/cli/*` — they're not interchangeable, and each rejects the other with an opaque 401. This also unlocks `cku analyzers` and `cku models`. The dashboard token expires every 24h with no refresh endpoint, so `cku dashboard login` saves your password (plain text, mode 0600, alongside the tokens) and re-logs in for you when it lapses. Pass `--no-save-password` to keep it off disk and re-enter it daily; `cku dashboard logout` deletes it.
168
+
169
+ ### Knowing which models are actually valid
170
+
171
+ ```bash
172
+ cku models # per slot, and which field each governs
173
+ cku models --slot agent
174
+ ```
175
+
176
+ Models are scoped per slot and **the slots disagree**: `agent` has 44, `post-call` has 9 and excludes `gpt-4o` and `o4-mini`. So the same value is valid in `model` and refused in `postcallmodel`. Works with or without a dashboard session, and says which source it read.
177
+
178
+ ### A catalogue that can't silently rot
179
+
180
+ The provider tables, and now the model lists, are regenerated from the server rather than hand-copied:
181
+
182
+ ```bash
183
+ npm run catalog:sync # refresh from the bundle + the live server
184
+ npm run catalog:check # fail if catalog.json disagrees with the snapshot
185
+ ```
186
+
187
+ `catalog:check` runs offline against a committed snapshot, so it works in CI with no credentials. On 1 October 2026 it caught shipped tables that listed withdrawn models *and* missed live ones in both directions. A wrong voice model otherwise persists silently and only surfaces as a broken call.
188
+
189
+ ### Smaller things
190
+
191
+ - `cku agents chat` — text chat with an agent's real prompt and tools, no phone call. Scriptable with `--say`, replayable with `--history`. Custom in-call functions run for real
192
+ - `cku scheduled list|queued|get` — scheduled calls and the queue of what will actually dial (dashboard login)
193
+ - `cku sim update` — edit a test case in place
194
+ - `cku calls list --postcall dnc_requested=true --provider-type plivo --sid <sid>` — filters the official CLI doesn't expose
195
+ - `cku calls logs` — grep/awk/sed over the raw call log, in-process, no subprocess and no shell
196
+ - `cku accounts status` — reports which account is in effect **and where that choice came from**
197
+ - Per-project binding, so parallel agents can't redirect each other
198
+ - `secrets set` without the value on the command line
199
+ - `--json` that stays unpaged for scripting, with human tables paged
200
+
201
+ ---
202
+
203
+ ## Staying current
204
+
205
+ A daily workflow checks npm for a newer `@callkaro-official/cli` and, when it finds one, regenerates the provider catalogue and opens a PR onto the `official` branch. It never merges anything itself.
206
+
207
+ | Branch | What's on it |
208
+ |---|---|
209
+ | `official` | Clean base. Changes only arrive through sync PRs. |
210
+ | `main` | `official` plus your customizations. Your working branch. |
211
+
212
+ To take an update: review the PR, merge into `official`, then merge `official` into `main`.
213
+
214
+ Worth knowing what the sync does and doesn't do. It regenerates `src/data/catalog.json` — the provider tables and the per-slot LLM model lists — because those change when the dashboard changes. It does **not** port command code, because the official source isn't available, so that's maintained by hand. The PR lists which commands were added or removed so you know what to look at.
215
+
216
+ Keep your customizations in as few files as you can. That diff is the one you have to resolve on every update.
217
+
218
+ ---
219
+
220
+ ## Development
221
+
222
+ ```bash
223
+ npm run build # tsc -> dist/, copy endpoints.json, chmod +x
224
+ npm test # build, then node --test
225
+ npm run test:only # tests without rebuilding
226
+ npm run dev # build and run
227
+ npm run catalog:sync # regenerate the catalogue: provider tables + per-slot LLM lists, from the server
228
+ npm run catalog:check # fail if catalog.json disagrees with the server snapshot (offline)
229
+ npm run catalog:check:live # same, against the live server (needs `cku dashboard login`)
230
+ ```
231
+
232
+ Single test file:
233
+
234
+ ```bash
235
+ node --test tests/agentUpdate.test.js
236
+ ```
237
+
238
+ 269 tests. No linter or formatter is configured.
239
+
240
+ ### Layout
241
+
242
+ `src/index.ts` is commander wiring and almost nothing else. Every command, flag and description is declared there. `src/commands/` holds one module per command group. `src/lib/` holds the shared layer, and that's where the rules worth knowing live:
243
+
244
+ - **`api.ts`** is the only place that talks to the backend. Adding an endpoint means adding a method here, not a raw `fetch` in a command.
245
+ - **`looseJson.ts`** has two parsers, chosen by where the text came from. Values from argv get a repair pass, because PowerShell strips quotes out of single-quoted arguments and `--set '{"name":"x"}'` arrives as `{name:x}`. Values from files or stdin are parsed strictly, since the shell never touched them and a real typo should be reported rather than guessed at.
246
+ - **`agentUpdate.ts`** merges updates into objects the backend replaces wholesale, so a partial update doesn't drop its siblings.
247
+ - **`ui.ts`** sets `process.exitCode` rather than calling `process.exit()`. On Windows, exiting while a fetch socket is still closing trips a libuv assertion that aborts with code 127 and a pile of C-level noise.
248
+
249
+ ### Regenerating docs
250
+
251
+ Both of these read from the code, so they can't drift:
252
+
253
+ ```bash
254
+ node scripts/gen-api-inventory.js # endpoint tables in docs/api.md
255
+ node scripts/gen-cli-reference.js ../callkaro-skills/skills/callkaro-cli/REFERENCE.md
256
+ ```
257
+
258
+ ---
259
+
260
+ ## Skills
261
+
262
+ The CLI installs a skill pack for Claude Code and other coding agents, so an agent can drive `cku` without being told how.
263
+
264
+ ```bash
265
+ cku skills install --claude # this fork's pack
266
+ cku skills install --claude --official # the upstream pack
267
+ cku skills update # refresh every install
268
+ ```
269
+
270
+ Targets include `--cursor --copilot --gemini --windsurf --roo --opencode --cline --codex --all`, plus `--project` to install into a repo rather than your user account. Skills ship from GitHub, so a new one reaches users without a CLI release.
271
+
272
+ ---
273
+
274
+ ## License
275
+
276
+ Apache-2.0, matching the upstream CLI.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "callkaro-cli-unofficial",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Unofficial fork of the CallKaro CLI — manage your voice AI agents from the terminal",
6
6
  "bin": {