@ubnt/cawcut 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 (76) hide show
  1. package/config/developer-capabilities.json +36 -0
  2. package/config/products.json +45 -0
  3. package/dist/commands/app.d.ts +2 -0
  4. package/dist/commands/app.js +156 -0
  5. package/dist/commands/app.js.map +1 -0
  6. package/dist/commands/auth.d.ts +2 -0
  7. package/dist/commands/auth.js +62 -0
  8. package/dist/commands/auth.js.map +1 -0
  9. package/dist/commands/capabilities.d.ts +2 -0
  10. package/dist/commands/capabilities.js +83 -0
  11. package/dist/commands/capabilities.js.map +1 -0
  12. package/dist/commands/generate.d.ts +2 -0
  13. package/dist/commands/generate.js +73 -0
  14. package/dist/commands/generate.js.map +1 -0
  15. package/dist/commands/set.d.ts +2 -0
  16. package/dist/commands/set.js +25 -0
  17. package/dist/commands/set.js.map +1 -0
  18. package/dist/commands/task.d.ts +2 -0
  19. package/dist/commands/task.js +48 -0
  20. package/dist/commands/task.js.map +1 -0
  21. package/dist/index.d.ts +2 -0
  22. package/dist/index.js +21 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/lib/app-inputs.d.ts +17 -0
  25. package/dist/lib/app-inputs.js +191 -0
  26. package/dist/lib/app-inputs.js.map +1 -0
  27. package/dist/lib/assets.d.ts +16 -0
  28. package/dist/lib/assets.js +42 -0
  29. package/dist/lib/assets.js.map +1 -0
  30. package/dist/lib/capabilities.d.ts +6 -0
  31. package/dist/lib/capabilities.js +17 -0
  32. package/dist/lib/capabilities.js.map +1 -0
  33. package/dist/lib/capability-catalog.d.ts +56 -0
  34. package/dist/lib/capability-catalog.js +135 -0
  35. package/dist/lib/capability-catalog.js.map +1 -0
  36. package/dist/lib/capability-catalog.json +2743 -0
  37. package/dist/lib/config.d.ts +46 -0
  38. package/dist/lib/config.js +177 -0
  39. package/dist/lib/config.js.map +1 -0
  40. package/dist/lib/credentials.d.ts +11 -0
  41. package/dist/lib/credentials.js +47 -0
  42. package/dist/lib/credentials.js.map +1 -0
  43. package/dist/lib/developer.d.ts +36 -0
  44. package/dist/lib/developer.js +75 -0
  45. package/dist/lib/developer.js.map +1 -0
  46. package/dist/lib/download.d.ts +3 -0
  47. package/dist/lib/download.js +38 -0
  48. package/dist/lib/download.js.map +1 -0
  49. package/dist/lib/generate-request.d.ts +20 -0
  50. package/dist/lib/generate-request.js +74 -0
  51. package/dist/lib/generate-request.js.map +1 -0
  52. package/dist/lib/http.d.ts +16 -0
  53. package/dist/lib/http.js +90 -0
  54. package/dist/lib/http.js.map +1 -0
  55. package/dist/lib/local-config.d.ts +6 -0
  56. package/dist/lib/local-config.js +23 -0
  57. package/dist/lib/local-config.js.map +1 -0
  58. package/dist/lib/oauth.d.ts +25 -0
  59. package/dist/lib/oauth.js +141 -0
  60. package/dist/lib/oauth.js.map +1 -0
  61. package/dist/lib/output.d.ts +4 -0
  62. package/dist/lib/output.js +22 -0
  63. package/dist/lib/output.js.map +1 -0
  64. package/dist/lib/poll.d.ts +12 -0
  65. package/dist/lib/poll.js +26 -0
  66. package/dist/lib/poll.js.map +1 -0
  67. package/dist/lib/result-output.d.ts +18 -0
  68. package/dist/lib/result-output.js +82 -0
  69. package/dist/lib/result-output.js.map +1 -0
  70. package/dist/lib/spinner.d.ts +5 -0
  71. package/dist/lib/spinner.js +39 -0
  72. package/dist/lib/spinner.js.map +1 -0
  73. package/dist/lib/validate-generate.d.ts +21 -0
  74. package/dist/lib/validate-generate.js +191 -0
  75. package/dist/lib/validate-generate.js.map +1 -0
  76. package/package.json +34 -0
@@ -0,0 +1,36 @@
1
+ {
2
+ "$comment": "CLI capability → AI Kit hybrid bindings. Keep in sync with flow.cawcut-workflow/internal/config/developer_capabilities.go",
3
+ "text-to-image": {
4
+ "hybridAppId": "image_hybrid",
5
+ "subAppId": "text_to_image",
6
+ "subType": "textToImage",
7
+ "defaultModel": "gpt-image-2"
8
+ },
9
+ "text-to-video": {
10
+ "hybridAppId": "video_hybrid",
11
+ "subAppId": "text_to_video",
12
+ "subType": "textToVideo",
13
+ "defaultModel": "Seedance 2.0"
14
+ },
15
+ "image-to-image": {
16
+ "hybridAppId": "image_hybrid",
17
+ "subAppId": "image_edit_v2",
18
+ "subType": "imageProcessor",
19
+ "defaultModel": "gpt-image-2",
20
+ "requiresMedia": "image"
21
+ },
22
+ "image-to-video": {
23
+ "hybridAppId": "video_hybrid",
24
+ "subAppId": "image_to_video",
25
+ "subType": "imageToVideo",
26
+ "defaultModel": "Seedance 2.0",
27
+ "requiresMedia": "image"
28
+ },
29
+ "omni-to-video": {
30
+ "hybridAppId": "video_hybrid",
31
+ "subAppId": "seedance_video_to_video",
32
+ "subType": "imageToVideo",
33
+ "defaultModel": "Seedance 2.0",
34
+ "requiresMedia": "omni"
35
+ }
36
+ }
@@ -0,0 +1,45 @@
1
+ {
2
+ "$comment": "Product URL registry for developer CLI + Agent Skill OAuth. Values align with vn.config-ssm (cawcut-user / cawcut-workflow). Override via CAWCUT_* env vars — see lib/config.ts.",
3
+ "$consentPath": "OAuth consent page path on fe-portal (FE定稿: /skill/auth; proto 示例 https://app.dev.cawcut.com/skill/auth).",
4
+ "$ssmRefs": {
5
+ "portalBase": "CAWCUT_USER_PORTAL_DOMAIN (cawcut-user/envs.json)",
6
+ "userApiBase": "{CAWCUT_USER_MAIL_UNSUBSCRIBE_CAWCUT_ORIGIN}/cawcut-user/api/v1",
7
+ "workflowApiBase": "{CAWCUT_USER_MAIL_UNSUBSCRIBE_CAWCUT_ORIGIN}/cawcut-workflow/api"
8
+ },
9
+ "products": {
10
+ "cawcut": {
11
+ "displayName": "CawCut",
12
+ "cliName": "cawcut",
13
+ "oauthEndpoint": "cawcut-cli",
14
+ "clientName": "cawcut",
15
+ "credentialsDir": ".cawcut",
16
+ "defaultEnv": "prd",
17
+ "env": {
18
+ "prd": {
19
+ "portalBase": "https://app.cawcut.com",
20
+ "userApiBase": "https://api.cawcut.com/cawcut-user/api/v1",
21
+ "workflowApiBase": "https://api.cawcut.com/cawcut-workflow/api",
22
+ "consentPath": "/skill/auth"
23
+ },
24
+ "proto": {
25
+ "portalBase": "https://app.dev.cawcut.com",
26
+ "userApiBase": "https://api.dev.cawcut.com/cawcut-user/api/v1",
27
+ "workflowApiBase": "https://api.dev.cawcut.com/cawcut-workflow/api",
28
+ "consentPath": "/skill/auth"
29
+ },
30
+ "cell-proto": {
31
+ "portalBase": "https://app.dev1.cawcut.com",
32
+ "userApiBase": "https://api.dev1.cawcut.com/cawcut-user/api/v1",
33
+ "workflowApiBase": "https://api.dev1.cawcut.com/cawcut-workflow/api",
34
+ "consentPath": "/skill/auth"
35
+ },
36
+ "local": {
37
+ "portalBase": "http://localhost:18101",
38
+ "userApiBase": "http://localhost:18081/cawcut-user/api/v1",
39
+ "workflowApiBase": "http://localhost:18080/cawcut-workflow/api",
40
+ "consentPath": "/skill/auth"
41
+ }
42
+ }
43
+ }
44
+ }
45
+ }
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerAppCommand(program: Command): void;
@@ -0,0 +1,156 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { loadConfig } from "../lib/config.js";
3
+ import { formatAppInputSchemaLines, formatAppInputsTable, parseAppInputSlots, resolveAppInputs, } from "../lib/app-inputs.js";
4
+ import { appIdFromToolName, developerRunApp, findDeveloperAppTool, isAppToolName, listDeveloperTools, parseInputPairs, } from "../lib/developer.js";
5
+ import { ApiError, TOKEN_EXPIRED_MESSAGE } from "../lib/http.js";
6
+ import { error, success } from "../lib/output.js";
7
+ import { emitAsyncResult } from "../lib/result-output.js";
8
+ import { startSpinner } from "../lib/spinner.js";
9
+ async function loadInputsFromJson(path) {
10
+ const raw = await readFile(path, "utf8");
11
+ const parsed = JSON.parse(raw);
12
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
13
+ throw new Error(`Invalid --input-json "${path}". Expected a JSON object.`);
14
+ }
15
+ return parsed;
16
+ }
17
+ export function registerAppCommand(program) {
18
+ const app = program.command("app").description("Published CawCut Apps");
19
+ app
20
+ .command("list")
21
+ .description("List available apps from Developer API")
22
+ .option("--json", "Output raw JSON response")
23
+ .option("--schema", "Include input_schema details for each app")
24
+ .action(async (options) => {
25
+ const config = loadConfig();
26
+ const spinner = options.json ? undefined : startSpinner("Loading apps…");
27
+ try {
28
+ const tools = await listDeveloperTools(config);
29
+ const apps = tools.filter((tool) => isAppToolName(tool.name));
30
+ spinner?.stop();
31
+ if (options.json) {
32
+ success(JSON.stringify(apps, null, 2));
33
+ return;
34
+ }
35
+ if (apps.length === 0) {
36
+ success("No published apps available.");
37
+ return;
38
+ }
39
+ for (const tool of apps) {
40
+ const appId = appIdFromToolName(tool.name);
41
+ const description = tool.description?.trim() || "(no description)";
42
+ success(`${appId}\t${description}`);
43
+ if (options.schema) {
44
+ const schemaLines = formatAppInputSchemaLines(tool.input_schema);
45
+ for (const line of schemaLines) {
46
+ success(line);
47
+ }
48
+ }
49
+ }
50
+ }
51
+ catch (err) {
52
+ spinner?.stop();
53
+ if (err instanceof ApiError && err.message === TOKEN_EXPIRED_MESSAGE) {
54
+ error(err.message);
55
+ process.exit(1);
56
+ }
57
+ error(err instanceof Error ? err.message : String(err));
58
+ process.exit(1);
59
+ }
60
+ });
61
+ app
62
+ .command("describe")
63
+ .description("Show app inputs (type, key, examples) before running")
64
+ .argument("<app_id>", "App unique ID")
65
+ .option("--json", "Output input_schema as JSON")
66
+ .action(async (appId, options) => {
67
+ const config = loadConfig();
68
+ const spinner = options.json ? undefined : startSpinner("Loading app…");
69
+ try {
70
+ const tool = await findDeveloperAppTool(config, appId);
71
+ spinner?.stop();
72
+ if (!tool) {
73
+ error(`App "${appId}" not found or not accessible.`);
74
+ process.exit(1);
75
+ }
76
+ if (options.json) {
77
+ success(JSON.stringify(tool.input_schema ?? {}, null, 2));
78
+ return;
79
+ }
80
+ const slots = parseAppInputSlots(tool.input_schema);
81
+ success(formatAppInputsTable(appId, tool.description, slots));
82
+ }
83
+ catch (err) {
84
+ spinner?.stop();
85
+ if (err instanceof ApiError && err.message === TOKEN_EXPIRED_MESSAGE) {
86
+ error(err.message);
87
+ process.exit(1);
88
+ }
89
+ error(err instanceof Error ? err.message : String(err));
90
+ process.exit(1);
91
+ }
92
+ });
93
+ app
94
+ .command("run")
95
+ .description("Run a published app")
96
+ .argument("<app_id>", "App unique ID")
97
+ .option("--input <pair...>", "Input as key=value (keys from cawcut app describe; media: URL or @/path)")
98
+ .option("--input-json <file>", "JSON file with inputs object")
99
+ .option("--wait", "Poll until async task completes (when task_id is returned)")
100
+ .option("--download [target]", "Download result file (default: ~/Downloads; use tmp for OS temp dir)")
101
+ .option("--json", "Output raw JSON response")
102
+ .action(async (appId, options) => {
103
+ const config = loadConfig();
104
+ let runSpinner = options.json ? undefined : startSpinner("Loading app…");
105
+ try {
106
+ let rawInputs;
107
+ if (options.inputJson) {
108
+ if (options.input && options.input.length > 0) {
109
+ runSpinner?.stop();
110
+ error("Use either --input or --input-json, not both.");
111
+ process.exit(1);
112
+ }
113
+ rawInputs = await loadInputsFromJson(options.inputJson);
114
+ }
115
+ else {
116
+ rawInputs = parseInputPairs(options.input);
117
+ }
118
+ const tool = await findDeveloperAppTool(config, appId);
119
+ if (!tool) {
120
+ runSpinner?.stop();
121
+ error(`App "${appId}" not found or not accessible.`);
122
+ process.exit(1);
123
+ }
124
+ const inputs = await resolveAppInputs(config, tool.input_schema, rawInputs);
125
+ runSpinner?.update("Sending request…");
126
+ const spinner = runSpinner;
127
+ runSpinner = undefined;
128
+ const result = await developerRunApp(config, appId, inputs);
129
+ const downloadEnabled = options.download !== undefined && options.download !== false;
130
+ const downloadTarget = typeof options.download === "string" ? options.download : undefined;
131
+ await emitAsyncResult(config, result, {
132
+ wait: options.wait,
133
+ download: downloadEnabled ? (downloadTarget ?? true) : undefined,
134
+ json: options.json,
135
+ actionLabel: "App run",
136
+ spinner,
137
+ });
138
+ }
139
+ catch (err) {
140
+ runSpinner?.stop();
141
+ if (err instanceof ApiError) {
142
+ if (err.message === TOKEN_EXPIRED_MESSAGE) {
143
+ error(err.message);
144
+ process.exit(1);
145
+ }
146
+ if (err.status === 404) {
147
+ error(`App "${appId}" not found or not accessible.`);
148
+ process.exit(1);
149
+ }
150
+ }
151
+ error(err instanceof Error ? err.message : String(err));
152
+ process.exit(1);
153
+ }
154
+ });
155
+ }
156
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/commands/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerAuthCommand(program: Command): void;
@@ -0,0 +1,62 @@
1
+ import { loadConfig } from "../lib/config.js";
2
+ import { deleteCredentials, isAccessTokenExpired, readCredentials, writeCredentials, } from "../lib/credentials.js";
3
+ import { OAUTH_DENIED_ERROR, OAUTH_PORT_CONFLICT_ERROR, runOAuthLogin } from "../lib/oauth.js";
4
+ import { error, info, success } from "../lib/output.js";
5
+ import { startSpinner } from "../lib/spinner.js";
6
+ export function registerAuthCommand(program) {
7
+ const auth = program.command("auth").description("OAuth authentication");
8
+ auth
9
+ .command("login")
10
+ .description("Open browser to authorize CawCut CLI access")
11
+ .action(async () => {
12
+ const config = loadConfig();
13
+ info("Opening browser for authorization…");
14
+ const spinner = startSpinner("Waiting for authorization in browser…");
15
+ try {
16
+ const credentials = await runOAuthLogin(config);
17
+ await writeCredentials(config.credentialsPath, credentials);
18
+ spinner.stop("Authentication successful");
19
+ }
20
+ catch (err) {
21
+ const message = err instanceof Error ? err.message : String(err);
22
+ spinner.stop();
23
+ if (message === OAUTH_DENIED_ERROR) {
24
+ error("Authorization denied");
25
+ process.exit(1);
26
+ }
27
+ if (message === OAUTH_PORT_CONFLICT_ERROR) {
28
+ error("Local callback port conflict. Close other apps using localhost ports and retry.");
29
+ process.exit(1);
30
+ }
31
+ error(message);
32
+ process.exit(1);
33
+ }
34
+ });
35
+ auth
36
+ .command("logout")
37
+ .description("Remove stored credentials")
38
+ .action(async () => {
39
+ const config = loadConfig();
40
+ await deleteCredentials(config.credentialsPath);
41
+ success("Logged out");
42
+ });
43
+ auth
44
+ .command("status")
45
+ .description("Show authentication status")
46
+ .action(async () => {
47
+ const config = loadConfig();
48
+ const credentials = await readCredentials(config.credentialsPath);
49
+ if (!credentials) {
50
+ success("Not authenticated. Run `cawcut auth login`.");
51
+ return;
52
+ }
53
+ const expired = isAccessTokenExpired(credentials);
54
+ const expiry = new Date(credentials.expire * 1000).toISOString();
55
+ if (expired) {
56
+ success(`Authenticated as user ${credentials.userId} (access token expired at ${expiry}; refresh on next API call).`);
57
+ return;
58
+ }
59
+ success(`Authenticated as user ${credentials.userId} (token valid until ${expiry}).`);
60
+ });
61
+ }
62
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/commands/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerCapabilitiesCommand(program: Command): void;
@@ -0,0 +1,83 @@
1
+ import { capabilityInputSchema, getCapabilitySpec, getModelSpec, listCatalogCapabilities, } from "../lib/capability-catalog.js";
2
+ import { listCapabilityKeys } from "../lib/capabilities.js";
3
+ import { error, success } from "../lib/output.js";
4
+ function capabilityToolName(key) {
5
+ return `generate_${key}`;
6
+ }
7
+ export function registerCapabilitiesCommand(program) {
8
+ const capabilities = program
9
+ .command("capabilities")
10
+ .description("Official generate capabilities (schema from AI Kit catalog)");
11
+ capabilities
12
+ .command("list")
13
+ .description("List built-in generate capabilities")
14
+ .option("--schema", "Print input_schema from local AI Kit catalog")
15
+ .option("--models", "List supported models per capability")
16
+ .option("--json", "Output raw JSON")
17
+ .action((options) => {
18
+ try {
19
+ const keys = listCapabilityKeys();
20
+ if (options.models) {
21
+ const items = listCatalogCapabilities().map((spec) => ({
22
+ capability: spec.capability,
23
+ defaultModel: spec.defaultModel,
24
+ requiresMedia: spec.requiresMedia,
25
+ configSource: spec.configSource,
26
+ models: spec.models.map((m) => ({
27
+ id: m.id,
28
+ vendor: m.vendorName,
29
+ media: m.media,
30
+ params: m.params.map((p) => p.name),
31
+ })),
32
+ }));
33
+ if (options.json) {
34
+ success(JSON.stringify(items, null, 2));
35
+ return;
36
+ }
37
+ for (const item of items) {
38
+ success(`${item.capability} (default: ${item.defaultModel})`);
39
+ for (const m of item.models) {
40
+ success(` ${m.id}\tparams: ${m.params.join(", ") || "(none)"}`);
41
+ }
42
+ }
43
+ return;
44
+ }
45
+ if (options.schema) {
46
+ const items = keys.map((key) => {
47
+ const spec = getCapabilitySpec(key);
48
+ const model = getModelSpec(spec);
49
+ return {
50
+ capability: key,
51
+ name: capabilityToolName(key),
52
+ configSource: spec.configSource,
53
+ defaultModel: spec.defaultModel,
54
+ input_schema: capabilityInputSchema(spec, model),
55
+ };
56
+ });
57
+ if (options.json) {
58
+ success(JSON.stringify(items, null, 2));
59
+ return;
60
+ }
61
+ for (const item of items) {
62
+ success(`${item.capability} [${item.configSource}]`);
63
+ success(JSON.stringify(item.input_schema, null, 2));
64
+ }
65
+ return;
66
+ }
67
+ if (options.json) {
68
+ success(JSON.stringify(keys, null, 2));
69
+ return;
70
+ }
71
+ for (const key of keys) {
72
+ const spec = getCapabilitySpec(key);
73
+ const media = spec?.requiresMedia ? ` (requires ${spec.requiresMedia})` : "";
74
+ success(`${key}${media}`);
75
+ }
76
+ }
77
+ catch (err) {
78
+ error(err instanceof Error ? err.message : String(err));
79
+ process.exit(1);
80
+ }
81
+ });
82
+ }
83
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/commands/capabilities.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerGenerateCommand(program: Command): void;
@@ -0,0 +1,73 @@
1
+ import { assertCapabilityKey, listCapabilityKeys } from "../lib/capabilities.js";
2
+ import { loadConfig } from "../lib/config.js";
3
+ import { parseParamFlags, runGenerate } from "../lib/generate-request.js";
4
+ import { ApiError, TOKEN_EXPIRED_MESSAGE } from "../lib/http.js";
5
+ import { error } from "../lib/output.js";
6
+ import { emitAsyncResult } from "../lib/result-output.js";
7
+ import { startSpinner } from "../lib/spinner.js";
8
+ function collectParam(value, previous) {
9
+ return previous.concat([value]);
10
+ }
11
+ export function registerGenerateCommand(program) {
12
+ program
13
+ .command("generate")
14
+ .description("Generate AI media via Developer API (BE dynamic graph)")
15
+ .argument("[prompt]", "Generation prompt")
16
+ .requiredOption("--capability <name>", `Capability: ${listCapabilityKeys().join(", ")}`)
17
+ .option("--model <id>", "AI Kit model id (default per capability; see cawcut capabilities list --models)")
18
+ .option("--param <key=value>", "Model parameter (repeatable)", collectParam, [])
19
+ .option("--image <file|url>", "Reference image (repeatable; local path uploads via POST /developer/assets)", collectParam, [])
20
+ .option("--video <file|url>", "Reference video (repeatable)", collectParam, [])
21
+ .option("--audio <file|url>", "Reference audio (repeatable; omni-to-video)", collectParam, [])
22
+ .option("--wait", "Poll until async task completes (when task_id is returned)")
23
+ .option("--download [target]", "Download result file (default: ~/Downloads; use tmp for OS temp dir)")
24
+ .option("--json", "Output raw JSON response")
25
+ .action(async (prompt, options) => {
26
+ const config = loadConfig();
27
+ try {
28
+ assertCapabilityKey(options.capability);
29
+ }
30
+ catch (err) {
31
+ error(err instanceof Error ? err.message : String(err));
32
+ process.exit(1);
33
+ }
34
+ if (!prompt?.trim() && !options.image?.length && !options.video?.length && !options.audio?.length) {
35
+ error("Prompt is required unless media inputs are provided.");
36
+ process.exit(1);
37
+ }
38
+ const downloadEnabled = options.download !== undefined && options.download !== false;
39
+ const downloadArg = downloadEnabled
40
+ ? typeof options.download === "string"
41
+ ? options.download
42
+ : true
43
+ : undefined;
44
+ const spinner = options.json ? undefined : startSpinner("Sending request…");
45
+ try {
46
+ const result = await runGenerate(config, {
47
+ capability: options.capability,
48
+ prompt,
49
+ model: options.model,
50
+ params: parseParamFlags(options.param),
51
+ image: options.image,
52
+ video: options.video,
53
+ audio: options.audio,
54
+ });
55
+ await emitAsyncResult(config, result, {
56
+ wait: options.wait,
57
+ download: downloadArg,
58
+ json: options.json,
59
+ spinner,
60
+ });
61
+ }
62
+ catch (err) {
63
+ spinner?.stop();
64
+ if (err instanceof ApiError && err.message === TOKEN_EXPIRED_MESSAGE) {
65
+ error(err.message);
66
+ process.exit(1);
67
+ }
68
+ error(err instanceof Error ? err.message : String(err));
69
+ process.exit(1);
70
+ }
71
+ });
72
+ }
73
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerSetCommand(program: Command): void;
@@ -0,0 +1,25 @@
1
+ import { getProductDefinition, listProductEnvironments, normalizeEnvName } from "../lib/config.js";
2
+ import { localConfigPath, readLocalConfig, writeLocalConfig } from "../lib/local-config.js";
3
+ import { error, success } from "../lib/output.js";
4
+ export function registerSetCommand(program) {
5
+ const setCmd = program
6
+ .command("set")
7
+ .description("Persist CLI settings to ~/.cawcut/config.json");
8
+ setCmd
9
+ .command("env <environment>")
10
+ .description("Set the active environment (prd, proto, cell-proto, local)")
11
+ .action(async (environment) => {
12
+ const normalized = normalizeEnvName(environment);
13
+ const valid = listProductEnvironments();
14
+ if (!normalized || !valid.includes(normalized)) {
15
+ error(`Unknown environment "${environment}". Valid: ${valid.join(", ")}`);
16
+ process.exit(1);
17
+ }
18
+ const product = getProductDefinition();
19
+ const path = localConfigPath(product.credentialsDir);
20
+ const existing = await readLocalConfig(path);
21
+ await writeLocalConfig(path, { ...existing, env: normalized });
22
+ success(`Active environment set to "${normalized}" (saved to ${path})`);
23
+ });
24
+ }
25
+ //# sourceMappingURL=set.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set.js","sourceRoot":"","sources":["../../src/commands/set.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACnG,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC5F,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,MAAM,GAAG,OAAO;SACnB,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,+CAA+C,CAAC,CAAC;IAEhE,MAAM;SACH,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,4DAA4D,CAAC;SACzE,MAAM,CAAC,KAAK,EAAE,WAAmB,EAAE,EAAE;QACpC,MAAM,UAAU,GAAG,gBAAgB,CAAC,WAAW,CAAC,CAAC;QACjD,MAAM,KAAK,GAAG,uBAAuB,EAAE,CAAC;QACxC,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YAC/C,KAAK,CAAC,wBAAwB,WAAW,aAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,eAAe,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACrD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QAC7C,MAAM,gBAAgB,CAAC,IAAI,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,8BAA8B,UAAU,eAAe,IAAI,GAAG,CAAC,CAAC;IAC1E,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerTaskCommand(program: Command): void;
@@ -0,0 +1,48 @@
1
+ import { loadConfig } from "../lib/config.js";
2
+ import { developerGetTask } from "../lib/developer.js";
3
+ import { ApiError, TOKEN_EXPIRED_MESSAGE } from "../lib/http.js";
4
+ import { pollUntilTerminal } from "../lib/poll.js";
5
+ import { error, success } from "../lib/output.js";
6
+ function formatTaskStatus(taskId, status) {
7
+ if (status.status === "done" && status.result_url) {
8
+ return status.result_url;
9
+ }
10
+ if (status.status === "failed") {
11
+ return status.error?.trim() || `Task ${taskId} failed.`;
12
+ }
13
+ return JSON.stringify({ task_id: taskId, ...status }, null, 2);
14
+ }
15
+ export function registerTaskCommand(program) {
16
+ const task = program.command("task").description("Async generation tasks");
17
+ task
18
+ .command("status")
19
+ .description("Get task status by ID")
20
+ .argument("<task_id>", "Task or execution ID")
21
+ .option("--wait", "Poll until terminal status")
22
+ .option("--json", "Output raw JSON response")
23
+ .action(async (taskId, options) => {
24
+ const config = loadConfig();
25
+ try {
26
+ const fetchStatus = () => developerGetTask(config, taskId);
27
+ const status = options.wait ? await pollUntilTerminal(fetchStatus) : await fetchStatus();
28
+ if (options.json) {
29
+ success(JSON.stringify(status, null, 2));
30
+ return;
31
+ }
32
+ if (status.status === "failed") {
33
+ error(formatTaskStatus(taskId, status));
34
+ process.exit(1);
35
+ }
36
+ success(formatTaskStatus(taskId, status));
37
+ }
38
+ catch (err) {
39
+ if (err instanceof ApiError && err.message === TOKEN_EXPIRED_MESSAGE) {
40
+ error(err.message);
41
+ process.exit(1);
42
+ }
43
+ error(err instanceof Error ? err.message : String(err));
44
+ process.exit(1);
45
+ }
46
+ });
47
+ }
48
+ //# sourceMappingURL=task.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task.js","sourceRoot":"","sources":["../../src/commands/task.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElD,SAAS,gBAAgB,CAAC,MAAc,EAAE,MAAoD;IAC5F,IAAI,MAAM,CAAC,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO,MAAM,CAAC,UAAU,CAAC;IAC3B,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,QAAQ,MAAM,UAAU,CAAC;IAC1D,CAAC;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,wBAAwB,CAAC,CAAC;IAE3E,IAAI;SACD,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,uBAAuB,CAAC;SACpC,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;SAC7C,MAAM,CAAC,QAAQ,EAAE,4BAA4B,CAAC;SAC9C,MAAM,CAAC,QAAQ,EAAE,0BAA0B,CAAC;SAC5C,MAAM,CAAC,KAAK,EAAE,MAAc,EAAE,OAA2C,EAAE,EAAE;QAC5E,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAE5B,IAAI,CAAC;YACH,MAAM,WAAW,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,MAAM,WAAW,EAAE,CAAC;YAEzF,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBACjB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;gBACzC,OAAO;YACT,CAAC;YAED,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC/B,KAAK,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;gBACxC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YAED,OAAO,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QAC5C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,QAAQ,IAAI,GAAG,CAAC,OAAO,KAAK,qBAAqB,EAAE,CAAC;gBACrE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;YACD,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;YACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import { registerAuthCommand } from "./commands/auth.js";
4
+ import { registerCapabilitiesCommand } from "./commands/capabilities.js";
5
+ import { registerGenerateCommand } from "./commands/generate.js";
6
+ import { registerAppCommand } from "./commands/app.js";
7
+ import { registerTaskCommand } from "./commands/task.js";
8
+ import { registerSetCommand } from "./commands/set.js";
9
+ const program = new Command();
10
+ program
11
+ .name("cawcut")
12
+ .description("CawCut developer CLI")
13
+ .version("0.1.0");
14
+ registerAuthCommand(program);
15
+ registerCapabilitiesCommand(program);
16
+ registerGenerateCommand(program);
17
+ registerAppCommand(program);
18
+ registerTaskCommand(program);
19
+ registerSetCommand(program);
20
+ program.parse();
21
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,4BAA4B,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,QAAQ,CAAC;KACd,WAAW,CAAC,sBAAsB,CAAC;KACnC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,2BAA2B,CAAC,OAAO,CAAC,CAAC;AACrC,uBAAuB,CAAC,OAAO,CAAC,CAAC;AACjC,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAC5B,mBAAmB,CAAC,OAAO,CAAC,CAAC;AAC7B,kBAAkB,CAAC,OAAO,CAAC,CAAC;AAE5B,OAAO,CAAC,KAAK,EAAE,CAAC"}