@soku-ai/cli 0.1.0-alpha.10 → 0.1.0-alpha.12

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.
@@ -1,461 +1,131 @@
1
1
  ---
2
2
  name: soku
3
3
  description: >-
4
- Use when calling Soku ads/GA4/PostHog marketing-data capabilities or SEO
5
- Hosting domain connections from the shell
6
- running `soku auth login`, switching org/brand with `soku org use` /
7
- `soku brand use`, discovering capabilities, calling a data action, routing a
8
- third-party API call (Ahrefs/DataForSEO/Firecrawl/Gemini/…) through
9
- `soku egress`, managing `soku seo-hosting connections`, managing
10
- `soku automation`, handling 401/403 errors, or installing/updating the Soku
11
- CLI.
4
+ Use when calling Soku CLI capabilities from a shell: auth, workspace
5
+ selection, ads/GA4/PostHog data reads, typed ads writes, SEO Hosting,
6
+ automations, Context Hub files, temporary file publishing, brand skills,
7
+ third-party egress, review-gated writes, skill installation, or CLI updates.
12
8
  license: Proprietary
13
9
  metadata:
14
10
  author: nex-ad
15
- version: "0.2"
11
+ version: "0.4"
16
12
  ---
17
13
 
18
14
  # Soku CLI
19
15
 
20
- The `soku` CLI calls Soku's ads, GA4, PostHog, SEO Hosting, and Automation
21
- capabilities over HTTP. It is the preferred way for an agent to use Soku from
22
- any shell, with no MCP host required. Output is JSON on stdout; errors are a
23
- JSON envelope on stderr with a semantic exit code.
16
+ The `soku` CLI is the shell-native way for an AI agent to use Soku from Claude
17
+ Code, Codex, Cursor, or any terminal. It talks to Soku over `/api/cli/*`; no MCP
18
+ host is required. Treat this file as the router. Load the relevant reference
19
+ file before acting on a detailed workflow.
24
20
 
25
- ## Output & exit codes
21
+ ## Reference Router
26
22
 
27
- Every command prints JSON. When piped (non-TTY) success is
28
- `{"ok": true, "data": ...}`; errors are `{"ok": false, "error": {"type", "message", "hint"}}`.
23
+ Read only the reference files needed for the user's task:
29
24
 
30
- | Exit | Meaning | What to do |
31
- |------|---------|------------|
32
- | 0 | Success | Parse `data`. |
33
- | 1 | Usage / no workspace selected | Fix arguments, or run `soku org use` / `soku brand use`. |
34
- | 2 | Auth not signed in or token expired/revoked | Run `soku auth login` (or set `SOKU_TOKEN`). |
35
- | 4 | Not found (unknown capability) | Re-check via `soku --help` / `soku <ns> --help`. |
36
- | 5 | Runtime / network | Retry; if behind a proxy set `ALL_PROXY`. |
25
+ | Task | Read |
26
+ | --- | --- |
27
+ | First-time setup, expired token, workspace selection, org/brand ambiguity | `references/auth-workspace.md` |
28
+ | Ads, GA4, or PostHog reads; raw `soku call`; command discovery | `references/data-capabilities.md` and `references/capability-flow.md` |
29
+ | Meta/Google Ads writes, uploads, bulk create, review-gated approval | `references/ads-write.md` |
30
+ | SEO Hosting, automations, Context Hub files, temporary public file URLs | `references/seo-automation-files.md` |
31
+ | Third-party APIs through server-side credential injection; security rules | `references/egress-security.md` |
32
+ | Installing, updating, or removing Soku-managed local skills | `references/skills-updates.md` |
37
33
 
38
- ## Authentication
34
+ For an installed business skill such as `soku-ads-report`, read that skill too.
35
+ Business skills carry their own "Running this skill with the Soku CLI" section.
39
36
 
40
- `soku` authenticates once per machine with a long-lived, **org-agnostic** session
41
- token. The org and brand are chosen at runtime (see Workspace), not at login.
37
+ ## Default Flow
42
38
 
43
- ### Agent path (recommended): non-blocking split-flow
44
-
45
- Do NOT block a turn waiting for a human at a browser. Start login with
46
- `--no-wait`, surface the URL, end your turn, then resume:
47
-
48
- ```bash
49
- soku auth login --no-wait
50
- ```
51
-
52
- This returns immediately, e.g.:
53
-
54
- ```json
55
- {"ok":true,"data":{"user_code":"MWVP-ZTSZ","verification_uri":"https://studio.nex.ad/device","verification_uri_complete":"https://studio.nex.ad/device?user_code=MWVP-ZTSZ","device_code":"...","next":"soku auth login --device-code ..."}}
56
- ```
57
-
58
- Surface `verification_uri` and `user_code` to the user as your turn's final
59
- message (treat the URL as an opaque string — do not edit, re-encode, or
60
- re-assemble it). After the user says they approved, resume polling:
61
-
62
- ```bash
63
- soku auth login --device-code <device_code>
64
- ```
65
-
66
- ### Human path
67
-
68
- `soku auth login` opens the browser and polls until the user approves. Add
69
- `--qr` to render the verification URL as a QR code.
70
-
71
- ### CI / non-interactive
72
-
73
- Set `SOKU_TOKEN` to a pre-issued token; it overrides stored credentials and
74
- skips all interactive auth. This is the right path for CI and headless agents —
75
- it also avoids the OS keychain, which may be unavailable in containers.
76
-
77
- ### Session state
78
-
79
- - `soku auth status` — show the current identity.
80
- - `soku auth logout` — delete the stored token.
81
- - On exit code 2 with `expired` / `key_revoked`, the stored token is dropped
82
- automatically; re-run `soku auth login`.
83
-
84
- ## Workspace (org + brand)
85
-
86
- The session token carries no org/brand. Pick a workspace before calling data
87
- actions; the selection is saved to `~/.soku/config.json` and sent as
88
- `X-Soku-Org` / `X-Soku-Brand` headers.
89
-
90
- ```bash
91
- soku org list # organizations you belong to
92
- soku org use <slug|id> # set active org (id, slug, or name; clears a now-mismatched brand)
93
- soku brand list # brands in the active org
94
- soku brand use <slug|id> # id, slug, or name
95
- soku workspace status # show the active org/brand and whether it is ready
96
- soku workspace resolve <brand> # inspect accessible brand matches across orgs
97
- soku workspace use-brand <brand> # set org + brand together when the match is unique
98
- ```
99
-
100
- Env overrides for one-off invocations: `SOKU_ORG_ID`, `SOKU_BRAND_ID`.
101
-
102
- Do not infer Soku workspace state from the current shell directory. The working
103
- directory may contain unrelated README/AGENTS/context files from the user's local
104
- project. Start with `soku workspace status`; if the target brand is unknown, use
105
- `soku workspace resolve <brand>` and then `soku workspace use-brand <brand>`.
106
-
107
- ## Brand memory
108
-
109
- Memory is scoped to the active Soku workspace, not to the local shell directory.
110
- After `soku workspace status` is ready, these commands read memory for the
111
- current brand only:
112
-
113
- ```bash
114
- soku memory list
115
- soku memory search "policy 2026-05-31"
116
- soku memory get reference noiz-policy-event
117
- ```
118
-
119
- Use brand memory as background, hypotheses, and investigation leads. Do not
120
- treat a memory note as a verified data fact unless this turn also confirms it
121
- with data actions, change history, billing evidence, or another authoritative
122
- source. In reports, label memory-derived context separately from data-confirmed
123
- findings.
124
-
125
- ## Calling capabilities (discover with --help, then run)
126
-
127
- Each data capability is a typed sub-command under its namespace. Discover and
128
- inspect them with `--help` — never guess action names or flags.
129
-
130
- ```bash
131
- soku resources list # what's granted (e.g. data-infra, seo-hosting, automation)
132
- soku --help # namespaces: ads, ga4, posthog, …
133
- soku ads --help # actions in the ads namespace
134
- soku posthog --help # customer PostHog read actions
135
- soku ads query-single-dimension --help # flags, types, and usage for one action
136
-
137
- soku ads list-ad-accounts --platform google
138
- soku ads query-single-dimension --account-id 123 --dimension campaign \
139
- --date-start 2026-05-01 --date-end 2026-05-18
140
- ```
141
-
142
- `<command> --help` is authoritative for valid flags, required vs optional, types,
143
- and usage. Read it before invoking an unfamiliar action. Typed command names use
144
- kebab-case (`soku ads query-single-dimension`); raw `soku call` action names use
145
- registry snake_case (`soku call ads query_single_dimension`). Object/list flags
146
- take a JSON string, e.g. `--filters '{"campaign_id":["123"]}'`.
147
-
148
- ### Google Ads GAQL fallback
149
-
150
- Prefer cached ads analytics first:
151
-
152
- ```bash
153
- soku ads list-dimensions --platform google --account-id 123
154
- soku ads query-single-dimension --account-id 123 --dimension campaign ...
155
- soku ads query-multi-dimension --account-id 123 --dimensions '["campaign","device"]' ...
156
- ```
157
-
158
- Use GAQL only when cached query actions cannot expose the Google-native fields
159
- or segment combination you need:
160
-
161
- ```bash
162
- soku ads get-resource-metadata --platform google --account-id 123 --resource-name campaign
163
- soku ads gaql-search --platform google --account-id 123 \
164
- --dimensions '["date","campaign"]' --metrics '["cost","clicks"]' --limit 20
165
- ```
166
-
167
- Do not write full `SELECT ... FROM ...` GAQL SQL. `gaql-search` takes structured
168
- `dimensions`, `metrics`, `filters`, `date_range`, `order_by`, and `limit`; the
169
- server translates those into real GAQL. For the same action through the raw
170
- escape hatch, use snake_case: `soku call ads gaql_search --payload '{...}'`.
171
-
172
- ### PostHog customer analytics
173
-
174
- PostHog data uses the same backend MCP forwarding gateway as the sandbox agent.
175
- Start by listing the current brand's granted projects, then inspect the live
176
- tool menu, then run an allowlisted read tool. Do not ask the user for a project
177
- id before listing projects.
178
-
179
- ```bash
180
- soku posthog list-projects
181
- soku posthog list-tools --project-id 12345
182
- soku posthog query --project-id 12345 --tool execute-sql \
183
- --arguments '{"query":"SELECT count() FROM events WHERE event = '\''$pageview'\''"}'
184
- ```
185
-
186
- Use `read-data-schema` before writing HogQL if field names are unclear:
187
-
188
- ```bash
189
- soku posthog query --project-id 12345 --tool read-data-schema --arguments '{}'
190
- ```
191
-
192
- The CLI default read surface does not expose `posthog/request_change`; writes and
193
- unvetted PostHog MCP tools remain outside the generated command tree.
194
-
195
- ### Raw escape hatch
196
-
197
- `soku call <namespace> <action>` runs any action by its raw (snake_case) name
198
- with a JSON payload. Use it only when a typed sub-command isn't available — e.g.
199
- a newer action than this CLI version ships:
200
-
201
- ```bash
202
- soku call ads list_ad_accounts -p platform=google
203
- soku call ads query_single_dimension --payload '{"account_id":"123","dimension":"campaign"}'
204
- soku call posthog query --payload '{"project_id":"12345","tool":"execute-sql","arguments":{"query":"SELECT count() FROM events"}}'
205
- ```
206
-
207
- ## Automations
208
-
209
- Use `soku automation` to manage automations for the active brand. The session
210
- must include the `automation` resource. Request it at login:
211
-
212
- ```bash
213
- soku auth login --resource automation
214
- # or include it with data access:
215
- soku auth login --resource data-infra,automation
216
- ```
217
-
218
- The workspace must be ready before any automation call:
39
+ 1. Check auth/workspace state:
219
40
 
220
41
  ```bash
42
+ soku auth status
221
43
  soku workspace status
222
- soku org use <slug|id>
223
- soku brand use <slug|id>
224
44
  soku resources list
225
45
  ```
226
46
 
227
- Commands:
228
-
229
- ```bash
230
- soku automation list
231
- soku automation create --name "Fast check" --prompt "Check account health" --cron "* * * * *" --timezone UTC
232
- soku automation trigger <automation_id>
233
- soku automation runs <automation_id>
234
- ```
235
-
236
- `create` requires exactly one schedule option:
237
-
238
- - `--cron <expr>` with optional `--timezone <iana>` (default `UTC`).
239
- - `--interval-seconds <seconds>` for interval schedules; must be at least
240
- `3600` and divisible by `60`.
241
- - `--once-at <iso>` for a one-time UTC instant.
242
-
243
- `runs` shows run status and a browser link when a conversation exists. The CLI
244
- does not read conversation content; open the printed link in Studio to inspect
245
- the actual chat. For local development links, set `SOKU_WEB_BASE`, for example:
246
-
247
- ```bash
248
- SOKU_WEB_BASE=http://127.0.0.1:47627 soku automation runs <automation_id>
249
- ```
250
-
251
- ## SEO Hosting domain connections
47
+ 2. If auth is missing or expired, use the agent split-flow from
48
+ `references/auth-workspace.md`.
252
49
 
253
- Use `soku seo-hosting` to manage SEO Hosting for the active brand. The session
254
- must include the `seo-hosting` resource. Request it at login:
50
+ 3. If the workspace is not ready, resolve and select the remote Soku brand:
255
51
 
256
52
  ```bash
257
- soku auth login --resource seo-hosting
258
- # or include it with data access:
259
- soku auth login --resource data-infra,seo-hosting
260
- ```
261
-
262
- The workspace must be ready before any connection call:
263
-
264
- ```bash
265
- soku workspace status
266
- soku org use <slug|id>
267
- soku brand use <slug|id>
53
+ soku workspace resolve <brand>
54
+ soku workspace use-brand <brand>
268
55
  ```
269
56
 
270
- ### Posts
57
+ 4. Pick the reference for the task. Do not infer Soku org/brand from the current
58
+ local repo directory.
271
59
 
272
- Use typed `pages` commands for the same SEO Hosting content actions exposed to
273
- runtime agents through `seo_hosting/*`. SEO Hosting pages are **complete HTML
274
- documents** (not Markdown) served as owned-media web pages on the brand's
275
- connected domain; they are identified by `section` + `slug` (there are no post
276
- ids). They are not social posts.
277
-
278
- Always check status first:
60
+ 5. Inspect command help before unfamiliar calls:
279
61
 
280
62
  ```bash
281
- soku seo-hosting status
63
+ soku --help
64
+ soku <namespace> --help
65
+ soku <namespace> <action> --help
282
66
  ```
283
67
 
284
- `status` shows each connected domain, whether it is `live`, and which sections it
285
- serves. If no domain is live, do not publish yet; connect or fix a domain first.
286
- When hosting is live:
287
-
288
- ```bash
289
- soku seo-hosting pages list --section blog --status draft
290
- soku seo-hosting pages put --section blog --slug how-to --title "How to ..." --html-file page.html
291
- soku seo-hosting pages publish --section blog --slug how-to
292
- soku seo-hosting pages unpublish --section blog --slug how-to
293
- soku seo-hosting pages delete --section blog --slug how-to --confirm
294
- soku seo-hosting pages upload-asset --path blog/how-to/hero.png --file ./hero.png
295
- ```
296
-
297
- `put` creates or overwrites a page as a **draft** and requires `--section`,
298
- `--slug`, `--title`, and exactly one HTML source: `--html`, `--html-file`, or
299
- `--html-stdin`. Optional metadata flags are `--description`, `--template`, and
300
- `--seo '<json object>'`. Reference images / CSS / fonts by the absolute URL
301
- returned from `pages upload-asset` (no custom JavaScript — HTML + CSS only).
302
-
303
- `publish` runs the validation gate (no `<script>` / inline JS) and
304
- makes the page live once a domain serves its section; it also prints advisory
305
- `Link warnings` for dead internal links (these do not block publishing — fix the
306
- links and re-publish). `unpublish` reverts it to draft. Writes run immediately
307
- (no-review), so confirm intent with the user before publishing or deleting.
308
-
309
- ### Domain connections
68
+ 6. Run the command and parse JSON output. In non-TTY contexts, success is
69
+ `{"ok":true,"data":...}` and errors are `{"ok":false,"error":...}`.
310
70
 
311
- Connection commands:
71
+ ## Non-Negotiable Rules
312
72
 
313
- ```bash
314
- soku seo-hosting connections list
315
- soku seo-hosting connections connect-cname --hostname blog.example.com
316
- soku seo-hosting connections verify <connection_id>
317
- soku seo-hosting connections disconnect <connection_id> --confirm
318
- ```
73
+ - Never print or persist the Soku access token.
74
+ - Never ask the user to paste third-party provider keys for covered providers.
75
+ - Do not fail just because an upstream provider key env var is unset. Use
76
+ `soku egress -- curl ...` for covered third-party APIs.
77
+ - Do not approve review-gated writes on the user's behalf. Surface the
78
+ `review_id` and let the user run `soku review approve <id>`.
79
+ - Pass user values as separate argv elements. Do not build a shell command by
80
+ string-concatenating untrusted values.
81
+ - Do not scan local repo files, `AGENTS.md`, or `context/` folders for Soku
82
+ workspace state unless the user explicitly asks about local files.
83
+ - When a command prints a hint, follow it before retrying. Do not loop blindly.
319
84
 
320
- Cloudflare Worker reverse proxy setup runs a probe before provisioning. Use it
321
- when the customer's root or existing hostname is already on Cloudflare and SEO
322
- Hosting needs to mount sections such as `/blog`, `/use-cases`, or
323
- `/alternatives`:
85
+ ## Exit Codes
324
86
 
325
- ```bash
326
- soku seo-hosting connections probe --hostname example.com --sections blog,use-cases
327
- soku seo-hosting connections connect-worker --hostname example.com \
328
- --sections blog,use-cases --cf-token-env CLOUDFLARE_API_TOKEN
329
- printf %s "$CLOUDFLARE_API_TOKEN" | soku seo-hosting connections connect-worker \
330
- --hostname example.com --sections blog --cf-token-stdin
331
- ```
332
-
333
- Allowed sections are `blog`, `use-cases`, and `alternatives`; omitted sections
334
- default to `blog`. If the probe reports existing mounted content, add
335
- `--accept-conflicts` only after the user confirms SEO Hosting may shadow those
336
- paths. If the hostname serves its own Next.js assets, add
337
- `--accept-next-assets-warning` only after confirming `/_next/static/*` may route
338
- through the Worker.
339
-
340
- Do not pass Cloudflare API tokens as literal argv values or print them. Use
341
- `--cf-token-env <ENV_NAME>` or `--cf-token-stdin` exactly once. Vercel OAuth
342
- domain connections are not exposed in the CLI yet; use the Studio web settings
343
- for Vercel-backed domains.
87
+ | Exit | Meaning | What to do |
88
+ | --- | --- | --- |
89
+ | 0 | Success | Parse `data`. |
90
+ | 1 | Usage or no workspace | Fix args, or run `soku workspace status` / `use-brand`. |
91
+ | 2 | Auth missing, expired, or revoked | Run `soku auth login --no-wait`. |
92
+ | 4 | Not found or unknown capability | Re-check `soku --help` / `soku <ns> --help`. |
93
+ | 5 | Runtime or network failure | Retry if transient; if behind a proxy set `ALL_PROXY`. |
344
94
 
345
- ## Write actions (human approval required)
95
+ ## Capability Discovery
346
96
 
347
- Some actions mutate state (e.g. conversion-group writes) and are **review-gated**.
348
- They are NOT in the typed command tree — call them with `soku call` and a
349
- required `--summary` describing the change. The call does NOT execute; it returns
350
- a pending review that a human approves.
97
+ Typed command names are kebab-case:
351
98
 
352
99
  ```bash
353
- soku call ads create_conversion_group --summary "create group: qualified leads" -p name="Qualified leads"
354
- # → {"ok":true,"data":{"status":"pending_review","pending_review_id":"<id>","summary":"..."}}
355
-
356
- soku review list # see pending reviews
357
- soku review show <id> # full payload + (after approval) result
358
- soku review approve <id> # a human approves → the action executes now
359
- soku review deny <id> --feedback "wrong account"
100
+ soku ads query-single-dimension --help
360
101
  ```
361
102
 
362
- - The write resource must be granted to the session (request it at login:
363
- `soku auth login --resource data-infra,conversion-groups-write`). Without it,
364
- `soku call` returns 403.
365
- - Approval is **single-use**: one review = one execution. Approving an already
366
- decided review is a no-op that returns the existing result.
367
- - Do NOT loop `soku review approve` expecting retries; a failed approval is
368
- terminal — create a fresh `soku call` to try again.
369
- - As an agent: surface the `pending_review_id` + summary to the user and let
370
- THEM run `soku review approve`. Do not approve on the user's behalf.
371
-
372
- ## Third-party APIs (egress)
373
-
374
- Skills that call third-party providers (Ahrefs, DataForSEO, Firecrawl, Gemini, …)
375
- must route the call through `soku egress`. The credential is injected
376
- server-side, so **no third-party API key lives on this machine**.
377
-
378
- Prefix the skill's `curl` with `soku egress --`:
103
+ Raw `soku call` action names use registry snake_case:
379
104
 
380
105
  ```bash
381
- soku egress -- curl -H "Authorization: Bearer $AHREFS_API_KEY" "https://api.ahrefs.com/v3/..."
106
+ soku call ads query_single_dimension --payload '{"account_id":"123","dimension":"campaign"}'
382
107
  ```
383
108
 
384
- `$AHREFS_API_KEY` is not set here, and that is expected — `soku egress` strips the
385
- empty auth header, Soku injects the real key, and the upstream response is
386
- returned verbatim on stdout.
109
+ Prefer typed commands when they exist. Use `soku call` only as a forward-compatible
110
+ escape hatch for a newer action or an action not yet exposed ergonomically.
387
111
 
388
- - Do NOT pre-flight check whether an API key env var is set, and do NOT abort a
389
- skill because a key looks missing (no `[ -z "$X_API_KEY" ]` guards, no
390
- `if not os.environ.get(...)` early-exits). Assume the credential is available;
391
- just make the call through `soku egress`.
392
- - A skill's own `SKILL.md` shows the raw `curl -H "Authorization: Bearer $X"`
393
- form for reference. Ignore whether the key is set — prefix the whole command
394
- with `soku egress --`.
395
- - `soku egress providers` lists the covered hosts. For a host NOT listed, the
396
- proxy does not inject a credential — follow that skill's own auth instead.
112
+ ## Installed Skill Names
397
113
 
398
- ## Installing / updating the skill
114
+ The bundled CLI meta skill is named `soku`. Business skills are installed with a
115
+ Soku prefix, for example `soku-ads-report` and `soku-google-ads`.
399
116
 
400
117
  ```bash
401
- soku update status # show CLI + installed skill update status
402
- soku update skills # refresh this meta-skill and installed business skills
403
- soku update cli # install the latest CLI from npm
404
- soku skill install # this meta-skill into .claude / .codex / .cursor (project)
405
- soku skill install --global # into ~/.claude, ~/.codex, ~/.cursor
406
- soku skill install --agent claude --global
118
+ soku skill list
119
+ soku skill install ads-report google-ads
120
+ soku skill status
407
121
  ```
408
122
 
409
- Normal `soku` commands schedule a background refresh for installed Soku-managed
410
- skills at most once every 24 hours. Set `SOKU_NO_SKILL_AUTO_UPDATE=1` to disable
411
- skill auto updates, or `SOKU_UPDATE_INTERVAL_HOURS=<n>` to change the interval.
123
+ When asking an AI client to invoke a business skill, write
124
+ `use @soku-ads-report skill`, not `@ads-report`.
412
125
 
413
- The CLI binary itself is advisory by default. To opt into automatic npm CLI
414
- updates, set `SOKU_AUTO_UPDATE_CLI=1`; otherwise run `soku update cli` when
415
- `soku update status` shows a newer version.
416
-
417
- A global `npm i -g @soku-ai/cli` refreshes this already-installed global
418
- meta-skill after npm finishes installing. It does not install new skills and it
419
- does not update project-local skills.
420
-
421
- ## Installing business skills (account audits, Google Ads, reports, …)
422
-
423
- Beyond this meta-skill, Soku publishes a catalog of domain skills (e.g.
424
- `account-audit`, `google-ads`, `ads-report`) that already know which `soku call`
425
- actions and `soku egress` providers to use — install one and your agent gains
426
- that playbook.
427
-
428
- ```bash
429
- soku skill list # browse the catalog
430
- soku skill install account-audit # install one (into soku-account-audit/)
431
- soku skill install ads-report google-ads
432
- soku skill install --all # install everything
433
- soku skill status # what's installed locally
434
- soku skill list-installed # same as status
435
- soku skill remove account-audit
436
- ```
126
+ ## Updating This Skill
437
127
 
438
- Catalog slugs are used for install/remove commands (`ads-report`). Installed AI
439
- client skill names are Soku-prefixed (`soku-ads-report`). When asking an agent to
440
- run an installed business skill, write `use @soku-ads-report skill`, not
441
- `@ads-report`.
442
-
443
- Business skill updates are detected from `.soku-skills.json`: for each installed
444
- catalog slug, Soku compares local `version`, `sha256`, and `source` against the
445
- latest catalog `index.json`. A changed version, changed hash, or old source is
446
- treated as an update; missing catalog entries are reported but not deleted.
447
-
448
- Each installed skill carries a "Running this skill with the Soku CLI" section
449
- (its data actions mapped to `soku call`, its third-party APIs to `soku egress`),
450
- so it runs through this same CLI — no in-sandbox tools, no local API keys.
451
-
452
- ## Security rules
453
-
454
- - Never print the access token (it grants account access). Prefer `SOKU_TOKEN`
455
- for CI rather than echoing it.
456
- - Reads (`data-infra`) run directly. Writes are review-gated: `soku call`
457
- creates a pending review and only `soku review approve` (a human action)
458
- executes it. Don't approve on the user's behalf, and don't assume a
459
- `--yes`-style bypass exists — there isn't one.
460
- - Pass user-provided values as separate argv elements (the `-p key=value` form),
461
- never by string-concatenating them into a shell command.
128
+ `soku update skills` refreshes the bundled `soku` meta skill and every installed
129
+ Soku-managed business skill recorded in `.soku-skills.json`. It also refreshes
130
+ legacy meta-only installs that have `soku/SKILL.md` but no manifest, so older
131
+ installations receive this `references/` directory.