clipugc 0.2.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 (77) hide show
  1. package/README.md +249 -0
  2. package/dist/cli.d.ts +2 -0
  3. package/dist/cli.js +31 -0
  4. package/dist/cli.js.map +1 -0
  5. package/dist/commands/account.d.ts +12 -0
  6. package/dist/commands/account.js +48 -0
  7. package/dist/commands/account.js.map +1 -0
  8. package/dist/commands/auth.d.ts +14 -0
  9. package/dist/commands/auth.js +152 -0
  10. package/dist/commands/auth.js.map +1 -0
  11. package/dist/commands/characters.d.ts +3 -0
  12. package/dist/commands/characters.js +261 -0
  13. package/dist/commands/characters.js.map +1 -0
  14. package/dist/commands/config.d.ts +5 -0
  15. package/dist/commands/config.js +69 -0
  16. package/dist/commands/config.js.map +1 -0
  17. package/dist/commands/credits.d.ts +2 -0
  18. package/dist/commands/credits.js +117 -0
  19. package/dist/commands/credits.js.map +1 -0
  20. package/dist/commands/hooks.d.ts +2 -0
  21. package/dist/commands/hooks.js +32 -0
  22. package/dist/commands/hooks.js.map +1 -0
  23. package/dist/commands/images.d.ts +3 -0
  24. package/dist/commands/images.js +257 -0
  25. package/dist/commands/images.js.map +1 -0
  26. package/dist/commands/videos.d.ts +2 -0
  27. package/dist/commands/videos.js +272 -0
  28. package/dist/commands/videos.js.map +1 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.js +24 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/services/api.d.ts +40 -0
  33. package/dist/services/api.js +139 -0
  34. package/dist/services/api.js.map +1 -0
  35. package/dist/services/characters.service.d.ts +135 -0
  36. package/dist/services/characters.service.js +276 -0
  37. package/dist/services/characters.service.js.map +1 -0
  38. package/dist/services/hooks.service.d.ts +9 -0
  39. package/dist/services/hooks.service.js +23 -0
  40. package/dist/services/hooks.service.js.map +1 -0
  41. package/dist/services/images.service.d.ts +95 -0
  42. package/dist/services/images.service.js +191 -0
  43. package/dist/services/images.service.js.map +1 -0
  44. package/dist/services/upload.service.d.ts +46 -0
  45. package/dist/services/upload.service.js +134 -0
  46. package/dist/services/upload.service.js.map +1 -0
  47. package/dist/services/user.service.d.ts +80 -0
  48. package/dist/services/user.service.js +35 -0
  49. package/dist/services/user.service.js.map +1 -0
  50. package/dist/services/videos.service.d.ts +100 -0
  51. package/dist/services/videos.service.js +187 -0
  52. package/dist/services/videos.service.js.map +1 -0
  53. package/dist/types/index.d.ts +47 -0
  54. package/dist/types/index.js +18 -0
  55. package/dist/types/index.js.map +1 -0
  56. package/dist/utils/config.d.ts +18 -0
  57. package/dist/utils/config.js +65 -0
  58. package/dist/utils/config.js.map +1 -0
  59. package/dist/utils/errors.d.ts +52 -0
  60. package/dist/utils/errors.js +74 -0
  61. package/dist/utils/errors.js.map +1 -0
  62. package/dist/utils/logger.d.ts +11 -0
  63. package/dist/utils/logger.js +28 -0
  64. package/dist/utils/logger.js.map +1 -0
  65. package/dist/utils/output.d.ts +16 -0
  66. package/dist/utils/output.js +53 -0
  67. package/dist/utils/output.js.map +1 -0
  68. package/dist/utils/poll.d.ts +37 -0
  69. package/dist/utils/poll.js +94 -0
  70. package/dist/utils/poll.js.map +1 -0
  71. package/dist/utils/prompt.d.ts +4 -0
  72. package/dist/utils/prompt.js +55 -0
  73. package/dist/utils/prompt.js.map +1 -0
  74. package/dist/version.d.ts +1 -0
  75. package/dist/version.js +12 -0
  76. package/dist/version.js.map +1 -0
  77. package/package.json +49 -0
@@ -0,0 +1,53 @@
1
+ import chalk from 'chalk';
2
+ /** True when the global --json flag is set (for scripting). */
3
+ export function isJsonMode(command) {
4
+ return Boolean(command.optsWithGlobals().json);
5
+ }
6
+ /** Print raw JSON data (the `data` part of the envelope) for --json mode. */
7
+ export function printJson(data) {
8
+ console.log(JSON.stringify(data, null, 2));
9
+ }
10
+ /** Render a simple aligned text table for humans. */
11
+ export function printTable(rows, columns) {
12
+ if (rows.length === 0) {
13
+ console.log(chalk.dim(' (no results)'));
14
+ return;
15
+ }
16
+ const cells = rows.map((row) => columns.map((col) => {
17
+ const v = col.value(row);
18
+ return v === null || v === undefined || v === '' ? '—' : String(v);
19
+ }));
20
+ const widths = columns.map((col, i) => Math.max(col.header.length, ...cells.map((r) => r[i].length)));
21
+ const headerLine = columns.map((col, i) => col.header.padEnd(widths[i])).join(' ');
22
+ console.log(chalk.bold(headerLine));
23
+ console.log(chalk.dim(widths.map((w) => '-'.repeat(w)).join(' ')));
24
+ for (const row of cells) {
25
+ console.log(row.map((cell, i) => cell.padEnd(widths[i])).join(' '));
26
+ }
27
+ }
28
+ /** Print a "page X of Y (N total)" footer for paginated lists. */
29
+ export function printPagination(pagination) {
30
+ if (!pagination)
31
+ return;
32
+ const { current_page, last_page, total } = pagination;
33
+ let line = `page ${current_page} of ${last_page} (${total} total)`;
34
+ if (pagination.has_more_pages)
35
+ line += ' — use --page to see more';
36
+ console.log(chalk.dim(line));
37
+ }
38
+ /** Colorize a pending|processing|completed|failed status. */
39
+ export function formatStatus(status) {
40
+ switch (status) {
41
+ case 'completed':
42
+ return chalk.green(status);
43
+ case 'failed':
44
+ return chalk.red(status);
45
+ case 'processing':
46
+ return chalk.yellow(status);
47
+ case 'pending':
48
+ return chalk.gray(status);
49
+ default:
50
+ return status;
51
+ }
52
+ }
53
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/utils/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { ResourceStatus } from '../types/index.js';
2
+ export interface PollOptions {
3
+ /** Interval between checks in ms (default 6000). */
4
+ intervalMs?: number;
5
+ /** Give up after this many ms (default 20 minutes). */
6
+ timeoutMs?: number;
7
+ /** Spinner label, e.g. "Generating image". */
8
+ label?: string;
9
+ /** Suppress spinner (for --json mode); still polls. */
10
+ quiet?: boolean;
11
+ }
12
+ export interface StatusCheck {
13
+ status: ResourceStatus | string;
14
+ /** Optional server-side failure explanation. */
15
+ failure_reason?: string | null;
16
+ error_message?: string | null;
17
+ }
18
+ /** Payload shape for merge polling (the video resource carries merge_status). */
19
+ export interface MergeStatusCheck {
20
+ merge_status?: string | null;
21
+ media?: {
22
+ has_merged?: boolean;
23
+ };
24
+ [key: string]: unknown;
25
+ }
26
+ /**
27
+ * Poll a merge until it finishes. A clip's own `status` stays "completed" during a
28
+ * merge, so we watch `merge_status` (processing → completed | failed), falling back
29
+ * to `media.has_merged` for older servers. Throws ApiError on merge failure/timeout.
30
+ */
31
+ export declare function waitForMerge<T extends MergeStatusCheck>(check: () => Promise<T>, options?: PollOptions): Promise<T>;
32
+ /**
33
+ * Poll `check()` until the resource reaches completed/failed.
34
+ * Shows an ora spinner with elapsed time. Throws ApiError on failed/timeout.
35
+ * Returns the final check payload on completion.
36
+ */
37
+ export declare function waitForCompletion<T extends StatusCheck>(check: () => Promise<T>, options?: PollOptions): Promise<T>;
@@ -0,0 +1,94 @@
1
+ import ora from 'ora';
2
+ import chalk from 'chalk';
3
+ import { ApiError } from './errors.js';
4
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
5
+ /**
6
+ * Poll a merge until it finishes. A clip's own `status` stays "completed" during a
7
+ * merge, so we watch `merge_status` (processing → completed | failed), falling back
8
+ * to `media.has_merged` for older servers. Throws ApiError on merge failure/timeout.
9
+ */
10
+ export async function waitForMerge(check, options = {}) {
11
+ const intervalMs = options.intervalMs ?? 6000;
12
+ const timeoutMs = options.timeoutMs ?? 20 * 60 * 1000;
13
+ const label = options.label ?? 'Merging video';
14
+ const start = Date.now();
15
+ const spinner = options.quiet ? null : ora(`${label}...`).start();
16
+ try {
17
+ for (;;) {
18
+ const result = await check();
19
+ const elapsed = Math.round((Date.now() - start) / 1000);
20
+ const merged = result.merge_status === 'completed' || result.media?.has_merged === true;
21
+ const failed = result.merge_status === 'failed';
22
+ if (merged) {
23
+ spinner?.succeed(`${label} completed in ${formatElapsed(elapsed)}`);
24
+ return result;
25
+ }
26
+ if (failed) {
27
+ spinner?.fail(`${label} failed — the merge credit was refunded.`);
28
+ throw new ApiError(`${label} failed. The merge credit was refunded; try again.`);
29
+ }
30
+ if (Date.now() - start > timeoutMs) {
31
+ spinner?.fail(`${label} timed out after ${formatElapsed(elapsed)} — it may still finish server-side.`);
32
+ throw new ApiError(`${label} timed out. Check \`clipugc videos status\` later.`);
33
+ }
34
+ if (spinner) {
35
+ spinner.text = `${label}... ${chalk.dim(`(${result.merge_status ?? 'processing'}, ${formatElapsed(elapsed)} elapsed)`)}`;
36
+ }
37
+ await sleep(intervalMs);
38
+ }
39
+ }
40
+ catch (err) {
41
+ if (spinner?.isSpinning)
42
+ spinner.stop();
43
+ throw err;
44
+ }
45
+ }
46
+ /**
47
+ * Poll `check()` until the resource reaches completed/failed.
48
+ * Shows an ora spinner with elapsed time. Throws ApiError on failed/timeout.
49
+ * Returns the final check payload on completion.
50
+ */
51
+ export async function waitForCompletion(check, options = {}) {
52
+ const intervalMs = options.intervalMs ?? 6000;
53
+ const timeoutMs = options.timeoutMs ?? 20 * 60 * 1000;
54
+ const label = options.label ?? 'Processing';
55
+ const start = Date.now();
56
+ const spinner = options.quiet ? null : ora(`${label}...`).start();
57
+ try {
58
+ // Poll loop
59
+ for (;;) {
60
+ const result = await check();
61
+ const elapsed = Math.round((Date.now() - start) / 1000);
62
+ if (result.status === 'completed') {
63
+ spinner?.succeed(`${label} completed in ${formatElapsed(elapsed)}`);
64
+ return result;
65
+ }
66
+ if (result.status === 'failed') {
67
+ const reason = result.failure_reason || result.error_message || 'no reason given';
68
+ spinner?.fail(`${label} failed (${reason})`);
69
+ throw new ApiError(`${label} failed: ${reason}`);
70
+ }
71
+ if (Date.now() - start > timeoutMs) {
72
+ spinner?.fail(`${label} timed out after ${formatElapsed(elapsed)} — it may still finish server-side.`);
73
+ throw new ApiError(`${label} timed out after ${formatElapsed(elapsed)}. Check status later.`);
74
+ }
75
+ if (spinner) {
76
+ spinner.text = `${label}... ${chalk.dim(`(${result.status}, ${formatElapsed(elapsed)} elapsed)`)}`;
77
+ }
78
+ await sleep(intervalMs);
79
+ }
80
+ }
81
+ catch (err) {
82
+ if (spinner?.isSpinning)
83
+ spinner.stop();
84
+ throw err;
85
+ }
86
+ }
87
+ function formatElapsed(totalSeconds) {
88
+ if (totalSeconds < 60)
89
+ return `${totalSeconds}s`;
90
+ const m = Math.floor(totalSeconds / 60);
91
+ const s = totalSeconds % 60;
92
+ return `${m}m ${s}s`;
93
+ }
94
+ //# sourceMappingURL=poll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../src/utils/poll.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export declare function confirm(message: string): Promise<boolean>;
2
+ export declare function promptInput(message: string): Promise<string>;
3
+ /** Prompt without echoing input (for API keys). Falls back to plain prompt when not a TTY. */
4
+ export declare function promptSecret(message: string): Promise<string>;
@@ -0,0 +1,55 @@
1
+ import readline from 'node:readline';
2
+ export async function confirm(message) {
3
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
4
+ return new Promise((resolve) => {
5
+ rl.question(`${message} (y/N) `, (answer) => {
6
+ rl.close();
7
+ resolve(answer.trim().toLowerCase() === 'y' || answer.trim().toLowerCase() === 'yes');
8
+ });
9
+ });
10
+ }
11
+ export async function promptInput(message) {
12
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
13
+ return new Promise((resolve) => {
14
+ rl.question(message, (answer) => {
15
+ rl.close();
16
+ resolve(answer.trim());
17
+ });
18
+ });
19
+ }
20
+ /** Prompt without echoing input (for API keys). Falls back to plain prompt when not a TTY. */
21
+ export async function promptSecret(message) {
22
+ if (!process.stdin.isTTY)
23
+ return promptInput(message);
24
+ return new Promise((resolve) => {
25
+ process.stdout.write(message);
26
+ const stdin = process.stdin;
27
+ stdin.setRawMode?.(true);
28
+ stdin.resume();
29
+ stdin.setEncoding('utf8');
30
+ let value = '';
31
+ const onData = (char) => {
32
+ if (char === '\n' || char === '\r' || char === '') {
33
+ stdin.setRawMode?.(false);
34
+ stdin.pause();
35
+ stdin.removeListener('data', onData);
36
+ process.stdout.write('\n');
37
+ resolve(value.trim());
38
+ }
39
+ else if (char === '') {
40
+ // Ctrl+C
41
+ stdin.setRawMode?.(false);
42
+ process.stdout.write('\n');
43
+ process.exit(130);
44
+ }
45
+ else if (char === '' || char === '\b') {
46
+ value = value.slice(0, -1);
47
+ }
48
+ else {
49
+ value += char;
50
+ }
51
+ };
52
+ stdin.on('data', onData);
53
+ });
54
+ }
55
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/utils/prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function getVersion(): string;
@@ -0,0 +1,12 @@
1
+ import { createRequire } from 'node:module';
2
+ /**
3
+ * Version is single-sourced from package.json, read at runtime.
4
+ * From dist/version.js (or src/version.ts via tsx), ../package.json is the
5
+ * package root's package.json.
6
+ */
7
+ const require = createRequire(import.meta.url);
8
+ export function getVersion() {
9
+ const pkg = require('../package.json');
10
+ return pkg.version;
11
+ }
12
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;GAIG;AACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE/C,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAwB,CAAC;IAC9D,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "clipugc",
3
+ "version": "0.2.0",
4
+ "description": "Official CLI for ClipUGC — create AI characters, generate looks, and produce UGC-style videos for your mobile app from the terminal.",
5
+ "type": "module",
6
+ "bin": {
7
+ "clipugc": "./dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "dev": "tsx src/index.ts",
15
+ "start": "node dist/index.js",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "e2e": "tsx scripts/e2e.ts"
19
+ },
20
+ "keywords": [
21
+ "clipugc",
22
+ "ugc",
23
+ "ai-video",
24
+ "cli",
25
+ "video-generation"
26
+ ],
27
+ "homepage": "https://clipugc.com",
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/mirzemehdi/ClipUGC-CLI.git"
31
+ },
32
+ "license": "MIT",
33
+ "dependencies": {
34
+ "chalk": "^5.4.1",
35
+ "commander": "^13.1.0",
36
+ "fs-extra": "^11.3.0",
37
+ "ora": "^8.2.0"
38
+ },
39
+ "devDependencies": {
40
+ "@types/fs-extra": "^11.0.4",
41
+ "@types/node": "^22.13.10",
42
+ "tsx": "^4.19.3",
43
+ "typescript": "^5.8.2",
44
+ "vitest": "^3.1.1"
45
+ },
46
+ "engines": {
47
+ "node": ">=20"
48
+ }
49
+ }