@soku-ai/cli 0.1.0-alpha.16 → 0.1.0-alpha.18

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 (49) hide show
  1. package/dist/commands/ads.d.ts +3 -0
  2. package/dist/commands/ads.d.ts.map +1 -1
  3. package/dist/commands/ads.js +373 -10
  4. package/dist/commands/ads.js.map +1 -1
  5. package/dist/commands/auth.d.ts +1 -3
  6. package/dist/commands/auth.d.ts.map +1 -1
  7. package/dist/commands/auth.js +18 -3
  8. package/dist/commands/auth.js.map +1 -1
  9. package/dist/commands/automation.d.ts +46 -0
  10. package/dist/commands/automation.d.ts.map +1 -1
  11. package/dist/commands/automation.js +150 -0
  12. package/dist/commands/automation.js.map +1 -1
  13. package/dist/commands/changelog.d.ts +79 -0
  14. package/dist/commands/changelog.d.ts.map +1 -0
  15. package/dist/commands/changelog.js +123 -0
  16. package/dist/commands/changelog.js.map +1 -0
  17. package/dist/commands/context.d.ts +54 -0
  18. package/dist/commands/context.d.ts.map +1 -1
  19. package/dist/commands/context.js +362 -43
  20. package/dist/commands/context.js.map +1 -1
  21. package/dist/commands/egress.d.ts +49 -1
  22. package/dist/commands/egress.d.ts.map +1 -1
  23. package/dist/commands/egress.js +222 -33
  24. package/dist/commands/egress.js.map +1 -1
  25. package/dist/commands/workspace.d.ts +13 -0
  26. package/dist/commands/workspace.d.ts.map +1 -1
  27. package/dist/commands/workspace.js +34 -7
  28. package/dist/commands/workspace.js.map +1 -1
  29. package/dist/generated/capabilities.json +4829 -1680
  30. package/dist/generated/changelog.json +1448 -0
  31. package/dist/http/client.d.ts +16 -0
  32. package/dist/http/client.d.ts.map +1 -1
  33. package/dist/http/client.js +25 -5
  34. package/dist/http/client.js.map +1 -1
  35. package/dist/index.js +2 -0
  36. package/dist/index.js.map +1 -1
  37. package/dist/upload-journal.d.ts +46 -0
  38. package/dist/upload-journal.d.ts.map +1 -0
  39. package/dist/upload-journal.js +102 -0
  40. package/dist/upload-journal.js.map +1 -0
  41. package/dist/version.d.ts +1 -1
  42. package/dist/version.js +1 -1
  43. package/package.json +3 -3
  44. package/skills/soku/SKILL.md +17 -2
  45. package/skills/soku/references/ads-write.md +48 -19
  46. package/skills/soku/references/auth-workspace.md +27 -12
  47. package/skills/soku/references/egress-security.md +44 -0
  48. package/skills/soku/references/seo-automation-files.md +67 -3
  49. package/skills/soku/references/skills-updates.md +23 -0
@@ -6,6 +6,22 @@ interface RequestOptions {
6
6
  /** Require the active org/brand headers (data endpoints). */
7
7
  workspace?: boolean;
8
8
  apiBase?: string;
9
+ /**
10
+ * Throw {@link ApiError} instead of printing and exiting.
11
+ *
12
+ * The default is to exit, which is right for a one-shot command: the error
13
+ * envelope is the output. It is wrong inside a batch, where one file's
14
+ * transient 503 would take down a run of hundreds and leave the caller no
15
+ * chance to retry it. Batch callers set this and handle the error themselves.
16
+ */
17
+ throwOnError?: boolean;
18
+ }
19
+ /** A failed request, raised only when the caller asked for `throwOnError`. */
20
+ export declare class ApiError extends Error {
21
+ readonly type: string;
22
+ readonly status: number;
23
+ readonly hint?: string | undefined;
24
+ constructor(type: string, message: string, status: number, hint?: string | undefined);
9
25
  }
10
26
  export declare function apiRequest<T = unknown>(path: string, opts?: RequestOptions): Promise<T>;
11
27
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"AAAA;gFACgF;AAMhF,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC,CA0FjG"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"AAAA;gFACgF;AAMhF,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;CACvB;AAED,8EAA8E;AAC9E,qBAAa,QAAS,SAAQ,KAAK;IAE/B,QAAQ,CAAC,IAAI,EAAE,MAAM;IAErB,QAAQ,CAAC,MAAM,EAAE,MAAM;IACvB,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM;gBAHb,IAAI,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACN,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,YAAA;CAKzB;AAED,wBAAsB,UAAU,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC,CAwGjG"}
@@ -3,6 +3,19 @@
3
3
  import { clearToken, loadToken } from '../auth/store.js';
4
4
  import { loadConfig, resolveApiBaseUrl } from '../config.js';
5
5
  import { emitError, ExitCode } from '../output/envelope.js';
6
+ /** A failed request, raised only when the caller asked for `throwOnError`. */
7
+ export class ApiError extends Error {
8
+ type;
9
+ status;
10
+ hint;
11
+ constructor(type, message, status, hint) {
12
+ super(message);
13
+ this.type = type;
14
+ this.status = status;
15
+ this.hint = hint;
16
+ this.name = 'ApiError';
17
+ }
18
+ }
6
19
  export async function apiRequest(path, opts = {}) {
7
20
  const token = await loadToken();
8
21
  if (!token) {
@@ -28,6 +41,13 @@ export async function apiRequest(path, opts = {}) {
28
41
  headers['X-Soku-Brand'] = brandId;
29
42
  }
30
43
  const base = resolveApiBaseUrl(opts.apiBase);
44
+ // Status 0 marks a failure that never reached the server, so a caller
45
+ // classifying retriability sees "no answer" rather than a fabricated code.
46
+ const fail = (type, message, status, code, hint) => {
47
+ if (opts.throwOnError)
48
+ throw new ApiError(type, message, status, hint);
49
+ return emitError(type, message, code, hint);
50
+ };
31
51
  let res;
32
52
  try {
33
53
  res = await fetch(`${base}${path}`, {
@@ -41,7 +61,7 @@ export async function apiRequest(path, opts = {}) {
41
61
  });
42
62
  }
43
63
  catch (err) {
44
- return emitError('network_error', `Could not reach ${base}: ${err.message}`, ExitCode.RUNTIME, 'Behind a proxy? Set ALL_PROXY.');
64
+ return fail('network_error', `Could not reach ${base}: ${err.message}`, 0, ExitCode.RUNTIME, 'Behind a proxy? Set ALL_PROXY.');
45
65
  }
46
66
  const text = await res.text();
47
67
  const parsed = text ? safeJson(text) : null;
@@ -51,16 +71,16 @@ export async function apiRequest(path, opts = {}) {
51
71
  // cleanly instead of looping on a dead credential.
52
72
  const code = parsed?.error ?? 'unauthorized';
53
73
  await clearToken();
54
- return emitError('unauthorized', `Authentication failed (${code}).`, ExitCode.AUTH, 'Run `soku auth login`.');
74
+ return fail('unauthorized', `Authentication failed (${code}).`, res.status, ExitCode.AUTH, 'Run `soku auth login`.');
55
75
  }
56
76
  if (res.status === 403) {
57
- return emitError('forbidden', describeError(parsed) ?? 'Access denied.', ExitCode.AUTH);
77
+ return fail('forbidden', describeError(parsed) ?? 'Access denied.', res.status, ExitCode.AUTH);
58
78
  }
59
79
  if (res.status === 404) {
60
- return emitError('not_found', describeError(parsed) ?? 'Not found.', ExitCode.NOT_FOUND);
80
+ return fail('not_found', describeError(parsed) ?? 'Not found.', res.status, ExitCode.NOT_FOUND);
61
81
  }
62
82
  if (res.status >= 400) {
63
- return emitError(describeCode(parsed) ?? 'request_failed', describeError(parsed) ?? `HTTP ${res.status}`, exitCodeForStatus(res.status), describeHint(parsed) ?? undefined);
83
+ return fail(describeCode(parsed) ?? 'request_failed', describeError(parsed) ?? `HTTP ${res.status}`, res.status, exitCodeForStatus(res.status), describeHint(parsed) ?? undefined);
64
84
  }
65
85
  return parsed;
66
86
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/http/client.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { registerAuthCommands } from './commands/auth.js';
6
6
  import { registerAutomationCommands } from './commands/automation.js';
7
7
  import { registerBrandCommands } from './commands/brand.js';
8
8
  import { registerCallCommand } from './commands/call.js';
9
+ import { registerChangelogCommand } from './commands/changelog.js';
9
10
  import { registerContextCommands } from './commands/context.js';
10
11
  import { registerEgressCommands } from './commands/egress.js';
11
12
  import { registerFilesCommands } from './commands/files.js';
@@ -41,6 +42,7 @@ registerContextCommands(program);
41
42
  registerFilesCommands(program);
42
43
  registerSkillCommand(program);
43
44
  registerUpdateCommand(program);
45
+ registerChangelogCommand(program);
44
46
  registerUpdateCheckCommand(program);
45
47
  function commandNames(command) {
46
48
  const names = new Set();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ /** Durable record of one `soku context upload` run.
2
+ *
3
+ * A bulk upload of hundreds of files will lose some of them to transient
4
+ * failures no matter how many times it retries. Without a record of what the
5
+ * run intended to do, the only recovery is to re-run the whole command and
6
+ * hope, which is what forced manual batching and hand-checking of file counts.
7
+ * The journal makes a run resumable: it stores every planned file and the
8
+ * outcome of each one, so a later `--resume <run-id>` re-attempts exactly the
9
+ * files that never landed.
10
+ *
11
+ * Journals live under `~/.soku/uploads/` and are pruned by age, not by count,
12
+ * so a resume is still possible days later.
13
+ */
14
+ export type UploadEntryStatus = 'pending' | 'done' | 'failed';
15
+ export interface UploadJournalEntry {
16
+ localPath: string;
17
+ targetDir: string;
18
+ filename: string;
19
+ status: UploadEntryStatus;
20
+ error?: string;
21
+ sizeBytes?: number;
22
+ contentType?: string;
23
+ }
24
+ export interface UploadJournal {
25
+ runId: string;
26
+ createdAt: string;
27
+ updatedAt: string;
28
+ /** Workspace the run targeted; a resume into a different brand is refused. */
29
+ orgId: string | null;
30
+ brandId: string | null;
31
+ dir: string;
32
+ entries: UploadJournalEntry[];
33
+ }
34
+ /** Journals older than this are pruned on the next run. */
35
+ export declare const JOURNAL_RETENTION_DAYS = 14;
36
+ export declare function journalDir(): string;
37
+ export declare function newRunId(): string;
38
+ export declare function saveJournal(journal: UploadJournal): void;
39
+ export declare function loadJournal(runId: string): UploadJournal | null;
40
+ export declare function deleteJournal(runId: string): void;
41
+ /** Entries a resume should re-attempt: everything that is not confirmed done. */
42
+ export declare function pendingEntries(journal: UploadJournal): UploadJournalEntry[];
43
+ export declare function listJournals(): UploadJournal[];
44
+ /** Drop journals past the retention window so the directory cannot grow forever. */
45
+ export declare function pruneJournals(now?: number): number;
46
+ //# sourceMappingURL=upload-journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-journal.d.ts","sourceRoot":"","sources":["../src/upload-journal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAQH,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAA;AAE7D,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE,iBAAiB,CAAA;IACzB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,8EAA8E;IAC9E,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,kBAAkB,EAAE,CAAA;CAC9B;AAED,2DAA2D;AAC3D,eAAO,MAAM,sBAAsB,KAAK,CAAA;AAExC,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAMD,wBAAgB,QAAQ,IAAI,MAAM,CAEjC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI,CAMxD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAM/D;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAMjD;AAED,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,OAAO,EAAE,aAAa,GAAG,kBAAkB,EAAE,CAE3E;AAED,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAe9C;AAED,oFAAoF;AACpF,wBAAgB,aAAa,CAAC,GAAG,SAAa,GAAG,MAAM,CAsBtD"}
@@ -0,0 +1,102 @@
1
+ /** Durable record of one `soku context upload` run.
2
+ *
3
+ * A bulk upload of hundreds of files will lose some of them to transient
4
+ * failures no matter how many times it retries. Without a record of what the
5
+ * run intended to do, the only recovery is to re-run the whole command and
6
+ * hope, which is what forced manual batching and hand-checking of file counts.
7
+ * The journal makes a run resumable: it stores every planned file and the
8
+ * outcome of each one, so a later `--resume <run-id>` re-attempts exactly the
9
+ * files that never landed.
10
+ *
11
+ * Journals live under `~/.soku/uploads/` and are pruned by age, not by count,
12
+ * so a resume is still possible days later.
13
+ */
14
+ import { mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from 'node:fs';
15
+ import { join } from 'node:path';
16
+ import { randomUUID } from 'node:crypto';
17
+ import { configDir } from './config.js';
18
+ /** Journals older than this are pruned on the next run. */
19
+ export const JOURNAL_RETENTION_DAYS = 14;
20
+ export function journalDir() {
21
+ return join(configDir(), 'uploads');
22
+ }
23
+ function journalPath(runId) {
24
+ return join(journalDir(), `${runId}.json`);
25
+ }
26
+ export function newRunId() {
27
+ return randomUUID();
28
+ }
29
+ export function saveJournal(journal) {
30
+ const path = journalPath(journal.runId);
31
+ mkdirSync(journalDir(), { recursive: true });
32
+ writeFileSync(path, JSON.stringify({ ...journal, updatedAt: new Date().toISOString() }, null, 2), {
33
+ mode: 0o600,
34
+ });
35
+ }
36
+ export function loadJournal(runId) {
37
+ try {
38
+ return JSON.parse(readFileSync(journalPath(runId), 'utf8'));
39
+ }
40
+ catch {
41
+ return null;
42
+ }
43
+ }
44
+ export function deleteJournal(runId) {
45
+ try {
46
+ rmSync(journalPath(runId));
47
+ }
48
+ catch {
49
+ // Already gone; a finished run leaving no journal behind is the goal.
50
+ }
51
+ }
52
+ /** Entries a resume should re-attempt: everything that is not confirmed done. */
53
+ export function pendingEntries(journal) {
54
+ return journal.entries.filter((entry) => entry.status !== 'done');
55
+ }
56
+ export function listJournals() {
57
+ let names;
58
+ try {
59
+ names = readdirSync(journalDir());
60
+ }
61
+ catch {
62
+ return [];
63
+ }
64
+ const journals = [];
65
+ for (const name of names) {
66
+ if (!name.endsWith('.json'))
67
+ continue;
68
+ const journal = loadJournal(name.slice(0, -'.json'.length));
69
+ if (journal)
70
+ journals.push(journal);
71
+ }
72
+ journals.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
73
+ return journals;
74
+ }
75
+ /** Drop journals past the retention window so the directory cannot grow forever. */
76
+ export function pruneJournals(now = Date.now()) {
77
+ const cutoff = now - JOURNAL_RETENTION_DAYS * 24 * 60 * 60 * 1000;
78
+ let names;
79
+ try {
80
+ names = readdirSync(journalDir());
81
+ }
82
+ catch {
83
+ return 0;
84
+ }
85
+ let removed = 0;
86
+ for (const name of names) {
87
+ if (!name.endsWith('.json'))
88
+ continue;
89
+ const path = join(journalDir(), name);
90
+ try {
91
+ if (statSync(path).mtimeMs < cutoff) {
92
+ rmSync(path);
93
+ removed += 1;
94
+ }
95
+ }
96
+ catch {
97
+ // A journal that vanished mid-prune needs no further attention.
98
+ }
99
+ }
100
+ return removed;
101
+ }
102
+ //# sourceMappingURL=upload-journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload-journal.js","sourceRoot":"","sources":["../src/upload-journal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAC/F,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAyBvC,2DAA2D;AAC3D,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAA;AAExC,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,CAAC,CAAA;AACrC,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,GAAG,KAAK,OAAO,CAAC,CAAA;AAC5C,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,UAAU,EAAE,CAAA;AACrB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,OAAsB;IAChD,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACvC,SAAS,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IAC5C,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAChG,IAAI,EAAE,KAAK;KACZ,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAkB,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,CAAC;QACH,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,sEAAsE;IACxE,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,OAAsB;IACnD,OAAO,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAA;AACnE,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,KAAe,CAAA;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;IACD,MAAM,QAAQ,GAAoB,EAAE,CAAA;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAQ;QACrC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAA;QAC3D,IAAI,OAAO;YAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACrC,CAAC;IACD,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;IAC/D,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,aAAa,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC5C,MAAM,MAAM,GAAG,GAAG,GAAG,sBAAsB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IACjE,IAAI,KAAe,CAAA;IACnB,IAAI,CAAC;QACH,KAAK,GAAG,WAAW,CAAC,UAAU,EAAE,CAAC,CAAA;IACnC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAA;IACV,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,CAAA;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAQ;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,IAAI,CAAC,CAAA;QACrC,IAAI,CAAC;YACH,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,MAAM,EAAE,CAAC;gBACpC,MAAM,CAAC,IAAI,CAAC,CAAA;gBACZ,OAAO,IAAI,CAAC,CAAA;YACd,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gEAAgE;QAClE,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC"}
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export declare const CLI_PACKAGE_NAME = "@soku-ai/cli";
2
- export declare const CLI_VERSION = "0.1.0-alpha.16";
2
+ export declare const CLI_VERSION = "0.1.0-alpha.18";
3
3
  //# sourceMappingURL=version.d.ts.map
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export const CLI_PACKAGE_NAME = '@soku-ai/cli';
2
- export const CLI_VERSION = '0.1.0-alpha.16';
2
+ export const CLI_VERSION = '0.1.0-alpha.18';
3
3
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@soku-ai/cli",
3
- "version": "0.1.0-alpha.16",
3
+ "version": "0.1.0-alpha.18",
4
4
  "description": "Soku CLI — call Soku ads/GA4/PostHog data capabilities from any AI agent or shell.",
5
5
  "license": "MIT",
6
6
  "author": "About Intelligence",
@@ -39,9 +39,9 @@
39
39
  "registry": "https://registry.npmjs.org/"
40
40
  },
41
41
  "scripts": {
42
- "build": "tsc && mkdir -p dist/generated && cp src/generated/capabilities.json dist/generated/capabilities.json",
42
+ "build": "tsc && mkdir -p dist/generated && cp src/generated/capabilities.json src/generated/changelog.json dist/generated/",
43
43
  "typecheck": "tsc --noEmit",
44
- "test": "tsc -p tsconfig.test.json && find .test-build -name '*.test.js' -print | sort | xargs node --test",
44
+ "test": "tsc -p tsconfig.test.json && mkdir -p .test-build/generated && cp src/generated/capabilities.json src/generated/changelog.json .test-build/generated/ && find .test-build -name '*.test.js' -print | sort | xargs node --test && node --test scripts/*.test.mjs",
45
45
  "clean": "rm -rf dist .test-build",
46
46
  "postinstall": "node postinstall.cjs",
47
47
  "prepublishOnly": "pnpm run clean && pnpm run build"
@@ -9,7 +9,10 @@ description: >-
9
9
  license: MIT
10
10
  metadata:
11
11
  author: About Intelligence
12
- version: "0.4"
12
+ version: "0.5"
13
+ # CLI release this skill was written against. `soku changelog --since <that
14
+ # version>` lists what moved if the installed CLI is newer.
15
+ cliVersion: "0.1.0-alpha.18"
13
16
  ---
14
17
 
15
18
  # Soku CLI
@@ -30,7 +33,7 @@ Read only the reference files needed for the user's task:
30
33
  | Meta/Google/ChatGPT Ads writes, uploads, bulk create, review-gated approval | `references/ads-write.md` |
31
34
  | SEO Hosting, automations, Context Hub files, temporary public file URLs | `references/seo-automation-files.md` |
32
35
  | Third-party APIs through server-side credential injection; security rules | `references/egress-security.md` |
33
- | Installing, updating, or removing Soku-managed local skills | `references/skills-updates.md` |
36
+ | Installing, updating, or removing Soku-managed local skills; finding out what an upgrade changed | `references/skills-updates.md` |
34
37
  | Migrate context, project files, or workspaces from Claude into Soku | Run `soku skill install migrate-from-claude`, then read the installed `soku-migrate-from-claude` skill. |
35
38
 
36
39
  For an installed business skill such as `soku-ads-report`, read that skill too.
@@ -71,6 +74,18 @@ soku <namespace> <action> --help
71
74
 
72
75
  ## Non-Negotiable Rules
73
76
 
77
+ - **Confirm the target brand immediately before any write, and read it back
78
+ after.** Run `soku workspace status` in the same turn as the write — not
79
+ earlier in the session — and check the reported brand is the one the user
80
+ named (its `source` field tells you whether saved config or a `SOKU_BRAND_ID`
81
+ environment variable decided it, which is what you would have to change). The
82
+ CLI keeps whatever brand was selected last, and it does not follow the brand
83
+ the user is looking at in the web app, so a brand confirmed three turns ago
84
+ proves nothing about this write. After the write, read the object back
85
+ (`soku automation get`, `soku context list`, `soku seo-hosting pages list`)
86
+ and confirm it landed where you intended. A write into the wrong brand
87
+ succeeds silently and looks identical to a correct one; the read-back is the
88
+ only thing that tells them apart.
74
89
  - Never print or persist the Soku access token.
75
90
  - Never ask the user to paste third-party provider keys for covered providers.
76
91
  - Do not fail just because an upstream provider key env var is unset. Use
@@ -157,32 +157,61 @@ The command path determines platform. Do not add `--platform`; the CLI injects
157
157
 
158
158
  ## ChatGPT Ads Writes
159
159
 
160
- ChatGPT Ads uses the generic `ads` action surface. The platform object model is
161
- ad unit first, campaign second:
160
+ Use:
162
161
 
163
- 1. Create one or more ad units with `ads/create_ad_unit`.
164
- 2. Create the campaign with `ads/create_campaign`, `platform=chatgpt_ads`, and a
165
- non-empty `ad_unit_ids` list.
166
- 3. Keep new campaigns paused. The backend forces create to paused; do not submit
167
- `update_campaign(status=active)` unless the user explicitly asks for
168
- activation and approves that exact review.
162
+ ```bash
163
+ soku ads chatgpt --help
164
+ soku ads chatgpt account --help
165
+ soku ads chatgpt campaign --help
166
+ soku ads chatgpt ad-group --help
167
+ soku ads chatgpt ad --help
168
+ ```
169
169
 
170
- Use `soku call` when a typed command is not obvious:
170
+ The command path determines platform. Do not add `--platform`; the CLI injects
171
+ `platform=chatgpt_ads`.
172
+
173
+ The object model is `Campaign → Ad Group → Ad`. `campaign create` requires a
174
+ non-empty inline ad-groups array (`--ad-groups '<json>'` or
175
+ `--ad-groups-file groups.json`); each group is `manual` (with authored `ads`)
176
+ or `generative`. Campaign, ad group, and ad creates are all forced paused by
177
+ the backend; activation is a separate review-gated
178
+ `soku ads chatgpt campaign activate` that the user must explicitly request and
179
+ approve. ChatGPT Ads status literals are lowercase `active` / `paused`, ads
180
+ live under `ad_group_id` (never `adset_id`), and every mutation requires
181
+ `--account-id`.
171
182
 
172
183
  ```bash
173
- soku call ads create_ad_unit \
174
- --payload '{"platform":"chatgpt_ads","account_id":"<account_id>","platform_extras":{"description":"Ad unit description","landing_page":"https://example.com/?utm_source=chatgpt_ads","static_ad_text":"Primary text","static_cta":"Learn more"}}' \
175
- --summary "Create paused ChatGPT Ads ad unit input"
176
-
177
- soku call ads create_campaign \
178
- --payload '{"platform":"chatgpt_ads","account_id":"<account_id>","name":"Launch Test","budget_daily_micros":300000000,"platform_extras":{"landing_page":"https://example.com/?utm_source=chatgpt_ads","campaign_objective":"clicks","ad_unit_ids":["<ad_unit_id>"]}}' \
184
+ soku ads chatgpt campaign create \
185
+ --account-id <account_id> --name "Launch Test" \
186
+ --landing-page "https://example.com/?utm_source=chatgpt_ads" \
187
+ --objective clicks --budget-daily 300 \
188
+ --ad-groups '[{"group_type":"manual","name":"AG 1","landing_page":"https://example.com/?utm_source=chatgpt_ads","brand_name":"Example","ads":[{"name":"Ad 1","headline":"Headline","copy":"Body","cta":"Learn more","landing_page":"https://example.com/?utm_source=chatgpt_ads"}]}]' \
179
189
  --summary "Create paused ChatGPT Ads campaign Launch Test"
190
+
191
+ soku ads chatgpt ad-group create \
192
+ --account-id <account_id> --campaign-id <campaign_id> \
193
+ --name "AG 2" --landing-page "https://example.com/?utm_source=chatgpt_ads" \
194
+ --brand-name "Example" --group-type generative \
195
+ --summary "Add generative ad group AG 2"
196
+
197
+ soku ads chatgpt ad create \
198
+ --account-id <account_id> --ad-group-id <ad_group_id> \
199
+ --name "Ad 2" --headline "Headline" --copy "Body" --cta "Learn more" \
200
+ --landing-page "https://example.com/?utm_source=chatgpt_ads" \
201
+ --summary "Add authored ad Ad 2"
180
202
  ```
181
203
 
182
- Available ChatGPT Ads write actions: `create_ad_unit`, `create_campaign`,
183
- `generate_ad_units`, `add_campaign_ad_units`, `replace_campaign_ad_units`,
184
- `update_campaign`, and `archive_ad_unit`. Treat `archive_ad_unit` as a toggle:
185
- verify current state before using it.
204
+ Reads need no `--summary`: `soku ads chatgpt account info` (billing facts plus
205
+ activation/tracking preflight), `campaign list|get`, `ad-group list|get`.
206
+ Archives (`campaign remove`, `ad-group archive`, `ad archive`) are
207
+ provider-side archive toggles — verify current state with a read first.
208
+
209
+ Legacy ad-unit campaigns (`create_ad_unit`, `generate_ad_units`,
210
+ `add_campaign_ad_units`, `replace_campaign_ad_units`, `archive_ad_unit`) are
211
+ deprecated and stay on the raw `soku call ads <action>` surface for existing
212
+ campaigns only; do not use them for new deployments. Migrate a legacy campaign
213
+ with `soku ads chatgpt campaign migrate-legacy` (moves ad units into paused Ad
214
+ Groups and authored Ads).
186
215
 
187
216
  ## Review Gate
188
217
 
@@ -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
@@ -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