@clickraft/cli 0.4.0 → 0.5.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.
- package/CHANGELOG.md +2 -3
- package/README.md +3 -0
- package/dist/cli.js +250 -36
- package/dist/cli.js.map +1 -1
- package/dist/index.js +250 -36
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
## [0.
|
|
1
|
+
## [0.5.0](https://github.com/clickraft/cli/compare/v0.4.0...v0.5.0) (2026-05-24)
|
|
2
2
|
|
|
3
3
|
### Features
|
|
4
4
|
|
|
5
|
-
* **
|
|
6
|
-
* **generate:** make --brand-model repeatable with pose support ([872209c](https://github.com/clickraft/cli/commit/872209cfab22f7cd31e2a7655fa072c437a78351))
|
|
5
|
+
* **models:** add models list command consuming agents/v1/models ([83761d1](https://github.com/clickraft/cli/commit/83761d11d136758e23c40cf80cd87c8f08dbaad6))
|
|
7
6
|
|
|
8
7
|
# Changelog
|
|
9
8
|
|
package/README.md
CHANGED
|
@@ -19,6 +19,8 @@ clickraft login
|
|
|
19
19
|
clickraft generate create --prompt "a serene mountain landscape at dawn"
|
|
20
20
|
clickraft balance
|
|
21
21
|
clickraft brand-model list
|
|
22
|
+
clickraft models list
|
|
23
|
+
clickraft models list --category image --tier pro
|
|
22
24
|
clickraft template list
|
|
23
25
|
clickraft template get <template-id>
|
|
24
26
|
clickraft template find "coffee brand"
|
|
@@ -56,6 +58,7 @@ export CLOUDFLARE_ACCESS_CLIENT_SECRET="<client-secret>"
|
|
|
56
58
|
clickraft tokens list --profile staging
|
|
57
59
|
clickraft balance --profile staging
|
|
58
60
|
clickraft brand-model list --profile staging
|
|
61
|
+
clickraft models list --profile staging
|
|
59
62
|
```
|
|
60
63
|
|
|
61
64
|
Both env vars must be set together — if only one is set the CLI exits with a configuration error. Production usage (the default) does not require these env vars.
|
package/dist/cli.js
CHANGED
|
@@ -2441,6 +2441,77 @@ function formatRevokeFailure(err, token) {
|
|
|
2441
2441
|
return `warning: server-side revoke failed (${reason}). Local profile removed; token ${redactTokenLikeValue(token)} remains server-valid until expiry.`;
|
|
2442
2442
|
}
|
|
2443
2443
|
|
|
2444
|
+
// src/schemas/models.ts
|
|
2445
|
+
import { z as z8 } from "zod";
|
|
2446
|
+
var ModelSummarySchema = z8.object({
|
|
2447
|
+
id: z8.string().uuid(),
|
|
2448
|
+
slug: z8.string(),
|
|
2449
|
+
displayName: z8.string(),
|
|
2450
|
+
description: z8.string().nullable(),
|
|
2451
|
+
shortDescription: z8.string().nullable(),
|
|
2452
|
+
providerSlug: z8.string(),
|
|
2453
|
+
providerName: z8.string(),
|
|
2454
|
+
modelType: z8.string(),
|
|
2455
|
+
category: z8.string(),
|
|
2456
|
+
costTier: z8.string(),
|
|
2457
|
+
creditCost: z8.number(),
|
|
2458
|
+
pricingStrategy: z8.string(),
|
|
2459
|
+
estimatedSeconds: z8.object({
|
|
2460
|
+
typical: z8.number(),
|
|
2461
|
+
range: z8.array(z8.number())
|
|
2462
|
+
}).passthrough().nullable(),
|
|
2463
|
+
status: z8.string(),
|
|
2464
|
+
modalities: z8.object({
|
|
2465
|
+
input: z8.array(z8.string()),
|
|
2466
|
+
output: z8.array(z8.string())
|
|
2467
|
+
}).passthrough().nullable(),
|
|
2468
|
+
bestFor: z8.array(z8.string()),
|
|
2469
|
+
badges: z8.array(z8.string()),
|
|
2470
|
+
isFeatured: z8.boolean(),
|
|
2471
|
+
isDefault: z8.boolean(),
|
|
2472
|
+
docsUrl: z8.string().nullable(),
|
|
2473
|
+
llmContext: z8.string().nullable(),
|
|
2474
|
+
constraints: z8.record(z8.unknown()).nullable(),
|
|
2475
|
+
modelFamily: z8.string().nullable(),
|
|
2476
|
+
isFamilyPrimary: z8.boolean().nullable()
|
|
2477
|
+
}).strict();
|
|
2478
|
+
var ModelsListResponseSchema = z8.object({
|
|
2479
|
+
models: z8.array(ModelSummarySchema)
|
|
2480
|
+
}).strict();
|
|
2481
|
+
|
|
2482
|
+
// src/commands/models/internal.ts
|
|
2483
|
+
async function buildModelClient(opts) {
|
|
2484
|
+
const cfg = await loadConfig({
|
|
2485
|
+
flagProfile: opts.profile,
|
|
2486
|
+
flagApiBaseUrl: opts.apiBaseUrl,
|
|
2487
|
+
flagToken: opts.token
|
|
2488
|
+
});
|
|
2489
|
+
return new ApiClient({
|
|
2490
|
+
apiBaseUrl: cfg.apiBaseUrl,
|
|
2491
|
+
accessToken: cfg.accessToken,
|
|
2492
|
+
signal: opts.signal,
|
|
2493
|
+
cloudflareAccess: cfg.cloudflareAccess
|
|
2494
|
+
});
|
|
2495
|
+
}
|
|
2496
|
+
|
|
2497
|
+
// src/commands/models/list.ts
|
|
2498
|
+
async function listModels(opts) {
|
|
2499
|
+
const client = opts.client ?? await buildModelClient(opts);
|
|
2500
|
+
const data = await client.request({
|
|
2501
|
+
method: "GET",
|
|
2502
|
+
path: "/models",
|
|
2503
|
+
query: {
|
|
2504
|
+
category: opts.category,
|
|
2505
|
+
tier: opts.tier,
|
|
2506
|
+
type: opts.type,
|
|
2507
|
+
featured: opts.featured !== void 0 ? String(opts.featured) : void 0
|
|
2508
|
+
},
|
|
2509
|
+
responseSchema: ModelsListResponseSchema,
|
|
2510
|
+
signal: opts.signal
|
|
2511
|
+
});
|
|
2512
|
+
return data;
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2444
2515
|
// src/telemetry/detect.ts
|
|
2445
2516
|
var AGENT_SIGNALS = [
|
|
2446
2517
|
{ envVar: "CLAUDE_CODE_SESSION_ID", agent: "claude-code" },
|
|
@@ -2531,33 +2602,33 @@ async function buildTemplateClient(opts) {
|
|
|
2531
2602
|
}
|
|
2532
2603
|
|
|
2533
2604
|
// src/schemas/templates.ts
|
|
2534
|
-
import { z as
|
|
2535
|
-
var DeclaredParamSchema =
|
|
2536
|
-
name:
|
|
2537
|
-
type:
|
|
2538
|
-
required:
|
|
2539
|
-
defaultValue:
|
|
2540
|
-
enumValues:
|
|
2541
|
-
description:
|
|
2605
|
+
import { z as z9 } from "zod";
|
|
2606
|
+
var DeclaredParamSchema = z9.object({
|
|
2607
|
+
name: z9.string(),
|
|
2608
|
+
type: z9.string(),
|
|
2609
|
+
required: z9.boolean(),
|
|
2610
|
+
defaultValue: z9.string().nullable().optional(),
|
|
2611
|
+
enumValues: z9.array(z9.string()).nullable().optional(),
|
|
2612
|
+
description: z9.string().nullable().optional()
|
|
2542
2613
|
}).strict();
|
|
2543
|
-
var TemplateSummarySchema =
|
|
2544
|
-
id:
|
|
2545
|
-
source:
|
|
2546
|
-
name:
|
|
2547
|
-
description:
|
|
2548
|
-
category:
|
|
2549
|
-
thumbnailUrl:
|
|
2550
|
-
tags:
|
|
2551
|
-
createdAt:
|
|
2614
|
+
var TemplateSummarySchema = z9.object({
|
|
2615
|
+
id: z9.string().uuid(),
|
|
2616
|
+
source: z9.enum(["own", "system"]),
|
|
2617
|
+
name: z9.string(),
|
|
2618
|
+
description: z9.string().nullable(),
|
|
2619
|
+
category: z9.string().nullable(),
|
|
2620
|
+
thumbnailUrl: z9.string().nullable(),
|
|
2621
|
+
tags: z9.array(z9.string()),
|
|
2622
|
+
createdAt: z9.string()
|
|
2552
2623
|
}).strict();
|
|
2553
2624
|
var TemplateDetailSchema = TemplateSummarySchema.extend({
|
|
2554
|
-
declaredParams:
|
|
2555
|
-
timesUsed:
|
|
2625
|
+
declaredParams: z9.array(DeclaredParamSchema),
|
|
2626
|
+
timesUsed: z9.number()
|
|
2556
2627
|
}).strict();
|
|
2557
|
-
var TemplatesListResponseSchema =
|
|
2558
|
-
templates:
|
|
2559
|
-
cursor:
|
|
2560
|
-
hasMore:
|
|
2628
|
+
var TemplatesListResponseSchema = z9.object({
|
|
2629
|
+
templates: z9.array(TemplateSummarySchema),
|
|
2630
|
+
cursor: z9.string().nullable(),
|
|
2631
|
+
hasMore: z9.boolean()
|
|
2561
2632
|
}).strict();
|
|
2562
2633
|
|
|
2563
2634
|
// src/commands/template/list.ts
|
|
@@ -2607,20 +2678,20 @@ async function getTemplate(opts) {
|
|
|
2607
2678
|
}
|
|
2608
2679
|
|
|
2609
2680
|
// src/commands/tokens/list.ts
|
|
2610
|
-
import { z as
|
|
2611
|
-
var TokenRowSchema =
|
|
2612
|
-
id:
|
|
2613
|
-
organizationId:
|
|
2614
|
-
userId:
|
|
2615
|
-
clientId:
|
|
2616
|
-
tokenPrefix:
|
|
2617
|
-
name:
|
|
2618
|
-
scopes:
|
|
2619
|
-
lastUsedAt:
|
|
2620
|
-
expiresAt:
|
|
2621
|
-
createdAt:
|
|
2681
|
+
import { z as z10 } from "zod";
|
|
2682
|
+
var TokenRowSchema = z10.object({
|
|
2683
|
+
id: z10.string().uuid(),
|
|
2684
|
+
organizationId: z10.string().uuid(),
|
|
2685
|
+
userId: z10.string().uuid(),
|
|
2686
|
+
clientId: z10.string().nullable(),
|
|
2687
|
+
tokenPrefix: z10.string(),
|
|
2688
|
+
name: z10.string().nullable(),
|
|
2689
|
+
scopes: z10.array(z10.string()),
|
|
2690
|
+
lastUsedAt: z10.string().nullable(),
|
|
2691
|
+
expiresAt: z10.string(),
|
|
2692
|
+
createdAt: z10.string()
|
|
2622
2693
|
}).strict();
|
|
2623
|
-
var TokensListResponseSchema =
|
|
2694
|
+
var TokensListResponseSchema = z10.array(TokenRowSchema);
|
|
2624
2695
|
async function listTokens(options) {
|
|
2625
2696
|
const config = await loadConfig({
|
|
2626
2697
|
flagProfile: options.profile,
|
|
@@ -2988,6 +3059,72 @@ function renderTemplateDetail(detail, out) {
|
|
|
2988
3059
|
}
|
|
2989
3060
|
out.write(lines.join("\n") + "\n");
|
|
2990
3061
|
}
|
|
3062
|
+
var TIER_ORDER = { premium: 0, pro: 1, standard: 2 };
|
|
3063
|
+
function renderModelsList(result, out, options) {
|
|
3064
|
+
const { models } = result;
|
|
3065
|
+
if (models.length === 0) {
|
|
3066
|
+
out.write("No models match your filters.\n");
|
|
3067
|
+
return;
|
|
3068
|
+
}
|
|
3069
|
+
const sorted = [...models].sort((a, b) => {
|
|
3070
|
+
const catCmp = a.category.localeCompare(b.category);
|
|
3071
|
+
if (catCmp !== 0) return catCmp;
|
|
3072
|
+
const tierA = TIER_ORDER[a.costTier] ?? 99;
|
|
3073
|
+
const tierB = TIER_ORDER[b.costTier] ?? 99;
|
|
3074
|
+
if (tierA !== tierB) return tierA - tierB;
|
|
3075
|
+
return a.slug.localeCompare(b.slug);
|
|
3076
|
+
});
|
|
3077
|
+
const filterParts = [];
|
|
3078
|
+
if (options?.filters) {
|
|
3079
|
+
for (const [k, v] of Object.entries(options.filters)) {
|
|
3080
|
+
if (v) filterParts.push(`${k}=${v}`);
|
|
3081
|
+
}
|
|
3082
|
+
}
|
|
3083
|
+
const filterSuffix = filterParts.length > 0 ? ` (filters: ${filterParts.join(", ")})` : "";
|
|
3084
|
+
out.write(`${sorted.length} models${filterSuffix}
|
|
3085
|
+
|
|
3086
|
+
`);
|
|
3087
|
+
const headers = ["SLUG", "NAME", "CATEGORY", "TIER", "CREDITS", "DEFAULT"];
|
|
3088
|
+
const data = sorted.map((m) => [
|
|
3089
|
+
m.slug,
|
|
3090
|
+
m.displayName,
|
|
3091
|
+
m.category,
|
|
3092
|
+
m.costTier,
|
|
3093
|
+
String(m.creditCost),
|
|
3094
|
+
m.isDefault ? "\u2713" : ""
|
|
3095
|
+
]);
|
|
3096
|
+
const widths = headers.map(
|
|
3097
|
+
(header, i) => Math.max(header.length, ...data.map((cells) => cells[i].length))
|
|
3098
|
+
);
|
|
3099
|
+
const padRow = (cells) => cells.map((cell, i) => cell.padEnd(widths[i])).join(" ").trimEnd();
|
|
3100
|
+
out.write(padRow(headers) + "\n");
|
|
3101
|
+
for (const cells of data) out.write(padRow(cells) + "\n");
|
|
3102
|
+
out.write(
|
|
3103
|
+
`
|
|
3104
|
+
Showing all ${sorted.length} models. Use --json for full details including constraints.
|
|
3105
|
+
`
|
|
3106
|
+
);
|
|
3107
|
+
if (options?.verbose) {
|
|
3108
|
+
out.write("\n");
|
|
3109
|
+
for (const m of sorted) {
|
|
3110
|
+
const pad = 16;
|
|
3111
|
+
out.write(`${m.slug} (${m.displayName})
|
|
3112
|
+
`);
|
|
3113
|
+
out.write(`${" Provider:".padEnd(pad)}${m.providerName}
|
|
3114
|
+
`);
|
|
3115
|
+
out.write(`${" Category:".padEnd(pad)}${m.category} / ${m.modelType}
|
|
3116
|
+
`);
|
|
3117
|
+
out.write(`${" Tier:".padEnd(pad)}${m.costTier} (${m.creditCost} credits)
|
|
3118
|
+
`);
|
|
3119
|
+
if (m.llmContext) {
|
|
3120
|
+
const ctx = m.llmContext.length > 100 ? m.llmContext.slice(0, 100) + "..." : m.llmContext;
|
|
3121
|
+
out.write(`${" Context:".padEnd(pad)}${ctx}
|
|
3122
|
+
`);
|
|
3123
|
+
}
|
|
3124
|
+
out.write("\n");
|
|
3125
|
+
}
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
2991
3128
|
function formatExpiresAt(iso) {
|
|
2992
3129
|
const ms = Date.parse(iso);
|
|
2993
3130
|
if (Number.isNaN(ms)) return iso;
|
|
@@ -3214,6 +3351,7 @@ function renderRootHelp(version) {
|
|
|
3214
3351
|
" tokens list List the caller's API tokens",
|
|
3215
3352
|
" balance Show credit balance and rate limits",
|
|
3216
3353
|
" brand-model list List available brand models",
|
|
3354
|
+
" models list List available AI models",
|
|
3217
3355
|
" telemetry inspect Show current telemetry state and payload shape",
|
|
3218
3356
|
" template list List available templates",
|
|
3219
3357
|
" template get Fetch a template by ID",
|
|
@@ -3293,6 +3431,38 @@ function renderCommandHelp(command) {
|
|
|
3293
3431
|
" --json Emit JSON envelope instead of human output",
|
|
3294
3432
|
""
|
|
3295
3433
|
].join("\n");
|
|
3434
|
+
case "models":
|
|
3435
|
+
return [
|
|
3436
|
+
"Usage: clickraft models <subcommand> [options]",
|
|
3437
|
+
"",
|
|
3438
|
+
"Subcommands:",
|
|
3439
|
+
" list List available AI models",
|
|
3440
|
+
""
|
|
3441
|
+
].join("\n");
|
|
3442
|
+
case "models list":
|
|
3443
|
+
return [
|
|
3444
|
+
"Usage: clickraft models list [options]",
|
|
3445
|
+
"",
|
|
3446
|
+
"List AI models available for generation. By default shows a summary table;",
|
|
3447
|
+
"use --json for full details including constraints and llmContext.",
|
|
3448
|
+
"",
|
|
3449
|
+
"Options:",
|
|
3450
|
+
" --category <name> Filter by category (image, video, audio, chat, edit)",
|
|
3451
|
+
" --tier <name> Filter by cost tier (standard, pro, premium)",
|
|
3452
|
+
" --type <name> Filter by model type (e.g. text-to-image)",
|
|
3453
|
+
" --featured Show only featured models",
|
|
3454
|
+
" --verbose Show expanded per-model details after the table",
|
|
3455
|
+
" --profile <name>",
|
|
3456
|
+
" --api-base-url <url>",
|
|
3457
|
+
" --token <token>",
|
|
3458
|
+
" --json",
|
|
3459
|
+
"",
|
|
3460
|
+
"Examples:",
|
|
3461
|
+
" clickraft models list",
|
|
3462
|
+
" clickraft models list --category image --tier pro",
|
|
3463
|
+
" clickraft models list --featured --json",
|
|
3464
|
+
""
|
|
3465
|
+
].join("\n");
|
|
3296
3466
|
case "telemetry inspect":
|
|
3297
3467
|
return [
|
|
3298
3468
|
"Usage: clickraft telemetry inspect [options]",
|
|
@@ -3488,6 +3658,12 @@ function matchNewCommand(argv) {
|
|
|
3488
3658
|
if (sub === void 0 || sub.startsWith("-")) return { kind: "sub-help", verb: "template" };
|
|
3489
3659
|
return { kind: "unknown-sub", verb: "template", sub };
|
|
3490
3660
|
}
|
|
3661
|
+
if (verb === "models") {
|
|
3662
|
+
const sub = argv[1];
|
|
3663
|
+
if (sub === "list") return { kind: "cmd", path: "models.list", verbTokenCount: 2 };
|
|
3664
|
+
if (sub === void 0 || sub.startsWith("-")) return { kind: "sub-help", verb: "models" };
|
|
3665
|
+
return { kind: "unknown-sub", verb: "models", sub };
|
|
3666
|
+
}
|
|
3491
3667
|
return null;
|
|
3492
3668
|
}
|
|
3493
3669
|
async function runNewCommand(newCmd, options, stdout, stderr) {
|
|
@@ -3544,6 +3720,8 @@ async function runNewCommand(newCmd, options, stdout, stderr) {
|
|
|
3544
3720
|
return await runTemplateGet(argvAfterVerb, ctx, rc);
|
|
3545
3721
|
case "template.find":
|
|
3546
3722
|
return await runTemplateFind(argvAfterVerb, ctx, rc);
|
|
3723
|
+
case "models.list":
|
|
3724
|
+
return await runModelsList(argvAfterVerb, ctx, rc);
|
|
3547
3725
|
}
|
|
3548
3726
|
} catch (err) {
|
|
3549
3727
|
if (isAbortedError(err, options.signal)) {
|
|
@@ -3821,6 +3999,42 @@ function emitTemplateDetail(detail, ctx, rc) {
|
|
|
3821
3999
|
}
|
|
3822
4000
|
renderTemplateDetail(detail, rc.stdout);
|
|
3823
4001
|
}
|
|
4002
|
+
async function runModelsList(argv, ctx, rc) {
|
|
4003
|
+
const parsed = parseArgs(argv, {
|
|
4004
|
+
string: [...COMMON_RICH_STRING_FLAGS, "category", "tier", "type"],
|
|
4005
|
+
boolean: [...COMMON_RICH_BOOL_FLAGS, "featured", "verbose"]
|
|
4006
|
+
});
|
|
4007
|
+
const result = await listModels({
|
|
4008
|
+
category: parsed.string.category,
|
|
4009
|
+
tier: parsed.string.tier,
|
|
4010
|
+
type: parsed.string.type,
|
|
4011
|
+
featured: parsed.boolean.featured,
|
|
4012
|
+
profile: parsed.string.profile,
|
|
4013
|
+
apiBaseUrl: parsed.string["api-base-url"],
|
|
4014
|
+
token: parsed.string.token,
|
|
4015
|
+
signal: rc.signal
|
|
4016
|
+
});
|
|
4017
|
+
emitModelsList(result, ctx, rc, parsed);
|
|
4018
|
+
return 0;
|
|
4019
|
+
}
|
|
4020
|
+
function emitModelsList(result, ctx, rc, parsed) {
|
|
4021
|
+
if (rc.signal?.aborted) {
|
|
4022
|
+
throw new AuthError("AUTH_FLOW_CANCELLED", "Cancelled.");
|
|
4023
|
+
}
|
|
4024
|
+
if (rc.jsonMode) {
|
|
4025
|
+
rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + "\n");
|
|
4026
|
+
return;
|
|
4027
|
+
}
|
|
4028
|
+
renderModelsList(result, rc.stdout, {
|
|
4029
|
+
verbose: parsed.boolean.verbose === true,
|
|
4030
|
+
filters: {
|
|
4031
|
+
category: parsed.string.category ?? "",
|
|
4032
|
+
tier: parsed.string.tier ?? "",
|
|
4033
|
+
type: parsed.string.type ?? "",
|
|
4034
|
+
featured: parsed.boolean.featured !== void 0 ? String(parsed.boolean.featured) : ""
|
|
4035
|
+
}
|
|
4036
|
+
});
|
|
4037
|
+
}
|
|
3824
4038
|
|
|
3825
4039
|
// src/index.ts
|
|
3826
4040
|
var __filename2 = fileURLToPath(import.meta.url);
|