@soku-ai/cli 0.1.0-alpha.17 → 0.1.0-alpha.19

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 (64) hide show
  1. package/README.md +33 -22
  2. package/dist/commands/auth.d.ts +1 -3
  3. package/dist/commands/auth.d.ts.map +1 -1
  4. package/dist/commands/auth.js +18 -3
  5. package/dist/commands/auth.js.map +1 -1
  6. package/dist/commands/automation.d.ts +46 -0
  7. package/dist/commands/automation.d.ts.map +1 -1
  8. package/dist/commands/automation.js +150 -0
  9. package/dist/commands/automation.js.map +1 -1
  10. package/dist/commands/brand-skill.d.ts +23 -0
  11. package/dist/commands/brand-skill.d.ts.map +1 -1
  12. package/dist/commands/brand-skill.js +82 -0
  13. package/dist/commands/brand-skill.js.map +1 -1
  14. package/dist/commands/changelog.d.ts +79 -0
  15. package/dist/commands/changelog.d.ts.map +1 -0
  16. package/dist/commands/changelog.js +123 -0
  17. package/dist/commands/changelog.js.map +1 -0
  18. package/dist/commands/context.d.ts +54 -0
  19. package/dist/commands/context.d.ts.map +1 -1
  20. package/dist/commands/context.js +362 -43
  21. package/dist/commands/context.js.map +1 -1
  22. package/dist/commands/egress.d.ts +49 -1
  23. package/dist/commands/egress.d.ts.map +1 -1
  24. package/dist/commands/egress.js +287 -33
  25. package/dist/commands/egress.js.map +1 -1
  26. package/dist/commands/generated.d.ts +8 -3
  27. package/dist/commands/generated.d.ts.map +1 -1
  28. package/dist/commands/generated.js +10 -3
  29. package/dist/commands/generated.js.map +1 -1
  30. package/dist/commands/live-surface.d.ts +15 -0
  31. package/dist/commands/live-surface.d.ts.map +1 -0
  32. package/dist/commands/live-surface.js +96 -0
  33. package/dist/commands/live-surface.js.map +1 -0
  34. package/dist/commands/workspace.d.ts +13 -0
  35. package/dist/commands/workspace.d.ts.map +1 -1
  36. package/dist/commands/workspace.js +34 -7
  37. package/dist/commands/workspace.js.map +1 -1
  38. package/dist/generated/capabilities.json +7710 -2318
  39. package/dist/generated/changelog.json +2232 -0
  40. package/dist/http/client.d.ts +17 -0
  41. package/dist/http/client.d.ts.map +1 -1
  42. package/dist/http/client.js +34 -5
  43. package/dist/http/client.js.map +1 -1
  44. package/dist/index.js +4 -0
  45. package/dist/index.js.map +1 -1
  46. package/dist/output/envelope.d.ts +2 -1
  47. package/dist/output/envelope.d.ts.map +1 -1
  48. package/dist/output/envelope.js +2 -2
  49. package/dist/output/envelope.js.map +1 -1
  50. package/dist/upload-journal.d.ts +46 -0
  51. package/dist/upload-journal.d.ts.map +1 -0
  52. package/dist/upload-journal.js +102 -0
  53. package/dist/upload-journal.js.map +1 -0
  54. package/dist/version.d.ts +1 -1
  55. package/dist/version.js +1 -1
  56. package/package.json +6 -5
  57. package/skills/soku/SKILL.md +74 -12
  58. package/skills/soku/agents/openai.yaml +4 -0
  59. package/skills/soku/references/ads-write.md +12 -6
  60. package/skills/soku/references/auth-workspace.md +27 -12
  61. package/skills/soku/references/data-capabilities.md +22 -1
  62. package/skills/soku/references/egress-security.md +63 -0
  63. package/skills/soku/references/seo-automation-files.md +67 -3
  64. package/skills/soku/references/skills-updates.md +54 -0
@@ -114,12 +114,16 @@ soku ads meta creative create \
114
114
  --summary "Create Meta dynamic creative"
115
115
  ```
116
116
 
117
- Status controls exist at delivery levels:
117
+ Status controls exist at delivery levels. A write that names an existing
118
+ campaign / ad set / ad must first read that object back (`soku ads meta
119
+ campaign get` / `adset get` / `ad get`, or the matching list command) and quote
120
+ its current name **and** literal id in `--summary`; the server rejects a summary
121
+ that omits a literal target id with `invalid_ads_payload`:
118
122
 
119
123
  ```bash
120
- soku ads meta campaign activate --campaign-id <campaign_id> --account-id <meta_account_id> --summary "Activate campaign"
121
- soku ads meta adset pause --adset-id <adset_id> --account-id <meta_account_id> --summary "Pause ad set"
122
- soku ads meta ad pause --ad-id <ad_id> --account-id <meta_account_id> --summary "Pause ad"
124
+ soku ads meta campaign activate --campaign-id <campaign_id> --account-id <meta_account_id> --summary "Activate campaign 'Launch Test' (campaign_id <campaign_id>)"
125
+ soku ads meta adset pause --adset-id <adset_id> --account-id <meta_account_id> --summary "Pause ad set 'US Prospecting' (adset_id <adset_id>)"
126
+ soku ads meta ad pause --ad-id <ad_id> --account-id <meta_account_id> --summary "Pause ad 'Hero image ad' (ad_id <ad_id>)"
123
127
  ```
124
128
 
125
129
  ## Bulk Meta Create
@@ -223,8 +227,10 @@ soku review show <review_id>
223
227
  ```
224
228
 
225
229
  As an agent, always show the review id and summary to the user first — a human
226
- must authorize the write. If your harness prompts for explicit human
227
- confirmation before each shell command (e.g. Claude Code's permission prompt),
230
+ must authorize the write. Do not tell the user a change is applied or live until
231
+ `soku review show <review_id>` reports the execution result and the read-back
232
+ matches; approval alone is not execution. If your harness prompts for explicit human
233
+ confirmation before each shell command (a per-command permission prompt),
228
234
  you MAY then run `soku review approve <id>` yourself: that prompt is the human
229
235
  gate, so never allowlist or auto-approve it. If your harness auto-runs commands
230
236
  without confirmation, do not self-approve — let the user run it. Approval is
@@ -30,9 +30,8 @@ with the exact `next` command returned by the CLI, prefixed the same way:
30
30
  SOKU_NO_KEYCHAIN=1 soku auth login --device-code <device_code>
31
31
  ```
32
32
 
33
- If the browser approval page shows no workspace options (for example, a
34
- platform admin with no org memberships), the user can approve directly without
35
- selecting a workspace. Select a brand after login with
33
+ If the browser approval page shows no workspace options, the user can approve
34
+ directly without selecting a workspace. Select a brand after login with
36
35
  `soku workspace use-brand`.
37
36
 
38
37
  For CI or headless contexts, use `SOKU_TOKEN`; do not echo it.
@@ -47,6 +46,22 @@ still return a HITL review the user approves; that is the only gate left
47
46
  (besides the active org/brand). The `--resource` flag and the `soku resources`
48
47
  command have been removed from the CLI.
49
48
 
49
+ ## What The Login Grants
50
+
51
+ The token is account-level, not brand-level. It reaches **every brand the signed-in
52
+ account can already access**, and the brand chosen on the approval page only sets
53
+ where the CLI starts.
54
+
55
+ Users regularly read that selection as the scope of the grant and are then
56
+ surprised to see other brands. If a user asks why they can see a brand they did
57
+ not authorize, say this plainly: the approval covered their whole account, and
58
+ the picker chose a starting point. `soku brand list` shows the full set.
59
+
60
+ The practical consequence is the opposite of a security concern and needs
61
+ stating too: **nothing stops a command from writing into the wrong brand.** The
62
+ active brand is sticky, does not follow the web app, and survives across
63
+ sessions. Confirm it in the same turn as any write.
64
+
50
65
  ## Workspace
51
66
 
52
67
  Never infer Soku workspace state from the local shell directory.
@@ -61,6 +76,15 @@ If `resolve` is ambiguous, show the candidates and ask the user which exact
61
76
  brand/org to use. For one-off scripts, `SOKU_ORG_ID` and `SOKU_BRAND_ID` can
62
77
  override saved config.
63
78
 
79
+ `workspace status` resolves the same way requests do, so it reports the brand a
80
+ write would actually reach whichever source set it. Its `source` field says
81
+ which one won:
82
+
83
+ - `config` — the saved active brand. `soku workspace use-brand` changes it.
84
+ - `env` — `SOKU_ORG_ID` / `SOKU_BRAND_ID` are set and override the saved config.
85
+ In this case `use-brand` writes the config file but does **not** change where
86
+ writes land; change the environment variables instead.
87
+
64
88
  Legacy commands still work, but prefer `workspace` for agent flows:
65
89
 
66
90
  ```bash
@@ -70,15 +94,6 @@ soku brand list
70
94
  soku brand use <slug-or-id>
71
95
  ```
72
96
 
73
- ## Platform Admins
74
-
75
- `soku auth status` reports `is_platform_admin`, which is `true` only for an
76
- active platform admin. An active platform admin can work across every active
77
- org without holding an org membership: `soku workspace use-brand`,
78
- `soku workspace resolve`, `soku org list`, and `soku brand list` cover the
79
- full set of active orgs and brands. Everyone else stays scoped to the orgs
80
- where they have a membership.
81
-
82
97
  ## Session State
83
98
 
84
99
  ```bash
@@ -31,7 +31,9 @@ soku ads query-multi-dimension \
31
31
  Use `query-single-dimension` for CPA, ROAS, conversion group fan-out, or one
32
32
  dimension. Use `query-multi-dimension` for raw multi-dimensional breakdowns.
33
33
 
34
- `--platform` accepts `google`, `meta`, `tiktok`, or `chatgpt_ads`:
34
+ Platform support varies by action and rollout. Read the command help and
35
+ connected accounts; do not assume every reporting action supports every ads
36
+ platform. For example:
35
37
 
36
38
  ```bash
37
39
  soku ads list-ad-accounts --platform chatgpt_ads
@@ -138,3 +140,22 @@ soku call posthog query --payload '{"project_id":"12345","tool":"execute-sql","a
138
140
  ```
139
141
 
140
142
  Review-gated writes through `soku call` require `--summary`.
143
+
144
+ ## Recently Added Integrations And Parameters
145
+
146
+ Discover the current command tree with `soku --help`. Recent data namespaces
147
+ include `admob`, `applovin_max`, `topon`, `cloudx`, `sensortower`, `thinkingdata`,
148
+ and Adjust API Token reporting (`adjust list-apps` / `adjust get-report`).
149
+ They still require the corresponding connected account, brand access, and
150
+ server rollout; command availability alone does not grant access. Soku-supplied
151
+ providers such as AIsa and BYOK egress providers are discovered with
152
+ `soku egress providers`, not a guessed data namespace.
153
+
154
+ Boolean flags support both explicit values: `--use-cache` sends true and
155
+ `--no-use-cache` sends false; omitting both leaves the server default intact.
156
+ For example, `soku thinkingdata query-metric --help` and
157
+ `soku applovin_max run-report --help` describe the relevant input flags.
158
+
159
+ Google `soku ads update-campaign` accepts `--tracking-url-template` and
160
+ `--final-url-suffix`. Omission preserves the current value; an explicitly empty
161
+ string clears it. The existing ads review and readback requirements still apply.
@@ -14,6 +14,50 @@ soku egress -- curl -H "Authorization: Bearer $AHREFS_API_KEY" "https://api.ahre
14
14
  `$AHREFS_API_KEY` may be unset locally. That is expected. The CLI strips empty
15
15
  placeholder auth and the Soku API injects the real credential.
16
16
 
17
+ ### Which curl flags are understood
18
+
19
+ `soku egress` forwards four things to the proxy — method, URL, headers, body —
20
+ so it parses the curl flags that decide those, and nothing else.
21
+
22
+ **Honored** (they change the request):
23
+
24
+ | Flag | Effect |
25
+ | --- | --- |
26
+ | `-X` / `--request` | HTTP method |
27
+ | `-I` / `--head` | method `HEAD` |
28
+ | `-H` / `--header` | request header |
29
+ | `-d` / `--data` / `--data-raw` / `--data-ascii` / `--data-binary` | body, sent verbatim |
30
+ | `--data-urlencode` | body, URL-encoded exactly as curl does |
31
+ | `-G` / `--get` | fold the accumulated data into the query string |
32
+ | `--url` | request URL |
33
+ | `-o` / `--output` | write the response body to this file |
34
+
35
+ Repeated data flags **accumulate**, joined with `&`, the way curl joins them.
36
+ `@file` reads a file and `@-` reads stdin, for both `-d` and `--data-urlencode`.
37
+
38
+ **Accepted and ignored**: `-s`, `-S`, `-i`, `-v`, `-k`, `-f`/`--fail`, `-L`,
39
+ `--compressed`, `-w`, `-m`/`--max-time`, `--connect-timeout`, `--retry`,
40
+ `--retry-delay`, `--retry-max-time`, `--retry-all-errors`, `--resolve`,
41
+ `--max-redirs`, `--limit-rate`, `-D`, and their long forms. These shape curl's
42
+ local behaviour — output noise, timeouts, retry policy — and cannot change the
43
+ request that is forwarded. Bundled short flags (`-sSL`) are understood.
44
+
45
+ **Anything else is an error.** A flag this list does not name stops the command
46
+ with a usage error naming the flag; the request is not sent. That is deliberate:
47
+ the previous behaviour skipped an unrecognised flag *and did not consume its
48
+ value*, so the value fell through and was dropped too. The request went out with
49
+ parameters missing and the third party answered about whatever it noticed first
50
+ — an error that pointed nowhere near the real cause. If a skill needs a flag
51
+ that is not listed, rewrite the request without it (inline the query in the URL,
52
+ move a `--form` upload to a body) rather than expecting it to be ignored.
53
+
54
+ ### Encoding matches curl exactly
55
+
56
+ `--data-urlencode` is form encoding: a space becomes `+` (not `%20`) and
57
+ percent-escapes use lowercase hex (`%2c`, not `%2C`). The CLI reproduces this
58
+ byte for byte, so prefixing an existing curl does not change what the third
59
+ party receives.
60
+
17
61
  List covered hosts:
18
62
 
19
63
  ```bash
@@ -52,3 +96,22 @@ success envelope. Soku-level failures use the normal CLI error envelope.
52
96
  - Pass user-provided values as separate argv elements.
53
97
  - Treat `verification_uri`, signed URLs, review ids, and provider URLs as
54
98
  opaque strings.
99
+
100
+ ## Discover And Call Endpoint Cards
101
+
102
+ ```bash
103
+ soku egress capabilities --provider adyntel --query linkedin
104
+ soku egress call adyntel linkedin_ads --args '{"company_domain":"example.com"}' --dry-run
105
+ soku egress call adyntel linkedin_ads --args @arguments.json --output result.json
106
+ ```
107
+
108
+ `capabilities` returns parameter contracts and quotes from the live server
109
+ registry. `call --dry-run` validates and binds arguments on the server, then
110
+ returns the request and `quote_usd_micros` without contacting the vendor or
111
+ incurring vendor charges. Review the quote and intended call with the user
112
+ before a paid execution. Removing `--dry-run` executes through the existing
113
+ metered egress proxy and streams the upstream response verbatim; `--output`
114
+ saves it to a file. Authentication stays server-side. A binding error stops
115
+ before execution. Raw `soku egress -- curl ...` remains available for endpoints
116
+ without published cards. Do not infer that an unlisted vendor is unsupported:
117
+ BYOK providers may be host-discoverable without priced endpoint cards.
@@ -1,11 +1,17 @@
1
1
  # SEO Hosting, Automations, And Files
2
2
 
3
- These commands operate on the active Soku workspace. Confirm workspace first:
3
+ These commands all write to the **active** Soku workspace. Confirm the brand in
4
+ the same turn as the write, and read the result back afterwards:
4
5
 
5
6
  ```bash
6
7
  soku workspace status
7
8
  ```
8
9
 
10
+ The CLI keeps whatever brand was selected last and does not follow the brand the
11
+ user has open in the web app. A write into the wrong brand succeeds and looks
12
+ exactly like a correct one, so the confirmation has to be immediate, not
13
+ something done earlier in the session.
14
+
9
15
  ## SEO Hosting Pages
10
16
 
11
17
  SEO Hosting pages are complete HTML documents, not Markdown. They are addressed
@@ -57,7 +63,13 @@ risk.
57
63
 
58
64
  ```bash
59
65
  soku automation list
66
+ soku automation get <automation_id>
60
67
  soku automation create --name "Fast check" --prompt "Check account health" --cron "* * * * *" --timezone UTC
68
+ soku automation update <automation_id> --prompt "Check account health and budget"
69
+ soku automation pause <automation_id>
70
+ soku automation resume <automation_id>
71
+ soku automation delete <automation_id> --confirm
72
+ soku automation deps <automation_id>
61
73
  soku automation trigger <automation_id>
62
74
  soku automation runs <automation_id>
63
75
  ```
@@ -68,8 +80,31 @@ soku automation runs <automation_id>
68
80
  - `--interval-seconds <seconds>`; at least 3600 and divisible by 60.
69
81
  - `--once-at <iso>` for a one-time UTC instant.
70
82
 
71
- `runs` prints a Studio link when a conversation exists. The CLI does not read
72
- conversation content.
83
+ `update` sends only the flags you pass; everything else keeps its stored value.
84
+ It takes the same schedule flags as `create` (at most one), plus `--name`,
85
+ `--prompt`, and `--status`. `--timezone` is only accepted together with
86
+ `--cron`, because the server rebuilds the schedule from a whole contract and a
87
+ lone timezone would be silently dropped.
88
+
89
+ **Do not rebuild an automation to change it.** `update` edits the existing row
90
+ and keeps its id, run history, and schedule version. Rebuilding loses all three,
91
+ and leaves the original still scheduled unless you also pause or delete it.
92
+
93
+ `pause` stops an automation and clears its next run; `resume` puts it back to
94
+ active and recomputes the next run. Both are `update --status` underneath.
95
+
96
+ `deps` reports whether the automation's saved dependencies still resolve:
97
+
98
+ - **attachments** are looked up for real, so a deleted or cross-brand file shows
99
+ as `missing` before the automation next fires.
100
+ - **context references** are classified, not verified. A reference marked
101
+ `brand-pinned` (ad account, campaign, ad set, ad, report) names a row inside
102
+ the current brand: copying the automation into another brand carries the id
103
+ across but not the thing it points at, so those must be re-picked there. A
104
+ `portable` reference (skill, integration) does not have that problem.
105
+
106
+ Run `deps` before migrating an automation between brands, and after any change
107
+ that may have deleted a referenced file.
73
108
 
74
109
  ## Context Hub
75
110
 
@@ -83,6 +118,35 @@ soku context rm research/brief.pdf
83
118
 
84
119
  Paths are context-relative. Do not include a `context/` prefix.
85
120
 
121
+ ### Bulk uploads
122
+
123
+ `upload` takes directories (recursing and preserving structure under `--dir`)
124
+ and runs files concurrently. For a large migration:
125
+
126
+ ```bash
127
+ soku context upload ./assets --dir assets --concurrency 8 --verify
128
+ soku context uploads # runs with unfinished files
129
+ soku context upload --resume <run_id> # finish one of them
130
+ soku context verify ./assets --dir assets # reconcile without uploading
131
+ ```
132
+
133
+ - Each file is retried on transient failures (no response, HTTP 408/429/5xx)
134
+ before the run gives up on it; `--retries <n>` changes the attempt count. A
135
+ permanent failure such as 403 is not retried.
136
+ - Every run records a resumable run id. If any file is still unfinished when the
137
+ run ends, the output carries `resume_command` — run it to re-upload only the
138
+ files that never landed. Finished runs leave no record behind.
139
+ - `--resume` refuses to run if the active brand is not the one the recorded run
140
+ targeted. Switch back with `soku workspace use-brand` rather than forcing it:
141
+ the files would otherwise land, in the wrong brand, and look successful.
142
+ - `--verify` (and the standalone `soku context verify`) reconciles against the
143
+ server by size **and** checksum. A file the server reports no checksum for is
144
+ reported as `unverified`, not `ok` — a missing hash is not proof of a good
145
+ upload. Both `upload --verify` and `verify` exit non-zero if anything is
146
+ missing, mismatched, or unverified, so a script can gate on them.
147
+
148
+ Do not hand-count files to check a migration. `verify` is the reconciliation.
149
+
86
150
  ## Temporary Public File URLs
87
151
 
88
152
  ```bash
@@ -87,3 +87,57 @@ soku skill remove soku
87
87
 
88
88
  Removing the last Soku-managed skill removes the local `.soku-skills.json`
89
89
  manifest.
90
+
91
+ ## After Upgrading The CLI
92
+
93
+ An upgrade can add, change, or retire capabilities, which invalidates whatever
94
+ this session believed the CLI could do. Ask the CLI itself rather than guessing:
95
+
96
+ ```bash
97
+ soku changelog --since <the version you upgraded from> --summary
98
+ soku changelog --since <the version you upgraded from>
99
+ ```
100
+
101
+ `--summary` gives counts per version; without it, each entry lists the actions
102
+ that were added or removed and, for a surviving action, which fields changed.
103
+ Output is the usual JSON envelope in a non-TTY context, so it can be parsed.
104
+
105
+ The changelog is bundled with the installed CLI, so it always describes the
106
+ binary that is running and needs no network call. It cannot speak for versions
107
+ older than its `historyStartsAt`; when `--since` reaches past that, the response
108
+ sets `truncated: true` and says so rather than implying nothing changed.
109
+
110
+ This skill records the CLI release it was written against in the line right
111
+ under its title. If the installed CLI is newer, run the command
112
+ above before relying on details in these reference files.
113
+
114
+ ## Community Skills In The Active Brand
115
+
116
+ Local `soku skill install` installs a business skill into the calling agent.
117
+ `brand skill` manages skills in the active Soku brand instead. Official catalog
118
+ installs and community installs have separate commands:
119
+
120
+ ```bash
121
+ soku workspace status
122
+ soku brand skill community list --query "audit" --sort installs --limit 30 --offset 0
123
+ soku brand skill community install growth-audit
124
+ soku brand skill community install growth-audit --expected-price-credits 300
125
+ soku brand skill publish my-skill --categories analytics,ads --price-credits 300
126
+ ```
127
+
128
+ Browse first: the list includes price, entitlement, installed version, and
129
+ available updates. Only pass `--expected-price-credits` after the user agrees
130
+ to that skill's exact one-time price for the active organization. Without the
131
+ flag, a paid skill needing purchase returns `purchase_required`; already owned,
132
+ free, and publisher-entitled skills can install without a new purchase.
133
+ A changed price returns `conflict` with `error.details.code = price_changed` and
134
+ `error.details.price_credits`. Obtain agreement to the new price before retrying;
135
+ never automatically restate the server's price. Reinstall upgrades an existing
136
+ community copy. Read it first if the brand has local edits.
137
+
138
+ `publish` publishes an uploaded private skill. Omit `--price-credits` to retain
139
+ the listing price; use 0 for free or 100–20000 for paid. Publishing paid versions
140
+ requires a paid plan and review: inspect `skill.status` and
141
+ `skill.pending_version.review_status`, and never describe a pending version as
142
+ live. New versions require a version bump in SKILL.md. These mutations are not
143
+ ads review-gated and run immediately subject to server admission.