@contenthero/cli 0.1.0

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 (94) hide show
  1. package/README.md +108 -0
  2. package/dist/args.d.ts +13 -0
  3. package/dist/args.d.ts.map +1 -0
  4. package/dist/args.js +35 -0
  5. package/dist/args.js.map +1 -0
  6. package/dist/commands/account.d.ts +7 -0
  7. package/dist/commands/account.d.ts.map +1 -0
  8. package/dist/commands/account.js +22 -0
  9. package/dist/commands/account.js.map +1 -0
  10. package/dist/commands/auth.d.ts +35 -0
  11. package/dist/commands/auth.d.ts.map +1 -0
  12. package/dist/commands/auth.js +210 -0
  13. package/dist/commands/auth.js.map +1 -0
  14. package/dist/commands/brandkit.d.ts +12 -0
  15. package/dist/commands/brandkit.d.ts.map +1 -0
  16. package/dist/commands/brandkit.js +159 -0
  17. package/dist/commands/brandkit.js.map +1 -0
  18. package/dist/commands/config.d.ts +11 -0
  19. package/dist/commands/config.d.ts.map +1 -0
  20. package/dist/commands/config.js +69 -0
  21. package/dist/commands/config.js.map +1 -0
  22. package/dist/commands/connected.d.ts +13 -0
  23. package/dist/commands/connected.d.ts.map +1 -0
  24. package/dist/commands/connected.js +86 -0
  25. package/dist/commands/connected.js.map +1 -0
  26. package/dist/commands/generate.d.ts +15 -0
  27. package/dist/commands/generate.d.ts.map +1 -0
  28. package/dist/commands/generate.js +215 -0
  29. package/dist/commands/generate.js.map +1 -0
  30. package/dist/commands/generation.d.ts +12 -0
  31. package/dist/commands/generation.d.ts.map +1 -0
  32. package/dist/commands/generation.js +61 -0
  33. package/dist/commands/generation.js.map +1 -0
  34. package/dist/commands/identity.d.ts +10 -0
  35. package/dist/commands/identity.d.ts.map +1 -0
  36. package/dist/commands/identity.js +83 -0
  37. package/dist/commands/identity.js.map +1 -0
  38. package/dist/commands/inspiration.d.ts +17 -0
  39. package/dist/commands/inspiration.d.ts.map +1 -0
  40. package/dist/commands/inspiration.js +124 -0
  41. package/dist/commands/inspiration.js.map +1 -0
  42. package/dist/commands/media.d.ts +11 -0
  43. package/dist/commands/media.d.ts.map +1 -0
  44. package/dist/commands/media.js +76 -0
  45. package/dist/commands/media.js.map +1 -0
  46. package/dist/commands/model.d.ts +10 -0
  47. package/dist/commands/model.d.ts.map +1 -0
  48. package/dist/commands/model.js +27 -0
  49. package/dist/commands/model.js.map +1 -0
  50. package/dist/commands/pipeline.d.ts +10 -0
  51. package/dist/commands/pipeline.d.ts.map +1 -0
  52. package/dist/commands/pipeline.js +21 -0
  53. package/dist/commands/pipeline.js.map +1 -0
  54. package/dist/commands/post.d.ts +14 -0
  55. package/dist/commands/post.d.ts.map +1 -0
  56. package/dist/commands/post.js +267 -0
  57. package/dist/commands/post.js.map +1 -0
  58. package/dist/commands/schema.d.ts +11 -0
  59. package/dist/commands/schema.d.ts.map +1 -0
  60. package/dist/commands/schema.js +82 -0
  61. package/dist/commands/schema.js.map +1 -0
  62. package/dist/commands/upscale.d.ts +11 -0
  63. package/dist/commands/upscale.d.ts.map +1 -0
  64. package/dist/commands/upscale.js +56 -0
  65. package/dist/commands/upscale.js.map +1 -0
  66. package/dist/config.d.ts +35 -0
  67. package/dist/config.d.ts.map +1 -0
  68. package/dist/config.js +68 -0
  69. package/dist/config.js.map +1 -0
  70. package/dist/context.d.ts +45 -0
  71. package/dist/context.d.ts.map +1 -0
  72. package/dist/context.js +63 -0
  73. package/dist/context.js.map +1 -0
  74. package/dist/errors.d.ts +32 -0
  75. package/dist/errors.d.ts.map +1 -0
  76. package/dist/errors.js +51 -0
  77. package/dist/errors.js.map +1 -0
  78. package/dist/generation.d.ts +34 -0
  79. package/dist/generation.d.ts.map +1 -0
  80. package/dist/generation.js +111 -0
  81. package/dist/generation.js.map +1 -0
  82. package/dist/index.d.ts +11 -0
  83. package/dist/index.d.ts.map +1 -0
  84. package/dist/index.js +42 -0
  85. package/dist/index.js.map +1 -0
  86. package/dist/output.d.ts +14 -0
  87. package/dist/output.d.ts.map +1 -0
  88. package/dist/output.js +33 -0
  89. package/dist/output.js.map +1 -0
  90. package/dist/program.d.ts +11 -0
  91. package/dist/program.d.ts.map +1 -0
  92. package/dist/program.js +69 -0
  93. package/dist/program.js.map +1 -0
  94. package/package.json +52 -0
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Per-invocation context: resolve global options, the API key, and the SDK client.
3
+ *
4
+ * Auth ladder (highest priority first):
5
+ * 1. --api-key flag
6
+ * 2. CONTENTHERO_API_KEY env
7
+ * 3. the stored credential file (written by `contenthero login`)
8
+ *
9
+ * Base URL ladder: --base-url flag, then CONTENTHERO_BASE_URL env, then the
10
+ * stored config, then the SDK default. The SDK reads the same env vars itself,
11
+ * but resolving here keeps the precedence explicit and lets us report the key
12
+ * source in `auth status` / `config list`.
13
+ */
14
+ import { ContentHero } from '@contenthero/sdk';
15
+ import { readConfig, readCredential } from './config.js';
16
+ import { CliError, EXIT } from './errors.js';
17
+ /** Read the merged global options off any command in the tree. */
18
+ export function globalsOf(command) {
19
+ const o = command.optsWithGlobals();
20
+ return {
21
+ // JSON is the default; --human turns it off; an explicit --json forces it back on.
22
+ json: o.json === true || o.human !== true,
23
+ human: o.human === true,
24
+ apiKey: typeof o.apiKey === 'string' ? o.apiKey : undefined,
25
+ baseUrl: typeof o.baseUrl === 'string' ? o.baseUrl : undefined,
26
+ };
27
+ }
28
+ /** Resolve the API key and where it came from, without constructing a client. */
29
+ export function resolveContext(command) {
30
+ const g = globalsOf(command);
31
+ let apiKey;
32
+ let keySource = 'none';
33
+ if (g.apiKey) {
34
+ apiKey = g.apiKey;
35
+ keySource = 'flag';
36
+ }
37
+ else if (process.env.CONTENTHERO_API_KEY) {
38
+ apiKey = process.env.CONTENTHERO_API_KEY;
39
+ keySource = 'env';
40
+ }
41
+ else {
42
+ const stored = readCredential();
43
+ if (stored?.apiKey) {
44
+ apiKey = stored.apiKey;
45
+ keySource = 'file';
46
+ }
47
+ }
48
+ const baseUrl = g.baseUrl || process.env.CONTENTHERO_BASE_URL || readConfig().baseUrl || undefined;
49
+ return { json: g.json, apiKey, keySource, baseUrl };
50
+ }
51
+ /**
52
+ * Build an authenticated SDK client for this command, or throw a CliError with
53
+ * the auth exit code when no key is configured anywhere in the ladder.
54
+ */
55
+ export function makeClient(command) {
56
+ const ctx = resolveContext(command);
57
+ if (!ctx.apiKey) {
58
+ throw new CliError('No API key found. Run `contenthero login`, set CONTENTHERO_API_KEY, or pass --api-key.', EXIT.AUTH);
59
+ }
60
+ const client = new ContentHero({ apiKey: ctx.apiKey, baseUrl: ctx.baseUrl });
61
+ return { client, ctx };
62
+ }
63
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAsB5C,kEAAkE;AAClE,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,MAAM,CAAC,GAAG,OAAO,CAAC,eAAe,EAA6B,CAAA;IAC9D,OAAO;QACL,mFAAmF;QACnF,IAAI,EAAE,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,IAAI;QACzC,KAAK,EAAE,CAAC,CAAC,KAAK,KAAK,IAAI;QACvB,MAAM,EAAE,OAAO,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QAC3D,OAAO,EAAE,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS;KAC/D,CAAA;AACH,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAA;IAE5B,IAAI,MAA0B,CAAA;IAC9B,IAAI,SAAS,GAAc,MAAM,CAAA;IACjC,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;QACb,MAAM,GAAG,CAAC,CAAC,MAAM,CAAA;QACjB,SAAS,GAAG,MAAM,CAAA;IACpB,CAAC;SAAM,IAAI,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC;QAC3C,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAA;QACxC,SAAS,GAAG,KAAK,CAAA;IACnB,CAAC;SAAM,CAAC;QACN,MAAM,MAAM,GAAG,cAAc,EAAE,CAAA;QAC/B,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;YACnB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;YACtB,SAAS,GAAG,MAAM,CAAA;QACpB,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GACX,CAAC,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,UAAU,EAAE,CAAC,OAAO,IAAI,SAAS,CAAA;IAEpF,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,CAAA;AACrD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,MAAM,GAAG,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;IACnC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,IAAI,QAAQ,CAChB,wFAAwF,EACxF,IAAI,CAAC,IAAI,CACV,CAAA;IACH,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IAC5E,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;AACxB,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * CLI error model + exit-code mapping.
3
+ *
4
+ * Exit codes follow the HeyGen CLI convention so shell/agent callers can branch
5
+ * on the result without parsing text:
6
+ * 0 success
7
+ * 1 general error (API / network / unexpected)
8
+ * 2 usage error (bad flags or arguments)
9
+ * 3 authentication error (missing / invalid / unauthorized key)
10
+ * 4 timeout: the work was accepted but did not finish in time (an outputId
11
+ * is still emitted, so the caller can keep polling)
12
+ *
13
+ * SDK errors are mapped here; `CliError` carries an explicit code for problems
14
+ * the CLI itself raises (e.g. no key configured).
15
+ */
16
+ export declare const EXIT: {
17
+ readonly OK: 0;
18
+ readonly GENERAL: 1;
19
+ readonly USAGE: 2;
20
+ readonly AUTH: 3;
21
+ readonly TIMEOUT: 4;
22
+ };
23
+ /** An error the CLI raises itself, carrying the exit code it should produce. */
24
+ export declare class CliError extends Error {
25
+ readonly exitCode: number;
26
+ constructor(message: string, exitCode?: number);
27
+ }
28
+ /** Map any thrown value onto a CLI exit code. */
29
+ export declare function exitCodeForError(err: unknown): number;
30
+ /** A human-readable message for any thrown value. */
31
+ export declare function messageForError(err: unknown): string;
32
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AASH,eAAO,MAAM,IAAI;;;;;;CAMP,CAAA;AAEV,gFAAgF;AAChF,qBAAa,QAAS,SAAQ,KAAK;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;gBACb,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAqB;CAK7D;AAED,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAMrD;AAED,qDAAqD;AACrD,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAGpD"}
package/dist/errors.js ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * CLI error model + exit-code mapping.
3
+ *
4
+ * Exit codes follow the HeyGen CLI convention so shell/agent callers can branch
5
+ * on the result without parsing text:
6
+ * 0 success
7
+ * 1 general error (API / network / unexpected)
8
+ * 2 usage error (bad flags or arguments)
9
+ * 3 authentication error (missing / invalid / unauthorized key)
10
+ * 4 timeout: the work was accepted but did not finish in time (an outputId
11
+ * is still emitted, so the caller can keep polling)
12
+ *
13
+ * SDK errors are mapped here; `CliError` carries an explicit code for problems
14
+ * the CLI itself raises (e.g. no key configured).
15
+ */
16
+ import { AuthenticationError, PermissionError, ValidationError, GenerationTimeoutError, } from '@contenthero/sdk';
17
+ export const EXIT = {
18
+ OK: 0,
19
+ GENERAL: 1,
20
+ USAGE: 2,
21
+ AUTH: 3,
22
+ TIMEOUT: 4,
23
+ };
24
+ /** An error the CLI raises itself, carrying the exit code it should produce. */
25
+ export class CliError extends Error {
26
+ exitCode;
27
+ constructor(message, exitCode = EXIT.GENERAL) {
28
+ super(message);
29
+ this.name = 'CliError';
30
+ this.exitCode = exitCode;
31
+ }
32
+ }
33
+ /** Map any thrown value onto a CLI exit code. */
34
+ export function exitCodeForError(err) {
35
+ if (err instanceof CliError)
36
+ return err.exitCode;
37
+ if (err instanceof AuthenticationError || err instanceof PermissionError)
38
+ return EXIT.AUTH;
39
+ if (err instanceof ValidationError)
40
+ return EXIT.USAGE;
41
+ if (err instanceof GenerationTimeoutError)
42
+ return EXIT.TIMEOUT;
43
+ return EXIT.GENERAL;
44
+ }
45
+ /** A human-readable message for any thrown value. */
46
+ export function messageForError(err) {
47
+ if (err instanceof Error)
48
+ return err.message;
49
+ return String(err);
50
+ }
51
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,eAAe,EACf,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AAEzB,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,EAAE,EAAE,CAAC;IACL,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,OAAO,EAAE,CAAC;CACF,CAAA;AAEV,gFAAgF;AAChF,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,QAAQ,CAAQ;IACzB,YAAY,OAAe,EAAE,WAAmB,IAAI,CAAC,OAAO;QAC1D,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,UAAU,CAAA;QACtB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;CACF;AAED,iDAAiD;AACjD,MAAM,UAAU,gBAAgB,CAAC,GAAY;IAC3C,IAAI,GAAG,YAAY,QAAQ;QAAE,OAAO,GAAG,CAAC,QAAQ,CAAA;IAChD,IAAI,GAAG,YAAY,mBAAmB,IAAI,GAAG,YAAY,eAAe;QAAE,OAAO,IAAI,CAAC,IAAI,CAAA;IAC1F,IAAI,GAAG,YAAY,eAAe;QAAE,OAAO,IAAI,CAAC,KAAK,CAAA;IACrD,IAAI,GAAG,YAAY,sBAAsB;QAAE,OAAO,IAAI,CAAC,OAAO,CAAA;IAC9D,OAAO,IAAI,CAAC,OAAO,CAAA;AACrB,CAAC;AAED,qDAAqD;AACrD,MAAM,UAAU,eAAe,CAAC,GAAY;IAC1C,IAAI,GAAG,YAAY,KAAK;QAAE,OAAO,GAAG,CAAC,OAAO,CAAA;IAC5C,OAAO,MAAM,CAAC,GAAG,CAAC,CAAA;AACpB,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shared generation plumbing: submit a request, optionally preflight its cost,
3
+ * optionally block until it finishes, and render the result. Used by the
4
+ * `generate`, `upscale`, and `generation` commands so they behave identically.
5
+ *
6
+ * Async contract (mirrors the SDK / MCP): image, video, and upscale return
7
+ * `processing`; audio returns `completed` inline. With --wait (the default) we
8
+ * poll to a terminal state; on timeout we emit the outputId and set exit 4 so
9
+ * the caller can keep polling and still script around it.
10
+ */
11
+ import { ContentHero, type GenerateBoardRequest, type GenerateRequest, type Generation } from '@contenthero/sdk';
12
+ import type { Context } from './context.js';
13
+ /** Drop undefined values so the request payload stays minimal. */
14
+ export declare function compact<T extends object>(obj: T): T;
15
+ /** Build a References object from parts, or undefined when empty. */
16
+ export declare function references(parts: GenerateRequest['references']): GenerateRequest['references'] | undefined;
17
+ export interface RunOptions {
18
+ cost: boolean;
19
+ wait: boolean;
20
+ /** Wait timeout in seconds. */
21
+ timeoutSec: number;
22
+ }
23
+ declare function generationHuman(g: Generation): string;
24
+ /**
25
+ * Submit a generation (or board) and render it. Honors --cost (preflight only),
26
+ * --wait (poll to terminal, the default), and --no-wait (return the submission).
27
+ */
28
+ export declare function runGeneration(client: ContentHero, ctx: Context, request: GenerateRequest, opts: RunOptions): Promise<void>;
29
+ /** Same as runGeneration, for the Reference Board pipeline. */
30
+ export declare function runBoard(client: ContentHero, ctx: Context, request: GenerateBoardRequest, opts: RunOptions): Promise<void>;
31
+ /** Block on one outputId to a terminal state and render it; exit 4 on timeout. */
32
+ export declare function waitAndRender(client: ContentHero, ctx: Context, outputId: string, timeoutSec: number): Promise<void>;
33
+ export { generationHuman };
34
+ //# sourceMappingURL=generation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../src/generation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACL,WAAW,EAGX,KAAK,oBAAoB,EACzB,KAAK,eAAe,EAEpB,KAAK,UAAU,EAChB,MAAM,kBAAkB,CAAA;AAGzB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAE3C,kEAAkE;AAClE,wBAAgB,OAAO,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAEnD;AAED,qEAAqE;AACrE,wBAAgB,UAAU,CACxB,KAAK,EAAE,eAAe,CAAC,YAAY,CAAC,GACnC,eAAe,CAAC,YAAY,CAAC,GAAG,SAAS,CAG3C;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAA;IACb,IAAI,EAAE,OAAO,CAAA;IACb,+BAA+B;IAC/B,UAAU,EAAE,MAAM,CAAA;CACnB;AAwBD,iBAAS,eAAe,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAa9C;AAeD;;;GAGG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,eAAe,EACxB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAIf;AAED,+DAA+D;AAC/D,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,oBAAoB,EAC7B,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAIf;AAgBD,kFAAkF;AAClF,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,GAAG,EAAE,OAAO,EACZ,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Shared generation plumbing: submit a request, optionally preflight its cost,
3
+ * optionally block until it finishes, and render the result. Used by the
4
+ * `generate`, `upscale`, and `generation` commands so they behave identically.
5
+ *
6
+ * Async contract (mirrors the SDK / MCP): image, video, and upscale return
7
+ * `processing`; audio returns `completed` inline. With --wait (the default) we
8
+ * poll to a terminal state; on timeout we emit the outputId and set exit 4 so
9
+ * the caller can keep polling and still script around it.
10
+ */
11
+ import { GenerationTimeoutError, } from '@contenthero/sdk';
12
+ import { EXIT } from './errors.js';
13
+ import { emit, keyValues } from './output.js';
14
+ /** Drop undefined values so the request payload stays minimal. */
15
+ export function compact(obj) {
16
+ return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== undefined));
17
+ }
18
+ /** Build a References object from parts, or undefined when empty. */
19
+ export function references(parts) {
20
+ const refs = compact(parts);
21
+ return Object.keys(refs).length > 0 ? refs : undefined;
22
+ }
23
+ function costHuman(est) {
24
+ return keyValues([
25
+ ['Estimated cost', `${est.creditsEstimate} credits`],
26
+ ...((est.modelId ? [['Model', est.modelId]] : [])),
27
+ ...((est.contentType ? [['Type', est.contentType]] : [])),
28
+ ]);
29
+ }
30
+ function resultHuman(r) {
31
+ const pairs = [
32
+ ['Output id', r.outputId],
33
+ ['Status', r.status],
34
+ ];
35
+ if (r.idempotentReplay)
36
+ pairs.push(['Idempotent replay', 'yes']);
37
+ if (r.creditsEstimate != null)
38
+ pairs.push(['Credits', r.creditsEstimate]);
39
+ for (const [i, url] of (r.outputUrls ?? []).entries())
40
+ pairs.push([`URL ${i + 1}`, url]);
41
+ if (r.status === 'processing') {
42
+ pairs.push(['Next', `contenthero generation status ${r.outputId}`]);
43
+ }
44
+ return keyValues(pairs);
45
+ }
46
+ function generationHuman(g) {
47
+ const pairs = [
48
+ ['Output id', g.outputId],
49
+ ['Status', g.status],
50
+ ['Model', g.modelId],
51
+ ['Type', g.contentType],
52
+ ];
53
+ if (g.error)
54
+ pairs.push(['Error', g.error]);
55
+ for (const [i, url] of g.outputUrls.entries())
56
+ pairs.push([`URL ${i + 1}`, url]);
57
+ if (g.status === 'processing' || g.status === 'pending') {
58
+ pairs.push(['Next', `contenthero generation status ${g.outputId}`]);
59
+ }
60
+ return keyValues(pairs);
61
+ }
62
+ /** Preflight a generation's cost and render the estimate. */
63
+ async function emitCost(client, ctx, request, isBoard) {
64
+ const est = isBoard
65
+ ? await client.estimateBoardCost(request)
66
+ : await client.estimateCost(request);
67
+ emit(est, ctx, costHuman);
68
+ }
69
+ /**
70
+ * Submit a generation (or board) and render it. Honors --cost (preflight only),
71
+ * --wait (poll to terminal, the default), and --no-wait (return the submission).
72
+ */
73
+ export async function runGeneration(client, ctx, request, opts) {
74
+ if (opts.cost)
75
+ return emitCost(client, ctx, request, false);
76
+ const submitted = await client.generate(request);
77
+ await renderSubmission(client, ctx, submitted, opts);
78
+ }
79
+ /** Same as runGeneration, for the Reference Board pipeline. */
80
+ export async function runBoard(client, ctx, request, opts) {
81
+ if (opts.cost)
82
+ return emitCost(client, ctx, request, true);
83
+ const submitted = await client.generateBoard(request);
84
+ await renderSubmission(client, ctx, submitted, opts);
85
+ }
86
+ /** Render a submission, polling to terminal when --wait and still processing. */
87
+ async function renderSubmission(client, ctx, submitted, opts) {
88
+ if (submitted.status === 'completed' || !opts.wait) {
89
+ emit(submitted, ctx, resultHuman);
90
+ return;
91
+ }
92
+ await waitAndRender(client, ctx, submitted.outputId, opts.timeoutSec);
93
+ }
94
+ /** Block on one outputId to a terminal state and render it; exit 4 on timeout. */
95
+ export async function waitAndRender(client, ctx, outputId, timeoutSec) {
96
+ try {
97
+ const gen = await client.waitForGeneration(outputId, { timeoutMs: timeoutSec * 1000 });
98
+ emit(gen, ctx, generationHuman);
99
+ }
100
+ catch (err) {
101
+ if (err instanceof GenerationTimeoutError) {
102
+ const snapshot = await client.getGeneration(outputId);
103
+ emit(snapshot, ctx, generationHuman);
104
+ process.exitCode = EXIT.TIMEOUT;
105
+ return;
106
+ }
107
+ throw err;
108
+ }
109
+ }
110
+ export { generationHuman };
111
+ //# sourceMappingURL=generation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generation.js","sourceRoot":"","sources":["../src/generation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ContentHero CLI entrypoint.
4
+ *
5
+ * Owns the single error boundary: commander runs with exitOverride, so every
6
+ * parse error, help/version display, and action rejection lands here and maps to
7
+ * one exit code (see errors.ts). Errors print as JSON by default (agent-first)
8
+ * and as a red line under --human, matching command output.
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}
package/dist/index.js ADDED
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * ContentHero CLI entrypoint.
4
+ *
5
+ * Owns the single error boundary: commander runs with exitOverride, so every
6
+ * parse error, help/version display, and action rejection lands here and maps to
7
+ * one exit code (see errors.ts). Errors print as JSON by default (agent-first)
8
+ * and as a red line under --human, matching command output.
9
+ */
10
+ import { CommanderError } from 'commander';
11
+ import pc from 'picocolors';
12
+ import { buildProgram } from './program.js';
13
+ import { EXIT, exitCodeForError, messageForError } from './errors.js';
14
+ async function main() {
15
+ const program = buildProgram();
16
+ // Bare invocation: show help and exit cleanly rather than erroring.
17
+ if (process.argv.slice(2).length === 0) {
18
+ program.outputHelp();
19
+ process.exit(EXIT.OK);
20
+ }
21
+ try {
22
+ await program.parseAsync(process.argv);
23
+ }
24
+ catch (err) {
25
+ // Help and version display, and parse errors, come through as CommanderError.
26
+ // Commander already wrote the message; we only set the exit code.
27
+ if (err instanceof CommanderError) {
28
+ process.exit(err.exitCode === 0 ? EXIT.OK : EXIT.USAGE);
29
+ }
30
+ const code = exitCodeForError(err);
31
+ const message = messageForError(err);
32
+ if (process.argv.includes('--human')) {
33
+ process.stderr.write(pc.red(`Error: ${message}`) + '\n');
34
+ }
35
+ else {
36
+ process.stderr.write(JSON.stringify({ error: message, exitCode: code }, null, 2) + '\n');
37
+ }
38
+ process.exit(code);
39
+ }
40
+ }
41
+ void main();
42
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,MAAM,YAAY,CAAA;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAErE,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,YAAY,EAAE,CAAA;IAE9B,oEAAoE;IACpE,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,UAAU,EAAE,CAAA;QACpB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACvB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,8EAA8E;QAC9E,kEAAkE;QAClE,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACzD,CAAC;QAED,MAAM,IAAI,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;QAClC,MAAM,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,CAAA;QACpC,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,CAAA;QAC1D,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;QAC1F,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpB,CAAC;AACH,CAAC;AAED,KAAK,IAAI,EAAE,CAAA"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Output rendering. JSON is the default (agent-first); `--human` opts into a
3
+ * compact table / key-value rendering. A command supplies both: the raw data
4
+ * (always the JSON form) and a `human` formatter used only under --human.
5
+ */
6
+ /** Print a result: pretty JSON by default, the human formatter under --human. */
7
+ export declare function emit(data: unknown, opts: {
8
+ json: boolean;
9
+ }, human?: (data: never) => string): void;
10
+ /** A two-space-gutter, left-aligned table with a dim header row. */
11
+ export declare function table(headers: string[], rows: Array<Array<string | number>>): string;
12
+ /** A `key: value` block, keys dim and right-padded to align. */
13
+ export declare function keyValues(pairs: Array<[string, string | number | boolean]>): string;
14
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,iFAAiF;AACjF,wBAAgB,IAAI,CAClB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,EACvB,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,MAAM,GAC9B,IAAI,CAMN;AAED,oEAAoE;AACpE,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CASpF;AAED,gEAAgE;AAChE,wBAAgB,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,MAAM,CAKnF"}
package/dist/output.js ADDED
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Output rendering. JSON is the default (agent-first); `--human` opts into a
3
+ * compact table / key-value rendering. A command supplies both: the raw data
4
+ * (always the JSON form) and a `human` formatter used only under --human.
5
+ */
6
+ import pc from 'picocolors';
7
+ /** Print a result: pretty JSON by default, the human formatter under --human. */
8
+ export function emit(data, opts, human) {
9
+ if (!opts.json && human) {
10
+ process.stdout.write(human(data) + '\n');
11
+ }
12
+ else {
13
+ process.stdout.write(JSON.stringify(data, null, 2) + '\n');
14
+ }
15
+ }
16
+ /** A two-space-gutter, left-aligned table with a dim header row. */
17
+ export function table(headers, rows) {
18
+ const cells = rows.map((r) => r.map((c) => String(c ?? '')));
19
+ const widths = headers.map((h, i) => Math.max(h.length, ...cells.map((r) => (r[i] ?? '').length), 0));
20
+ const line = (vals) => vals.map((v, i) => v.padEnd(widths[i] ?? 0)).join(' ').trimEnd();
21
+ const out = [pc.dim(line(headers))];
22
+ for (const r of cells)
23
+ out.push(line(r));
24
+ return out.join('\n');
25
+ }
26
+ /** A `key: value` block, keys dim and right-padded to align. */
27
+ export function keyValues(pairs) {
28
+ const width = Math.max(...pairs.map(([k]) => k.length), 0);
29
+ return pairs
30
+ .map(([k, v]) => `${pc.dim((k + ':').padEnd(width + 1))} ${String(v)}`)
31
+ .join('\n');
32
+ }
33
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,iFAAiF;AACjF,MAAM,UAAU,IAAI,CAClB,IAAa,EACb,IAAuB,EACvB,KAA+B;IAE/B,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,IAAa,CAAC,GAAG,IAAI,CAAC,CAAA;IACnD,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,KAAK,CAAC,OAAiB,EAAE,IAAmC;IAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAA;IAC5D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAClC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAChE,CAAA;IACD,MAAM,IAAI,GAAG,CAAC,IAAc,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,CAAA;IAClG,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACnC,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACxC,OAAO,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACvB,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,SAAS,CAAC,KAAiD;IACzE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;IAC1D,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;SACtE,IAAI,CAAC,IAAI,CAAC,CAAA;AACf,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Build the commander program: global options + the command tree.
3
+ *
4
+ * Global options are defined on the root and merged onto every command via
5
+ * `optsWithGlobals()` (see context.ts). `exitOverride` makes commander throw a
6
+ * CommanderError instead of calling process.exit, so index.ts owns all exit
7
+ * codes in one place.
8
+ */
9
+ import { Command } from 'commander';
10
+ export declare function buildProgram(): Command;
11
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA8BnC,wBAAgB,YAAY,IAAI,OAAO,CAkCtC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Build the commander program: global options + the command tree.
3
+ *
4
+ * Global options are defined on the root and merged onto every command via
5
+ * `optsWithGlobals()` (see context.ts). `exitOverride` makes commander throw a
6
+ * CommanderError instead of calling process.exit, so index.ts owns all exit
7
+ * codes in one place.
8
+ */
9
+ import { readFileSync } from 'node:fs';
10
+ import { fileURLToPath } from 'node:url';
11
+ import { dirname, join } from 'node:path';
12
+ import { Command } from 'commander';
13
+ import { registerAuth } from './commands/auth.js';
14
+ import { registerConfig } from './commands/config.js';
15
+ import { registerAccount } from './commands/account.js';
16
+ import { registerModel } from './commands/model.js';
17
+ import { registerGenerate } from './commands/generate.js';
18
+ import { registerUpscale } from './commands/upscale.js';
19
+ import { registerGeneration } from './commands/generation.js';
20
+ import { registerMedia } from './commands/media.js';
21
+ import { registerPost } from './commands/post.js';
22
+ import { registerPipeline } from './commands/pipeline.js';
23
+ import { registerBrandKit } from './commands/brandkit.js';
24
+ import { registerIdentity } from './commands/identity.js';
25
+ import { registerInspiration } from './commands/inspiration.js';
26
+ import { registerBrandAccount, registerConnectedAccount } from './commands/connected.js';
27
+ import { registerSchema } from './commands/schema.js';
28
+ /** Read our own version from package.json (kept in lockstep with sdk + mcp). */
29
+ function readVersion() {
30
+ try {
31
+ const here = dirname(fileURLToPath(import.meta.url));
32
+ const pkg = JSON.parse(readFileSync(join(here, '..', 'package.json'), 'utf8'));
33
+ return pkg.version ?? '0.0.0';
34
+ }
35
+ catch {
36
+ return '0.0.0';
37
+ }
38
+ }
39
+ export function buildProgram() {
40
+ const program = new Command();
41
+ program
42
+ .name('contenthero')
43
+ .description('ContentHero CLI: generate media, run the content pipeline, and read your brand and research context.')
44
+ .version(readVersion(), '-v, --version', 'print the CLI version')
45
+ .option('--json', 'output raw JSON (the default)')
46
+ .option('--human', 'render human-readable output instead of JSON')
47
+ .option('--api-key <key>', 'API key (overrides env and the stored credential)')
48
+ .option('--base-url <url>', 'API base URL (overrides env and stored config)')
49
+ .showHelpAfterError('(add --help for usage)')
50
+ .exitOverride();
51
+ registerAuth(program);
52
+ registerConfig(program);
53
+ registerAccount(program);
54
+ registerModel(program);
55
+ registerGenerate(program);
56
+ registerUpscale(program);
57
+ registerGeneration(program);
58
+ registerMedia(program);
59
+ registerPost(program);
60
+ registerPipeline(program);
61
+ registerBrandKit(program);
62
+ registerIdentity(program);
63
+ registerInspiration(program);
64
+ registerBrandAccount(program);
65
+ registerConnectedAccount(program);
66
+ registerSchema(program);
67
+ return program;
68
+ }
69
+ //# sourceMappingURL=program.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["../src/program.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@contenthero/cli",
3
+ "version": "0.1.0",
4
+ "description": "Official ContentHero CLI. Generate media, run the content pipeline, and read your brand/research context from the terminal or any agent shell. Rides the @contenthero/sdk kernel.",
5
+ "type": "module",
6
+ "bin": {
7
+ "contenthero": "./dist/index.js"
8
+ },
9
+ "main": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "files": [
12
+ "dist",
13
+ "README.md"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "clean": "rm -rf dist",
18
+ "test": "tsx --test \"src/**/*.test.ts\"",
19
+ "prepublishOnly": "npm run clean && npm run build"
20
+ },
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/contenthero-ai/contenthero-sdk.git",
27
+ "directory": "packages/cli"
28
+ },
29
+ "keywords": [
30
+ "contenthero",
31
+ "cli",
32
+ "ai",
33
+ "image-generation",
34
+ "video-generation",
35
+ "text-to-speech",
36
+ "content-pipeline"
37
+ ],
38
+ "engines": {
39
+ "node": ">=20"
40
+ },
41
+ "license": "MIT",
42
+ "private": false,
43
+ "dependencies": {
44
+ "@contenthero/sdk": "^0.2.2",
45
+ "commander": "^12.1.0",
46
+ "picocolors": "^1.1.1"
47
+ },
48
+ "devDependencies": {
49
+ "@types/node": "^22.19.19",
50
+ "tsx": "^4.22.3"
51
+ }
52
+ }