@clickraft/cli 0.14.0 → 0.15.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../../sdk/src/redact.ts","../../sdk/src/contracts/balance.ts","../../sdk/src/contracts/brand-model.ts","../../sdk/src/contracts/product.ts","../../sdk/src/errors/api-error.ts","../../sdk/src/errors/schema-mismatch.ts","../../sdk/src/contracts/tokens.ts","../../sdk/src/contracts/templates.ts","../../sdk/src/contracts/jobs.ts","../../sdk/src/contracts/assets.ts","../../sdk/src/contracts/node-types.ts","../../sdk/src/contracts/workflows.ts","../../sdk/src/errors/codes.ts","../../sdk/src/long-poll.ts","../../sdk/src/http/client.ts","../../sdk/src/http/idempotency.ts","../../sdk/src/http/retry.ts","../../sdk/src/http/types.ts","../../sdk/src/orchestration/workflow-apply.ts","../../sdk/src/orchestration/upload.ts","../../sdk/src/orchestration/create-and-wait.ts","../src/errors/codes.ts","../src/api/client.ts","../src/auth/errors.ts","../src/api/envelope.ts","../src/auth/credentials.ts","../src/config/paths.ts","../src/auth/types.ts","../src/config/loader.ts","../src/commands/balance.ts","../src/commands/brand-model/list.ts","../src/commands/upload.ts","../src/commands/generate/internal.ts","../src/commands/generate/wait.ts","../src/commands/generate/create.ts","../src/commands/generate/get.ts","../src/cli/args.ts","../src/commands/generate/parse-brand-model-spec.ts","../src/commands/generate/parse-product-spec.ts","../src/auth/device-flow.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/schemas/models.ts","../src/commands/models/internal.ts","../src/commands/models/list.ts","../src/commands/nodes/internal.ts","../src/commands/nodes/describe.ts","../src/commands/nodes/list.ts","../src/auth/scopes.ts","../src/commands/product/create.ts","../src/commands/product/list.ts","../src/commands/product/parse-image-spec.ts","../src/telemetry/detect.ts","../src/commands/telemetry/inspect.ts","../src/commands/template/internal.ts","../src/commands/template/list.ts","../src/commands/template/find.ts","../src/commands/template/get.ts","../src/commands/tokens/list.ts","../src/commands/workflow/internal.ts","../src/commands/workflow/apply.ts","../src/commands/workflow/create.ts","../src/commands/workflow/get.ts","../src/commands/workflow/list.ts","../src/errors/format.ts","../src/cli/parse-args.ts","../src/cli/progress.ts","../src/cli/render.ts","../src/cli/dispatch.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { dispatch } from './cli/dispatch.js';\nimport { type ExitCode } from './errors/codes.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8')) as {\n version: string;\n};\n\nexport async function run(args: string[], signal?: AbortSignal): Promise<ExitCode> {\n return dispatch({\n argv: args,\n version: pkg.version,\n signal,\n });\n}\n","// Token-shaped patterns that must never reach stderr or audit logs.\n//\n// `TOKEN_FIELD_PATTERN` targets the JSON-encoded form `\"<field>\":\"<value>\"`\n// so it matches verbatim server response bodies without first parsing them.\n// `BARE_TOKEN_PATTERN` covers tokens inlined in plain text (e.g. a server\n// error message like `token ck_live_xxx rejected`) that the JSON pattern\n// would miss.\nconst TOKEN_FIELD_PATTERN =\n /\"(access_token|refresh_token|device_code|user_code|code_verifier|client_secret)\"\\s*:\\s*\"[^\"]*\"/gi;\nconst BARE_TOKEN_PATTERN = /\\bck_(?:live|dev|test)_[A-Za-z0-9_-]+/gi;\n\nexport function redactTokenLikeFields(input: string): string {\n return input\n .replace(TOKEN_FIELD_PATTERN, '\"$1\":\"[REDACTED]\"')\n .replace(BARE_TOKEN_PATTERN, '[REDACTED]');\n}\n\nexport function redactTokenLikeValue(token: string | undefined): string {\n if (!token) return '<empty>';\n if (token.length <= 12) return '[REDACTED]';\n return `${token.slice(0, 8)}...[REDACTED]`;\n}\n","import { z } from 'zod';\n\nexport const BalanceResponseSchema = z\n .object({\n totalCredits: z.number(),\n subscriptionCredits: z.number(),\n purchasedCredits: z.number(),\n promotionalCredits: z.number(),\n rateLimit: z\n .object({\n apiBurstPerMinute: z.number(),\n })\n .strict(),\n })\n .strict();\n\nexport type BalanceData = z.infer<typeof BalanceResponseSchema>;\n","import { z } from 'zod';\n\nexport const BrandModelSummarySchema = z\n .object({\n id: z.string().uuid(),\n source: z.enum(['system', 'user']),\n slug: z.string().nullable(),\n name: z.string(),\n description: z.string().nullable(),\n thumbnailUrl: z.string().nullable(),\n tags: z.array(z.string()),\n category: z.string().nullable(),\n isPremium: z.boolean().nullable(),\n isFeatured: z.boolean().nullable(),\n badgeText: z.string().nullable(),\n usageCount: z.number().nullable(),\n createdAt: z.string(),\n })\n .strict();\n\nexport const BrandModelsListResponseSchema = z\n .object({\n brandModels: z.array(BrandModelSummarySchema),\n })\n .strict();\n\nexport type BrandModelSummary = z.infer<typeof BrandModelSummarySchema>;\n","import { z } from 'zod';\n\nimport { ApiError } from '../errors/api-error.js';\nimport { formatSchemaIssues } from '../errors/schema-mismatch.js';\n\n/**\n * RFC 9562 UUID. The source of truth is the vendored golden's published\n * `pattern` for `\"format\": \"uuid\"` fields, NOT Zod's built-in `.uuid()`.\n *\n * This package is on Zod 3 and the server validates with Zod 4. Zod 3's\n * `.uuid()` constrains neither the version nibble nor the variant nibble, so it\n * accepts ids the server rejects — `...-0794-...` and `...-c543-...` both pass\n * here and 400 on the wire. That turns a local, well-worded failure into a\n * round trip and defeats the point of mirroring the schema at all.\n *\n * Kept as a literal rather than read from the golden at runtime: the golden is\n * ~38 KB and this package is bundled (tsup `noExternal`) into both the CLI and\n * the MCP server, so importing it would ship 38 KB twice to compile one regex.\n * The literal is PINNED BY TEST instead (`product.test.ts`, \"UUID_RE matches the\n * golden\"), which reads the golden offline exactly as `contract-checker.test.ts`\n * does. The nightly refresh updates the golden; CI then fails here. Checked,\n * not copied.\n *\n * No flags. The character classes are explicit about case, and adding `i` would\n * widen the pattern without changing `.source`, which would defeat the pin.\n */\nexport const UUID_RE =\n /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;\n\n/** A UUID string field validated against {@link UUID_RE}, not Zod's `.uuid()`. */\nexport const uuidString = (): z.ZodString => z.string().regex(UUID_RE, 'Must be a UUID.');\n\nexport const ProductImageSummarySchema = z.object({\n id: z.string().uuid(),\n url: z.string(),\n altText: z.string().nullable(),\n isPrimary: z.boolean(),\n sortOrder: z.number().int(),\n});\n\nexport const ProductSummarySchema = z.object({\n id: z.string().uuid(),\n title: z.string(),\n sourceType: z.string(),\n syncStatus: z.enum(['synced', 'pending', 'stale', 'error', 'deleted_upstream']).nullable(),\n vendor: z.string().nullable(),\n productType: z.string().nullable(),\n tags: z.array(z.string()),\n images: z.array(ProductImageSummarySchema),\n});\n\nexport const ProductsListResponseSchema = z.object({\n items: z.array(ProductSummarySchema),\n nextCursor: z.string().nullable(),\n});\n\nexport type ProductImageSummary = z.infer<typeof ProductImageSummarySchema>;\nexport type ProductSummary = z.infer<typeof ProductSummarySchema>;\n\n// ─── POST /api/agents/v1/products ────────────────────────────────────────────\n//\n// Mirrors `lib/agents/schemas/products.ts` in the app repo, including `.strict()`.\n// The response side needs nothing new: the HTTP client unwraps the `{ data }`\n// envelope, so `responseSchema` is `ProductSummarySchema` above.\n\n/** Per-request image cap. Shared by the schema, both callers and their tests. */\nexport const MAX_PRODUCT_IMAGES = 10;\n\n/**\n * Request-body cap. The server enforces this by READING the stream, not by\n * trusting Content-Length, so the client must measure the same thing: UTF-8\n * bytes of the exact JSON it will send.\n */\nexport const MAX_PRODUCT_CREATE_BODY_BYTES = 32 * 1024;\n\nexport const ProductCreateImageSchema = z\n .object({\n /**\n * An image `library_items.id`. Uploads via `POST /assets` are one source;\n * rows of kind 'generation' are equally admissible.\n */\n assetId: uuidString(),\n altText: z.string().trim().max(500).optional(),\n isPrimary: z.boolean().optional(),\n })\n .strict();\n\n/**\n * `.strict()` IS the guardrail, not a style choice. `variants`, `sourceType`,\n * `integrationId`, `status`, `tags` and `sku` are absent from this schema, so\n * sending any of them is a rejection rather than a silent drop — matching the\n * server, which answers 400 for exactly that reason.\n *\n * `sortOrder` is not on the wire either: it is the array index.\n */\nexport const ProductCreateRequestSchema = z\n .object({\n name: z.string().trim().min(1).max(200),\n description: z.string().trim().max(5000).optional(),\n images: z.array(ProductCreateImageSchema).min(1).max(MAX_PRODUCT_IMAGES),\n })\n .strict()\n .superRefine((v, ctx) => {\n if (v.images.filter((i) => i.isPrimary).length > 1) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['images'],\n message: 'At most one image may be marked isPrimary.',\n });\n }\n });\n\nexport type ProductCreateImage = z.infer<typeof ProductCreateImageSchema>;\nexport type ProductCreateRequest = z.infer<typeof ProductCreateRequestSchema>;\n\n/**\n * The one owner of client-side product-create validation.\n *\n * Both the CLI command and the MCP tool call this, so the two surfaces cannot\n * drift on which payloads they reject locally. Returns the normalized request,\n * ready to hand straight to `client.request({ body })`.\n *\n * Three checks the schema alone cannot express:\n * - duplicate `assetId`, which the server answers with\n * PRODUCT_IMAGE_ASSET_DUPLICATE. Caught here so it costs no round trip.\n * - the 32 KiB body cap, measured in UTF-8 BYTES of the serialized body. A\n * description of multibyte characters can sit under the cap by `.length`\n * and over it on the wire, so `.length` would let exactly the interesting\n * case through.\n * - at-most-one-`isPrimary`, which lives in the schema's superRefine above\n * but is only reachable through this function on the MCP path.\n *\n * Throws ApiError('INPUT_INVALID_FORMAT'), never a raw ZodError, so both\n * surfaces get their existing formatting: the CLI maps it to exit 2 and the MCP\n * tool renders it through `toToolError`.\n */\nexport function parseProductCreateRequest(input: unknown): ProductCreateRequest {\n const parsed = ProductCreateRequestSchema.safeParse(input);\n if (!parsed.success) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Invalid product create request: ${formatSchemaIssues(parsed.error)}`,\n // `issues` is an array of { path, code, message }, which is the shape the\n // MCP server's summarizeValidationDetails recognizes and renders.\n { retryable: false, details: parsed.error.issues },\n );\n }\n\n const request = parsed.data;\n\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const img of request.images) {\n if (seen.has(img.assetId)) duplicates.add(img.assetId);\n seen.add(img.assetId);\n }\n if (duplicates.size > 0) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `The same assetId appears more than once in images: ${[...duplicates].join(', ')}.`,\n { retryable: false },\n );\n }\n\n // Measured on the SAME string the client will send: `client.request` does\n // `JSON.stringify(body)` on this exact object, so the two cannot disagree.\n const bytes = Buffer.byteLength(JSON.stringify(request), 'utf8');\n if (bytes > MAX_PRODUCT_CREATE_BODY_BYTES) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Request body is ${bytes} bytes; the endpoint caps at ${MAX_PRODUCT_CREATE_BODY_BYTES}.`,\n { retryable: false },\n );\n }\n\n return request;\n}\n","// The error type the Clickraft HTTP client raises for every non-success path:\n// server-returned errors, network failures, parse/schema mismatches, and\n// aborts/timeouts. `code` is narrowed to `ApiErrorCode` (Server | Client) — the\n// CLI's auth/credential codes are surfaced via AuthError/CredentialsError and\n// are never carried by ApiError.\n\nimport type { ApiErrorCode } from './codes.js';\n\nexport interface ApiErrorMeta {\n status?: number;\n requestId?: string;\n retryable: boolean;\n retryAfterMs?: number;\n redactedBody?: string;\n details?: unknown;\n hint?: string;\n}\n\nexport class ApiError extends Error {\n public readonly code: ApiErrorCode;\n public readonly meta: ApiErrorMeta;\n public override readonly cause?: unknown;\n\n constructor(code: ApiErrorCode, message: string, meta: ApiErrorMeta, cause?: unknown) {\n super(message);\n this.name = 'ApiError';\n this.code = code;\n this.meta = meta;\n this.cause = cause;\n }\n}\n","// Formats a Zod validation failure into a one-line, human-readable summary\n// suitable for inclusion in the E_SCHEMA_MISMATCH error message. The summary\n// names the offending path(s), the zod issue code, and (when available) the\n// expected vs received types — enough to diagnose drift without having to\n// re-run with --debug or inspect the raw response.\n\nimport type { ZodError, ZodIssue } from 'zod';\n\nconst MAX_ISSUES = 5;\n\nexport function formatSchemaIssues(error: ZodError): string {\n const issues = error.issues;\n const shown = issues.slice(0, MAX_ISSUES).map(formatIssue);\n const remaining = issues.length - shown.length;\n const joined = shown.join('; ');\n return remaining > 0 ? `${joined} (+${remaining} more)` : joined;\n}\n\nfunction formatIssue(issue: ZodIssue): string {\n const path = formatPath(issue.path);\n if (issue.code === 'invalid_type') {\n return `${path}: ${issue.code} (expected ${issue.expected}, received ${issue.received})`;\n }\n if (issue.code === 'invalid_string') {\n const validation =\n typeof issue.validation === 'string'\n ? issue.validation\n : (Object.keys(issue.validation)[0] ?? 'string');\n return `${path}: ${issue.code} (${validation})`;\n }\n return `${path}: ${issue.code}`;\n}\n\nfunction formatPath(path: ReadonlyArray<string | number>): string {\n if (path.length === 0) return '(root)';\n return path.map(String).join('.');\n}\n","import { z } from 'zod';\n\nexport const TokenRowSchema = z\n .object({\n id: z.string().uuid(),\n organizationId: z.string().uuid(),\n userId: z.string().uuid(),\n clientId: z.string().nullable(),\n tokenPrefix: z.string(),\n name: z.string().nullable(),\n scopes: z.array(z.string()),\n lastUsedAt: z.string().nullable(),\n expiresAt: z.string(),\n createdAt: z.string(),\n })\n .strict();\n\nexport const TokensListResponseSchema = z.array(TokenRowSchema);\n\nexport type TokenRow = z.infer<typeof TokenRowSchema>;\n","import { z } from 'zod';\n\nexport const DeclaredParamSchema = z\n .object({\n name: z.string(),\n type: z.string(),\n required: z.boolean().optional(),\n defaultValue: z.unknown().optional(),\n enumValues: z.array(z.string()).nullable().optional(),\n description: z.string().nullable().optional(),\n })\n .strict();\n\nexport const TemplateSummarySchema = z\n .object({\n id: z.string().uuid(),\n source: z.enum(['own', 'system']),\n name: z.string(),\n description: z.string().nullable(),\n category: z.string().nullable(),\n thumbnailUrl: z.string().nullable(),\n tags: z.array(z.string()),\n createdAt: z.string(),\n })\n .strict();\n\nexport const TemplateDetailSchema = TemplateSummarySchema.extend({\n declaredParams: z.array(DeclaredParamSchema),\n timesUsed: z.number(),\n}).strict();\n\nexport const TemplatesListResponseSchema = z\n .object({\n templates: z.array(TemplateSummarySchema),\n cursor: z.string().nullable(),\n hasMore: z.boolean(),\n })\n .strict();\n\nexport type DeclaredParam = z.infer<typeof DeclaredParamSchema>;\nexport type TemplateSummary = z.infer<typeof TemplateSummarySchema>;\nexport type TemplateDetail = z.infer<typeof TemplateDetailSchema>;\nexport type TemplatesListResponse = z.infer<typeof TemplatesListResponseSchema>;\n","// Zod schemas for the generation-job endpoints documented in\n// `docs-internal/agents/01-day1-rfc/01-tool-surface.md` §4.3 (generate create)\n// and §4.4 (generate wait/get).\n//\n// Object schemas are .strict() so unexpected fields surface as SCHEMA_MISMATCH\n// during development rather than silently passing through.\n//\n// §4.3 reference images: the canonical wire shape for `referenceImages` is the\n// object array `{ url, label? }[]`. The server still tolerates legacy bare\n// strings and canonicalizes them to `{ url }`, but this contract emits/accepts\n// objects only. `referenceImageUrl` (the single-image field) remains a bare\n// string on both server and client.\n\nimport { z } from 'zod';\n\n// §4.3 — POST /api/agents/v1/jobs\nconst ProductReferenceSchema = z\n .object({\n id: z.string().uuid(),\n imageId: z.string().uuid().optional(),\n })\n .strict();\n\n// Canonical per-reference shape. `label` mirrors the server's optional caption\n// (max 80 chars); it is part of the contract but not yet exposed as CLI/MCP input.\nconst ReferenceImageSchema = z\n .object({\n url: z.string().url(),\n label: z.string().max(80).optional(),\n })\n .strict();\n\nexport type ReferenceImage = z.infer<typeof ReferenceImageSchema>;\n\nexport const GenerateCreateRequestSchema = z\n .object({\n modelSlug: z.string().min(1).max(100),\n input: z\n .object({\n prompt: z.string().max(10000).optional(),\n referenceImageUrl: z.string().url().optional(),\n referenceImages: z.array(ReferenceImageSchema).max(8).optional(),\n aspectRatio: z\n .string()\n .regex(/^\\d+:\\d+$/)\n .optional(),\n resolution: z\n .string()\n .regex(\n /^(\\d+x\\d+|\\d{2,4}p|\\d+[Kk])$/,\n 'resolution must match WxH (e.g. 1280x720), p-token (e.g. 720p), or K-token (e.g. 1K)',\n )\n .optional(),\n durationSeconds: z.number().int().min(1).max(60).optional(),\n // The model's quality tier (e.g. 'low' | 'medium' | 'high'). The valid set is\n // per model, so it is checked server-side: an unoffered value returns 400\n // INPUT_INVALID_FORMAT with the supported options in `details.allowed`.\n quality: z.string().min(1).max(40).optional(),\n width: z.number().int().min(64).max(8192).optional(),\n height: z.number().int().min(64).max(8192).optional(),\n providerParams: z.record(z.string(), z.unknown()).optional(),\n })\n .strict(),\n options: z\n .object({\n workflowId: z.string().uuid().optional(),\n nodeId: z.string().optional(),\n })\n .strict()\n .optional(),\n products: z.array(ProductReferenceSchema).min(1).max(10).optional(),\n })\n .strict();\n\nexport type GenerateCreateRequest = z.infer<typeof GenerateCreateRequestSchema>;\n\n// §4.3 — create response (4 states; no `uploading` or `cancelled` at create time)\nexport const GenerateCreateResponseSchema = z\n .object({\n jobId: z.string().uuid(),\n status: z.enum(['queued', 'processing', 'completed', 'failed']),\n estimatedSeconds: z.number().int().nonnegative().nullable(),\n creditsCharged: z.number().int().nonnegative(),\n })\n .strict();\n\nexport type GenerateCreateResponse = z.infer<typeof GenerateCreateResponseSchema>;\n\n// §4.4 — GET /api/agents/v1/jobs/:id?wait=0-30\n//\n// The full result schema returned by `generate wait` / `generate get`. `wait`\n// accepts 0–30 seconds; 0 means no long-poll, N means the server holds the\n// request up to N seconds before responding with the latest state.\nexport const GenerationStatusSchema = z.enum([\n 'queued',\n 'processing',\n 'uploading',\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\nexport type GenerationStatus = z.infer<typeof GenerationStatusSchema>;\n\nexport const TERMINAL_STATUSES: ReadonlySet<GenerationStatus> = new Set<GenerationStatus>([\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\nexport function isTerminalStatus(status: GenerationStatus): boolean {\n return TERMINAL_STATUSES.has(status);\n}\n\nexport const GenerationResultSchema = z\n .object({\n jobId: z.string().uuid(),\n status: GenerationStatusSchema,\n modelSlug: z.string(),\n resultUrl: z.string().url().nullable(),\n thumbnailUrl: z.string().url().nullable(),\n errorCode: z.string().nullable(),\n errorMessage: z.string().nullable(),\n creditsCharged: z.number().int().nonnegative(),\n creditsRefunded: z.boolean(),\n startedAt: z.string().nullable(),\n completedAt: z.string().nullable(),\n })\n .strict();\n\nexport type GenerationResult = z.infer<typeof GenerationResultSchema>;\n","// Zod schemas for the upload endpoint documented in\n// `docs-internal/agents/01-day1-rfc/01-tool-surface.md` §4.6.\n//\n// The endpoint is two-step: the client POSTs file metadata + a sha256\n// content hash, the server returns a 5-minute signed GCS upload URL, and the\n// client PUTs the bytes to that URL. §7.1 #2 covers partial-upload retry:\n// the client retries with the same contentHash and the server either signals\n// `deduplicated: true` (bytes already landed) or issues a fresh signed URL.\n\nimport { z } from 'zod';\n\nexport const MAX_UPLOAD_SIZE_BYTES = 15 * 1024 * 1024;\n\nexport const UploadRequestSchema = z\n .object({\n filename: z.string().min(1).max(255),\n contentType: z.string().regex(/^[\\w-]+\\/[\\w+.-]+$/),\n sizeBytes: z.number().int().positive().max(MAX_UPLOAD_SIZE_BYTES),\n contentHash: z.string().regex(/^sha256:[0-9a-f]{64}$/),\n })\n .strict();\n\nexport type UploadRequest = z.infer<typeof UploadRequestSchema>;\n\nexport const UploadResponseSchema = z\n .object({\n assetId: z.string().uuid(),\n // `z.string()` (not `.url()`): the server emits `uploadUrl: ''` on the\n // dedup branch (`deduplicated: true`) — see server `assets.ts` comment.\n uploadUrl: z.string(),\n publicUrl: z.string().url(),\n deduplicated: z.boolean(),\n })\n .strict();\n\nexport type UploadResponse = z.infer<typeof UploadResponseSchema>;\n","import { z } from 'zod';\n\nexport const NodeTypeSummarySchema = z\n .object({\n type: z.string(),\n portCount: z.number(),\n })\n .strict();\n\nexport const NodeTypePortSchema = z\n .object({\n handleId: z.string(),\n direction: z.enum(['input', 'output']),\n dataType: z.string(),\n })\n .strict();\n\nexport const NodeTypeDetailSchema = z\n .object({\n type: z.string(),\n ports: z.array(NodeTypePortSchema),\n agentWritableFields: z.array(z.string()),\n })\n .strict();\n\nexport const NodeTypesListResponseSchema = z\n .object({\n nodeTypes: z.array(NodeTypeSummarySchema),\n })\n .strict();\n\nexport type NodeTypeSummary = z.infer<typeof NodeTypeSummarySchema>;\nexport type NodeTypePort = z.infer<typeof NodeTypePortSchema>;\nexport type NodeTypeDetail = z.infer<typeof NodeTypeDetailSchema>;\nexport type NodeTypesListResponse = z.infer<typeof NodeTypesListResponseSchema>;\n","import { z } from 'zod';\n\nexport const WorkflowDeclaredParamSchema = z\n .object({\n name: z.string(),\n type: z.string(),\n required: z.boolean().optional(),\n defaultValue: z.unknown().optional(),\n description: z.unknown().optional(),\n })\n .passthrough();\n\nexport const WorkflowSummarySchema = z\n .object({\n id: z.string().uuid(),\n name: z.string(),\n tags: z.array(z.string()),\n declared_params: z.array(WorkflowDeclaredParamSchema).nullable().default([]),\n canvas_rev: z.number().int().nonnegative(),\n updated_at: z.string(),\n })\n .strict();\n\nexport const WorkflowsListResponseSchema = z\n .object({\n items: z.array(WorkflowSummarySchema),\n nextCursor: z.string().nullable(),\n })\n .strict();\n\nexport const WorkflowDetailSchema = z\n .object({\n id: z.string().uuid(),\n name: z.string(),\n description: z.string().nullable(),\n tags: z.array(z.string()),\n declared_params: z.array(WorkflowDeclaredParamSchema).nullable().default([]),\n canvas_rev: z.number().int().nonnegative(),\n nodes: z.array(z.unknown()),\n edges: z.array(z.unknown()),\n created_at: z.string(),\n updated_at: z.string(),\n })\n .strict();\n\nexport const WorkflowCreateResponseSchema = z\n .object({\n id: z.string().uuid(),\n name: z.string(),\n description: z.string().nullable(),\n tags: z.array(z.string()),\n declared_params: z.array(WorkflowDeclaredParamSchema).nullable().default([]),\n canvas_rev: z.number().int().nonnegative(),\n created_at: z.string(),\n updated_at: z.string(),\n })\n .strict();\n\nexport const WorkflowMutateResponseSchema = z\n .object({\n canvas_rev: z.number().int().nonnegative(),\n applied: z.number().int().nonnegative(),\n workflow: WorkflowDetailSchema,\n })\n .strict();\n\nexport type WorkflowDeclaredParam = z.infer<typeof WorkflowDeclaredParamSchema>;\nexport type WorkflowSummary = z.infer<typeof WorkflowSummarySchema>;\nexport type WorkflowsListResponse = z.infer<typeof WorkflowsListResponseSchema>;\nexport type WorkflowDetail = z.infer<typeof WorkflowDetailSchema>;\nexport type WorkflowCreateResponse = z.infer<typeof WorkflowCreateResponseSchema>;\nexport type WorkflowMutateResponse = z.infer<typeof WorkflowMutateResponseSchema>;\n","// Error-code taxonomy: the set of machine-readable codes the Agents API can\n// surface. These are pure string-literal unions with no exit-code/hint policy\n// attached — that policy (the EXIT_CODE_MAP and friends) stays on the CLI side.\n//\n// The server codes come from `docs-internal/agents/01-day1-rfc/01-tool-surface.md`\n// §5 and `02-oauth.md` §2.6. The client codes cover failure modes only the\n// client can observe (network errors after retries exhausted, abort timeouts,\n// parse failures, schema mismatches).\n\n// The 61 server error codes, as a runtime array. `ServerErrorCode` (the type)\n// is DERIVED from this array so the two can never drift — adding a code in one\n// place without the other is a compile error. `KNOWN_SERVER_CODES` (the\n// allow-list the HTTP client trusts from the server) is also built from it.\nexport const SERVER_ERROR_CODES = [\n 'AUTH_TOKEN_MISSING',\n 'AUTH_TOKEN_INVALID',\n 'AUTH_TOKEN_EXPIRED',\n 'AUTH_TOKEN_REVOKED',\n 'AUTH_TOKEN_SCOPE_INSUFFICIENT',\n 'AUTH_ORG_MISMATCH',\n 'AUTH_DEVICE_CODE_PENDING',\n 'AUTH_DEVICE_CODE_EXPIRED',\n 'AUTH_DEVICE_CODE_SLOW_DOWN',\n 'IDEMPOTENCY_KEY_MISSING',\n 'IDEMPOTENCY_KEY_CONFLICT',\n 'PLAN_FEATURE_LOCKED',\n 'PLAN_QUOTA_EXCEEDED',\n 'INSUFFICIENT_CREDITS',\n 'CREDIT_DEDUCTION_FAILED',\n 'RATE_LIMITED',\n 'INPUT_INVALID_FORMAT',\n 'INPUT_TOO_LONG',\n 'WORKFLOW_VALIDATION_FAILED',\n 'WORKFLOW_NODE_TYPE_UNKNOWN',\n 'CANVAS_REV_MISMATCH',\n 'CANVAS_REV_REQUIRED',\n 'WORKER_UNREACHABLE',\n 'IDEMPOTENCY_IN_PROGRESS',\n 'TOKEN_NAME_INVALID',\n 'WORKFLOW_NOT_FOUND',\n 'NOT_FOUND',\n 'NODE_TYPE_NOT_FOUND',\n 'FEATURE_DISABLED',\n 'FORBIDDEN',\n 'MODEL_NOT_FOUND',\n 'PROVIDER_UNAVAILABLE',\n 'STORAGE_UPLOAD_FAILED',\n 'STORAGE_QUOTA_EXCEEDED',\n 'GEN_CONTENT_REFUSAL',\n 'GEN_OUTPUT_SCHEMA_MISMATCH',\n 'GEN_EMPTY_OUTPUT',\n 'GEN_ITEM_COUNT_MISMATCH',\n 'AGENT_FINGERPRINT_REJECTED',\n 'INTERNAL_ERROR',\n 'BRAND_MODEL_NOT_FOUND',\n 'BRAND_MODEL_NOT_A_MODEL',\n 'BRAND_MODEL_NOT_ACTIVE',\n 'BRAND_MODEL_NO_REFERENCES',\n 'BRAND_MODEL_POSE_NOT_FOUND',\n 'BRAND_MODEL_DUPLICATE_ID',\n 'MODEL_DOES_NOT_SUPPORT_REFERENCES',\n 'REFERENCE_LIMIT_EXCEEDED',\n 'PRODUCT_NOT_FOUND',\n 'PRODUCT_DUPLICATE_REFERENCE',\n 'PRODUCT_IMAGE_NOT_FOUND',\n 'PRODUCT_IMAGE_MISMATCH',\n 'PRODUCT_SYNC_ERROR',\n 'PRODUCT_DELETED_UPSTREAM',\n 'PRODUCT_NO_PRIMARY_IMAGE',\n 'PRODUCT_SOURCE_MANAGED',\n // Product create (`POST /api/agents/v1/products`). Without these five in the\n // allow-list the HTTP client folds each one into INTERNAL_ERROR, which loses\n // the server's message, the actionable `details.assetIds`, and the CLI exit\n // code the failure should map to. STORAGE_UNAVAILABLE additionally loses its\n // retryability, turning a transient 503 the server marked retryable into a\n // one-shot failure.\n 'PRODUCT_IMAGE_ASSET_DUPLICATE',\n 'PRODUCT_IMAGE_ASSET_NOT_FOUND',\n 'PRODUCT_IMAGE_ASSET_NOT_IMAGE',\n 'PRODUCT_IMAGE_ASSET_INCOMPLETE',\n 'STORAGE_UNAVAILABLE',\n] as const;\n\nexport type ServerErrorCode = (typeof SERVER_ERROR_CODES)[number];\n\nexport type ClientErrorCode = 'NETWORK_ERROR' | 'TIMEOUT' | 'PARSE_ERROR' | 'SCHEMA_MISMATCH';\n\n// The codes `ApiError` can actually carry: every error the HTTP client either\n// receives from the server (ServerErrorCode) or synthesizes itself\n// (ClientErrorCode). Deliberately NOT the CLI's `AllErrorCode` — auth/credential\n// codes are surfaced via AuthError/CredentialsError, never via ApiError.\nexport type ApiErrorCode = ServerErrorCode | ClientErrorCode;\n\n// Allow-list of codes the HTTP client is willing to accept from the server.\n// Anything outside this set is mapped to INTERNAL_ERROR so the strict-Zod\n// guarantees aren't bypassed by a typo or future server addition. Derived from\n// SERVER_ERROR_CODES so it is exactly the server taxonomy — the CLI-only client\n// codes are never valid as a server-supplied `error.code`.\nexport const KNOWN_SERVER_CODES: ReadonlySet<string> = new Set(SERVER_ERROR_CODES);\n","// Generic long-poll helper for the `wait` commands. Each `fetcher()` call is\n// expected to already encode a server-side hold (e.g. `?wait=30` per RFC §4.4),\n// so the helper does NOT impose a client-side interval — it just loops back-to-\n// back until the result is terminal or the overall deadline expires.\n//\n// Phase 8 Q9 of `wave-1-investigation.md` settled the wait UX: default overall\n// timeout 120s, server long-poll rounds 30s, no exponential backoff.\n\nimport { ApiError } from './errors/api-error.js';\n\nexport interface LongPollOptions<T> {\n // One round of the long-poll. Should carry the server `?wait=N` query so\n // each call holds for up to N seconds before returning the latest state.\n // The helper passes an iteration AbortSignal composed from `opts.signal`\n // and the remaining-time deadline; fetchers SHOULD forward it to the HTTP\n // request so e.g. `--timeout 1` doesn't get blocked by a 30s server hold.\n // The args parameter is optional to keep existing test fetchers compatible.\n fetcher: (args?: { signal?: AbortSignal }) => Promise<T>;\n // Returns true when `result` represents a terminal state and the loop\n // should stop. Caller decides what constitutes terminal (e.g. completed\n // ∪ failed ∪ cancelled for generation jobs).\n isTerminal: (result: T) => boolean;\n // Overall hard deadline in milliseconds. Once elapsed >= timeoutMs the\n // helper throws ApiError('TIMEOUT', ...).\n timeoutMs: number;\n // Optional abort signal. If it fires the helper throws ApiError('TIMEOUT',\n // ...) to keep all \"we gave up\" paths under a single exit-code category.\n signal?: AbortSignal;\n // Test-only clock seam. Defaults to Date.now.\n now?: () => number;\n}\n\nexport async function longPoll<T>(opts: LongPollOptions<T>): Promise<T> {\n const now = opts.now ?? Date.now;\n const started = now();\n\n for (;;) {\n if (opts.signal?.aborted) {\n throw new ApiError('TIMEOUT', 'Wait was aborted.', { retryable: true });\n }\n\n // Pre-fetch deadline check — must come BEFORE the fetcher so we never\n // begin a fresh server hold once we've already blown past the user's\n // overall timeout.\n const elapsedBefore = now() - started;\n if (elapsedBefore >= opts.timeoutMs) {\n throw new ApiError(\n 'TIMEOUT',\n `Wait exceeded ${opts.timeoutMs}ms without reaching a terminal state.`,\n { retryable: true },\n );\n }\n\n const remainingMs = opts.timeoutMs - elapsedBefore;\n const iterationSignal = composeIterationSignal(opts.signal, remainingMs);\n\n let result: T;\n try {\n result = await opts.fetcher({ signal: iterationSignal });\n } catch (err) {\n // The fetcher rejects (typically AbortError) when the composed iteration\n // signal aborts — either the overall deadline elapsed (AbortSignal.timeout)\n // or the caller aborted (opts.signal). Both are \"we gave up\" → ApiError\n // TIMEOUT, sharing one exit-code category. Classify from the signal's\n // already-settled aborted state, NOT a wall-clock re-read: the timer and\n // Date.now() can disagree by ~1ms, which used to rethrow the raw AbortError.\n if (iterationSignal.aborted) {\n throw new ApiError(\n 'TIMEOUT',\n opts.signal?.aborted\n ? 'Wait was aborted.'\n : `Wait exceeded ${opts.timeoutMs}ms without reaching a terminal state.`,\n { retryable: true },\n );\n }\n // Genuine non-abort fetcher error — propagate verbatim.\n throw err;\n }\n\n if (opts.signal?.aborted) {\n throw new ApiError('TIMEOUT', 'Wait was aborted.', { retryable: true });\n }\n\n // Post-fetch deadline check — a fetcher that resolves AT or AFTER the\n // overall deadline must not be allowed to satisfy the wait. We do this\n // BEFORE the terminal check so terminal-arrived-too-late still surfaces\n // as TIMEOUT (the contract is \"give an answer within timeoutMs\").\n const elapsedAfter = now() - started;\n if (elapsedAfter >= opts.timeoutMs) {\n throw new ApiError(\n 'TIMEOUT',\n `Wait exceeded ${opts.timeoutMs}ms without reaching a terminal state.`,\n { retryable: true },\n );\n }\n\n if (opts.isTerminal(result)) {\n return result;\n }\n }\n}\n\nfunction composeIterationSignal(\n userSignal: AbortSignal | undefined,\n remainingMs: number,\n): AbortSignal {\n const deadlineSignal = AbortSignal.timeout(Math.max(remainingMs, 0));\n return userSignal ? AbortSignal.any([userSignal, deadlineSignal]) : deadlineSignal;\n}\n","// HTTP client for the Clickraft Agents API. Wraps `undici.request` with:\n//\n// - Bearer auth + User-Agent + Idempotency-Key headers\n// - JSON body serialization + JSON response parsing\n// - Strict Zod schema validation on success payloads\n// - Exponential-backoff retry that honors `Retry-After` and the\n// `error.retryAfter` field per RFC §4.1 / Phase 8 Q7\n// - AbortSignal composition (client signal + per-request signal)\n// - Token redaction on every error body via redactTokenLikeFields from 1A.1\n//\n// Retryability of server error codes and warning emission are CLI policy and\n// are injected via `ApiClientOptions.isRetryableServerCode` / `.onWarning`; this\n// module never reads the CLI's exit-code policy table. See plan-file for the contract.\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\nimport { z } from 'zod';\n\nimport type { CloudflareAccessCredentials } from '../config-types.js';\nimport { ApiError } from '../errors/api-error.js';\nimport { KNOWN_SERVER_CODES, type ServerErrorCode } from '../errors/codes.js';\nimport { formatSchemaIssues } from '../errors/schema-mismatch.js';\nimport { redactTokenLikeFields } from '../redact.js';\n\nimport { generateIdempotencyKey } from './idempotency.js';\nimport { DEFAULT_RETRY_OPTIONS, decideRetry, sleep, type RetryOptions } from './retry.js';\nimport { ServerErrorBodySchema, ServerSuccessSchema, type ServerErrorBody } from './types.js';\n\nexport interface ApiClientOptions {\n apiBaseUrl: string;\n accessToken: string | null;\n userAgent?: string;\n signal?: AbortSignal;\n dispatcher?: Dispatcher;\n retryDefaults?: Partial<RetryOptions>;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n // Sink for non-fatal warnings (unknown server code, Retry-After clipping).\n // Injected by the CLI to forward to stderr; absent ⇒ silent.\n onWarning?: (msg: string) => void;\n // Decides whether a known server error code is retryable. Injected by the CLI\n // (backed by its exit-code policy, the single source of retryability truth).\n // When absent, the client falls back to the HTTP-status heuristic below.\n isRetryableServerCode?: (code: ServerErrorCode) => boolean;\n}\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface RequestOptions<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {\n method: HttpMethod;\n path: string;\n body?: unknown;\n query?: Record<string, string | number | string[] | undefined>;\n idempotencyKey?: string;\n retry?: Partial<RetryOptions>;\n responseSchema?: TSchema;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\nconst REDACT_BODY_LIMIT = 1024;\n// Cap the input to redaction so the regex doesn't traverse pathologically\n// large bodies. Anything past this is dropped before truncation; the trade-\n// off vs. token leakage is documented in plan-wobbly-floyd.md (C2).\nconst REDACT_INPUT_CAP = 100 * 1024;\nconst DEFAULT_USER_AGENT = 'clickraft-cli';\n\nexport class ApiClient {\n private readonly options: ApiClientOptions;\n private readonly retryDefaults: RetryOptions;\n\n constructor(options: ApiClientOptions) {\n this.options = options;\n this.retryDefaults = {\n ...DEFAULT_RETRY_OPTIONS,\n ...options.retryDefaults,\n };\n }\n\n // Issues a request with built-in retry, Zod validation, and token redaction.\n //\n // Non-GET requests get an auto-generated UUIDv4 `X-Idempotency-Key` per\n // Phase 8 Q8 of the wave-1 investigation. The key is computed once and\n // reused across every retry attempt so the server can deduplicate. Callers\n // may pass `opts.idempotencyKey` to override the default — the upload\n // command uses this to derive the key from the content's SHA-256.\n async request<TData = unknown, TSchema extends z.ZodTypeAny = z.ZodTypeAny>(\n opts: RequestOptions<TSchema>,\n ): Promise<TData> {\n const retry: RetryOptions = {\n ...this.retryDefaults,\n ...opts.retry,\n };\n const signal = composeSignals([this.options.signal, opts.signal, retry.signal]);\n const url = buildUrl(this.options.apiBaseUrl, opts.path, opts.query);\n const effectiveIdempotencyKey =\n opts.method === 'GET'\n ? opts.idempotencyKey\n : (opts.idempotencyKey ?? generateIdempotencyKey());\n const headers = this.buildHeaders({ ...opts, idempotencyKey: effectiveIdempotencyKey });\n const bodyText = serializeBody(opts);\n\n let attempt = 0;\n let lastError: ApiError | undefined;\n\n // First attempt is attempt=1; we retry up to retry.maxAttempts total.\n while (attempt < retry.maxAttempts) {\n attempt += 1;\n if (signal.aborted) {\n throw toAbortApiError(signal);\n }\n\n try {\n return await this.singleAttempt<TData>({\n url,\n method: opts.method,\n headers,\n bodyText,\n signal,\n responseSchema: opts.responseSchema,\n });\n } catch (err) {\n if (!(err instanceof ApiError)) throw err;\n lastError = err;\n\n const isNetworkError = err.code === 'NETWORK_ERROR';\n const isRetryable = err.meta.retryable;\n const decision = decideRetry({\n attempt,\n options: { ...retry, signal },\n serverRetryAfterMs: err.meta.retryAfterMs,\n isNetworkError,\n isRetryable,\n onWarning: this.options.onWarning,\n });\n\n if (!decision.shouldRetry) throw err;\n try {\n await sleep(decision.delayMs, signal);\n } catch (sleepErr) {\n throw toAbortApiError(signal, sleepErr);\n }\n }\n }\n\n // Loop only exits via return or throw above, but TS needs a fallback.\n throw (\n lastError ??\n new ApiError('INTERNAL_ERROR', 'Retry loop terminated unexpectedly.', {\n retryable: false,\n })\n );\n }\n\n private buildHeaders(opts: RequestOptions): Record<string, string> {\n const h: Record<string, string> = {\n accept: 'application/json',\n 'user-agent': this.options.userAgent ?? DEFAULT_USER_AGENT,\n };\n if (this.options.accessToken) {\n h.authorization = `Bearer ${this.options.accessToken}`;\n }\n if (this.options.cloudflareAccess) {\n h['cf-access-client-id'] = this.options.cloudflareAccess.clientId;\n h['cf-access-client-secret'] = this.options.cloudflareAccess.clientSecret;\n }\n if (opts.body !== undefined && opts.method !== 'GET' && opts.method !== 'DELETE') {\n h['content-type'] = 'application/json';\n }\n if (opts.idempotencyKey) {\n h['x-idempotency-key'] = opts.idempotencyKey;\n }\n if (opts.headers) {\n for (const [k, v] of Object.entries(opts.headers)) {\n h[k.toLowerCase()] = v;\n }\n }\n return h;\n }\n\n private async singleAttempt<TData>(args: {\n url: string;\n method: HttpMethod;\n headers: Record<string, string>;\n bodyText?: string;\n signal: AbortSignal;\n responseSchema?: z.ZodTypeAny;\n }): Promise<TData> {\n let response: Dispatcher.ResponseData;\n try {\n response = await undiciRequest(args.url, {\n method: args.method,\n headers: args.headers,\n body: args.bodyText,\n signal: args.signal,\n dispatcher: this.options.dispatcher,\n });\n } catch (err) {\n if (isAbortError(err)) {\n throw toAbortApiError(args.signal, err);\n }\n throw new ApiError(\n 'NETWORK_ERROR',\n `Network request failed: ${errorMessage(err)}`,\n { retryable: true },\n err,\n );\n }\n\n const { statusCode, headers: responseHeaders, body } = response;\n let bodyText: string;\n try {\n bodyText = await body.text();\n } catch (err) {\n if (isAbortError(err)) {\n throw toAbortApiError(args.signal, err);\n }\n throw new ApiError(\n 'NETWORK_ERROR',\n `Failed to read response body: ${errorMessage(err)}`,\n { status: statusCode, retryable: true },\n err,\n );\n }\n\n const requestId = pickHeader(responseHeaders, 'x-correlation-id');\n\n if (statusCode >= 200 && statusCode < 300) {\n return parseSuccessBody<TData>({\n bodyText,\n statusCode,\n requestId,\n responseSchema: args.responseSchema,\n });\n }\n\n throw parseErrorBody({\n bodyText,\n statusCode,\n requestId,\n retryAfterHeader: pickHeader(responseHeaders, 'retry-after'),\n onWarning: this.options.onWarning,\n isRetryableServerCode: this.options.isRetryableServerCode,\n });\n }\n}\n\n// Constructs an ApiClient from resolved options. The factory exists so callers\n// (and the CLI's policy-injecting wrapper) have a single, stable entry point\n// that does not depend on the class shape.\nexport function createClient(options: ApiClientOptions): ApiClient {\n return new ApiClient(options);\n}\n\nfunction parseSuccessBody<TData>(args: {\n bodyText: string;\n statusCode: number;\n requestId?: string;\n responseSchema?: z.ZodTypeAny;\n}): TData {\n let parsed: unknown;\n try {\n parsed = JSON.parse(args.bodyText);\n } catch (err) {\n throw new ApiError(\n 'PARSE_ERROR',\n 'Server returned a non-JSON response.',\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: false,\n redactedBody: redactAndTruncate(args.bodyText),\n },\n err,\n );\n }\n\n const envelope = ServerSuccessSchema(args.responseSchema ?? z.unknown()).safeParse(parsed);\n if (!envelope.success) {\n const issues = formatSchemaIssues(envelope.error);\n throw new ApiError(\n 'SCHEMA_MISMATCH',\n `Server response did not match the expected schema. Issues: ${issues}`,\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: false,\n redactedBody: redactAndTruncate(args.bodyText),\n },\n );\n }\n return envelope.data.data as TData;\n}\n\nfunction parseErrorBody(args: {\n bodyText: string;\n statusCode: number;\n requestId?: string;\n retryAfterHeader?: string;\n onWarning?: (msg: string) => void;\n isRetryableServerCode?: (code: ServerErrorCode) => boolean;\n}): ApiError {\n const redactedBody = redactAndTruncate(args.bodyText);\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(args.bodyText);\n } catch {\n return new ApiError(\n 'PARSE_ERROR',\n `Server returned a ${args.statusCode} response with a non-JSON body.`,\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: args.statusCode >= 500,\n redactedBody,\n },\n );\n }\n\n const envelope = ServerErrorBodySchema.safeParse(parsed);\n if (!envelope.success) {\n return new ApiError(\n 'PARSE_ERROR',\n `Server returned ${args.statusCode} but body did not match the error envelope.`,\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: args.statusCode >= 500,\n redactedBody,\n },\n );\n }\n\n return apiErrorFromServerBody({\n body: envelope.data,\n statusCode: args.statusCode,\n requestId: args.requestId,\n retryAfterHeader: args.retryAfterHeader,\n redactedBody,\n onWarning: args.onWarning,\n isRetryableServerCode: args.isRetryableServerCode,\n });\n}\n\nfunction apiErrorFromServerBody(args: {\n body: ServerErrorBody;\n statusCode: number;\n requestId?: string;\n retryAfterHeader?: string;\n redactedBody?: string;\n onWarning?: (msg: string) => void;\n isRetryableServerCode?: (code: ServerErrorCode) => boolean;\n}): ApiError {\n const { error } = args.body;\n\n // S1 — reject unknown codes so a server typo or future addition cannot\n // bypass the strict mapping. Unknown codes are folded into INTERNAL_ERROR\n // with a warning; the raw code is redacted before logging in case the\n // server (or an attacker) embedded a token in it.\n let code: ServerErrorCode;\n let safeMessage: string;\n if (KNOWN_SERVER_CODES.has(error.code)) {\n code = error.code as ServerErrorCode;\n // C3 — server-provided messages can echo tokens. Strip them before the\n // string reaches ApiError.message (which surfaces via stderr, JSON\n // envelope, and any default Error stringification).\n safeMessage = redactTokenLikeFields(error.message);\n } else {\n const redactedRawCode = redactTokenLikeFields(error.code);\n args.onWarning?.(`Unknown server error code: ${redactedRawCode}. Treating as INTERNAL_ERROR.`);\n code = 'INTERNAL_ERROR';\n safeMessage = `Unknown server error code: ${redactedRawCode}.`;\n }\n\n // Retryability is CLI policy, injected as `isRetryableServerCode` (backed by\n // the CLI's exit-code policy). The status heuristic is the fallback when no\n // predicate is injected — it lives here because the predicate has no access to\n // statusCode.\n const retryable =\n args.isRetryableServerCode?.(code) ?? (args.statusCode >= 500 || args.statusCode === 429);\n\n // Prefer the structured `error.retryAfter` field (seconds) over the\n // Retry-After header per Phase 8 Q7 & the RFC §4.1 error envelope.\n const retryAfterMs =\n typeof error.retryAfter === 'number'\n ? error.retryAfter * 1000\n : parseRetryAfterHeader(args.retryAfterHeader);\n\n return new ApiError(code, safeMessage, {\n status: args.statusCode,\n requestId: error.correlationId ?? args.requestId,\n retryable,\n retryAfterMs,\n redactedBody: args.redactedBody,\n details: error.details,\n });\n}\n\n// Parses a Retry-After HTTP header. Per RFC 7231 §7.1.3 the value is either\n// a non-negative integer number of seconds OR an HTTP-date. We are strict\n// here because `parseInt(\"2garbage\")` would otherwise return `2` and the\n// CLI would sleep for an attacker- or proxy-chosen window.\nexport function parseRetryAfterHeader(headerValue: string | undefined): number | undefined {\n if (!headerValue) return undefined;\n const trimmed = headerValue.trim();\n if (/^\\d+$/.test(trimmed)) {\n return Number.parseInt(trimmed, 10) * 1000;\n }\n // Only fall through to HTTP-date if the input actually looks like one\n // (i.e. contains letters). `Date.parse(\"2.5\")` accidentally parses on V8.\n if (/[A-Za-z]/.test(trimmed)) {\n const parsed = Date.parse(trimmed);\n if (!Number.isNaN(parsed)) {\n return Math.max(0, parsed - Date.now());\n }\n }\n return undefined;\n}\n\nfunction buildUrl(\n baseUrl: string,\n path: string,\n query?: Record<string, string | number | string[] | undefined>,\n): string {\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n const relative = path.startsWith('/') ? path.slice(1) : path;\n const url = new URL(relative, base);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const item of value) url.searchParams.append(key, item);\n continue;\n }\n url.searchParams.append(key, String(value));\n }\n }\n return url.toString();\n}\n\nfunction serializeBody(opts: RequestOptions): string | undefined {\n if (opts.body === undefined) return undefined;\n if (opts.method === 'GET') return undefined;\n return JSON.stringify(opts.body);\n}\n\nfunction composeSignals(signals: Array<AbortSignal | undefined>): AbortSignal {\n const present = signals.filter((s): s is AbortSignal => s !== undefined);\n if (present.length === 0) return new AbortController().signal;\n if (present.length === 1) return present[0]!;\n\n // `AbortSignal.any` landed in Node 20.3; the project's `engines.node` floor\n // is 20.0, so fall back to a hand-rolled merger when it's not available.\n type AbortSignalCtor = typeof AbortSignal & { any?: (signals: AbortSignal[]) => AbortSignal };\n const any = (AbortSignal as AbortSignalCtor).any;\n if (typeof any === 'function') return any(present);\n\n const ctrl = new AbortController();\n for (const s of present) {\n if (s.aborted) {\n ctrl.abort(s.reason);\n break;\n }\n s.addEventListener('abort', () => ctrl.abort(s.reason), { once: true });\n }\n return ctrl.signal;\n}\n\nfunction pickHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string,\n): string | undefined {\n const value = headers[name] ?? headers[name.toLowerCase()];\n if (Array.isArray(value)) return value[0];\n return value;\n}\n\n// Redact token-shaped JSON fields, THEN truncate to REDACT_BODY_LIMIT. The\n// order matters: the redact regex requires a closing quote, so truncating\n// first can slice mid-string and leak the token's prefix into the survivor.\nfunction redactAndTruncate(body: string): string {\n const input = body.length > REDACT_INPUT_CAP ? body.slice(0, REDACT_INPUT_CAP) : body;\n const redacted = redactTokenLikeFields(input);\n return redacted.length > REDACT_BODY_LIMIT\n ? `${redacted.slice(0, REDACT_BODY_LIMIT)}…`\n : redacted;\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n return err.name === 'AbortError' || /aborted/i.test(err.message);\n}\n\nfunction toAbortApiError(signal: AbortSignal, cause?: unknown): ApiError {\n const reasonMessage =\n signal.reason instanceof Error ? signal.reason.message : 'Request was aborted.';\n return new ApiError('TIMEOUT', reasonMessage, { retryable: true }, cause);\n}\n\nfunction errorMessage(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n","// Idempotency-Key generation per Phase 8 Q8 of `wave-1-investigation.md`.\n//\n// Default: crypto.randomUUID() returns an RFC 4122 v4 UUID — generated once\n// per command invocation and reused across automatic retries within that\n// invocation. Memory-only; no on-disk cache.\n//\n// Exception: upload uses sha256(content) + scope per\n// `01-tool-surface.md` §7.1 edge case 2, so identical content uploaded twice\n// hits the server's content-hash dedup path and surfaces as\n// `deduplicated: true` with no duplicate charge.\n\nimport { createHash, randomUUID } from 'node:crypto';\n\nexport function generateIdempotencyKey(): string {\n return randomUUID();\n}\n\nexport function generateUploadIdempotencyKey(content: Buffer | Uint8Array, scope: string): string {\n const hash = createHash('sha256').update(content).digest('hex');\n return `upload-${scope}-${hash}`;\n}\n","// Retry policy used by the HTTP client. Exponential backoff with jitter,\n// capped at maxDelayMs. `decideRetry` is pure so the client's retry loop is\n// easy to test in isolation.\n\nexport interface RetryOptions {\n maxAttempts: number;\n baseDelayMs: number;\n maxDelayMs: number;\n jitterFraction: number;\n signal?: AbortSignal;\n}\n\nexport const DEFAULT_RETRY_OPTIONS: Omit<RetryOptions, 'signal'> = {\n maxAttempts: 3,\n baseDelayMs: 200,\n maxDelayMs: 10_000,\n jitterFraction: 0.25,\n};\n\nexport type RetryReason =\n | 'retryable_error'\n | 'network_failure'\n | 'rate_limited'\n | 'aborted'\n | 'max_attempts'\n | 'not_retryable';\n\nexport interface RetryDecision {\n shouldRetry: boolean;\n delayMs: number;\n reason: RetryReason;\n}\n\n// Absolute upper bound on server-supplied Retry-After. A misconfigured server\n// or buggy proxy could send an unreasonably large value; we clip it here to\n// avoid stalling the CLI for hours.\nexport const ABSOLUTE_MAX_RETRY_AFTER_MS = 5 * 60 * 1000;\n\nexport function computeBackoffMs(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number,\n jitterFraction: number,\n): number {\n const exp = Math.min(baseDelayMs * 2 ** Math.max(0, attempt - 1), maxDelayMs);\n const jitter = exp * jitterFraction * (Math.random() * 2 - 1);\n return Math.max(0, Math.round(exp + jitter));\n}\n\n// Decides whether to retry and how long to wait. Server-supplied\n// Retry-After overrides `maxDelayMs` — clamping it would let the CLI retry\n// faster than the server requested, which defeats the rate-limit signal.\n// An absolute safety cap (`ABSOLUTE_MAX_RETRY_AFTER_MS`) bounds pathological\n// values; the optional `onWarning` sink is notified when clipping occurs.\nexport function decideRetry(params: {\n attempt: number;\n options: RetryOptions;\n serverRetryAfterMs?: number;\n isNetworkError: boolean;\n isRetryable: boolean;\n onWarning?: (msg: string) => void;\n}): RetryDecision {\n const { attempt, options, serverRetryAfterMs, isNetworkError, isRetryable, onWarning } = params;\n\n if (options.signal?.aborted) {\n return { shouldRetry: false, delayMs: 0, reason: 'aborted' };\n }\n if (attempt >= options.maxAttempts) {\n return { shouldRetry: false, delayMs: 0, reason: 'max_attempts' };\n }\n if (!isNetworkError && !isRetryable) {\n return { shouldRetry: false, delayMs: 0, reason: 'not_retryable' };\n }\n\n if (typeof serverRetryAfterMs === 'number' && serverRetryAfterMs >= 0) {\n let delayMs = serverRetryAfterMs;\n if (delayMs > ABSOLUTE_MAX_RETRY_AFTER_MS) {\n onWarning?.(`Server Retry-After exceeded ${ABSOLUTE_MAX_RETRY_AFTER_MS}ms; clipping.`);\n delayMs = ABSOLUTE_MAX_RETRY_AFTER_MS;\n }\n return { shouldRetry: true, delayMs, reason: 'rate_limited' };\n }\n\n const delayMs = computeBackoffMs(\n attempt,\n options.baseDelayMs,\n options.maxDelayMs,\n options.jitterFraction,\n );\n return {\n shouldRetry: true,\n delayMs,\n reason: isNetworkError ? 'network_failure' : 'retryable_error',\n };\n}\n\n// Abortable sleep. Resolves at `delayMs`; rejects with an AbortError-shaped\n// DOMException if the signal aborts first.\nexport async function sleep(delayMs: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n throw signalToAbortError(signal);\n }\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, delayMs);\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(signalToAbortError(signal));\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nfunction signalToAbortError(signal: AbortSignal | undefined): Error {\n const reason = signal?.reason;\n if (reason instanceof Error) return reason;\n const err = new Error('The operation was aborted.');\n err.name = 'AbortError';\n return err;\n}\n","// Zod schemas for the server response envelopes documented in\n// `docs-internal/agents/01-day1-rfc/01-tool-surface.md` §3.7 and §4.1.\n//\n// All schemas use `.strict()` per 1A.1 convention — unknown fields fail\n// validation loudly rather than passing through silently.\n\nimport { z } from 'zod';\n\nexport const ServerSuccessSchema = <T extends z.ZodTypeAny>(payload: T) =>\n z.object({ data: payload }).strict();\n\n// Match what the server emits: code/message/optional correlationId, retryAfter\n// (seconds), and free-form details. Keep the schema strict so unexpected fields\n// surface as PARSE_ERROR during development rather than silently dropping.\nexport const ServerErrorBodySchema = z\n .object({\n error: z\n .object({\n code: z.string().min(1),\n message: z.string(),\n correlationId: z.string().optional(),\n retryAfter: z.number().int().nonnegative().optional(),\n details: z.unknown().optional(),\n })\n .strict(),\n })\n .strict();\n\nexport type ServerErrorBody = z.infer<typeof ServerErrorBodySchema>;\n","// Workflow-apply orchestration (Phase 4a). The auto-rev-retry algorithm that\n// wraps PATCH /workflows/{id}: try → on a canvas-rev conflict re-fetch the\n// current rev and retry the PATCH once with a fresh idempotency key.\n//\n// This is the pilot for the Phase 4 orchestration-injection pattern: the\n// function takes a REQUIRED ApiClient and the response schemas it needs\n// INJECTED (the SDK stays domain-agnostic and never imports cli/schemas). It is\n// UX-free and disk-free — config resolution, rendering, and exit codes stay in\n// the CLI. See docs-internal/decisions/sdk-orchestration-injection-pattern.md.\n\nimport type { ZodTypeAny } from 'zod';\n\nimport { ApiError } from '../errors/api-error.js';\nimport type { ApiClient } from '../http/client.js';\n\n// Minimal shapes the algorithm reads. The CLI injects richer schemas whose\n// inferred types extend these; the generics carry the precise types back to the\n// caller without the SDK importing any domain schema.\nexport interface MutateResponseShape {\n canvas_rev: number;\n applied: number;\n workflow: unknown;\n}\n\nexport interface DetailRevShape {\n canvas_rev: number;\n}\n\nexport interface ApplyWorkflowWithRetryParams {\n // REQUIRED — there is no config fallback in the SDK. The CLI resolves config\n // and constructs the client before calling.\n client: ApiClient;\n id: string;\n canvasRev: number;\n operations: Record<string, unknown>[];\n idempotencyKey?: string;\n autoRev?: boolean;\n signal?: AbortSignal;\n // Injected by the CLI. Typed ZodTypeAny to match client.request's own\n // responseSchema param (the response data types are carried by the\n // <TMutate>/<TDetail> generics on applyWorkflowWithRetry, not by the schemas).\n schemas: { mutate: ZodTypeAny; detail: ZodTypeAny };\n}\n\nexport interface ApplyWorkflowWithRetryResult<TMutate extends MutateResponseShape> {\n canvasRev: number;\n applied: number;\n workflow: TMutate['workflow'];\n retriedWithRev?: number;\n}\n\nexport async function applyWorkflowWithRetry<\n TMutate extends MutateResponseShape,\n TDetail extends DetailRevShape,\n>(params: ApplyWorkflowWithRetryParams): Promise<ApplyWorkflowWithRetryResult<TMutate>> {\n try {\n return await patch<TMutate>(params);\n } catch (err) {\n if (!(err instanceof ApiError)) throw err;\n\n const isRevConflict =\n err.code === 'CANVAS_REV_MISMATCH' || (err.meta.status === 409 && err.meta.details != null);\n\n if (!isRevConflict || !params.autoRev) throw err;\n\n const snapshot = await params.client.request<TDetail>({\n method: 'GET',\n path: `/workflows/${encodeURIComponent(params.id)}`,\n responseSchema: params.schemas.detail,\n signal: params.signal,\n });\n\n const retryResult = await patch<TMutate>({\n ...params,\n canvasRev: snapshot.canvas_rev,\n // Fresh key — the body changed (different canvas_rev), so reusing the\n // caller's key would trigger IDEMPOTENCY_KEY_CONFLICT.\n idempotencyKey: undefined,\n });\n\n return { ...retryResult, retriedWithRev: snapshot.canvas_rev };\n }\n}\n\nasync function patch<TMutate extends MutateResponseShape>(\n params: ApplyWorkflowWithRetryParams,\n): Promise<ApplyWorkflowWithRetryResult<TMutate>> {\n const data = await params.client.request<TMutate>({\n method: 'PATCH',\n path: `/workflows/${encodeURIComponent(params.id)}`,\n body: {\n canvas_rev: params.canvasRev,\n operations: params.operations,\n },\n idempotencyKey: params.idempotencyKey,\n responseSchema: params.schemas.mutate,\n signal: params.signal,\n });\n\n return {\n canvasRev: data.canvas_rev,\n applied: data.applied,\n workflow: data.workflow,\n };\n}\n","// Upload orchestration (Phase 4b). The buffer-onward half of the two-step asset\n// upload: derive metadata (content-type, sha256, content-hash idempotency key),\n// POST /assets, then PUT the bytes to the signed GCS URL with retry-once.\n//\n// Follows the Phase-4 orchestration-injection pattern: a REQUIRED ApiClient and\n// the response schema INJECTED, UX-free and DISK-free — the bytes arrive as an\n// already-read Buffer (the CLI owns all filesystem I/O). See\n// docs-internal/decisions/sdk-orchestration-injection-pattern.md.\n\nimport { createHash } from 'node:crypto';\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\nimport type { ZodTypeAny } from 'zod';\n\nimport { ApiError } from '../errors/api-error.js';\nimport type { ApiClient } from '../http/client.js';\nimport { generateUploadIdempotencyKey } from '../http/idempotency.js';\n\n// Minimal POST /assets response shape the orchestration reads. The CLI injects\n// the real (strict) UploadResponseSchema; the SDK validates against it and only\n// reads these fields.\nexport interface UploadResponseShape {\n assetId: string;\n uploadUrl: string;\n publicUrl: string;\n deduplicated: boolean;\n}\n\nexport interface UploadAssetParams {\n // REQUIRED — there is no config fallback in the SDK. The CLI resolves config\n // and constructs the client before calling.\n client: ApiClient;\n // INJECTED — the SDK never reads disk. The CLI reads the file and passes bytes.\n content: Buffer;\n // basename, computed CLI-side (a pure string — no filesystem semantics here).\n filename: string;\n // Resolved CLI-side (default `user-uploads`); drives the content-hash key.\n scope: string;\n signal?: AbortSignal;\n // Test seam for the raw GCS PUT (MockAgent), threaded from the CLI.\n putDispatcher?: Dispatcher;\n // Injected UploadResponseSchema (assets.ts stays in the CLI).\n schema: ZodTypeAny;\n}\n\nexport interface UploadAssetResult {\n assetId: string;\n publicUrl: string;\n deduplicated: boolean;\n bytes: number;\n contentHash: string;\n}\n\nexport async function uploadAsset(params: UploadAssetParams): Promise<UploadAssetResult> {\n const contentType = detectContentType(params.filename, params.content);\n const sha = sha256Hex(params.content);\n const contentHash = `sha256:${sha}`;\n const idempotencyKey = generateUploadIdempotencyKey(params.content, params.scope);\n\n // HTTP step 1 — POST /assets via the ApiClient (auth, envelope, schema, retry).\n const response = await params.client.request<UploadResponseShape>({\n method: 'POST',\n path: '/assets',\n body: {\n filename: params.filename,\n contentType,\n sizeBytes: params.content.length,\n contentHash,\n },\n idempotencyKey,\n responseSchema: params.schema,\n signal: params.signal,\n });\n\n if (!response.deduplicated) {\n // §7.1 #2 — On PUT failure we retry once against the SAME signed URL with\n // the SAME bytes. We do NOT re-POST to /assets on PUT failure: if partial\n // bytes already landed, a fresh POST may report `deduplicated:true` and we\n // would skip the PUT entirely, surfacing a publicUrl backed by corrupt or\n // truncated data.\n const first = await tryPut({\n uploadUrl: response.uploadUrl,\n content: params.content,\n contentType,\n signal: params.signal,\n dispatcher: params.putDispatcher,\n });\n if (!first.ok) {\n if (first.kind === 'fatal') {\n throw new ApiError(\n 'STORAGE_UPLOAD_FAILED',\n `Upload to signed URL failed for ${params.filename} (HTTP ${first.status ?? 'unknown'}).`,\n { retryable: false },\n );\n }\n const retry = await tryPut({\n uploadUrl: response.uploadUrl,\n content: params.content,\n contentType,\n signal: params.signal,\n dispatcher: params.putDispatcher,\n });\n if (!retry.ok) {\n throw new ApiError(\n 'STORAGE_UPLOAD_FAILED',\n `Upload to signed URL failed for ${params.filename} after one retry.`,\n { retryable: true },\n );\n }\n }\n }\n\n return {\n assetId: response.assetId,\n publicUrl: response.publicUrl,\n deduplicated: response.deduplicated,\n bytes: params.content.length,\n contentHash,\n };\n}\n\ntype PutOutcome = { ok: true } | { ok: false; kind: 'retryable' | 'fatal'; status?: number };\n\n// HTTP step 2 — raw undici PUT to the signed GCS URL (no auth, no envelope, no\n// zod; GCS returns an empty body on success and a small XML doc on failure).\nasync function tryPut(args: {\n uploadUrl: string;\n content: Buffer;\n contentType: string;\n signal?: AbortSignal;\n dispatcher?: Dispatcher;\n}): Promise<PutOutcome> {\n try {\n const response = await undiciRequest(args.uploadUrl, {\n method: 'PUT',\n body: args.content,\n headers: {\n 'content-type': args.contentType,\n 'content-length': String(args.content.length),\n },\n signal: args.signal,\n dispatcher: args.dispatcher,\n });\n // Drain the body so the connection can be released; ignore the contents.\n await response.body.text();\n const status = response.statusCode;\n if (status >= 200 && status < 300) return { ok: true };\n // 4xx — signed URL is dead (expired, malformed, auth). Re-POSTing risks a\n // deduplicated:true echo that hides corrupt partial bytes, so we surface\n // STORAGE_UPLOAD_FAILED and let the user re-run upload to mint a fresh URL.\n if (status >= 400 && status < 500) return { ok: false, kind: 'fatal', status };\n // 5xx / 3xx — transient; safe to retry against the same URL.\n return { ok: false, kind: 'retryable', status };\n } catch {\n // Network error, socket reset, abort — retryable.\n return { ok: false, kind: 'retryable' };\n }\n}\n\nfunction sha256Hex(content: Buffer): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\n// Magic-number sniffing for the formats Wave 1 care about. Falls back to the\n// extension and then to application/octet-stream. We deliberately do NOT pull\n// in a `mime-types` dependency for one helper.\n//\n// GIF and MP4 are handled inline in detectContentType because they need\n// offset-aware or exact-length checks that don't fit the fixed-prefix model.\nconst MAGIC_NUMBERS: Array<{ contentType: string; prefix: number[] }> = [\n { contentType: 'image/png', prefix: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] },\n { contentType: 'image/jpeg', prefix: [0xff, 0xd8, 0xff] },\n { contentType: 'image/webp', prefix: [0x52, 0x49, 0x46, 0x46] }, // also matches WAV — disambiguated below\n];\n\nconst EXTENSION_FALLBACK: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n mp4: 'video/mp4',\n mov: 'video/quicktime',\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n pdf: 'application/pdf',\n txt: 'text/plain',\n json: 'application/json',\n};\n\n// Derives the content type from the bytes (and the filename, used only as a\n// string for the extension fallback — no filesystem access).\nexport function detectContentType(filename: string, content: Buffer): string {\n // GIF: require an exact 6-byte signature so files that merely begin with\n // \"GIF8\" don't get mistyped as image/gif.\n if (content.length >= 6) {\n const head = content.subarray(0, 6).toString('ascii');\n if (head === 'GIF87a' || head === 'GIF89a') return 'image/gif';\n }\n // MP4 / ISO BMFF: the \"ftyp\" box sits at offset 4-8.\n if (content.length >= 12 && content.subarray(4, 8).toString('ascii') === 'ftyp') {\n return 'video/mp4';\n }\n for (const { contentType, prefix } of MAGIC_NUMBERS) {\n if (matchesPrefix(content, prefix)) {\n if (contentType === 'image/webp') {\n // RIFF container — disambiguate WEBP vs WAV via the 4-byte format ID.\n const formatId = content.subarray(8, 12).toString('ascii');\n if (formatId === 'WEBP') return 'image/webp';\n if (formatId === 'WAVE') return 'audio/wav';\n // Unknown RIFF — fall through to extension.\n break;\n }\n return contentType;\n }\n }\n const ext = filename.toLowerCase().split('.').pop();\n if (ext && EXTENSION_FALLBACK[ext]) {\n return EXTENSION_FALLBACK[ext];\n }\n return 'application/octet-stream';\n}\n\nfunction matchesPrefix(content: Buffer, prefix: number[]): boolean {\n if (content.length < prefix.length) return false;\n for (let i = 0; i < prefix.length; i++) {\n if (content[i] !== prefix[i]) return false;\n }\n return true;\n}\n","// Generation create→wait→result orchestration (Phase 4c). The transport control\n// flow that wraps the generate job lifecycle: POST /jobs, then (if waiting)\n// longPoll the job until it reaches a terminal state, else project the create\n// response into a result.\n//\n// Follows the Phase-4 orchestration-injection pattern: a REQUIRED ApiClient, the\n// response schemas + terminal predicate + create-projection INJECTED, UX-free\n// and DISK-free. Reference-image resolution and request-body shaping stay in the\n// CLI; the SDK receives an already-built body. See\n// docs-internal/decisions/sdk-orchestration-injection-pattern.md.\n\nimport type { ZodTypeAny } from 'zod';\n\nimport type { ApiClient } from '../http/client.js';\nimport { longPoll } from '../long-poll.js';\n\nexport interface WaitForGenerationParams<TResult> {\n client: ApiClient;\n jobId: string;\n timeoutMs: number;\n // Per-round server hold in seconds (the CLI passes SERVER_LONG_POLL_SECONDS).\n serverWaitSeconds: number;\n signal?: AbortSignal;\n // Injected GenerationResultSchema (jobs.ts stays in the CLI).\n resultSchema: ZodTypeAny;\n // Injected; the CLI passes (r) => isTerminalStatus(r.status).\n isTerminal: (result: TResult) => boolean;\n}\n\n// Long-polls GET /jobs/{id}?wait=N until the injected predicate reports terminal\n// (or the overall deadline / abort fires — handled inside longPoll).\nexport function waitForGeneration<TResult>(\n params: WaitForGenerationParams<TResult>,\n): Promise<TResult> {\n return longPoll<TResult>({\n // Forward the iteration signal so the in-flight server hold is aborted as\n // soon as the overall deadline expires — otherwise `--timeout 1` would still\n // block for the full server long-poll round.\n fetcher: (args) =>\n params.client.request<TResult>({\n method: 'GET',\n path: `/jobs/${encodeURIComponent(params.jobId)}`,\n query: { wait: params.serverWaitSeconds },\n responseSchema: params.resultSchema,\n signal: args?.signal,\n }),\n isTerminal: params.isTerminal,\n timeoutMs: params.timeoutMs,\n signal: params.signal,\n });\n}\n\nexport interface CreateGenerationParams<TCreate extends { jobId: string }, TResult> {\n // REQUIRED — there is no config fallback in the SDK. The CLI resolves config\n // and constructs the client before calling.\n client: ApiClient;\n // Already built + validated by the CLI (buildRequestBody) — the SDK never\n // shapes or validates the request, and never resolves reference images.\n body: unknown;\n modelSlug: string;\n wait: boolean;\n timeoutMs: number;\n serverWaitSeconds: number;\n signal?: AbortSignal;\n // Injected GenerateCreateResponseSchema.\n createSchema: ZodTypeAny;\n // Injected GenerationResultSchema (for the wait path).\n resultSchema: ZodTypeAny;\n isTerminal: (result: TResult) => boolean;\n // Injected projection of the create response → result, for the no-wait branch.\n projectCreated: (created: TCreate, modelSlug: string) => TResult;\n}\n\nexport async function createGeneration<TCreate extends { jobId: string }, TResult>(\n params: CreateGenerationParams<TCreate, TResult>,\n): Promise<TResult> {\n const created = await params.client.request<TCreate>({\n method: 'POST',\n path: '/jobs',\n body: params.body,\n responseSchema: params.createSchema,\n signal: params.signal,\n });\n\n if (!params.wait) {\n return params.projectCreated(created, params.modelSlug);\n }\n\n return waitForGeneration<TResult>({\n client: params.client,\n jobId: created.jobId,\n timeoutMs: params.timeoutMs,\n serverWaitSeconds: params.serverWaitSeconds,\n signal: params.signal,\n resultSchema: params.resultSchema,\n isTerminal: params.isTerminal,\n });\n}\n","// Sparse exit-code mapping for every error the CLI can surface.\n//\n// The 37 RFC codes come from `docs-internal/agents/01-day1-rfc/01-tool-surface.md`\n// §5 (35 server codes) and `02-oauth.md` §2.6 (CREDENTIALS_LOCKED,\n// CREDENTIALS_PERMISSIONS_LOOSE), remapped per Phase 8 Q7 of\n// `wave-1-investigation.md`.\n//\n// 1A.1 introduced five additional codes beyond Q7 — they are mapped here using\n// the same Q7 category semantics: auth (3), permission (4), quota (5),\n// network (6), conflict (7), runtime (1), usage (2), signal (130), success (0).\n//\n// Four CLI-synthetic codes cover failure modes only the client can observe\n// (network errors after retries exhausted, abort timeouts, parse failures,\n// schema mismatches).\n\nimport type { ApiErrorCode } from '@clickraft/sdk';\n\nimport type { AuthErrorCode } from '../auth/errors.js';\n\n// The server/client error-code taxonomy now lives in @clickraft/sdk. Re-export\n// both so existing `from '../errors/codes.js'` importers keep resolving.\n// AllErrorCode stays CLI-side (AuthErrorCode is CLI-only); it composes the SDK's\n// ApiErrorCode (= ServerErrorCode | ClientErrorCode) with the auth codes,\n// preserving the exact same membership as the previous three-way union.\nexport type { ClientErrorCode, ServerErrorCode } from '@clickraft/sdk';\n\nexport type AllErrorCode = ApiErrorCode | AuthErrorCode;\n\nexport type ExitCode = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 130;\n\nexport type ErrorCategory =\n | 'success'\n | 'runtime'\n | 'usage'\n | 'auth'\n | 'permission'\n | 'quota'\n | 'network'\n | 'conflict'\n | 'signal';\n\nexport interface ExitCodeMapping {\n exitCode: ExitCode;\n category: ErrorCategory;\n retryable: boolean;\n hint?: string;\n}\n\nconst LOGIN_HINT = 'Run `clickraft login` to authenticate.';\nconst RELOGIN_HINT = 'Run `clickraft login` to refresh.';\n\nexport const EXIT_CODE_MAP: Record<AllErrorCode, ExitCodeMapping> = {\n // --- 37 Phase 8 Q7 codes ----------------------------------------------------\n AUTH_TOKEN_MISSING: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Set `CLICKRAFT_TOKEN` or run `clickraft login`.',\n },\n AUTH_TOKEN_INVALID: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'The token is malformed or unknown. Run `clickraft login`.',\n },\n AUTH_TOKEN_EXPIRED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: RELOGIN_HINT,\n },\n AUTH_TOKEN_REVOKED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Token was revoked. Run `clickraft login` to mint a new one.',\n },\n AUTH_TOKEN_SCOPE_INSUFFICIENT: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'This token does not have the required scope. Re-run `clickraft login` selecting the needed scopes.',\n },\n AUTH_ORG_MISMATCH: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: \"This token's org no longer exists or you have been removed.\",\n },\n AUTH_DEVICE_CODE_PENDING: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Continue polling.',\n },\n AUTH_DEVICE_CODE_EXPIRED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Device code expired. Re-run `clickraft login`.',\n },\n AUTH_DEVICE_CODE_SLOW_DOWN: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Increase polling interval (Retry-After).',\n },\n IDEMPOTENCY_KEY_MISSING: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Add `X-Idempotency-Key` header (or `--idempotency-key`).',\n },\n IDEMPOTENCY_KEY_CONFLICT: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'Same key was used with a different request body. Use a new key.',\n },\n PLAN_FEATURE_LOCKED: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'API access is not enabled on your plan. Visit billing settings.',\n },\n PLAN_QUOTA_EXCEEDED: {\n exitCode: 5,\n category: 'quota',\n retryable: false,\n hint: 'Daily API quota exhausted. Wait, or upgrade your plan.',\n },\n INSUFFICIENT_CREDITS: {\n exitCode: 5,\n category: 'quota',\n retryable: false,\n hint: 'Top up credits to retry.',\n },\n CREDIT_DEDUCTION_FAILED: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Could not charge credits. Retry; no charge was made.',\n },\n RATE_LIMITED: {\n exitCode: 5,\n category: 'quota',\n retryable: true,\n hint: 'Slow down. Honor Retry-After.',\n },\n INPUT_INVALID_FORMAT: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Check input format and try again.',\n },\n INPUT_TOO_LONG: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Field exceeded max length.',\n },\n WORKFLOW_VALIDATION_FAILED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Run `workflow validate` for the full list of errors.',\n },\n WORKFLOW_NODE_TYPE_UNKNOWN: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Run `clickraft nodes list` for the current set of node types.',\n },\n CANVAS_REV_MISMATCH: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'The workflow was updated elsewhere. Re-fetch and retry with the current canvas_rev.',\n },\n CANVAS_REV_REQUIRED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Include --canvas-rev or use --auto-rev.',\n },\n WORKER_UNREACHABLE: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Collaboration service temporarily unavailable. Retry.',\n },\n IDEMPOTENCY_IN_PROGRESS: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'A request with this idempotency key is currently in-flight. Retry in a moment.',\n },\n TOKEN_NAME_INVALID: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Agent token name is malformed.',\n },\n WORKFLOW_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'No workflow with that ID in your org.',\n },\n NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Resource not found.',\n },\n NODE_TYPE_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Run `clickraft nodes list` for the current set of node types.',\n },\n FEATURE_DISABLED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'This endpoint is not enabled. Contact support if you believe this is in error.',\n },\n FORBIDDEN: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'Your role does not permit this action.',\n },\n MODEL_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Unknown `modelSlug`. Run `brand-model list` for the current set.',\n },\n PROVIDER_UNAVAILABLE: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Provider is temporarily unavailable. Retry shortly.',\n },\n STORAGE_UPLOAD_FAILED: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Upload failed mid-stream. Retry.',\n },\n STORAGE_QUOTA_EXCEEDED: {\n exitCode: 5,\n category: 'quota',\n retryable: false,\n hint: 'Org storage quota exceeded. Free space or upgrade.',\n },\n GEN_CONTENT_REFUSAL: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'The model declined the request via safety policy.',\n },\n GEN_OUTPUT_SCHEMA_MISMATCH: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Provider returned malformed output. Full refund issued. Retry.',\n },\n GEN_EMPTY_OUTPUT: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Provider returned no usable output. Full refund issued. Retry.',\n },\n GEN_ITEM_COUNT_MISMATCH: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Partial output kept; no refund.',\n },\n AGENT_FINGERPRINT_REJECTED: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'This client identification is not permitted. Contact support.',\n },\n INTERNAL_ERROR: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Server error. Retry; if it persists, contact support with the request ID.',\n },\n CREDENTIALS_LOCKED: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Another CLI invocation holds the credentials lock. Retry shortly.',\n },\n CREDENTIALS_PERMISSIONS_LOOSE: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Credentials file mode is wider than 0600; continuing.',\n },\n\n // --- 5 additional codes introduced by 1A.1 ---------------------------------\n AUTH_ACCESS_DENIED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'You denied the OAuth grant. Re-run `clickraft login` to retry.',\n },\n AUTH_FLOW_CANCELLED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Authentication was cancelled. Re-run `clickraft login`.',\n },\n CREDENTIALS_CORRUPT: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Credentials file is unreadable. Remove it and run `clickraft login`.',\n },\n CREDENTIALS_NOT_FOUND: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: LOGIN_HINT,\n },\n CREDENTIALS_PROFILE_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'No such profile. Use `clickraft auth profiles` to list available profiles.',\n },\n\n // --- 8 brand model resolution codes -----------------------------------------\n BRAND_MODEL_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'No brand model with that ID. Run `clickraft brand-model list`.',\n },\n BRAND_MODEL_NOT_A_MODEL: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'The specified asset is not a brand model.',\n },\n BRAND_MODEL_NOT_ACTIVE: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Brand model is not active. Check its status in the dashboard.',\n },\n BRAND_MODEL_NO_REFERENCES: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Brand model has no reference images. Upload references first.',\n },\n BRAND_MODEL_POSE_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Requested pose not found. Valid: front, 3/4-right, right, left, 3/4-left, back, approved.',\n },\n BRAND_MODEL_DUPLICATE_ID: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Same brand model ID appears more than once.',\n },\n MODEL_DOES_NOT_SUPPORT_REFERENCES: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'This model does not support brand model references.',\n },\n REFERENCE_LIMIT_EXCEEDED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Too many reference images. Check model limits.',\n },\n\n // --- 8 product reference resolver codes -------------------------------------\n PRODUCT_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'No product with that ID in your org. Run `clickraft product list`.',\n },\n PRODUCT_DUPLICATE_REFERENCE: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Same (productId, imageId) tuple appears twice in the request.',\n },\n PRODUCT_IMAGE_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'imageId does not exist in the product images.',\n },\n PRODUCT_IMAGE_MISMATCH: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'imageId belongs to a different product.',\n },\n PRODUCT_SYNC_ERROR: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: \"Product sync status is 'error'. Re-sync or use a different product.\",\n },\n PRODUCT_DELETED_UPSTREAM: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Product was deleted upstream. Remove it or re-sync.',\n },\n PRODUCT_NO_PRIMARY_IMAGE: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Product has no primary image. Specify --product <id>:<imageId> explicitly.',\n },\n PRODUCT_SOURCE_MANAGED: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'Product is managed by an external integration.',\n },\n\n // --- 5 product create codes (`POST /products`) ------------------------------\n //\n // `lib/errors/app-error.ts` in the app repo annotates the four asset codes\n // \"CLI exit 7\". That is wrong and the app repo is being corrected: exit 7 is\n // the `conflict` category, reserved here for idempotency and canvas-rev\n // conflicts, and none of these are conflicts. Exit-code policy is CLI-side by\n // design (see the SDK's `errors/codes.ts` header), so the mapping below is the\n // authority.\n //\n // The three `usage` codes are all \"the caller named something unusable\", which\n // is exit 2 for MODEL_NOT_FOUND and WORKFLOW_NOT_FOUND already.\n PRODUCT_IMAGE_ASSET_DUPLICATE: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'The same asset id appears more than once in the images list.',\n },\n PRODUCT_IMAGE_ASSET_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'One or more asset ids do not exist in your organization. Upload them first, or check the ids.',\n },\n PRODUCT_IMAGE_ASSET_NOT_IMAGE: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'One or more referenced assets are not images.',\n },\n // Deliberately NOT `usage`. The asset row exists and belongs to the caller;\n // its bytes never landed, which is an upload that half-completed on our side.\n // Retrying the create cannot help — the asset has to be uploaded again — so\n // this is runtime/non-retryable rather than a caller mistake.\n PRODUCT_IMAGE_ASSET_INCOMPLETE: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'An asset has no uploaded bytes. Re-run `clickraft upload` for it, then retry.',\n },\n // `retryable: true` is load-bearing, not decorative: this table is the single\n // source of retryability for the SDK client via `isRetryableServerCode`, so\n // flipping it to false makes the CLI ignore a 503 the server explicitly marked\n // retryable and sent a Retry-After for.\n STORAGE_UNAVAILABLE: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Object storage is temporarily unavailable. Retry with the same idempotency key.',\n },\n\n // --- 4 CLI-synthetic codes --------------------------------------------------\n NETWORK_ERROR: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Network connection failed. Check connectivity and retry.',\n },\n TIMEOUT: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Request timed out. Retry; consider increasing the timeout.',\n },\n PARSE_ERROR: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Server returned an unexpected response. Contact support with the request ID.',\n },\n SCHEMA_MISMATCH: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Server response did not match the expected schema. Update the CLI.',\n },\n};\n\n// KNOWN_SERVER_CODES (the allow-list the HTTP client trusts from the server)\n// now lives in @clickraft/sdk, derived from SERVER_ERROR_CODES. It is the\n// server taxonomy exactly — the four CLI-only client codes (NETWORK_ERROR,\n// TIMEOUT, PARSE_ERROR, SCHEMA_MISMATCH) are never valid server `error.code`s.\n\nexport function getMapping(code: AllErrorCode): ExitCodeMapping | undefined {\n return EXIT_CODE_MAP[code];\n}\n\nexport function getExitCode(code: AllErrorCode): ExitCode {\n return EXIT_CODE_MAP[code]?.exitCode ?? 1;\n}\n\nexport function getHint(code: AllErrorCode): string | undefined {\n return EXIT_CODE_MAP[code]?.hint;\n}\n\nexport function isRetryable(code: AllErrorCode): boolean {\n return EXIT_CODE_MAP[code]?.retryable ?? false;\n}\n\n// Phase 8 Q10 — envelope error codes are `E_*` prefixed. Idempotent against\n// already-prefixed input so an upstream caller cannot accidentally produce\n// `E_E_FOO`. Param is widened to `string` because unknown server codes flow\n// through here before being mapped to INTERNAL_ERROR (see S1).\nexport function toEnvelopeCode(code: string): string {\n return code.startsWith('E_') ? code : `E_${code}`;\n}\n\n// SIGINT is delivered as a process signal, not as an AllErrorCode. CLIs map it\n// to exit 130 (POSIX 128 + 2). Kept here as a named constant so callers don't\n// hard-code the number.\nexport const SIGINT_EXIT_CODE: ExitCode = 130;\n","// The HTTP client now lives in @clickraft/sdk (Phase 3). This module re-exports\n// it from its historical path so existing `from '../api/client.js'` importers\n// keep resolving unchanged, and adds the CLI's policy-injecting factory.\n//\n// Retryability and warning emission are CLI policy: the SDK client takes them as\n// injected callbacks. `createApiClient` wires `EXIT_CODE_MAP` (the single source\n// of retryability truth, which stays in the CLI) and a console.warn sink.\n\nimport {\n createClient,\n type ApiClient,\n type CloudflareAccessCredentials,\n type ServerErrorCode,\n} from '@clickraft/sdk';\n\nimport { EXIT_CODE_MAP } from '../errors/codes.js';\n\nexport { ApiClient, ApiError, createClient, parseRetryAfterHeader } from '@clickraft/sdk';\nexport type {\n ApiClientOptions,\n ApiErrorMeta,\n HttpMethod,\n RequestOptions,\n ServerErrorCode,\n} from '@clickraft/sdk';\n\n// SINGLE source of truth for retryability is the CLI's EXIT_CODE_MAP. `code` is\n// always a known ServerErrorCode at the call site (unknown codes are folded to\n// INTERNAL_ERROR before this runs), so the index is total. The HTTP-status\n// fallback for the no-predicate path lives in the SDK client, which has the\n// statusCode this predicate signature deliberately does not.\nexport const isRetryableServerCode = (code: ServerErrorCode): boolean =>\n EXIT_CODE_MAP[code].retryable;\n\nexport const onWarning = (msg: string): void => {\n console.warn(msg);\n};\n\n// Single CLI entry point for constructing a client: maps the resolved config\n// fields onto ApiClientOptions and injects the two policy callbacks. All\n// production construction sites go through this.\nexport function createApiClient(opts: {\n apiBaseUrl: string;\n accessToken: string | null;\n signal?: AbortSignal;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n}): ApiClient {\n return createClient({ ...opts, onWarning, isRetryableServerCode });\n}\n","// Auth + credentials error codes used by 1A.1. The full 37-code map and the\n// mapping to sparse exit codes (0-7, 130) lands in 1A.2 — see\n// wave-1-investigation.md Phase 8 Q7.\n//\n// AUTH_FLOW_CANCELLED extends the catalog in 02-oauth.md §6.1 to cover\n// AbortSignal-driven cancellation of the device-flow loop.\nexport type AuthErrorCode =\n | 'AUTH_TOKEN_MISSING'\n | 'AUTH_TOKEN_INVALID'\n | 'AUTH_TOKEN_EXPIRED'\n | 'AUTH_TOKEN_REVOKED'\n | 'AUTH_DEVICE_CODE_PENDING'\n | 'AUTH_DEVICE_CODE_EXPIRED'\n | 'AUTH_DEVICE_CODE_SLOW_DOWN'\n | 'AUTH_ACCESS_DENIED'\n | 'AUTH_FLOW_CANCELLED'\n | 'CREDENTIALS_LOCKED'\n | 'CREDENTIALS_PERMISSIONS_LOOSE'\n | 'CREDENTIALS_CORRUPT'\n | 'CREDENTIALS_NOT_FOUND'\n | 'CREDENTIALS_PROFILE_NOT_FOUND';\n\nexport type CredentialsErrorCode = Extract<AuthErrorCode, `CREDENTIALS_${string}`>;\n\nexport class AuthError extends Error {\n public readonly code: AuthErrorCode;\n public override readonly cause?: unknown;\n\n constructor(code: AuthErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'AuthError';\n this.code = code;\n this.cause = cause;\n }\n}\n\nexport class CredentialsError extends Error {\n public readonly code: CredentialsErrorCode;\n public override readonly cause?: unknown;\n\n constructor(code: CredentialsErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'CredentialsError';\n this.code = code;\n this.cause = cause;\n }\n}\n","// CLI-side {ok,data,error,meta} envelope per Phase 8 Q6 of\n// `wave-1-investigation.md`. The envelope is applied only at the `--json`\n// output layer — server endpoints continue to return `{ data: T }` /\n// `{ error: { ... } }` per `01-tool-surface.md` §3.7.\n//\n// Envelope error codes carry the `E_*` prefix per Phase 8 Q10 (\"Stable\n// E_* codes are public API\"). `retry_after_ms` lives inside `error`, not\n// `meta`, per the Phase 8 Q6 example.\n\nimport { AuthError, CredentialsError, type AuthErrorCode } from '../auth/errors.js';\nimport { EXIT_CODE_MAP, toEnvelopeCode, type AllErrorCode } from '../errors/codes.js';\n\nimport { ApiError } from './client.js';\n\nexport interface EnvelopeMeta {\n request_id?: string;\n command: string;\n version: string;\n duration_ms: number;\n next_cursor?: string;\n}\n\nexport interface SuccessEnvelope<T> {\n ok: true;\n data: T;\n error: null;\n meta: EnvelopeMeta;\n}\n\nexport interface EnvelopeErrorPayload {\n code: string;\n message: string;\n retryable: boolean;\n retry_after_ms?: number;\n request_id?: string;\n hint?: string;\n details?: unknown;\n}\n\nexport interface ErrorEnvelope {\n ok: false;\n data: null;\n error: EnvelopeErrorPayload;\n meta: EnvelopeMeta;\n}\n\nexport type Envelope<T> = SuccessEnvelope<T> | ErrorEnvelope;\n\nexport interface EnvelopeContext {\n startMs: number;\n command: string;\n version: string;\n requestId?: string;\n nextCursor?: string;\n}\n\nexport function wrapSuccess<T>(data: T, ctx: EnvelopeContext): SuccessEnvelope<T> {\n const meta: EnvelopeMeta = {\n command: ctx.command,\n version: ctx.version,\n duration_ms: Math.max(0, Date.now() - ctx.startMs),\n };\n if (ctx.requestId) meta.request_id = ctx.requestId;\n if (ctx.nextCursor) meta.next_cursor = ctx.nextCursor;\n return { ok: true, data, error: null, meta };\n}\n\nexport function wrapError(err: unknown, ctx: EnvelopeContext): ErrorEnvelope {\n const payload = errorToEnvelopePayload(err);\n const meta: EnvelopeMeta = {\n command: ctx.command,\n version: ctx.version,\n duration_ms: Math.max(0, Date.now() - ctx.startMs),\n };\n if (payload.request_id ?? ctx.requestId) {\n meta.request_id = payload.request_id ?? ctx.requestId;\n }\n return { ok: false, data: null, error: payload, meta };\n}\n\nfunction errorToEnvelopePayload(err: unknown): EnvelopeErrorPayload {\n if (err instanceof ApiError) {\n return buildPayload({\n code: err.code,\n message: err.message,\n retryable: err.meta.retryable,\n retryAfterMs: err.meta.retryAfterMs,\n requestId: err.meta.requestId,\n details: err.meta.details,\n hint: err.meta.hint,\n });\n }\n if (err instanceof AuthError || err instanceof CredentialsError) {\n const code = err.code as AuthErrorCode;\n const mapping = EXIT_CODE_MAP[code];\n return buildPayload({\n code,\n message: err.message,\n retryable: mapping?.retryable ?? false,\n });\n }\n // Unknown error — fall back to INTERNAL_ERROR.\n const message = err instanceof Error ? err.message : String(err);\n return buildPayload({\n code: 'INTERNAL_ERROR' as AllErrorCode,\n message,\n retryable: false,\n });\n}\n\nfunction buildPayload(args: {\n code: AllErrorCode;\n message: string;\n retryable: boolean;\n retryAfterMs?: number;\n requestId?: string;\n details?: unknown;\n hint?: string;\n}): EnvelopeErrorPayload {\n const mapping = EXIT_CODE_MAP[args.code];\n const payload: EnvelopeErrorPayload = {\n code: toEnvelopeCode(args.code),\n message: args.message,\n retryable: args.retryable,\n };\n if (typeof args.retryAfterMs === 'number') payload.retry_after_ms = args.retryAfterMs;\n if (args.requestId) payload.request_id = args.requestId;\n const resolvedHint = args.hint ?? mapping?.hint;\n if (resolvedHint) payload.hint = resolvedHint;\n if (args.details != null) payload.details = args.details;\n return payload;\n}\n","import {\n access,\n chmod,\n mkdir,\n readFile,\n rename,\n rm,\n stat,\n unlink,\n writeFile,\n} from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport * as lockfile from 'proper-lockfile';\n\nimport { getCredentialsPath } from '../config/paths.js';\n\nimport { CredentialsError } from './errors.js';\nimport {\n CredentialsFileSchema,\n CredentialsProfileSchema,\n type CredentialsFile,\n type CredentialsProfile,\n} from './types.js';\n\n// proper-lockfile substitutes for the POSIX flock contract described in\n// 02-oauth.md §2.6. It uses mkdir-based locking (a `<path>.lock/` directory\n// adjacent to the target) rather than fcntl/flock, which makes it work\n// uniformly across Linux, macOS, and Windows. The functional outcome —\n// mutual exclusion + atomic-rename writes — is preserved.\n//\n// `realpath: false` is required so we can lock a not-yet-existent file\n// during first write (proper-lockfile's default resolves realpath and\n// fails on ENOENT). Retry budget caps at ~3.8s, well under the 5s\n// CREDENTIALS_LOCKED threshold.\n//\n// `stale: 5000` matches the spec's ≤5s lock-acquisition budget — a holder\n// killed mid-write (SIGKILL / OOM) won't strand the lock for 10s (default).\n// `update: 2000` makes live holders refresh their lock mtime every 2s, well\n// inside the stale window, so a healthy process is never mistaken for dead.\nconst LOCK_OPTS = {\n retries: { retries: 10, factor: 1.5, minTimeout: 100, maxTimeout: 500 },\n realpath: false,\n stale: 5000,\n update: 2000,\n} as const;\n\nconst IS_WINDOWS = process.platform === 'win32';\n\nexport async function readCredentials(path?: string): Promise<CredentialsFile | null> {\n const target = path ?? getCredentialsPath();\n\n try {\n await access(target);\n } catch {\n return null;\n }\n\n if (!IS_WINDOWS) {\n try {\n const s = await stat(target);\n if ((s.mode & 0o077) !== 0) {\n const modeStr = (s.mode & 0o777).toString(8).padStart(3, '0');\n console.warn(\n `[clickraft] credentials file at ${target} has loose permissions (mode ${modeStr}). ` +\n `Run \\`chmod 600 ${target}\\` to restrict it.`,\n );\n }\n } catch {\n // stat failure shouldn't block reading\n }\n }\n\n return parseCredentialsFile(await readFile(target, 'utf8'), target);\n}\n\nexport async function writeCredentials(file: CredentialsFile, path?: string): Promise<void> {\n const target = path ?? getCredentialsPath();\n const validated = validateFile(file);\n await withLock(target, async () => {\n await writeAtomic(target, serialize(validated));\n });\n}\n\nexport async function setProfile(\n name: string,\n profile: CredentialsProfile,\n path?: string,\n): Promise<void> {\n const target = path ?? getCredentialsPath();\n const validatedProfile = validateProfile(profile);\n await withLock(target, async () => {\n const current = (await readUnderLock(target)) ?? {\n version: 1 as const,\n defaultProfile: name,\n profiles: {},\n };\n current.profiles[name] = validatedProfile;\n await writeAtomic(target, serialize(current));\n });\n}\n\nexport async function removeProfile(name: string, path?: string): Promise<void> {\n const target = path ?? getCredentialsPath();\n await withLock(target, async () => {\n const current = await readUnderLock(target);\n if (!current) {\n throw new CredentialsError(\n 'CREDENTIALS_NOT_FOUND',\n `No credentials file at ${target}; nothing to remove.`,\n );\n }\n if (!(name in current.profiles)) {\n throw new CredentialsError(\n 'CREDENTIALS_PROFILE_NOT_FOUND',\n `Profile \"${name}\" not found in credentials file.`,\n );\n }\n delete current.profiles[name];\n if (current.defaultProfile === name) {\n const remaining = Object.keys(current.profiles);\n current.defaultProfile = remaining[0] ?? '';\n }\n await writeAtomic(target, serialize(current));\n });\n}\n\nexport async function deleteCredentials(path?: string): Promise<void> {\n const target = path ?? getCredentialsPath();\n await withLock(target, async () => {\n try {\n await rm(target);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n });\n}\n\nasync function withLock<T>(target: string, fn: () => Promise<T>): Promise<T> {\n await ensureDir(dirname(target));\n let release: () => Promise<void>;\n try {\n release = await lockfile.lock(target, LOCK_OPTS);\n } catch (err) {\n throw new CredentialsError(\n 'CREDENTIALS_LOCKED',\n `Failed to acquire exclusive lock on ${target}. ` +\n `Another clickraft process may be holding it; retry shortly.`,\n err,\n );\n }\n try {\n return await fn();\n } finally {\n try {\n await release();\n } catch {\n // best-effort release; the lock dir will be cleaned up by proper-lockfile's stale detection\n }\n }\n}\n\nasync function readUnderLock(target: string): Promise<CredentialsFile | null> {\n try {\n await access(target);\n } catch {\n return null;\n }\n return parseCredentialsFile(await readFile(target, 'utf8'), target);\n}\n\nfunction validateFile(file: CredentialsFile): CredentialsFile {\n const result = CredentialsFileSchema.safeParse(file);\n if (!result.success) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n 'Refusing to write credentials file: input failed schema validation.',\n result.error,\n );\n }\n return result.data;\n}\n\nfunction validateProfile(profile: CredentialsProfile): CredentialsProfile {\n const result = CredentialsProfileSchema.safeParse(profile);\n if (!result.success) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n 'Refusing to write credentials profile: input failed schema validation.',\n result.error,\n );\n }\n return result.data;\n}\n\nfunction parseCredentialsFile(raw: string, target: string): CredentialsFile {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n `credentials file at ${target} is not valid JSON. Run \\`clickraft login\\` to re-authenticate.`,\n err,\n );\n }\n const result = CredentialsFileSchema.safeParse(parsed);\n if (!result.success) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n `credentials file at ${target} has an unexpected shape. Run \\`clickraft login\\` to re-authenticate.`,\n result.error,\n );\n }\n return result.data;\n}\n\nasync function ensureDir(dir: string): Promise<void> {\n const opts = IS_WINDOWS ? { recursive: true } : { recursive: true, mode: 0o700 };\n await mkdir(dir, opts);\n}\n\nasync function writeAtomic(target: string, payload: string): Promise<void> {\n const tmp = `${target}.tmp`;\n const writeOpts = IS_WINDOWS\n ? { encoding: 'utf8' as const }\n : { encoding: 'utf8' as const, mode: 0o600 };\n await writeFile(tmp, payload, writeOpts);\n try {\n if (!IS_WINDOWS) {\n // chmod is idempotent and guards against umask-induced mode drift\n // on filesystems where the writeFile mode flag is advisory only.\n await chmod(tmp, 0o600);\n }\n await rename(tmp, target);\n } catch (err) {\n try {\n await unlink(tmp);\n } catch {\n // best-effort cleanup\n }\n throw err;\n }\n}\n\nfunction serialize(file: CredentialsFile): string {\n return JSON.stringify(file, null, 2) + '\\n';\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// Resolved per 02-oauth.md §2.6 + XDG Base Directory Specification.\n// 1. XDG_CONFIG_HOME (if set) → $XDG_CONFIG_HOME/clickraft\n// 2. Windows → %APPDATA%/clickraft (fallback: <home>/AppData/Roaming/clickraft)\n// 3. Otherwise (Linux/macOS) → ~/.config/clickraft\n\nexport interface PathResolutionContext {\n env?: NodeJS.ProcessEnv;\n platform?: NodeJS.Platform;\n home?: string;\n}\n\nconst CREDENTIALS_FILE = 'credentials.json';\nconst APP_DIR = 'clickraft';\n\nexport function getConfigDir(ctx: PathResolutionContext = {}): string {\n const env = ctx.env ?? process.env;\n const platform = ctx.platform ?? process.platform;\n const home = ctx.home ?? homedir();\n\n const xdg = env.XDG_CONFIG_HOME;\n if (xdg && xdg.length > 0) {\n return join(xdg, APP_DIR);\n }\n\n if (platform === 'win32') {\n const appData = env.APPDATA;\n if (appData && appData.length > 0) {\n return join(appData, APP_DIR);\n }\n return join(home, 'AppData', 'Roaming', APP_DIR);\n }\n\n return join(home, '.config', APP_DIR);\n}\n\nexport function getCredentialsPath(ctx: PathResolutionContext = {}): string {\n return join(getConfigDir(ctx), CREDENTIALS_FILE);\n}\n","import { z } from 'zod';\n\n// OAuth 2.0 Device Authorization Grant (RFC 8628) request/response shapes.\n// Source of truth: 02-oauth.md §3.1.\n\nexport const DeviceAuthorizationRequestSchema = z.object({\n client_id: z.string(),\n scope: z.string(),\n});\nexport type DeviceAuthorizationRequest = z.infer<typeof DeviceAuthorizationRequestSchema>;\n\n// `verification_uri_complete` is OPTIONAL per RFC 8628 §3.2; `interval`\n// defaults to 5 seconds when absent per §3.5. `user_code` is intentionally\n// unstructured: RFC 8628 §6.1 leaves the format to the server, so the CLI\n// only checks it is non-empty.\nexport const DeviceAuthorizationResponseSchema = z.object({\n device_code: z.string(),\n user_code: z.string().min(1),\n verification_uri: z.string().url(),\n verification_uri_complete: z.string().url().optional(),\n expires_in: z.number().int().positive(),\n interval: z.number().int().positive().default(5),\n});\nexport type DeviceAuthorizationResponse = z.infer<typeof DeviceAuthorizationResponseSchema>;\n\nexport const DeviceTokenPollRequestSchema = z.object({\n client_id: z.string(),\n device_code: z.string(),\n grant_type: z.literal('urn:ietf:params:oauth:grant-type:device_code'),\n});\nexport type DeviceTokenPollRequest = z.infer<typeof DeviceTokenPollRequestSchema>;\n\nexport const TokenResponseSchema = z.object({\n access_token: z.string(),\n token_type: z.literal('Bearer'),\n expires_in: z.number().int().positive(),\n scope: z.string(),\n});\nexport type TokenResponse = z.infer<typeof TokenResponseSchema>;\n\nexport const DeviceTokenPollErrorCodeSchema = z.enum([\n 'authorization_pending',\n 'slow_down',\n 'access_denied',\n 'expired_token',\n 'invalid_client',\n 'invalid_grant',\n 'unauthorized_client',\n 'unsupported_grant_type',\n 'invalid_scope',\n]);\nexport type DeviceTokenPollErrorCode = z.infer<typeof DeviceTokenPollErrorCodeSchema>;\n\nexport const DeviceTokenPollErrorSchema = z.object({\n error: DeviceTokenPollErrorCodeSchema,\n error_description: z.string().optional(),\n});\nexport type DeviceTokenPollError = z.infer<typeof DeviceTokenPollErrorSchema>;\n\n// Credentials file shape. Source of truth: 02-oauth.md §2.6.\n// No refreshToken field — 90-day access tokens only per 02-oauth.md §2.5.\n\nexport const CredentialsProfileSchema = z\n .object({\n apiBaseUrl: z.string().url(),\n accessToken: z.string(),\n tokenType: z.literal('Bearer'),\n tokenPrefix: z.string(),\n organizationId: z.string().uuid(),\n organizationSlug: z.string(),\n userId: z.string().uuid(),\n scopes: z.array(z.string()),\n expiresAt: z.string().datetime(),\n issuedAt: z.string().datetime(),\n clientId: z.string(),\n })\n .strict();\nexport type CredentialsProfile = z.infer<typeof CredentialsProfileSchema>;\n\nexport const CredentialsFileSchema = z\n .object({\n version: z.literal(1),\n defaultProfile: z.string(),\n profiles: z.record(z.string(), CredentialsProfileSchema),\n })\n .strict();\nexport type CredentialsFile = z.infer<typeof CredentialsFileSchema>;\n","import type { CloudflareAccessCredentials } from '@clickraft/sdk';\n\nimport { ApiError } from '../api/client.js';\nimport { readCredentials } from '../auth/credentials.js';\n\nimport { getCredentialsPath } from './paths.js';\n\n// Per-field precedence ladder per wave-1-investigation.md Phase 8 Q4:\n// accessToken : --token → CLICKRAFT_TOKEN → profile.accessToken → null\n// profileName : --profile → CLICKRAFT_PROFILE → file.defaultProfile → \"default\"\n// apiBaseUrl : --api-base-url → CLICKRAFT_API_BASE_URL → profile.apiBaseUrl → DEFAULT_API_BASE_URL\n//\n// The credentials file is read only when at least one field still needs to\n// resolve from it after flag/env are applied.\n\nexport const DEFAULT_API_BASE_URL = 'https://clickraft.ai/api/agents/v1';\nexport const DEFAULT_PROFILE_NAME = 'default';\n\nexport const TOKEN_ENV_VAR = 'CLICKRAFT_TOKEN';\nexport const PROFILE_ENV_VAR = 'CLICKRAFT_PROFILE';\nexport const API_BASE_URL_ENV_VAR = 'CLICKRAFT_API_BASE_URL';\n// Telemetry implementation lands in 1A.3+; the var name is fixed here so all\n// modules import the same constant. Source: PR #104 S1 fix.\nexport const TELEMETRY_DISABLE_ENV_VAR = 'CLICKRAFT_DISABLE_TELEMETRY';\n\nexport const CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR = 'CLOUDFLARE_ACCESS_CLIENT_ID';\nexport const CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR = 'CLOUDFLARE_ACCESS_CLIENT_SECRET';\n\nexport interface ConfigLoaderOptions {\n flagToken?: string;\n flagProfile?: string;\n flagApiBaseUrl?: string;\n env?: NodeJS.ProcessEnv;\n credentialsPath?: string;\n}\n\nexport interface ResolvedConfig {\n accessToken: string | null;\n profileName: string;\n apiBaseUrl: string;\n cloudflareAccess: CloudflareAccessCredentials | null;\n /**\n * Scopes recorded when THIS token was minted, or `null` when unknown.\n *\n * Populated only when `accessToken` came from the credentials file. A token\n * supplied via `--token` or `CLICKRAFT_TOKEN` has no recorded scopes, and\n * pairing it with the file profile's scopes would answer a question about one\n * token using facts about a different one — so `null`, and callers must treat\n * that as \"cannot check\" rather than \"has nothing\".\n *\n * This is a SNAPSHOT from login, not live truth: scopes can be revoked or\n * widened server-side afterwards. It is good enough to fail fast before a\n * request, never good enough to authorize one. The server's 403 remains the\n * authority (see `assertScope`).\n */\n scopes: string[] | null;\n}\n\nexport async function loadConfig(options: ConfigLoaderOptions = {}): Promise<ResolvedConfig> {\n const env = options.env ?? process.env;\n\n // Validate Cloudflare Access service-token pair before any other work so\n // a misconfigured env fails fast, before file IO or network.\n const cloudflareAccess = loadCloudflareAccess(env);\n\n const flagToken = trim(options.flagToken);\n const envToken = trim(env[TOKEN_ENV_VAR]);\n const flagProfile = trim(options.flagProfile);\n const envProfile = trim(env[PROFILE_ENV_VAR]);\n const flagApiBaseUrl = trim(options.flagApiBaseUrl);\n const envApiBaseUrl = trim(env[API_BASE_URL_ENV_VAR]);\n\n // Determine profile name first — it gates which profile we read from file.\n const profileName = flagProfile ?? envProfile;\n\n // If every field can resolve without the file, skip the read entirely.\n const tokenFromFlagOrEnv = flagToken ?? envToken;\n const apiBaseFromFlagOrEnv = flagApiBaseUrl ?? envApiBaseUrl;\n const needsFile = !tokenFromFlagOrEnv || !apiBaseFromFlagOrEnv || !profileName;\n\n let fileProfileName: string | undefined;\n let fileAccessToken: string | undefined;\n let fileApiBaseUrl: string | undefined;\n let fileScopes: string[] | undefined;\n\n if (needsFile) {\n const path = options.credentialsPath ?? getCredentialsPath();\n const file = await readCredentials(path);\n if (file) {\n const resolvedName = profileName ?? file.defaultProfile ?? DEFAULT_PROFILE_NAME;\n fileProfileName = file.defaultProfile;\n const profile = file.profiles[resolvedName];\n if (profile) {\n fileAccessToken = profile.accessToken;\n fileApiBaseUrl = profile.apiBaseUrl;\n fileScopes = profile.scopes;\n }\n }\n }\n\n return {\n accessToken: tokenFromFlagOrEnv ?? fileAccessToken ?? null,\n profileName: profileName ?? fileProfileName ?? DEFAULT_PROFILE_NAME,\n apiBaseUrl: apiBaseFromFlagOrEnv ?? fileApiBaseUrl ?? DEFAULT_API_BASE_URL,\n cloudflareAccess,\n // Scopes describe the FILE's token. If the flag/env token won the\n // precedence ladder above, the scopes we happen to have on disk belong to a\n // different credential, so report `null` rather than something plausible\n // and wrong.\n scopes: tokenFromFlagOrEnv ? null : (fileScopes ?? null),\n };\n}\n\nfunction loadCloudflareAccess(env: NodeJS.ProcessEnv): CloudflareAccessCredentials | null {\n const clientId = trim(env[CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR]);\n const clientSecret = trim(env[CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR]);\n\n if (clientId && clientSecret) {\n return { clientId, clientSecret };\n }\n if (!clientId && !clientSecret) {\n return null;\n }\n\n const onlySet = clientId\n ? CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR\n : CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR;\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `${CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR} and ${CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR} must both be set, or neither. Got only ${onlySet}.`,\n { retryable: false },\n );\n}\n\nfunction trim(value: string | undefined): string | undefined {\n if (value === undefined) return undefined;\n const t = value.trim();\n return t.length === 0 ? undefined : t;\n}\n","import { BalanceResponseSchema, type BalanceData } from '@clickraft/sdk';\n\nimport { createApiClient, type ApiClient } from '../api/client.js';\nimport { AuthError } from '../auth/errors.js';\nimport { loadConfig } from '../config/loader.js';\n\nexport interface BalanceOptions {\n profile?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nexport async function getBalance(options: BalanceOptions): Promise<BalanceData> {\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const data = await client.request<BalanceData>({\n method: 'GET',\n path: '/balance',\n responseSchema: BalanceResponseSchema,\n signal: options.signal,\n });\n\n return data;\n}\n","import { BrandModelsListResponseSchema, type BrandModelSummary } from '@clickraft/sdk';\nimport { z } from 'zod';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface BrandModelListOptions {\n profile?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nexport async function listBrandModels(\n options: BrandModelListOptions,\n): Promise<BrandModelSummary[]> {\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const data = await client.request<z.infer<typeof BrandModelsListResponseSchema>>({\n method: 'GET',\n path: '/brand-models',\n responseSchema: BrandModelsListResponseSchema,\n signal: options.signal,\n });\n\n return data.brandModels;\n}\n","// `clickraft upload <file-path>` — uploads a local file to the Agents API.\n//\n// Two-step flow per RFC §4.6 (POST /assets metadata + PUT bytes to the signed\n// GCS URL with retry-once). As of Phase 4b the buffer-onward orchestration lives\n// in @clickraft/sdk (uploadAsset); this module is the thin CLI wrapper that owns\n// the filesystem side: stat → size validation → read → fs-error mapping, then\n// hands the Buffer to the SDK with the client + injected response schema.\n\nimport { readFile, stat } from 'node:fs/promises';\nimport { basename } from 'node:path';\n\nimport { uploadAsset, MAX_UPLOAD_SIZE_BYTES, UploadResponseSchema } from '@clickraft/sdk';\nimport { type Dispatcher } from 'undici';\n\nimport { ApiError, createApiClient, type ApiClient } from '../api/client.js';\nimport { loadConfig } from '../config/loader.js';\n\nexport const DEFAULT_UPLOAD_SCOPE = 'user-uploads';\n\nexport interface UploadOptions {\n filePath: string;\n scope?: string;\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n // Injected when the caller (e.g. `generate create` for path auto-upload)\n // already has an ApiClient; saves a redundant config + client construction.\n client?: ApiClient;\n // Injected for testing the GCS PUT against MockAgent without an extra round\n // of undici plumbing. Threaded through to the SDK upload orchestration.\n putDispatcher?: Dispatcher;\n}\n\nexport interface UploadResult {\n assetId: string;\n publicUrl: string;\n deduplicated: boolean;\n bytes: number;\n contentHash: string;\n}\n\n// Public entry — used by `clickraft upload` (CLI command) and by\n// generate/create's reference-image path auto-upload.\nexport async function uploadFile(opts: UploadOptions): Promise<UploadResult> {\n const scope = opts.scope ?? DEFAULT_UPLOAD_SCOPE;\n // stat() first so oversized files are rejected before we buffer them and\n // so missing/EISDIR/EACCES surface as INPUT_INVALID_FORMAT (exit 2) rather\n // than propagating as INTERNAL_ERROR (exit 1).\n const size = await safeStatSize(opts.filePath);\n validateSize(size);\n const content = await safeReadFile(opts.filePath);\n\n const client = opts.client ?? (await buildClient(opts));\n\n // Disk work is done — hand the bytes to the SDK orchestration (POST /assets +\n // PUT-to-GCS with retry-once). The SDK never reads disk.\n return uploadAsset({\n client,\n content,\n filename: basename(opts.filePath),\n scope,\n signal: opts.signal,\n putDispatcher: opts.putDispatcher,\n schema: UploadResponseSchema,\n });\n}\n\nasync function buildClient(opts: UploadOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n\nasync function safeStatSize(filePath: string): Promise<number> {\n let stats;\n try {\n stats = await stat(filePath);\n } catch (err) {\n throw toFsApiError(err, filePath);\n }\n if (stats.isDirectory()) {\n throw new ApiError('INPUT_INVALID_FORMAT', `Expected a file, got a directory: ${filePath}`, {\n retryable: false,\n });\n }\n if (!stats.isFile()) {\n throw new ApiError('INPUT_INVALID_FORMAT', `Expected a regular file: ${filePath}`, {\n retryable: false,\n });\n }\n return stats.size;\n}\n\nasync function safeReadFile(filePath: string): Promise<Buffer> {\n try {\n return await readFile(filePath);\n } catch (err) {\n throw toFsApiError(err, filePath);\n }\n}\n\nfunction toFsApiError(err: unknown, filePath: string): unknown {\n if (err instanceof Error && 'code' in err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n return new ApiError('INPUT_INVALID_FORMAT', `File not found: ${filePath}`, {\n retryable: false,\n });\n }\n if (code === 'EISDIR') {\n return new ApiError('INPUT_INVALID_FORMAT', `Expected a file, got a directory: ${filePath}`, {\n retryable: false,\n });\n }\n if (code === 'EACCES' || code === 'EPERM') {\n return new ApiError('INPUT_INVALID_FORMAT', `Permission denied: ${filePath}`, {\n retryable: false,\n });\n }\n }\n return err;\n}\n\nfunction validateSize(bytes: number): void {\n if (bytes === 0) {\n throw new ApiError('INPUT_INVALID_FORMAT', 'Refusing to upload an empty file.', {\n retryable: false,\n });\n }\n if (bytes > MAX_UPLOAD_SIZE_BYTES) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `File is ${bytes} bytes; the upload endpoint caps at ${MAX_UPLOAD_SIZE_BYTES} bytes.`,\n { retryable: false },\n );\n }\n}\n","// Shared helpers for the `generate` command family.\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface GenerateClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildGenerateClient(opts: GenerateClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n\n// Returns true for absolute http(s) URLs only. Everything else (ftp://, data:,\n// mailto:, file://, plus all filesystem paths) is treated as a local path and\n// routed through the upload primitive. The server only accepts http(s)\n// reference images, so accepting other schemes here would just defer the\n// failure into the API round-trip.\nexport function isUrlLike(value: string): boolean {\n return value.startsWith('http://') || value.startsWith('https://');\n}\n","// `clickraft generate wait <jobId>` — long-polls until the job reaches a\n// terminal state (completed / failed / cancelled) or the overall timeout\n// elapses.\n//\n// As of Phase 4c the long-poll orchestration lives in @clickraft/sdk\n// (waitForGeneration, built on the SDK longPoll); this module is the thin CLI\n// wrapper that resolves config+client and injects the result schema + terminal\n// predicate. Each wait round is a `?wait=30` request (RFC §4.4 + Phase 8 Q9).\n\nimport {\n waitForGeneration,\n GenerationResultSchema,\n isTerminalStatus,\n type GenerationResult,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildGenerateClient, type GenerateClientOptions } from './internal.js';\n\nexport const DEFAULT_WAIT_TIMEOUT_SECONDS = 120;\nexport const SERVER_LONG_POLL_SECONDS = 30;\n\nexport interface GenerateWaitOptions extends GenerateClientOptions {\n jobId: string;\n timeoutSeconds?: number;\n client?: ApiClient;\n}\n\nexport async function generateWait(opts: GenerateWaitOptions): Promise<GenerationResult> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n return waitForGeneration<GenerationResult>({\n client,\n jobId: opts.jobId,\n timeoutMs: (opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS) * 1000,\n serverWaitSeconds: SERVER_LONG_POLL_SECONDS,\n signal: opts.signal,\n resultSchema: GenerationResultSchema,\n isTerminal: (r) => isTerminalStatus(r.status),\n });\n}\n","// `clickraft generate create` — submits a generation job and (by default)\n// waits up to 120s for completion via the server long-poll mechanism. Per\n// Phase 8 Q9 of `wave-1-investigation.md` and RFC §4.4, each wait round is a\n// `?wait=30` request to the server.\n//\n// Reference images may be supplied as URLs (sent verbatim) or as local paths\n// (auto-uploaded via the upload primitive; the resulting publicUrl is then\n// sent to the API).\n\nimport {\n createGeneration,\n GenerateCreateRequestSchema,\n GenerateCreateResponseSchema,\n GenerationResultSchema,\n isTerminalStatus,\n type GenerateCreateResponse,\n type GenerationResult,\n} from '@clickraft/sdk';\n\nimport { ApiError, type ApiClient } from '../../api/client.js';\nimport { uploadFile, DEFAULT_UPLOAD_SCOPE } from '../upload.js';\n\nimport { buildGenerateClient, isUrlLike, type GenerateClientOptions } from './internal.js';\nimport type { BrandModelSpec } from './parse-brand-model-spec.js';\nimport type { ProductSpec } from './parse-product-spec.js';\nimport { DEFAULT_WAIT_TIMEOUT_SECONDS, SERVER_LONG_POLL_SECONDS } from './wait.js';\n\nexport interface GenerateCreateOptions extends GenerateClientOptions {\n prompt?: string;\n modelSlug: string;\n // RFC §4.3: at most 8 reference images. Each value is either a URL (sent\n // verbatim) or a local filesystem path (auto-uploaded via uploadFile).\n // Always routed to the `referenceImages[]` array (the references category),\n // regardless of count — see buildRequestBody.\n referenceImages?: string[];\n // Image-to-video start frame. Emitted as the scalar `referenceImageUrl`, which\n // the server maps to `start_image` — distinct from the reference images above.\n // A URL (sent verbatim) or a local path (auto-uploaded via uploadFile).\n startFrame?: string;\n aspectRatio?: string;\n resolution?: string;\n durationSeconds?: number;\n // The model's quality tier (e.g. low | medium | high). Checked server-side\n // against the model's options; an unsupported value fails before any charge.\n quality?: string;\n brandModels?: BrandModelSpec[];\n products?: ProductSpec[];\n workflowId?: string;\n nodeId?: string;\n // Defaults to true. When false, returns immediately after the POST with the\n // create response projected into the GenerationResult shape.\n wait?: boolean;\n timeoutSeconds?: number;\n client?: ApiClient;\n}\n\nexport type GenerateCreateOutput = GenerationResult;\n\n// Placeholder URL used during the pre-upload validation pass. We substitute\n// local paths with this sentinel so the strict request schema (which requires\n// `.url()` for reference images) can vet every non-upload field BEFORE we\n// commit any bytes to the network — invalid aspectRatio / prompt length /\n// modelSlug / etc. now fail before we upload, not after.\nconst PREFLIGHT_PLACEHOLDER_URL = 'https://placeholder.invalid/pending-upload';\n\nexport async function generateCreate(opts: GenerateCreateOptions): Promise<GenerateCreateOutput> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n\n // Preflight: replace each local path with a placeholder URL and run the\n // request schema. Any non-upload validation failure surfaces here, before\n // we read or upload a single byte.\n const preflightRefs = (opts.referenceImages ?? []).map((v) =>\n isUrlLike(v) ? v : PREFLIGHT_PLACEHOLDER_URL,\n );\n const preflightStartFrame =\n opts.startFrame === undefined\n ? undefined\n : isUrlLike(opts.startFrame)\n ? opts.startFrame\n : PREFLIGHT_PLACEHOLDER_URL;\n buildRequestBody({ ...opts, referenceImages: preflightRefs, startFrame: preflightStartFrame });\n\n const referenceImages = await resolveReferenceImages({\n items: opts.referenceImages ?? [],\n client,\n signal: opts.signal,\n });\n // The start frame goes through the same URL/local-path resolution (single item).\n const startFrame =\n opts.startFrame === undefined\n ? undefined\n : (\n await resolveReferenceImages({\n items: [opts.startFrame],\n client,\n signal: opts.signal,\n })\n )[0];\n\n const body = buildRequestBody({ ...opts, referenceImages, startFrame });\n\n // POST /jobs → (if waiting) longPoll to terminal → project. The orchestration\n // lives in @clickraft/sdk; the CLI injects the schemas, the terminal predicate,\n // and the create-projection, and passes the already-built/validated body.\n return createGeneration<GenerateCreateResponse, GenerationResult>({\n client,\n body,\n modelSlug: opts.modelSlug,\n wait: opts.wait ?? true,\n timeoutMs: (opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS) * 1000,\n serverWaitSeconds: SERVER_LONG_POLL_SECONDS,\n signal: opts.signal,\n createSchema: GenerateCreateResponseSchema,\n resultSchema: GenerationResultSchema,\n isTerminal: (r) => isTerminalStatus(r.status),\n projectCreated: projectCreateToResult,\n });\n}\n\nasync function resolveReferenceImages(args: {\n items: string[];\n client: ApiClient;\n signal?: AbortSignal;\n}): Promise<string[]> {\n const out: string[] = [];\n for (const item of args.items) {\n if (isUrlLike(item)) {\n out.push(item);\n continue;\n }\n const uploaded = await uploadFile({\n filePath: item,\n scope: DEFAULT_UPLOAD_SCOPE,\n client: args.client,\n signal: args.signal,\n });\n out.push(uploaded.publicUrl);\n }\n return out;\n}\n\nfunction buildRequestBody(\n args: GenerateCreateOptions & { referenceImages: string[]; startFrame?: string },\n): unknown {\n const input: Record<string, unknown> = {};\n if (args.prompt !== undefined) input.prompt = args.prompt;\n // --reference-image is ALWAYS a reference (references category), regardless of\n // count. Canonical wire shape: object array { url, label? }[]; we only emit\n // `url` (no label UX yet). Do NOT collapse a single ref to referenceImageUrl —\n // that scalar is the start-frame slot (server start_image). This block must\n // match apps/mcp-server/src/tools/generate.ts exactly.\n if (args.referenceImages.length > 0) {\n input.referenceImages = args.referenceImages.map((url) => ({ url }));\n }\n // --start-frame → scalar referenceImageUrl → server start_image (image-to-video).\n if (args.startFrame !== undefined) {\n input.referenceImageUrl = args.startFrame;\n }\n if (args.aspectRatio !== undefined) input.aspectRatio = args.aspectRatio;\n if (args.resolution !== undefined) input.resolution = args.resolution;\n if (args.durationSeconds !== undefined) input.durationSeconds = args.durationSeconds;\n if (args.quality !== undefined) input.quality = args.quality;\n if (args.brandModels !== undefined && args.brandModels.length > 0) {\n input.providerParams = {\n brandModels: args.brandModels.map((spec) => {\n const entry: Record<string, string> = { id: spec.id };\n if (spec.imageType) entry.imageType = spec.imageType;\n return entry;\n }),\n };\n }\n\n const body: Record<string, unknown> = {\n modelSlug: args.modelSlug,\n input,\n };\n\n if (args.workflowId !== undefined || args.nodeId !== undefined) {\n const options: Record<string, unknown> = {};\n if (args.workflowId !== undefined) options.workflowId = args.workflowId;\n if (args.nodeId !== undefined) options.nodeId = args.nodeId;\n body.options = options;\n }\n\n if (args.products !== undefined && args.products.length > 0) {\n body.products = args.products.map((spec) => {\n const entry: Record<string, string> = { id: spec.id };\n if (spec.imageId) entry.imageId = spec.imageId;\n return entry;\n });\n }\n\n const parsed = GenerateCreateRequestSchema.safeParse(body);\n if (!parsed.success) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Invalid generate create request: ${parsed.error.message}`,\n { retryable: false },\n );\n }\n return parsed.data;\n}\n\nfunction projectCreateToResult(\n response: GenerateCreateResponse,\n modelSlug: string,\n): GenerationResult {\n return {\n jobId: response.jobId,\n status: response.status,\n modelSlug,\n resultUrl: null,\n thumbnailUrl: null,\n errorCode: null,\n errorMessage: null,\n creditsCharged: response.creditsCharged,\n creditsRefunded: false,\n startedAt: null,\n completedAt: null,\n };\n}\n","// `clickraft generate get <jobId>` — fetches the current state of a generation\n// job without holding the request. Returns the full GenerationResult.\n\nimport { GenerationResultSchema, type GenerationResult } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildGenerateClient, type GenerateClientOptions } from './internal.js';\n\nexport interface GenerateGetOptions extends GenerateClientOptions {\n jobId: string;\n client?: ApiClient;\n // Optional server-side hold in seconds (0-30). Defaults to 0 for `generate\n // get` (no hold). The wait command sets this to 30 for each round.\n waitSeconds?: number;\n}\n\nexport async function generateGet(opts: GenerateGetOptions): Promise<GenerationResult> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n return client.request<GenerationResult>({\n method: 'GET',\n path: `/jobs/${encodeURIComponent(opts.jobId)}`,\n query: opts.waitSeconds && opts.waitSeconds > 0 ? { wait: opts.waitSeconds } : undefined,\n responseSchema: GenerationResultSchema,\n signal: opts.signal,\n });\n}\n","// Minimal flag parser used by the Wave 1 CLI dispatcher. We do not pull in\n// commander/yargs yet — the surface is small enough that a hand-rolled parser\n// avoids the dependency footprint and keeps `clickraft --help` instant.\n//\n// Syntax supported:\n// --flag value -> string : { foo: \"value\" }\n// --flag=value -> string : { foo: \"value\" }\n// --bool -> boolean : { bool: true }\n// --no-bool -> boolean : { bool: false }\n// --repeat a --repeat b -> array : { repeat: [\"a\", \"b\"] }\n// -- -> stop flag parsing (everything after is positional)\n//\n// Anything not matched by `string`, `boolean`, or `array` is treated as\n// positional. Unknown long flags throw a usage error so typos surface loudly.\n\nexport interface FlagSpec {\n string?: readonly string[];\n boolean?: readonly string[];\n array?: readonly string[];\n aliases?: Readonly<Record<string, string>>;\n}\n\nexport interface ParsedArgs {\n positional: string[];\n string: Record<string, string>;\n boolean: Record<string, boolean>;\n array: Record<string, string[]>;\n}\n\nexport class ArgError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ArgError';\n }\n}\n\nexport function parseArgs(argv: readonly string[], spec: FlagSpec): ParsedArgs {\n const result: ParsedArgs = {\n positional: [],\n string: {},\n boolean: {},\n array: {},\n };\n\n const stringFlags = new Set(spec.string ?? []);\n const booleanFlags = new Set(spec.boolean ?? []);\n const arrayFlags = new Set(spec.array ?? []);\n const aliases = spec.aliases ?? {};\n\n let i = 0;\n let stopFlags = false;\n\n while (i < argv.length) {\n const raw = argv[i];\n if (raw === undefined) {\n i += 1;\n continue;\n }\n\n if (stopFlags) {\n result.positional.push(raw);\n i += 1;\n continue;\n }\n\n if (raw === '--') {\n stopFlags = true;\n i += 1;\n continue;\n }\n\n if (!raw.startsWith('--')) {\n result.positional.push(raw);\n i += 1;\n continue;\n }\n\n // --flag or --flag=value or --no-flag\n const eqIdx = raw.indexOf('=');\n const flagToken = eqIdx >= 0 ? raw.slice(2, eqIdx) : raw.slice(2);\n const inlineValue = eqIdx >= 0 ? raw.slice(eqIdx + 1) : undefined;\n const canonical = resolveCanonical(flagToken, { booleanFlags, aliases });\n\n if (booleanFlags.has(canonical)) {\n if (inlineValue !== undefined) {\n result.boolean[canonical] = parseBool(inlineValue);\n } else if (flagToken.startsWith('no-') && booleanFlags.has(flagToken.slice(3))) {\n result.boolean[flagToken.slice(3)] = false;\n } else {\n result.boolean[canonical] = true;\n }\n i += 1;\n continue;\n }\n\n if (stringFlags.has(canonical) || arrayFlags.has(canonical)) {\n let value: string;\n if (inlineValue !== undefined) {\n value = inlineValue;\n } else {\n const next = argv[i + 1];\n if (next === undefined || next.startsWith('--')) {\n throw new ArgError(`Flag --${canonical} requires a value.`);\n }\n value = next;\n i += 1;\n }\n if (arrayFlags.has(canonical)) {\n const existing = result.array[canonical] ?? [];\n existing.push(value);\n result.array[canonical] = existing;\n } else {\n result.string[canonical] = value;\n }\n i += 1;\n continue;\n }\n\n throw new ArgError(`Unknown flag --${flagToken}`);\n }\n\n return result;\n}\n\nfunction resolveCanonical(\n flagToken: string,\n ctx: { booleanFlags: Set<string>; aliases: Readonly<Record<string, string>> },\n): string {\n if (ctx.aliases[flagToken]) return ctx.aliases[flagToken];\n if (flagToken.startsWith('no-') && ctx.booleanFlags.has(flagToken.slice(3))) {\n return flagToken.slice(3);\n }\n return flagToken;\n}\n\nfunction parseBool(value: string): boolean {\n if (value === 'true' || value === '1') return true;\n if (value === 'false' || value === '0') return false;\n throw new ArgError(`Expected boolean value (true/false), got \"${value}\".`);\n}\n","import { ArgError } from '../../cli/args.js';\n\nexport const VALID_POSES = [\n 'front',\n '3/4-right',\n 'right',\n 'left',\n '3/4-left',\n 'back',\n 'approved',\n] as const;\n\nexport type Pose = (typeof VALID_POSES)[number];\n\nexport interface BrandModelSpec {\n id: string;\n imageType?: Pose;\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function parseBrandModelSpec(raw: string): BrandModelSpec {\n if (!raw) throw new ArgError('--brand-model value cannot be empty.');\n\n const colonIdx = raw.indexOf(':');\n const uuid = colonIdx >= 0 ? raw.slice(0, colonIdx) : raw;\n const poseRaw = colonIdx >= 0 ? raw.slice(colonIdx + 1) : undefined;\n\n if (!UUID_RE.test(uuid)) {\n throw new ArgError(\n `Invalid brand model ID: '${uuid}'. Expected a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).`,\n );\n }\n\n if (poseRaw !== undefined) {\n if (!poseRaw) {\n throw new ArgError(\n `Empty pose for brand model ${uuid}. Valid poses: ${VALID_POSES.join(', ')}.`,\n );\n }\n if (!VALID_POSES.includes(poseRaw as Pose)) {\n throw new ArgError(\n `Unknown pose '${poseRaw}' for brand model ${uuid}. Valid poses: ${VALID_POSES.join(', ')}.`,\n );\n }\n return { id: uuid.toLowerCase(), imageType: poseRaw as Pose };\n }\n\n return { id: uuid.toLowerCase() };\n}\n\nexport function validateBrandModelSpecs(specs: BrandModelSpec[]): void {\n if (specs.length > 3) {\n throw new ArgError(`Too many --brand-model flags (${specs.length}). Maximum is 3.`);\n }\n const seen = new Set<string>();\n for (const spec of specs) {\n if (seen.has(spec.id)) {\n throw new ArgError(\n `Duplicate brand model ID: ${spec.id}. Each --brand-model must reference a different model.`,\n );\n }\n seen.add(spec.id);\n }\n}\n","import { ArgError } from '../../cli/args.js';\n\nexport interface ProductSpec {\n id: string;\n imageId?: string;\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function parseProductSpec(raw: string): ProductSpec {\n if (!raw) throw new ArgError('--product value cannot be empty.');\n\n const colonIdx = raw.indexOf(':');\n const productId = colonIdx >= 0 ? raw.slice(0, colonIdx) : raw;\n const imageIdRaw = colonIdx >= 0 ? raw.slice(colonIdx + 1) : undefined;\n\n if (!UUID_RE.test(productId)) {\n throw new ArgError(\n `Invalid product ID: '${productId}'. Expected a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).`,\n );\n }\n\n if (imageIdRaw !== undefined) {\n if (!imageIdRaw) {\n throw new ArgError(\n `Empty image ID for product ${productId.toLowerCase()}. Omit the colon or provide a valid UUID.`,\n );\n }\n if (!UUID_RE.test(imageIdRaw)) {\n throw new ArgError(\n `Invalid image ID: '${imageIdRaw}' for product ${productId.toLowerCase()}. Expected a UUID.`,\n );\n }\n return { id: productId.toLowerCase(), imageId: imageIdRaw.toLowerCase() };\n }\n\n return { id: productId.toLowerCase() };\n}\n\nexport function validateProductSpecs(specs: ProductSpec[]): void {\n const seen = new Set<string>();\n for (const spec of specs) {\n const key = spec.imageId ? `${spec.id}:${spec.imageId}` : spec.id;\n if (seen.has(key)) {\n throw new ArgError(`Duplicate product reference: ${key}. Each --product must be unique.`);\n }\n seen.add(key);\n }\n}\n","import { setTimeout as delay } from 'node:timers/promises';\n\nimport { redactTokenLikeFields, type CloudflareAccessCredentials } from '@clickraft/sdk';\nimport { request } from 'undici';\n\nimport { ApiError } from '../api/client.js';\n\nimport { AuthError } from './errors.js';\nimport {\n DeviceAuthorizationResponseSchema,\n DeviceTokenPollErrorSchema,\n TokenResponseSchema,\n type DeviceAuthorizationResponse,\n type TokenResponse,\n} from './types.js';\n\n// OAuth 2.0 Device Authorization Grant (RFC 8628) client.\n// Source of truth: 02-oauth.md §3.1 (shapes) and §5.1 (sequence).\n\nconst GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code';\nconst FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded';\n\nexport interface DeviceFlowOptions {\n apiBaseUrl: string;\n clientId: string;\n scope: string;\n /**\n * The subset to fall back to when the server refuses `scope` outright.\n * Required for a downgrade to be possible; absent means no fallback exists.\n */\n requiredScope?: string;\n /**\n * Whether a refusal of `scope` may be retried with `requiredScope`.\n *\n * Passed explicitly by the caller rather than inferred here, because only the\n * caller knows whether `scope` came from its own defaults or from a\n * user-supplied `--scope`. Inferring it would put the decision in the wrong\n * place and make it invisible at the call site.\n */\n allowScopeDowngrade?: boolean;\n /** Fired once, before the retry, so the CLI can warn on stderr. */\n onScopeDowngrade?: (info: {\n requested: string;\n retryingWith: string;\n description: string | undefined;\n }) => void;\n onUserCode?: (info: {\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresAt: Date;\n }) => void;\n onPoll?: (event: {\n iteration: number;\n intervalSeconds: number;\n status: 'pending' | 'slow_down';\n }) => void;\n signal?: AbortSignal;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n}\n\nexport async function runDeviceFlow(opts: DeviceFlowOptions): Promise<TokenResponse> {\n throwIfCancelled(opts.signal);\n\n const authResp = await requestDeviceAuthorization(opts);\n const deadlineMs = Date.now() + authResp.expires_in * 1000;\n\n opts.onUserCode?.({\n userCode: authResp.user_code,\n verificationUri: authResp.verification_uri,\n verificationUriComplete: authResp.verification_uri_complete ?? authResp.verification_uri,\n expiresAt: new Date(deadlineMs),\n });\n\n let intervalSeconds = authResp.interval;\n let iteration = 0;\n let consecutiveNetworkFailures = 0;\n const MAX_CONSECUTIVE_NETWORK_FAILURES = 5;\n\n // RFC 8628 §3.5: the client waits `interval` seconds before each poll.\n // `expires_in` is a hard deadline — we bound each sleep by the remaining\n // time so an expired flow never waits past the cutoff.\n while (true) {\n const sleepMs = Math.min(intervalSeconds * 1000, deadlineMs - Date.now());\n if (sleepMs <= 0) {\n throw new AuthError(\n 'AUTH_DEVICE_CODE_EXPIRED',\n `Device authorization expired after ${authResp.expires_in}s. Run \\`clickraft login\\` again.`,\n );\n }\n await abortableSleep(sleepMs, opts.signal);\n throwIfCancelled(opts.signal);\n\n if (Date.now() >= deadlineMs) {\n throw new AuthError(\n 'AUTH_DEVICE_CODE_EXPIRED',\n `Device authorization expired after ${authResp.expires_in}s. Run \\`clickraft login\\` again.`,\n );\n }\n\n iteration += 1;\n const result = await pollToken({\n apiBaseUrl: opts.apiBaseUrl,\n clientId: opts.clientId,\n deviceCode: authResp.device_code,\n signal: opts.signal,\n cloudflareAccess: opts.cloudflareAccess,\n });\n\n if (result.kind === 'success') {\n return result.token;\n }\n if (result.kind === 'pending') {\n consecutiveNetworkFailures = 0;\n opts.onPoll?.({ iteration, intervalSeconds, status: 'pending' });\n continue;\n }\n if (result.kind === 'slow_down') {\n consecutiveNetworkFailures = 0;\n intervalSeconds *= 2;\n opts.onPoll?.({ iteration, intervalSeconds, status: 'slow_down' });\n continue;\n }\n if (result.kind === 'network_error') {\n consecutiveNetworkFailures += 1;\n if (consecutiveNetworkFailures >= MAX_CONSECUTIVE_NETWORK_FAILURES) {\n throw new ApiError(\n 'NETWORK_ERROR',\n `Network repeatedly failed during polling (${MAX_CONSECUTIVE_NETWORK_FAILURES} consecutive errors).`,\n { retryable: true },\n result.cause,\n );\n }\n intervalSeconds *= 2;\n opts.onPoll?.({ iteration, intervalSeconds, status: 'slow_down' });\n continue;\n }\n throw result.error;\n }\n}\n\n/**\n * Request a device code, degrading once if the server refuses an optional scope.\n *\n * `POST /oauth/device-authorization` validates the requested scope list\n * ATOMICALLY: if any member falls outside the client's `allowed_scopes` it\n * rejects the WHOLE request with `invalid_scope`, rather than intersecting and\n * proceeding. So a CLI that adds one new scope to its request list cannot log\n * in AT ALL against a server that has not granted it yet — the failure is the\n * entire authentication flow, not the one feature the scope was for.\n *\n * Correct release ordering (grant the scope server-side first, ship the client\n * second) should mean this never fires. It exists anyway because the client and\n * the server release independently: this package publishes to npm on every\n * merge, while the grant is a migration in another repo applied by hand, and\n * the window between them is invisible from either side.\n *\n * The retry is deliberately narrow. See `allowScopeDowngrade`.\n */\nasync function requestDeviceAuthorization(\n opts: DeviceFlowOptions,\n): Promise<DeviceAuthorizationResponse> {\n try {\n return await attemptDeviceAuthorization(opts, opts.scope);\n } catch (err) {\n if (!(err instanceof ScopeRefusedError)) throw err;\n\n // An explicit --scope is a WHOLESALE override: the caller stated the exact\n // set they want. Silently substituting a different one hands them a token\n // whose powers they never asked for and would not think to re-check, so\n // refuse instead and name what the server rejected.\n if (!opts.allowScopeDowngrade || opts.requiredScope === undefined) {\n throw new AuthError('AUTH_TOKEN_INVALID', scopeRefusalMessage(err.description));\n }\n\n opts.onScopeDowngrade?.({\n requested: opts.scope,\n retryingWith: opts.requiredScope,\n description: err.description,\n });\n\n try {\n return await attemptDeviceAuthorization(opts, opts.requiredScope);\n } catch (retryErr) {\n // A second refusal means even the required set is not granted, which is\n // a server-side misconfiguration rather than a version skew. One retry,\n // never a loop.\n if (retryErr instanceof ScopeRefusedError) {\n throw new AuthError('AUTH_TOKEN_INVALID', scopeRefusalMessage(retryErr.description));\n }\n throw retryErr;\n }\n }\n}\n\nfunction scopeRefusalMessage(description: string | undefined): string {\n return (\n `The authorization server refused the requested scopes${description ? `: ${description}` : '.'}` +\n ' Re-run `clickraft login` without --scope to request the defaults.'\n );\n}\n\n/** Internal signal that the server answered `invalid_scope`. Never surfaced. */\nclass ScopeRefusedError extends Error {\n constructor(readonly description: string | undefined) {\n super('invalid_scope');\n this.name = 'ScopeRefusedError';\n }\n}\n\nasync function attemptDeviceAuthorization(\n opts: DeviceFlowOptions,\n scope: string,\n): Promise<DeviceAuthorizationResponse> {\n const body = new URLSearchParams({ client_id: opts.clientId, scope }).toString();\n const headers: Record<string, string> = { 'content-type': FORM_CONTENT_TYPE };\n if (opts.cloudflareAccess) {\n headers['cf-access-client-id'] = opts.cloudflareAccess.clientId;\n headers['cf-access-client-secret'] = opts.cloudflareAccess.clientSecret;\n }\n let resp;\n try {\n resp = await request(`${opts.apiBaseUrl}/oauth/device-authorization`, {\n method: 'POST',\n headers,\n body,\n signal: opts.signal,\n });\n } catch (err) {\n if (isAbortError(err) || opts.signal?.aborted) {\n throw new AuthError(\n 'AUTH_FLOW_CANCELLED',\n 'Device flow cancelled during authorization request.',\n err,\n );\n }\n throw new ApiError(\n 'NETWORK_ERROR',\n `Network error contacting authorization endpoint: ${(err as Error).message}`,\n { retryable: true },\n err,\n );\n }\n\n const text = await resp.body.text();\n if (resp.statusCode !== 200) {\n // Classify `invalid_scope` before the generic path so the caller can decide\n // whether a downgrade is permitted. Reuses DeviceTokenPollErrorSchema: the\n // authorization and token endpoints emit the same `{error, error_description}`\n // envelope, and that enum already contains `invalid_scope`.\n if (resp.statusCode === 400) {\n const maybe = DeviceTokenPollErrorSchema.safeParse(safeParseJson(text));\n if (maybe.success && maybe.data.error === 'invalid_scope') {\n throw new ScopeRefusedError(maybe.data.error_description);\n }\n }\n const redacted = redactTokenLikeFields(truncate(text));\n throw new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Authorization endpoint returned HTTP ${resp.statusCode}: ${redacted}`,\n {\n status: resp.statusCode,\n redactedBody: redactTokenLikeFields(text),\n headers: safeHeaders(resp.headers),\n },\n );\n }\n const parsed = parseJson(text, 'authorization');\n const validated = DeviceAuthorizationResponseSchema.safeParse(parsed);\n if (!validated.success) {\n // No token has been issued yet at this point in the flow, so an\n // `AUTH_TOKEN_INVALID` would mislead the user into thinking their saved\n // credentials are bad. Surface a schema mismatch instead (exit 1) per\n // 1A.2 — the CLI is out of sync with the server contract.\n throw new ApiError(\n 'SCHEMA_MISMATCH',\n 'Authorization endpoint response did not match the expected schema.',\n {\n status: resp.statusCode,\n retryable: false,\n redactedBody: redactTokenLikeFields(truncate(text)),\n },\n validated.error,\n );\n }\n return validated.data;\n}\n\ntype PollResult =\n | { kind: 'success'; token: TokenResponse }\n | { kind: 'pending' }\n | { kind: 'slow_down' }\n | { kind: 'network_error'; cause: unknown }\n | { kind: 'error'; error: AuthError | ApiError };\n\n// undici / Node error codes that mean \"the request never reached a server\n// response\" — RFC 8628 §3.5 says these should be treated like slow_down.\nconst TRANSIENT_NETWORK_CODES = new Set([\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n 'UND_ERR_SOCKET',\n 'UND_ERR_CONNECT_TIMEOUT',\n 'UND_ERR_HEADERS_TIMEOUT',\n]);\n\nfunction isTransientNetworkError(err: unknown): boolean {\n const code = (err as { code?: unknown }).code;\n return typeof code === 'string' && TRANSIENT_NETWORK_CODES.has(code);\n}\n\nasync function pollToken(args: {\n apiBaseUrl: string;\n clientId: string;\n deviceCode: string;\n signal?: AbortSignal;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n}): Promise<PollResult> {\n const body = new URLSearchParams({\n client_id: args.clientId,\n device_code: args.deviceCode,\n grant_type: GRANT_TYPE,\n }).toString();\n const headers: Record<string, string> = { 'content-type': FORM_CONTENT_TYPE };\n if (args.cloudflareAccess) {\n headers['cf-access-client-id'] = args.cloudflareAccess.clientId;\n headers['cf-access-client-secret'] = args.cloudflareAccess.clientSecret;\n }\n\n let resp;\n try {\n resp = await request(`${args.apiBaseUrl}/oauth/token`, {\n method: 'POST',\n headers,\n body,\n signal: args.signal,\n });\n } catch (err) {\n if (isAbortError(err) || args.signal?.aborted) {\n return {\n kind: 'error',\n error: new AuthError('AUTH_FLOW_CANCELLED', 'Device flow cancelled mid-poll.', err),\n };\n }\n if (isTransientNetworkError(err)) {\n return { kind: 'network_error', cause: err };\n }\n return {\n kind: 'error',\n error: new ApiError(\n 'NETWORK_ERROR',\n `Network error contacting token endpoint: ${(err as Error).message}`,\n { retryable: true },\n err,\n ),\n };\n }\n\n const text = await resp.body.text();\n\n if (resp.statusCode === 200) {\n return parseTokenSuccess(text);\n }\n if (resp.statusCode === 400) {\n return parseTokenError(text);\n }\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Token endpoint returned unexpected HTTP ${resp.statusCode}: ${redactTokenLikeFields(truncate(text))}`,\n {\n status: resp.statusCode,\n redactedBody: redactTokenLikeFields(text),\n headers: safeHeaders(resp.headers),\n },\n ),\n };\n}\n\nfunction parseTokenSuccess(text: string): PollResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n return {\n kind: 'error',\n error: new AuthError('AUTH_TOKEN_INVALID', 'Token endpoint returned invalid JSON.', err),\n };\n }\n const validated = TokenResponseSchema.safeParse(parsed);\n if (!validated.success) {\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n 'Token endpoint success response failed schema validation.',\n validated.error,\n ),\n };\n }\n return { kind: 'success', token: validated.data };\n}\n\nfunction parseTokenError(text: string): PollResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n return {\n kind: 'error',\n error: new AuthError('AUTH_TOKEN_INVALID', 'Token error response was not valid JSON.', err),\n };\n }\n const validated = DeviceTokenPollErrorSchema.safeParse(parsed);\n if (!validated.success) {\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n 'Token error response failed schema validation.',\n validated.error,\n ),\n };\n }\n const { error, error_description } = validated.data;\n switch (error) {\n case 'authorization_pending':\n return { kind: 'pending' };\n case 'slow_down':\n return { kind: 'slow_down' };\n case 'access_denied':\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_ACCESS_DENIED',\n error_description ?? 'User denied the device authorization request.',\n ),\n };\n case 'expired_token':\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_DEVICE_CODE_EXPIRED',\n error_description ?? 'Device code has expired. Run `clickraft login` again.',\n ),\n };\n default:\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Token endpoint returned error: ${error}${error_description ? ` (${error_description})` : ''}`,\n ),\n };\n }\n}\n\nasync function abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n try {\n await delay(ms, undefined, { signal });\n } catch (err) {\n if (isAbortError(err)) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Device flow cancelled while waiting.', err);\n }\n throw err;\n }\n}\n\nfunction throwIfCancelled(signal?: AbortSignal): void {\n if (signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Device flow cancelled.');\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (err instanceof Error) {\n if (err.name === 'AbortError') return true;\n if ((err as { code?: string }).code === 'ABORT_ERR') return true;\n }\n return false;\n}\n\n/** Parse or give up quietly. Used only for classifying an error body. */\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction parseJson(text: string, label: string): unknown {\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new AuthError(\n 'AUTH_TOKEN_INVALID',\n `${label} endpoint returned invalid JSON: ${redactTokenLikeFields(truncate(text))}`,\n err,\n );\n }\n}\n\nfunction truncate(text: string, max = 200): string {\n return text.length > max ? `${text.slice(0, max)}...` : text;\n}\n\nfunction safeHeaders(\n headers: Record<string, string | string[] | undefined>,\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(headers)) {\n if (typeof v === 'string') out[k] = v;\n }\n return out;\n}\n","// `clickraft login` — interactive OAuth device flow → credentials on disk.\n//\n// Wave 1 limitation (TODO(wave-2)): the `/oauth/token` response per\n// `02-oauth.md` §3.1 returns only {access_token, token_type, expires_in,\n// scope}. CredentialsProfile requires organizationId / organizationSlug /\n// userId — there is no `/me` endpoint to fetch them and `src/auth/types.ts`\n// is locked. Wave 1 writes placeholder identity (nil UUID + slug \"unknown\"),\n// which validates against the Zod schema but degrades the human display.\n// Wave 2 lifts this by extending the token response to carry identity.\n\nimport { setProfile, readCredentials } from '../auth/credentials.js';\nimport { runDeviceFlow, type DeviceFlowOptions } from '../auth/device-flow.js';\nimport { AuthError } from '../auth/errors.js';\nimport { type CredentialsProfile, type TokenResponse } from '../auth/types.js';\nimport { DEFAULT_API_BASE_URL, DEFAULT_PROFILE_NAME, loadConfig } from '../config/loader.js';\n\nconst PLACEHOLDER_UUID = '00000000-0000-0000-0000-000000000000';\nconst PLACEHOLDER_ORG_SLUG = 'unknown';\nconst CLIENT_ID = 'clickraft-cli';\n\n// Default scopes per `02-oauth.md` §2.4. Reads are not implied by writes.\n//\n// Split into required and optional because the authorization endpoint validates\n// the list ATOMICALLY: one member the server has not granted rejects the whole\n// request with `invalid_scope`, and login fails entirely. Anything added here\n// after the CLI has shipped is therefore a breaking change until the server\n// grants it, and belongs in OPTIONAL_SCOPES so a refusal degrades to a warning\n// instead of locking every user out. See device-flow.ts.\nexport const REQUIRED_SCOPES: readonly string[] = [\n 'templates:read',\n 'generations:write',\n 'generations:read',\n 'workflows:write',\n 'workflows:read',\n 'brand-models:read',\n 'products:read',\n 'models:read',\n 'assets:write',\n 'balance:read',\n];\n\n// `products:write` gates `clickraft product create`. Granted by migration 0075\n// on the first-party OAuth clients; a server without it refuses the whole list.\nexport const OPTIONAL_SCOPES: readonly string[] = ['products:write'];\n\nexport const DEFAULT_SCOPES: readonly string[] = [...REQUIRED_SCOPES, ...OPTIONAL_SCOPES];\n\nexport interface LoginOptions {\n profile?: string;\n apiBaseUrl?: string;\n scope?: string;\n forceReauth: boolean;\n openBrowser: boolean;\n signal?: AbortSignal;\n credentialsPath?: string;\n // UI callbacks — wired to progress.ts by the dispatcher. Pulled out as\n // injectable hooks so tests can drive the flow without touching stderr.\n onUserCode?: DeviceFlowOptions['onUserCode'];\n onPoll?: DeviceFlowOptions['onPoll'];\n onScopeDowngrade?: DeviceFlowOptions['onScopeDowngrade'];\n // Override the device-flow function — only set in tests.\n runDeviceFlow?: typeof runDeviceFlow;\n}\n\nexport interface LoginResult {\n profileName: string;\n tokenPrefix: string;\n expiresAt: string;\n scopes: string[];\n identityKnown: boolean;\n organizationId: string;\n organizationSlug: string;\n userId: string;\n}\n\nexport async function login(options: LoginOptions): Promise<LoginResult> {\n const config = await loadConfig({\n flagProfile: options.profile,\n flagApiBaseUrl: options.apiBaseUrl,\n credentialsPath: options.credentialsPath,\n });\n const profileName = config.profileName || DEFAULT_PROFILE_NAME;\n const apiBaseUrl = options.apiBaseUrl ?? config.apiBaseUrl ?? DEFAULT_API_BASE_URL;\n\n if (!options.forceReauth) {\n const existing = await readCredentials(options.credentialsPath);\n const profile = existing?.profiles[profileName];\n if (profile && !isExpired(profile.expiresAt)) {\n throw new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Profile \"${profileName}\" is already logged in (token valid until ${profile.expiresAt}). ` +\n `Pass --force-reauth to mint a new token.`,\n );\n }\n }\n\n const explicitScope = options.scope?.trim();\n const scope = explicitScope || DEFAULT_SCOPES.join(' ');\n const flow = options.runDeviceFlow ?? runDeviceFlow;\n const token = await flow({\n apiBaseUrl,\n clientId: CLIENT_ID,\n scope,\n requiredScope: REQUIRED_SCOPES.join(' '),\n // ONLY when the list is ours. An explicit --scope is a wholesale override,\n // and quietly requesting a different set than the caller asked for would\n // hand them a token whose powers they never chose and cannot see.\n allowScopeDowngrade: !explicitScope,\n onScopeDowngrade: options.onScopeDowngrade,\n onUserCode: options.onUserCode,\n onPoll: options.onPoll,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n });\n\n const profile = buildCredentialsProfile({ token, apiBaseUrl });\n await setProfile(profileName, profile, options.credentialsPath);\n\n return {\n profileName,\n tokenPrefix: profile.tokenPrefix,\n expiresAt: profile.expiresAt,\n scopes: profile.scopes,\n identityKnown: false,\n organizationId: profile.organizationId,\n organizationSlug: profile.organizationSlug,\n userId: profile.userId,\n };\n}\n\nfunction buildCredentialsProfile(args: {\n token: TokenResponse;\n apiBaseUrl: string;\n}): CredentialsProfile {\n const now = Date.now();\n const issuedAt = new Date(now).toISOString();\n const expiresAt = new Date(now + args.token.expires_in * 1000).toISOString();\n\n // Token prefix is the first 12 chars per `02-oauth.md` §2.3 (\"ck_live_AbCdEf01gH\").\n const tokenPrefix = args.token.access_token.slice(0, 12);\n const scopes = args.token.scope.split(/\\s+/).filter(Boolean);\n\n return {\n apiBaseUrl: args.apiBaseUrl,\n accessToken: args.token.access_token,\n tokenType: args.token.token_type,\n tokenPrefix,\n organizationId: PLACEHOLDER_UUID,\n organizationSlug: PLACEHOLDER_ORG_SLUG,\n userId: PLACEHOLDER_UUID,\n scopes,\n expiresAt,\n issuedAt,\n clientId: CLIENT_ID,\n };\n}\n\nfunction isExpired(expiresAt: string): boolean {\n const t = Date.parse(expiresAt);\n if (Number.isNaN(t)) return true;\n return t <= Date.now();\n}\n","// `clickraft logout` — removes a credentials profile and, by default,\n// revokes the access token server-side via POST /oauth/revoke.\n//\n// Per `02-oauth.md` §3.3 the revoke endpoint always returns 200 (RFC 7009)\n// — but network failures, server outages, or 4xx-on-our-bug do happen.\n// We treat revocation as best-effort: any failure is logged to stderr and\n// the local profile is still removed.\n\nimport { redactTokenLikeFields, redactTokenLikeValue } from '@clickraft/sdk';\n\nimport { createApiClient, type ApiClient } from '../api/client.js';\nimport { deleteCredentials, readCredentials, removeProfile } from '../auth/credentials.js';\nimport { CredentialsError } from '../auth/errors.js';\nimport { DEFAULT_PROFILE_NAME, loadConfig } from '../config/loader.js';\n\nexport interface LogoutOptions {\n profile?: string;\n all: boolean;\n revoke: boolean;\n signal?: AbortSignal;\n credentialsPath?: string;\n // Test seam.\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n // Sink for revoke-failure warnings; defaults to process.stderr. Tests\n // capture this without touching real stderr.\n warn?: (line: string) => void;\n}\n\nexport interface LogoutResult {\n profilesRemoved: string[];\n serverRevoked: boolean;\n revokeFailureMessage?: string;\n}\n\nexport async function logout(options: LogoutOptions): Promise<LogoutResult> {\n if (options.all) {\n await deleteCredentials(options.credentialsPath);\n return { profilesRemoved: ['*'], serverRevoked: false };\n }\n\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n const profileName = config.profileName || DEFAULT_PROFILE_NAME;\n\n const file = await readCredentials(options.credentialsPath);\n const profile = file?.profiles[profileName];\n if (!profile) {\n throw new CredentialsError(\n 'CREDENTIALS_PROFILE_NOT_FOUND',\n `Profile \"${profileName}\" not found. Use \\`clickraft logout --all\\` to clear all credentials.`,\n );\n }\n\n let serverRevoked = false;\n let revokeFailureMessage: string | undefined;\n\n if (options.revoke) {\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(profile.apiBaseUrl, profile.accessToken);\n try {\n // The server returns 200 with empty/JSON body per RFC 7009. ApiClient\n // requires a JSON envelope on 200 — supply z.unknown() so any body\n // shape passes. If the server returns 2xx with non-JSON, parseSuccessBody\n // throws PARSE_ERROR which we then catch and downgrade to a warning.\n await client.request({\n method: 'POST',\n path: '/oauth/revoke',\n body: { token: profile.accessToken },\n });\n serverRevoked = true;\n } catch (err) {\n revokeFailureMessage = formatRevokeFailure(err, profile.accessToken);\n const sink = options.warn ?? ((line: string) => process.stderr.write(`${line}\\n`));\n sink(revokeFailureMessage);\n }\n }\n\n await removeProfile(profileName, options.credentialsPath);\n\n return {\n profilesRemoved: [profileName],\n serverRevoked,\n ...(revokeFailureMessage ? { revokeFailureMessage } : {}),\n };\n}\n\nfunction formatRevokeFailure(err: unknown, token: string): string {\n const reason = redactTokenLikeFields(err instanceof Error ? err.message : String(err));\n return (\n `warning: server-side revoke failed (${reason}). ` +\n `Local profile removed; token ${redactTokenLikeValue(token)} remains server-valid until expiry.`\n );\n}\n","import { z } from 'zod';\n\nexport const ModelSummarySchema = z\n .object({\n id: z.string().uuid(),\n slug: z.string(),\n displayName: z.string(),\n description: z.string().nullable(),\n shortDescription: z.string().nullable(),\n providerSlug: z.string(),\n providerName: z.string(),\n modelType: z.string(),\n category: z.string(),\n costTier: z.string(),\n creditCost: z.number(),\n pricingStrategy: z.string(),\n estimatedSeconds: z\n .object({\n typical: z.number(),\n range: z.array(z.number()),\n })\n .passthrough()\n .nullable(),\n status: z.string(),\n modalities: z\n .object({\n input: z.array(z.string()),\n output: z.array(z.string()),\n })\n .passthrough()\n .nullable(),\n bestFor: z.array(z.string()),\n badges: z.array(\n z\n .object({\n type: z.string(),\n label: z.string(),\n color: z.string(),\n expires_at: z.string().nullable().optional(),\n })\n .strict(),\n ),\n isFeatured: z.boolean(),\n isDefault: z.boolean(),\n docsUrl: z.string().nullable(),\n llmContext: z.string().nullable(),\n // Server (AgentModelSchema) types constraints as any-typed (anyOf[{}, null]); mirror it with\n // z.unknown().nullable() rather than narrowing to object|null, so a non-object emit is accepted.\n constraints: z.unknown().nullable(),\n modelFamily: z.string().nullable(),\n isFamilyPrimary: z.boolean().nullable(),\n // Optional lifecycle fields the server emits (string|null, absent when not set).\n deprecatedAt: z.string().nullable().optional(),\n sunsetAt: z.string().nullable().optional(),\n successorSlug: z.string().nullable().optional(),\n })\n .strict();\n\nexport const ModelsListResponseSchema = z\n .object({\n models: z.array(ModelSummarySchema),\n })\n .strict();\n\nexport type ModelSummary = z.infer<typeof ModelSummarySchema>;\nexport type ModelsListResponse = z.infer<typeof ModelsListResponseSchema>;\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface ModelClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildModelClient(opts: ModelClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import type { ApiClient } from '../../api/client.js';\nimport {\n ModelsListResponseSchema,\n type ModelSummary,\n type ModelsListResponse,\n} from '../../schemas/models.js';\n\nimport { buildModelClient, type ModelClientOptions } from './internal.js';\n\nexport interface ModelListOptions extends ModelClientOptions {\n category?: string;\n tier?: string;\n type?: string;\n featured?: boolean;\n client?: ApiClient;\n}\n\nexport interface ModelListResult {\n models: ModelSummary[];\n}\n\nexport async function listModels(opts: ModelListOptions): Promise<ModelListResult> {\n const client = opts.client ?? (await buildModelClient(opts));\n\n const data = await client.request<ModelsListResponse>({\n method: 'GET',\n path: '/models',\n query: {\n category: opts.category,\n tier: opts.tier,\n type: opts.type,\n featured: opts.featured !== undefined ? String(opts.featured) : undefined,\n },\n responseSchema: ModelsListResponseSchema,\n signal: opts.signal,\n });\n\n return data;\n}\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface NodesClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildNodesClient(opts: NodesClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import { NodeTypeDetailSchema, type NodeTypeDetail } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildNodesClient, type NodesClientOptions } from './internal.js';\n\nexport interface NodesDescribeOptions extends NodesClientOptions {\n type: string;\n client?: ApiClient;\n}\n\nexport async function describeNode(opts: NodesDescribeOptions): Promise<NodeTypeDetail> {\n const client = opts.client ?? (await buildNodesClient(opts));\n return client.request<NodeTypeDetail>({\n method: 'GET',\n path: `/node-types/${encodeURIComponent(opts.type)}`,\n responseSchema: NodeTypeDetailSchema,\n signal: opts.signal,\n });\n}\n","import {\n NodeTypesListResponseSchema,\n type NodeTypeSummary,\n type NodeTypesListResponse,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildNodesClient, type NodesClientOptions } from './internal.js';\n\nexport interface NodesListOptions extends NodesClientOptions {\n client?: ApiClient;\n}\n\nexport interface NodesListResult {\n nodeTypes: NodeTypeSummary[];\n}\n\nexport async function listNodes(opts: NodesListOptions): Promise<NodesListResult> {\n const client = opts.client ?? (await buildNodesClient(opts));\n\n const data = await client.request<NodeTypesListResponse>({\n method: 'GET',\n path: '/node-types',\n responseSchema: NodeTypesListResponseSchema,\n signal: opts.signal,\n });\n\n return data;\n}\n","// Client-side scope pre-flight.\n//\n// A token minted before a scope existed cannot use the endpoints that require\n// it, and the server's answer is a bare 403 that says nothing about re-login\n// being the fix. This module turns the scopes recorded at login into a fast,\n// offline failure with an actionable remedy.\n//\n// IT IS NOT AUTHORIZATION. The recorded scopes are a snapshot from login, and\n// they can be revoked or widened server-side afterwards, so this check is\n// necessarily both incomplete and potentially stale:\n//\n// - stale-permissive: a scope was revoked after login. The check passes and\n// the server still 403s, which is why the curated server-response mapping\n// in dispatch.ts stays armed regardless of what happens here.\n// - unknowable: the token came from --token or CLICKRAFT_TOKEN, so there are\n// no recorded scopes at all. The check must then do NOTHING. Failing closed\n// on an unknown would break every CI caller that supplies a token by env\n// var, and those are exactly the callers most likely to hold a fresh token.\n//\n// So: a fast path over an authority that always runs, never a replacement.\n\nimport { ApiError } from '../api/client.js';\nimport type { ResolvedConfig } from '../config/loader.js';\n\nexport const PRODUCTS_WRITE_SCOPE = 'products:write';\n\n/**\n * Throw when the recorded scopes are known and do not include `scope`.\n *\n * No-op when `config.scopes` is null (unknown), which is the flag/env-token\n * case. `hint` matches what the server-response mapping produces for the same\n * failure, so the user sees one consistent remedy whichever path reports it.\n */\nexport function assertScope(config: ResolvedConfig, scope: string, hint: string): void {\n if (config.scopes === null) return;\n if (config.scopes.includes(scope)) return;\n\n throw new ApiError('AUTH_TOKEN_SCOPE_INSUFFICIENT', hint, { retryable: false, hint });\n}\n","import {\n ProductSummarySchema,\n parseProductCreateRequest,\n type ProductCreateImage,\n type ProductSummary,\n} from '@clickraft/sdk';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { PRODUCTS_WRITE_SCOPE, assertScope } from '../../auth/scopes.js';\nimport { ArgError } from '../../cli/args.js';\nimport { loadConfig } from '../../config/loader.js';\n\nimport type { ParsedImageSpec } from './parse-image-spec.js';\n\nexport interface ProductCreateOptions {\n name: string;\n description?: string;\n images: ParsedImageSpec[];\n /** assetId of the image to mark primary. Must be one of `images`. */\n primary?: string;\n /**\n * Overrides the SDK's per-invocation UUID. The only way to get idempotency\n * ACROSS process invocations, which a shell script wrapping the CLI in its\n * own retry loop needs.\n */\n idempotencyKey?: string;\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n scopeHint: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nconst IDEMPOTENCY_KEY_MAX = 255;\n\nexport async function createProduct(options: ProductCreateOptions): Promise<ProductSummary> {\n if (options.idempotencyKey !== undefined) {\n const len = options.idempotencyKey.length;\n if (len < 1 || len > IDEMPOTENCY_KEY_MAX) {\n throw new ArgError(`--idempotency-key must be 1..${IDEMPOTENCY_KEY_MAX} characters.`);\n }\n }\n\n const config = await loadConfig({\n flagProfile: options.profile,\n flagApiBaseUrl: options.apiBaseUrl,\n flagToken: options.token,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n // Before the client is even built: a token that provably lacks the scope\n // cannot succeed, and a wasted round trip buys nothing but a worse message.\n // Silent when the scopes are unknown — see auth/scopes.ts.\n assertScope(config, PRODUCTS_WRITE_SCOPE, options.scopeHint);\n\n const body = buildRequestBody(options);\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n // `responseSchema` is the INNER shape: the SDK client unwraps `{ data }`\n // before validating, so this is ProductSummarySchema and not a wrapper.\n //\n // No `idempotencyKey` passed means the SDK mints a UUIDv4 once, outside its\n // retry loop, so every attempt of THIS call carries the same key. That is what\n // makes the 503 STORAGE_UNAVAILABLE retry replay instead of double-creating.\n return client.request<ProductSummary>({\n method: 'POST',\n path: '/products',\n body,\n idempotencyKey: options.idempotencyKey,\n responseSchema: ProductSummarySchema,\n signal: options.signal,\n });\n}\n\n/**\n * Assemble and validate the request body.\n *\n * `--primary` is resolved here rather than defaulted: when it is absent no\n * `isPrimary` is sent at all and the SERVER decides (index 0 becomes primary).\n * Duplicating that rule client-side would create a second place for it to drift.\n */\nfunction buildRequestBody(options: ProductCreateOptions): unknown {\n if (options.images.length === 0) {\n throw new ArgError('At least one --image is required.');\n }\n\n if (options.primary !== undefined) {\n const known = options.images.some((img) => img.assetId === options.primary);\n if (!known) {\n throw new ArgError(`--primary ${options.primary} is not among the --image assets provided.`);\n }\n }\n\n const images: ProductCreateImage[] = options.images.map((img) => {\n const entry: ProductCreateImage = { assetId: img.assetId };\n if (img.altText !== undefined) entry.altText = img.altText;\n // Only the chosen image carries the flag. The others omit it rather than\n // sending `false`: same server branch, smaller body, and it keeps \"the\n // caller expressed no preference\" distinguishable in the payload.\n if (options.primary === img.assetId) entry.isPrimary = true;\n return entry;\n });\n\n const raw: Record<string, unknown> = { name: options.name, images };\n if (options.description !== undefined) raw.description = options.description;\n\n // The SDK owns duplicate-detection, the image cap, field bounds and the byte\n // cap, so the CLI and the MCP tool reject exactly the same payloads.\n return parseProductCreateRequest(raw);\n}\n","// TODO: brand-model/list.ts and template schemas use .strict() on response\n// schemas, causing SCHEMA_MISMATCH when the server adds fields. Audit and\n// relax those separately — out of scope for this PR.\n\nimport { ProductsListResponseSchema, type ProductSummary } from '@clickraft/sdk';\nimport { z } from 'zod';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface ProductListOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n cursor?: string;\n limit?: number;\n syncStatus?: string;\n sourceType?: string;\n search?: string;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nconst DEFAULT_LIMIT = 50;\n\nexport interface ProductListResult {\n products: ProductSummary[];\n nextCursor: string | null;\n hasMore: boolean;\n}\n\nexport async function listProducts(options: ProductListOptions): Promise<ProductListResult> {\n const config = await loadConfig({\n flagProfile: options.profile,\n flagApiBaseUrl: options.apiBaseUrl,\n flagToken: options.token,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const query: Record<string, string | number | undefined> = {\n limit: options.limit ?? DEFAULT_LIMIT,\n };\n if (options.cursor) query.cursor = options.cursor;\n if (options.syncStatus) query.syncStatus = options.syncStatus;\n if (options.sourceType) query.sourceType = options.sourceType;\n if (options.search) query.search = options.search;\n\n const data = await client.request<z.infer<typeof ProductsListResponseSchema>>({\n method: 'GET',\n path: '/products',\n query,\n responseSchema: ProductsListResponseSchema,\n signal: options.signal,\n });\n\n return {\n products: data.items,\n nextCursor: data.nextCursor,\n hasMore: data.nextCursor !== null,\n };\n}\n","// Parses a `--image` spec into a product-create image entry.\n//\n// Shape: `<assetId>[:<altText>]`, matching the colon-spec idiom already used by\n// `--product` and `--brand-model`.\n\nimport { UUID_RE } from '@clickraft/sdk';\n\nimport { ArgError } from '../../cli/args.js';\n\nexport interface ParsedImageSpec {\n assetId: string;\n altText?: string;\n}\n\n/**\n * Split on the FIRST colon only, so alt text may contain colons\n * (`--image \"<uuid>:Mug: the sequel\"`). That is unambiguous because the left\n * side must be a UUID, which never contains one.\n *\n * `UUID_RE` comes from the SDK rather than a local regex on purpose: it is\n * pinned to the server's own published pattern, and a second copy here would be\n * the drift this CLI just spent a commit eliminating.\n */\nexport function parseImageSpec(spec: string): ParsedImageSpec {\n const trimmed = spec.trim();\n if (trimmed.length === 0) {\n throw new ArgError('--image requires a value of the form <assetId>[:<altText>].');\n }\n\n const colon = trimmed.indexOf(':');\n // Both sides are trimmed independently: trimming only the whole spec leaves\n // `<uuid> : alt` with a trailing space on the id, which then fails UUID_RE\n // with a confusing \"not a UUID\" message about a string that plainly is one.\n const assetId = (colon === -1 ? trimmed : trimmed.slice(0, colon)).trim();\n const rawAlt = colon === -1 ? undefined : trimmed.slice(colon + 1).trim();\n\n if (!UUID_RE.test(assetId)) {\n throw new ArgError(\n `--image expects an asset id (UUID) before the colon, got \"${assetId}\". ` +\n 'Use the assetId returned by `clickraft upload`.',\n );\n }\n\n // `<uuid>:` with nothing after it means no alt text, not empty alt text: the\n // server would reject \"\" against `.min(1)`-less but trimmed semantics, and an\n // empty string is never what the caller meant.\n return rawAlt ? { assetId, altText: rawAlt } : { assetId };\n}\n","// Agent / CI environment detection. Source: 04-fingerprinting.md §2.1–§2.4\n// and wave-1-investigation.md Phase 8 Q3 (\"default OFF in non-interactive /\n// CI / agent contexts\"). The detection here is read-only — telemetry SDKs\n// will consult `detectAgents(process.env).detected` before initializing.\n\nexport interface DetectedAgents {\n detected: string[];\n signals: Record<string, string>;\n}\n\n// `signal → agent label` lookup. The order does not matter; signals are\n// independent. If multiple variables for the same agent are set, the agent\n// appears once in `detected` and every triggered env var lands in `signals`.\nconst AGENT_SIGNALS: ReadonlyArray<{ envVar: string; agent: string }> = [\n { envVar: 'CLAUDE_CODE_SESSION_ID', agent: 'claude-code' },\n { envVar: 'CLAUDECODE', agent: 'claude-code' },\n { envVar: 'CURSOR_SESSION', agent: 'cursor' },\n { envVar: 'CURSOR_TRACE_ID', agent: 'cursor' },\n { envVar: 'OPENAI_CODEX_ENV', agent: 'codex' },\n { envVar: 'CODEX_CLI', agent: 'codex' },\n { envVar: 'CI', agent: 'ci' },\n];\n\nexport function detectAgents(env: NodeJS.ProcessEnv = process.env): DetectedAgents {\n const detected = new Set<string>();\n const signals: Record<string, string> = {};\n\n for (const { envVar, agent } of AGENT_SIGNALS) {\n const value = env[envVar];\n if (value !== undefined && value !== '' && value !== '0') {\n detected.add(agent);\n signals[envVar] = agent;\n }\n }\n\n return { detected: [...detected].sort(), signals };\n}\n","// `clickraft telemetry inspect` — transparency surface per Phase 8 Q3.\n//\n// Wave 1: no telemetry SDK is wired in (Sentry crash SDK is planned for the\n// Wave 1 release pipeline, PostHog product-analytics SDK is deferred to\n// Wave 2 per `wave-1-investigation.md` line 484). This command reports the\n// current opt-in/opt-out state, what would be sent, and which agent-detection\n// signals are tripping.\n\nimport { TELEMETRY_DISABLE_ENV_VAR } from '../../config/loader.js';\nimport { detectAgents } from '../../telemetry/detect.js';\n\nexport type CrashReportsReason = 'default' | 'env-disabled' | 'opt-out';\nexport type ProductAnalyticsReason = 'opt-in-pending' | 'opt-in-active';\n\nexport interface TelemetryState {\n crashReports: {\n enabled: boolean;\n reason: CrashReportsReason;\n sdkShipped: boolean;\n };\n productAnalytics: {\n enabled: boolean;\n reason: ProductAnalyticsReason;\n sdkShipped: boolean;\n };\n agentDetection: {\n enabled: boolean;\n signals: Record<string, string>;\n detected: string[];\n };\n envOverrides: {\n CLICKRAFT_DISABLE_TELEMETRY: boolean;\n DO_NOT_TRACK: boolean;\n };\n payloadShape: {\n crashReports: Record<string, unknown>;\n productAnalytics: Record<string, unknown>;\n };\n}\n\nexport interface InspectOptions {\n env?: NodeJS.ProcessEnv;\n}\n\nexport function inspectTelemetry(options: InspectOptions = {}): TelemetryState {\n const env = options.env ?? process.env;\n const optedOut = env[TELEMETRY_DISABLE_ENV_VAR] === '1' || env.DO_NOT_TRACK === '1';\n const agents = detectAgents(env);\n\n // SDK shipped status — currently both false in Wave 1.\n const crashSdkShipped = false;\n const productSdkShipped = false;\n\n return {\n crashReports: {\n enabled: false, // SDK not shipped → not enabled regardless of opt-out flags\n reason: optedOut ? 'env-disabled' : 'default',\n sdkShipped: crashSdkShipped,\n },\n productAnalytics: {\n enabled: false,\n reason: 'opt-in-pending',\n sdkShipped: productSdkShipped,\n },\n agentDetection: {\n enabled: agents.detected.length > 0,\n signals: agents.signals,\n detected: agents.detected,\n },\n envOverrides: {\n CLICKRAFT_DISABLE_TELEMETRY: env[TELEMETRY_DISABLE_ENV_VAR] === '1',\n DO_NOT_TRACK: env.DO_NOT_TRACK === '1',\n },\n payloadShape: {\n crashReports: {\n event: 'unhandled_exception',\n error_type: 'string',\n error_message: 'string (token-redacted)',\n stack_redacted: 'string',\n cli_version: 'string',\n node_version: 'string',\n platform: 'string',\n agents_detected: 'string[]',\n },\n productAnalytics: {\n event: 'command_completed',\n command: 'string (e.g. \"tokens.list\")',\n exit_code: 'number',\n duration_ms: 'number',\n cli_version: 'string',\n agents_detected: 'string[]',\n },\n },\n };\n}\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface TemplateClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildTemplateClient(opts: TemplateClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import {\n TemplatesListResponseSchema,\n type TemplateSummary,\n type TemplatesListResponse,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildTemplateClient, type TemplateClientOptions } from './internal.js';\n\nexport interface TemplateListOptions extends TemplateClientOptions {\n q?: string;\n tags?: string[];\n scope?: 'own' | 'system' | 'all';\n cursor?: string;\n limit?: number;\n client?: ApiClient;\n}\n\nexport interface TemplateListResult {\n templates: TemplateSummary[];\n cursor: string | null;\n hasMore: boolean;\n}\n\nexport async function listTemplates(opts: TemplateListOptions): Promise<TemplateListResult> {\n const client = opts.client ?? (await buildTemplateClient(opts));\n\n const data = await client.request<TemplatesListResponse>({\n method: 'GET',\n path: '/templates',\n query: {\n q: opts.q,\n tags: opts.tags,\n scope: opts.scope,\n cursor: opts.cursor,\n limit: opts.limit,\n },\n responseSchema: TemplatesListResponseSchema,\n signal: opts.signal,\n });\n\n return data;\n}\n","import type { ApiClient } from '../../api/client.js';\n\nimport { type TemplateClientOptions } from './internal.js';\nimport { listTemplates, type TemplateListResult } from './list.js';\n\nexport interface TemplateFindOptions extends TemplateClientOptions {\n query: string;\n tags?: string[];\n scope?: 'own' | 'system' | 'all';\n limit?: number;\n cursor?: string;\n client?: ApiClient;\n}\n\nexport async function findTemplates(opts: TemplateFindOptions): Promise<TemplateListResult> {\n return listTemplates({\n q: opts.query,\n tags: opts.tags,\n scope: opts.scope,\n limit: opts.limit,\n cursor: opts.cursor,\n profile: opts.profile,\n apiBaseUrl: opts.apiBaseUrl,\n token: opts.token,\n signal: opts.signal,\n client: opts.client,\n });\n}\n","import { TemplateDetailSchema, type TemplateDetail } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildTemplateClient, type TemplateClientOptions } from './internal.js';\n\nexport interface TemplateGetOptions extends TemplateClientOptions {\n id: string;\n client?: ApiClient;\n}\n\nexport async function getTemplate(opts: TemplateGetOptions): Promise<TemplateDetail> {\n const client = opts.client ?? (await buildTemplateClient(opts));\n return client.request<TemplateDetail>({\n method: 'GET',\n path: `/templates/${encodeURIComponent(opts.id)}`,\n responseSchema: TemplateDetailSchema,\n signal: opts.signal,\n });\n}\n","// `clickraft tokens list` — GET /api/agents/v1/tokens.\n//\n// The RFC names the endpoint (`01-tool-surface.md` §7.2, `02-oauth.md` §7)\n// but does not pin the per-row shape. The per-row contract (now in\n// @clickraft/sdk) is the CLI's assumption; if the server diverges the\n// integration test will surface it via SCHEMA_MISMATCH from ApiClient's\n// strict Zod validation.\n\nimport { TokensListResponseSchema, type TokenRow } from '@clickraft/sdk';\nimport { z } from 'zod';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface TokensListOptions {\n profile?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nexport async function listTokens(options: TokensListOptions): Promise<TokenRow[]> {\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const data = await client.request<z.infer<typeof TokensListResponseSchema>>({\n method: 'GET',\n path: '/tokens',\n responseSchema: TokensListResponseSchema,\n signal: options.signal,\n });\n\n return data;\n}\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface WorkflowClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildWorkflowClient(opts: WorkflowClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import {\n applyWorkflowWithRetry,\n WorkflowDetailSchema,\n WorkflowMutateResponseSchema,\n type ApiClient,\n type WorkflowDetail,\n type WorkflowMutateResponse,\n} from '@clickraft/sdk';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowApplyOptions extends WorkflowClientOptions {\n id: string;\n canvasRev: number;\n operations: Record<string, unknown>[];\n idempotencyKey?: string;\n autoRev?: boolean;\n client?: ApiClient;\n}\n\nexport interface WorkflowApplyResult {\n canvasRev: number;\n applied: number;\n workflow: WorkflowDetail;\n retriedWithRev?: number;\n}\n\n// Thin CLI wrapper around the SDK orchestration (Phase 4a). The CLI resolves\n// config + builds the client, then injects the real response schemas; the\n// auto-rev-retry algorithm itself lives in @clickraft/sdk and is UX-free /\n// disk-free. Rendering and exit codes stay in the dispatcher.\nexport async function applyWorkflow(opts: WorkflowApplyOptions): Promise<WorkflowApplyResult> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n return applyWorkflowWithRetry<WorkflowMutateResponse, WorkflowDetail>({\n client,\n id: opts.id,\n canvasRev: opts.canvasRev,\n operations: opts.operations,\n idempotencyKey: opts.idempotencyKey,\n autoRev: opts.autoRev,\n signal: opts.signal,\n schemas: { mutate: WorkflowMutateResponseSchema, detail: WorkflowDetailSchema },\n });\n}\n","import { WorkflowCreateResponseSchema, type WorkflowCreateResponse } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\nimport { ArgError } from '../../cli/args.js';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowCreateOptions extends WorkflowClientOptions {\n name: string;\n description?: string;\n tags?: string[];\n declaredParams?: Record<string, unknown> | Array<Record<string, unknown>>;\n client?: ApiClient;\n}\n\nfunction toParamArray(\n input: Record<string, unknown> | Array<Record<string, unknown>>,\n): Array<Record<string, unknown>> {\n if (Array.isArray(input)) return input;\n return Object.entries(input).map(([key, val]) => {\n const def = typeof val === 'object' && val !== null ? (val as Record<string, unknown>) : {};\n if (def.name !== undefined && def.name !== key) {\n throw new ArgError(\n `declared_params key '${key}' conflicts with inner name '${String(def.name)}'.`,\n );\n }\n return { name: key, ...def };\n });\n}\n\nexport async function createWorkflow(opts: WorkflowCreateOptions): Promise<WorkflowCreateResponse> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n const body: Record<string, unknown> = { name: opts.name };\n if (opts.description !== undefined) body.description = opts.description;\n if (opts.tags !== undefined && opts.tags.length > 0) body.tags = opts.tags;\n if (opts.declaredParams !== undefined) body.declared_params = toParamArray(opts.declaredParams);\n\n return client.request<WorkflowCreateResponse>({\n method: 'POST',\n path: '/workflows',\n body,\n responseSchema: WorkflowCreateResponseSchema,\n signal: opts.signal,\n });\n}\n","import { WorkflowDetailSchema, type WorkflowDetail } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowGetOptions extends WorkflowClientOptions {\n id: string;\n client?: ApiClient;\n}\n\nexport async function getWorkflow(opts: WorkflowGetOptions): Promise<WorkflowDetail> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n return client.request<WorkflowDetail>({\n method: 'GET',\n path: `/workflows/${encodeURIComponent(opts.id)}`,\n responseSchema: WorkflowDetailSchema,\n signal: opts.signal,\n });\n}\n","import {\n WorkflowsListResponseSchema,\n type WorkflowSummary,\n type WorkflowsListResponse,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowListOptions extends WorkflowClientOptions {\n cursor?: string;\n limit?: number;\n tags?: string[];\n declaredParamsHasKey?: string;\n client?: ApiClient;\n}\n\nexport interface WorkflowListResult {\n items: WorkflowSummary[];\n nextCursor: string | null;\n hasMore: boolean;\n}\n\nexport async function listWorkflows(opts: WorkflowListOptions): Promise<WorkflowListResult> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n const data = await client.request<WorkflowsListResponse>({\n method: 'GET',\n path: '/workflows',\n query: {\n cursor: opts.cursor,\n limit: opts.limit,\n tags: opts.tags?.join(','),\n declared_params_has_key: opts.declaredParamsHasKey,\n },\n responseSchema: WorkflowsListResponseSchema,\n signal: opts.signal,\n });\n\n return {\n items: data.items,\n nextCursor: data.nextCursor,\n hasMore: data.nextCursor !== null,\n };\n}\n","// Dual error format per Phase 8 Q10 of `wave-1-investigation.md`.\n//\n// Human (stderr): 4-line template\n// Error: <message>\n// Code: E_<CODE>\n// Try: <hint or fallback>\n// Request ID: <id or 'n/a'>\n//\n// JSON (stdout): full envelope via wrapError.\n\nimport { ApiError } from '../api/client.js';\nimport { wrapError, type EnvelopeContext } from '../api/envelope.js';\nimport { AuthError, CredentialsError } from '../auth/errors.js';\n\nimport { EXIT_CODE_MAP, toEnvelopeCode, type AllErrorCode } from './codes.js';\n\nconst FALLBACK_HINT = 'See `clickraft --help` or contact support.';\n\nexport function formatHumanError(err: unknown): string {\n const view = errorToView(err);\n const lines = [\n `Error: ${view.message}`,\n `Code: ${view.code}`,\n `Try: ${view.hint}`,\n `Request ID: ${view.requestId ?? 'n/a'}`,\n ];\n if (view.details) lines.push(`Details: ${view.details}`);\n return lines.join('\\n');\n}\n\nexport function formatJsonError(err: unknown, ctx: EnvelopeContext): string {\n return JSON.stringify(wrapError(err, ctx));\n}\n\ninterface ErrorView {\n code: string;\n message: string;\n hint: string;\n requestId?: string;\n details?: string;\n}\n\nfunction formatDetails(details: unknown): string | undefined {\n if (details == null) return undefined;\n if (typeof details !== 'object') return String(details);\n const entries = Object.entries(details as Record<string, unknown>);\n if (entries.length === 0) return undefined;\n return entries.map(([k, v]) => `${k}=${v}`).join(', ');\n}\n\nfunction errorToView(err: unknown): ErrorView {\n if (err instanceof ApiError) {\n return {\n code: toEnvelopeCode(err.code),\n message: err.message,\n hint: err.meta.hint ?? EXIT_CODE_MAP[err.code]?.hint ?? FALLBACK_HINT,\n requestId: err.meta.requestId,\n details: formatDetails(err.meta.details),\n };\n }\n if (err instanceof AuthError || err instanceof CredentialsError) {\n const code = err.code as AllErrorCode;\n return {\n code: toEnvelopeCode(code),\n message: err.message,\n hint: EXIT_CODE_MAP[code]?.hint ?? FALLBACK_HINT,\n };\n }\n return {\n code: toEnvelopeCode('INTERNAL_ERROR'),\n message: err instanceof Error ? err.message : String(err),\n hint: FALLBACK_HINT,\n };\n}\n","// Minimal argv parser for the Wave 1 command surface. 0-dep state machine.\n//\n// Surface today: subcommand path + flags only (no positional args until 1A.4\n// introduces `upload <file>` and `generate get <id>`). If the surface outgrows\n// this, swap to `commander@^12` at that point.\n\nexport interface ParsedArgs {\n command: string[];\n flags: Record<string, string | boolean | undefined>;\n positional: string[];\n}\n\nconst SHORT_ALIASES: Record<string, string> = {\n h: 'help',\n v: 'version',\n};\n\n// Long flags whose value follows in the next argv token (`--profile staging`\n// vs `--profile=staging`). Anything not in this set is treated as a boolean\n// switch — keeps `--json` and friends from greedily eating the next arg.\nconst VALUE_FLAGS: ReadonlySet<string> = new Set(['profile', 'api-base-url', 'scope', 'token']);\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const flags: Record<string, string | boolean | undefined> = {};\n const positional: string[] = [];\n const command: string[] = [];\n let commandLocked = false;\n\n let i = 0;\n while (i < argv.length) {\n const raw = argv[i]!;\n\n if (raw === '--') {\n // Everything after `--` is positional, no flag parsing.\n for (let j = i + 1; j < argv.length; j += 1) positional.push(argv[j]!);\n break;\n }\n\n if (raw.startsWith('--')) {\n const eq = raw.indexOf('=');\n const name = eq === -1 ? raw.slice(2) : raw.slice(2, eq);\n const inline = eq === -1 ? undefined : raw.slice(eq + 1);\n\n if (name.startsWith('no-')) {\n flags[name.slice(3)] = false;\n i += 1;\n commandLocked = true;\n continue;\n }\n\n if (VALUE_FLAGS.has(name)) {\n if (inline !== undefined) {\n flags[name] = inline;\n } else {\n const next = argv[i + 1];\n if (next === undefined || next.startsWith('-')) {\n // Missing value — leave as boolean true so the command handler\n // can surface a clear \"flag requires a value\" error.\n flags[name] = true;\n } else {\n flags[name] = next;\n i += 1;\n }\n }\n } else {\n flags[name] = inline ?? true;\n }\n i += 1;\n commandLocked = true;\n continue;\n }\n\n if (raw.startsWith('-') && raw.length > 1) {\n // Short flags: only -h / -v are recognized; everything else falls\n // through as a positional so error messages can point at it.\n const short = raw.slice(1);\n const aliased = SHORT_ALIASES[short];\n if (aliased) {\n flags[aliased] = true;\n i += 1;\n commandLocked = true;\n continue;\n }\n positional.push(raw);\n i += 1;\n commandLocked = true;\n continue;\n }\n\n if (!commandLocked) {\n command.push(raw);\n } else {\n positional.push(raw);\n }\n i += 1;\n }\n\n return { command, flags, positional };\n}\n","// User-facing progress UI for `clickraft login`. All output goes to stderr so\n// stdout stays clean for `--json` consumers and shell redirection.\n\nimport { spawn } from 'node:child_process';\n\nexport interface UserCodePromptInfo {\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresAt: Date;\n}\n\nexport function renderUserCodePrompt(\n info: UserCodePromptInfo,\n stream: NodeJS.WritableStream = process.stderr,\n): void {\n const lines = [\n '',\n 'To complete login, visit:',\n ` ${info.verificationUriComplete}`,\n '',\n `And enter the code: ${info.userCode}`,\n `Code expires at: ${info.expiresAt.toISOString()}`,\n '',\n ];\n stream.write(lines.join('\\n'));\n}\n\n// Best-effort browser open. Returns true if a spawn was issued. Never throws —\n// a failure here is a UX degradation, not a flow-blocking error.\nexport function openBrowser(url: string): boolean {\n if (!process.stderr.isTTY) return false;\n\n const command = pickBrowserCommand();\n if (!command) return false;\n\n try {\n const child = spawn(command.bin, [...command.args, url], {\n stdio: 'ignore',\n detached: true,\n });\n child.on('error', () => {\n // Swallow — caller has already printed the URL.\n });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n\nfunction pickBrowserCommand(): { bin: string; args: string[] } | undefined {\n if (process.platform === 'darwin') return { bin: 'open', args: [] };\n if (process.platform === 'win32') return { bin: 'cmd', args: ['/c', 'start', ''] };\n if (process.platform === 'linux') return { bin: 'xdg-open', args: [] };\n return undefined;\n}\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\nconst SPINNER_INTERVAL_MS = 80;\n\nexport interface Spinner {\n stop(): void;\n}\n\nexport function startPollingSpinner(\n label = 'Waiting for authorization…',\n stream: NodeJS.WriteStream = process.stderr,\n): Spinner {\n if (!stream.isTTY) {\n return { stop() {} };\n }\n\n let frame = 0;\n const handle = setInterval(() => {\n stream.write(`\\r${SPINNER_FRAMES[frame]!} ${label}`);\n frame = (frame + 1) % SPINNER_FRAMES.length;\n }, SPINNER_INTERVAL_MS);\n\n return {\n stop(): void {\n clearInterval(handle);\n // Erase the spinner line so subsequent output starts clean.\n stream.write(`\\r${' '.repeat(label.length + 4)}\\r`);\n },\n };\n}\n","// Human-mode result renderers. JSON mode uses wrapSuccess directly from the\n// dispatcher — this module only deals with the friendly stdout/stderr output\n// shown to a terminal user.\n\nimport type {\n BalanceData,\n BrandModelSummary,\n NodeTypeDetail,\n ProductSummary,\n TemplateDetail,\n TokenRow,\n WorkflowCreateResponse,\n WorkflowDetail,\n} from '@clickraft/sdk';\n\nimport { type LoginResult } from '../commands/login.js';\nimport { type LogoutResult } from '../commands/logout.js';\nimport { type ModelListResult } from '../commands/models/list.js';\nimport { type NodesListResult } from '../commands/nodes/list.js';\nimport { type ProductListResult } from '../commands/product/list.js';\nimport { type TelemetryState } from '../commands/telemetry/inspect.js';\nimport { type TemplateListResult } from '../commands/template/list.js';\nimport { type WorkflowApplyResult } from '../commands/workflow/apply.js';\nimport { type WorkflowListResult } from '../commands/workflow/list.js';\nimport { type ModelSummary } from '../schemas/models.js';\n\nexport function renderLoginResult(result: LoginResult, out: NodeJS.WritableStream): void {\n const expiresHuman = formatExpiresAt(result.expiresAt);\n const lines = [\n `✓ Logged in (profile: ${result.profileName}).`,\n ` Token prefix: ${result.tokenPrefix}`,\n ` Expires: ${expiresHuman}`,\n ` Scopes: ${result.scopes.join(' ')}`,\n ];\n if (!result.identityKnown) {\n // Surface the Wave 1 limitation so the user knows organizationSlug /\n // userId in the credentials file are placeholders. Quiet enough not to\n // alarm; specific enough to be auditable.\n lines.push(\n ` Note: Identity not populated (Wave 1 server-response gap, see PR description).`,\n );\n }\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderLogoutResult(result: LogoutResult, out: NodeJS.WritableStream): void {\n if (result.profilesRemoved[0] === '*') {\n out.write('✓ Removed all profiles.\\n');\n return;\n }\n const name = result.profilesRemoved[0] ?? '(unknown)';\n if (result.serverRevoked) {\n out.write(`✓ Logged out of profile \"${name}\" (server-side token revoked).\\n`);\n } else if (result.revokeFailureMessage) {\n out.write(`✓ Logged out of profile \"${name}\" locally; server-side revoke failed.\\n`);\n } else {\n out.write(`✓ Logged out of profile \"${name}\" (local only).\\n`);\n }\n}\n\nexport function renderTokensList(rows: TokenRow[], out: NodeJS.WritableStream): void {\n if (rows.length === 0) {\n out.write('No tokens.\\n');\n return;\n }\n\n const headers = ['PREFIX', 'NAME', 'SCOPES', 'LAST USED', 'EXPIRES'];\n const data = rows.map((row) => [\n row.tokenPrefix,\n row.name ?? '—',\n row.scopes.join(',') || '—',\n row.lastUsedAt ?? 'never',\n row.expiresAt,\n ]);\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n}\n\nexport function renderTelemetryState(state: TelemetryState, out: NodeJS.WritableStream): void {\n const crash = state.crashReports;\n const product = state.productAnalytics;\n const agents = state.agentDetection;\n\n const lines = [\n 'Telemetry state:',\n '',\n ` Crash reports: ${crash.enabled ? 'ON' : 'OFF'} (${crash.reason}${crash.sdkShipped ? '' : ', SDK not shipped'})`,\n ` Product analytics: ${product.enabled ? 'ON' : 'OFF'} (${product.reason}${product.sdkShipped ? '' : ', SDK not shipped'})`,\n ` Agent detection: ${agents.enabled ? 'ON' : 'OFF'}`,\n ` Detected agents: ${agents.detected.length === 0 ? '(none)' : agents.detected.join(', ')}`,\n '',\n 'Env overrides:',\n ` CLICKRAFT_DISABLE_TELEMETRY=${state.envOverrides.CLICKRAFT_DISABLE_TELEMETRY ? '1' : '0'}`,\n ` DO_NOT_TRACK=${state.envOverrides.DO_NOT_TRACK ? '1' : '0'}`,\n '',\n 'Payload shape (illustrative — no data is currently sent):',\n ` ${JSON.stringify(state.payloadShape, null, 2).split('\\n').join('\\n ')}`,\n ];\n out.write(lines.join('\\n') + '\\n');\n}\n\nconst fmtNum = new Intl.NumberFormat('en-US');\n\nexport function renderBalance(data: BalanceData, out: NodeJS.WritableStream): void {\n const pad = 22;\n const lines = [\n `${'Total credits:'.padEnd(pad)}${fmtNum.format(data.totalCredits).padStart(12)}`,\n `${'├─ Subscription:'.padEnd(pad)}${fmtNum.format(data.subscriptionCredits).padStart(12)}`,\n `${'├─ Purchased:'.padEnd(pad)}${fmtNum.format(data.purchasedCredits).padStart(12)}`,\n `${'└─ Promotional:'.padEnd(pad)}${fmtNum.format(data.promotionalCredits).padStart(12)}`,\n '',\n `${'Rate limit:'.padEnd(pad)}${fmtNum.format(data.rateLimit.apiBurstPerMinute).padStart(12)} req/min`,\n ];\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderBrandModelsList(\n models: BrandModelSummary[],\n out: NodeJS.WritableStream,\n): void {\n if (models.length === 0) {\n out.write('No brand models.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['SOURCE', 'NAME', 'SLUG', 'CATEGORY', 'TAGS'];\n const data = models.map((m) => {\n const shown = m.tags.slice(0, MAX_TAGS).join(', ');\n const extra = m.tags.length > MAX_TAGS ? ` +${m.tags.length - MAX_TAGS} more` : '';\n return [\n m.source,\n m.name,\n m.slug ?? '—',\n m.category ?? '—',\n m.tags.length > 0 ? shown + extra : '—',\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n}\n\nexport function renderProductsList(result: ProductListResult, out: NodeJS.WritableStream): void {\n const { products } = result;\n if (products.length === 0) {\n out.write('No products.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['ID', 'TITLE', 'SOURCE', 'SYNC', 'IMAGES', 'PRIMARY IMAGE', 'VENDOR', 'TAGS'];\n const data = products.map((p) => {\n const shown = p.tags.slice(0, MAX_TAGS).join(', ');\n const extra = p.tags.length > MAX_TAGS ? ` +${p.tags.length - MAX_TAGS} more` : '';\n const primary =\n p.images.find((img) => img.isPrimary) ?? p.images.find((img) => img.sortOrder === 0);\n return [\n p.id,\n p.title,\n p.sourceType,\n p.syncStatus ?? '—',\n String(p.images.length),\n primary?.id ?? '—',\n p.vendor ?? '—',\n p.tags.length > 0 ? shown + extra : '—',\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n if (result.hasMore) {\n out.write('\\nMore results available. Use --cursor to fetch the next page.\\n');\n }\n}\n\nexport function renderProductCreateResult(\n product: ProductSummary,\n out: NodeJS.WritableStream,\n): void {\n const lines = [\n `Created product \"${product.title}\"`,\n ` ID: ${product.id}`,\n ` Source: ${product.sourceType}`,\n ` Images: ${product.images.length}`,\n ];\n for (const img of product.images) {\n // The primary marker matters downstream: `generate create --product <id>`\n // resolves the primary image when no imageId is given, so which one it is\n // decides what a later generation actually references.\n lines.push(\n ` ${img.isPrimary ? '*' : '-'} ${img.id}${img.altText ? ` ${img.altText}` : ''}`,\n );\n }\n lines.push('', `Use it with: clickraft generate create --product ${product.id} ...`);\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderTemplatesList(result: TemplateListResult, out: NodeJS.WritableStream): void {\n const { templates } = result;\n if (templates.length === 0) {\n out.write('No templates.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['SOURCE', 'NAME', 'CATEGORY', 'TAGS', 'CREATED'];\n const data = templates.map((t) => {\n const shown = t.tags.slice(0, MAX_TAGS).join(', ');\n const extra = t.tags.length > MAX_TAGS ? ` +${t.tags.length - MAX_TAGS} more` : '';\n return [\n t.source,\n t.name,\n t.category ?? '—',\n t.tags.length > 0 ? shown + extra : '—',\n t.createdAt.slice(0, 10),\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n if (result.hasMore) {\n out.write('\\nMore results available. Use --cursor to fetch the next page.\\n');\n }\n}\n\nexport function renderTemplateDetail(detail: TemplateDetail, out: NodeJS.WritableStream): void {\n const pad = 17;\n const lines = [\n detail.name,\n `${'ID:'.padEnd(pad)}${detail.id}`,\n `${'Source:'.padEnd(pad)}${detail.source}`,\n `${'Category:'.padEnd(pad)}${detail.category ?? '—'}`,\n `${'Tags:'.padEnd(pad)}${detail.tags.length > 0 ? detail.tags.join(', ') : '—'}`,\n `${'Created:'.padEnd(pad)}${detail.createdAt.slice(0, 10)}`,\n `${'Times used:'.padEnd(pad)}${detail.timesUsed}`,\n ];\n\n if (detail.description) {\n lines.push('', detail.description);\n }\n\n lines.push('', 'Declared parameters:');\n if (detail.declaredParams.length === 0) {\n lines.push(' (none)');\n } else {\n for (const p of detail.declaredParams) {\n const req = p.required ? 'required' : 'optional';\n const desc = p.description ? `: ${p.description}` : '';\n lines.push(` - ${p.name} (${p.type}, ${req})${desc}`);\n }\n }\n\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderNodesList(result: NodesListResult, out: NodeJS.WritableStream): void {\n const { nodeTypes } = result;\n if (nodeTypes.length === 0) {\n out.write('No node types.\\n');\n return;\n }\n\n const headers = ['TYPE', 'PORTS'];\n const data = nodeTypes.map((n) => [n.type, String(n.portCount)]);\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n}\n\nexport function renderNodeDetail(detail: NodeTypeDetail, out: NodeJS.WritableStream): void {\n const lines = [detail.type, '', 'Ports:'];\n if (detail.ports.length === 0) {\n lines.push(' (none)');\n } else {\n // handleId is the canonical edge identifier — print it verbatim, never\n // renamed or prettified, so an agent can copy it to build edges.\n for (const p of detail.ports) {\n lines.push(` - ${p.handleId} (${p.direction}, ${p.dataType})`);\n }\n }\n\n lines.push('', 'Agent-writable fields:');\n if (detail.agentWritableFields.length === 0) {\n lines.push(' (none)');\n } else {\n for (const field of detail.agentWritableFields) {\n lines.push(` - ${field}`);\n }\n }\n\n out.write(lines.join('\\n') + '\\n');\n}\n\nconst TIER_ORDER: Record<string, number> = { premium: 0, pro: 1, standard: 2 };\n\nexport interface RenderModelsListOptions {\n verbose?: boolean;\n filters?: Record<string, string>;\n}\n\nexport function renderModelsList(\n result: ModelListResult,\n out: NodeJS.WritableStream,\n options?: RenderModelsListOptions,\n): void {\n const { models } = result;\n if (models.length === 0) {\n out.write('No models match your filters.\\n');\n return;\n }\n\n const sorted = [...models].sort((a: ModelSummary, b: ModelSummary) => {\n const catCmp = a.category.localeCompare(b.category);\n if (catCmp !== 0) return catCmp;\n const tierA = TIER_ORDER[a.costTier] ?? 99;\n const tierB = TIER_ORDER[b.costTier] ?? 99;\n if (tierA !== tierB) return tierA - tierB;\n return a.slug.localeCompare(b.slug);\n });\n\n const filterParts: string[] = [];\n if (options?.filters) {\n for (const [k, v] of Object.entries(options.filters)) {\n if (v) filterParts.push(`${k}=${v}`);\n }\n }\n const filterSuffix = filterParts.length > 0 ? ` (filters: ${filterParts.join(', ')})` : '';\n out.write(`${sorted.length} models${filterSuffix}\\n\\n`);\n\n const MAX_BADGES = 3;\n const headers = ['SLUG', 'NAME', 'CATEGORY', 'TIER', 'CREDITS', 'DEFAULT', 'BADGES'];\n const data = sorted.map((m) => {\n const labels = m.badges.map((b) => b.label);\n const shown = labels.slice(0, MAX_BADGES).join(', ');\n const extra = labels.length > MAX_BADGES ? ` +${labels.length - MAX_BADGES} more` : '';\n return [\n m.slug,\n m.displayName,\n m.category,\n m.costTier,\n String(m.creditCost),\n m.isDefault ? '✓' : '',\n labels.length > 0 ? shown + extra : '—',\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n out.write(\n `\\nShowing all ${sorted.length} models. Use --json for full details including constraints.\\n`,\n );\n\n if (options?.verbose) {\n out.write('\\n');\n for (const m of sorted) {\n const pad = 16;\n out.write(`${m.slug} (${m.displayName})\\n`);\n out.write(`${' Provider:'.padEnd(pad)}${m.providerName}\\n`);\n out.write(`${' Category:'.padEnd(pad)}${m.category} / ${m.modelType}\\n`);\n out.write(`${' Tier:'.padEnd(pad)}${m.costTier} (${m.creditCost} credits)\\n`);\n if (m.llmContext) {\n const ctx = m.llmContext.length > 100 ? m.llmContext.slice(0, 100) + '...' : m.llmContext;\n out.write(`${' Context:'.padEnd(pad)}${ctx}\\n`);\n }\n out.write('\\n');\n }\n }\n}\n\nfunction formatExpiresAt(iso: string): string {\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return iso;\n const date = new Date(ms);\n const days = Math.round((ms - Date.now()) / (24 * 60 * 60 * 1000));\n return `${date.toISOString()} (~${days}d)`;\n}\n\n// ---------------------------------------------------------------------------\n// Workflow renderers\n// ---------------------------------------------------------------------------\n\nexport function renderWorkflowCreateResult(\n result: WorkflowCreateResponse,\n out: NodeJS.WritableStream,\n): void {\n const lines = [\n `Created workflow \"${result.name}\"`,\n ` ID: ${result.id}`,\n ` Canvas rev: ${result.canvas_rev}`,\n ` Created: ${result.created_at.slice(0, 19)}`,\n ];\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderWorkflowsList(result: WorkflowListResult, out: NodeJS.WritableStream): void {\n const { items } = result;\n if (items.length === 0) {\n out.write('No workflows.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['ID', 'NAME', 'TAGS', 'REV', 'UPDATED'];\n const data = items.map((w) => {\n const shown = w.tags.slice(0, MAX_TAGS).join(', ');\n const extra = w.tags.length > MAX_TAGS ? ` +${w.tags.length - MAX_TAGS} more` : '';\n return [\n w.id.slice(0, 8),\n w.name,\n w.tags.length > 0 ? shown + extra : '—',\n String(w.canvas_rev),\n w.updated_at.slice(0, 10),\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n if (result.hasMore) {\n out.write('\\nMore results available. Use --cursor to fetch the next page.\\n');\n }\n}\n\nexport function renderWorkflowDetail(detail: WorkflowDetail, out: NodeJS.WritableStream): void {\n const pad = 17;\n const lines = [\n detail.name,\n `${'ID:'.padEnd(pad)}${detail.id}`,\n `${'Canvas rev:'.padEnd(pad)}${detail.canvas_rev}`,\n `${'Tags:'.padEnd(pad)}${detail.tags.length > 0 ? detail.tags.join(', ') : '—'}`,\n `${'Created:'.padEnd(pad)}${detail.created_at.slice(0, 19)}`,\n `${'Updated:'.padEnd(pad)}${detail.updated_at.slice(0, 19)}`,\n `${'Nodes:'.padEnd(pad)}${detail.nodes.length}`,\n `${'Edges:'.padEnd(pad)}${detail.edges.length}`,\n ];\n\n if (detail.description) {\n lines.push('', detail.description);\n }\n\n const params = detail.declared_params;\n lines.push('', 'Declared parameters:');\n if (!params || params.length === 0) {\n lines.push(' (none)');\n } else {\n for (const p of params) {\n const req = p.required ? 'required' : 'optional';\n const desc = p.description ? `: ${p.description}` : '';\n lines.push(` - ${p.name} (${p.type}, ${req})${desc}`);\n }\n }\n\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderWorkflowApplyResult(\n result: WorkflowApplyResult,\n out: NodeJS.WritableStream,\n): void {\n const lines = [\n `Applied ${result.applied} operation${result.applied === 1 ? '' : 's'}. New canvas_rev: ${result.canvasRev}`,\n ];\n if (result.retriedWithRev !== undefined) {\n lines.push(` (auto-rev: resolved conflict, retried with canvas_rev ${result.retriedWithRev})`);\n }\n out.write(lines.join('\\n') + '\\n');\n}\n","// Maps a ParsedArgs into a command handler, builds the EnvelopeContext,\n// renders output in human vs --json mode, and converts thrown errors into\n// the right exit code per Phase 8 Q7 / Q10.\n\nimport type {\n BalanceData,\n BrandModelSummary,\n GenerationResult,\n NodeTypeDetail,\n ProductSummary,\n TemplateDetail,\n TokenRow,\n WorkflowCreateResponse,\n WorkflowDetail,\n} from '@clickraft/sdk';\n\nimport { ApiError } from '../api/client.js';\nimport { wrapSuccess, type EnvelopeContext } from '../api/envelope.js';\nimport { AuthError } from '../auth/errors.js';\nimport { getBalance } from '../commands/balance.js';\nimport { listBrandModels } from '../commands/brand-model/list.js';\nimport { generateCreate } from '../commands/generate/create.js';\nimport { generateGet } from '../commands/generate/get.js';\nimport {\n parseBrandModelSpec,\n validateBrandModelSpecs,\n} from '../commands/generate/parse-brand-model-spec.js';\nimport { parseProductSpec, validateProductSpecs } from '../commands/generate/parse-product-spec.js';\nimport { generateWait } from '../commands/generate/wait.js';\nimport { jobsWait } from '../commands/jobs/wait.js';\nimport { DEFAULT_SCOPES, login, type LoginResult } from '../commands/login.js';\nimport { logout, type LogoutResult } from '../commands/logout.js';\nimport { listModels, type ModelListResult } from '../commands/models/list.js';\nimport { describeNode } from '../commands/nodes/describe.js';\nimport { listNodes, type NodesListResult } from '../commands/nodes/list.js';\nimport { createProduct } from '../commands/product/create.js';\nimport { listProducts, type ProductListResult } from '../commands/product/list.js';\nimport { parseImageSpec } from '../commands/product/parse-image-spec.js';\nimport { inspectTelemetry, type TelemetryState } from '../commands/telemetry/inspect.js';\nimport { findTemplates } from '../commands/template/find.js';\nimport { getTemplate } from '../commands/template/get.js';\nimport { listTemplates, type TemplateListResult } from '../commands/template/list.js';\nimport { listTokens } from '../commands/tokens/list.js';\nimport { uploadFile, type UploadResult } from '../commands/upload.js';\nimport { applyWorkflow, type WorkflowApplyResult } from '../commands/workflow/apply.js';\nimport { createWorkflow } from '../commands/workflow/create.js';\nimport { getWorkflow } from '../commands/workflow/get.js';\nimport { listWorkflows, type WorkflowListResult } from '../commands/workflow/list.js';\nimport {\n EXIT_CODE_MAP,\n getExitCode,\n SIGINT_EXIT_CODE,\n type AllErrorCode,\n type ExitCode,\n} from '../errors/codes.js';\nimport { formatHumanError, formatJsonError } from '../errors/format.js';\n\nimport { ArgError, parseArgs as parseArgsRich, type ParsedArgs as ParsedArgsRich } from './args.js';\nimport { parseArgs, type ParsedArgs } from './parse-args.js';\nimport { openBrowser, renderUserCodePrompt, startPollingSpinner } from './progress.js';\nimport {\n renderBalance,\n renderBrandModelsList,\n renderLoginResult,\n renderLogoutResult,\n renderModelsList,\n renderNodeDetail,\n renderNodesList,\n renderProductCreateResult,\n renderProductsList,\n renderTelemetryState,\n renderTemplateDetail,\n renderTemplatesList,\n renderTokensList,\n renderWorkflowApplyResult,\n renderWorkflowCreateResult,\n renderWorkflowDetail,\n renderWorkflowsList,\n} from './render.js';\n\nexport interface DispatchOptions {\n argv: string[];\n version: string;\n stdout?: NodeJS.WritableStream;\n stderr?: NodeJS.WritableStream;\n signal?: AbortSignal;\n // Test seam: skip the real browser-open / spinner UI.\n uiHooks?: {\n onUserCode?: (info: Parameters<typeof renderUserCodePrompt>[0]) => void;\n onPoll?: () => void;\n };\n}\n\nexport async function dispatch(options: DispatchOptions): Promise<ExitCode> {\n const stdout = options.stdout ?? process.stdout;\n const stderr = options.stderr ?? process.stderr;\n\n // PR #4 commands (generate / jobs / upload) take positional arguments and\n // repeatable flags, which `./parse-args.ts` does not support. Route them to\n // a separate handler that uses the richer parser in `./args.ts`, before the\n // shared parser greedily folds positionals into the command path.\n const newCmd = matchNewCommand(options.argv);\n if (newCmd !== null) {\n return runNewCommand(newCmd, options, stdout, stderr);\n }\n\n const parsed = parseArgs(options.argv);\n const jsonMode = parsed.flags.json === true;\n\n // Top-level --version / --help short-circuit BEFORE dispatch.\n if (parsed.flags.version === true) {\n stdout.write(`${options.version}\\n`);\n return 0;\n }\n\n if (parsed.command.length === 0 || parsed.flags.help === true) {\n if (parsed.command.length === 0) {\n stdout.write(renderRootHelp(options.version));\n } else {\n stdout.write(renderCommandHelp(parsed.command));\n }\n return 0;\n }\n\n const commandName = parsed.command.join('.');\n const ctx: EnvelopeContext = {\n startMs: Date.now(),\n command: commandName,\n version: options.version,\n };\n\n try {\n validateFlags(parsed);\n return await runCommand(parsed, ctx, {\n stdout,\n stderr,\n jsonMode,\n version: options.version,\n signal: options.signal,\n uiHooks: options.uiHooks,\n });\n } catch (err) {\n if (isAbortedError(err, options.signal)) {\n if (jsonMode) {\n // Synthesize an AUTH_FLOW_CANCELLED-shaped envelope so JSON consumers\n // get a structured response on SIGINT.\n stdout.write(\n formatJsonError(new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.'), ctx) + '\\n',\n );\n } else {\n stderr.write('Cancelled.\\n');\n }\n return SIGINT_EXIT_CODE;\n }\n\n const code = extractCode(err);\n if (jsonMode) {\n stdout.write(formatJsonError(err, ctx) + '\\n');\n } else {\n stderr.write(formatHumanError(err) + '\\n');\n }\n return getExitCode(code);\n }\n}\n\ninterface RunContext {\n stdout: NodeJS.WritableStream;\n stderr: NodeJS.WritableStream;\n jsonMode: boolean;\n version: string;\n signal?: AbortSignal;\n uiHooks?: DispatchOptions['uiHooks'];\n}\n\nasync function runCommand(\n parsed: ParsedArgs,\n ctx: EnvelopeContext,\n rc: RunContext,\n): Promise<ExitCode> {\n const path = parsed.command.join('.');\n\n switch (path) {\n case 'login': {\n const result = await loginCommand(parsed, rc);\n emit(result, renderLoginResult, ctx, rc);\n return 0;\n }\n case 'logout': {\n const result = await logoutCommand(parsed, rc);\n emit(result, renderLogoutResult, ctx, rc);\n return 0;\n }\n case 'tokens.list': {\n const rows = await listTokens({\n profile: stringFlag(parsed.flags.profile),\n signal: rc.signal,\n });\n emit<TokenRow[]>(rows, renderTokensList, ctx, rc);\n return 0;\n }\n case 'telemetry.inspect': {\n const state = inspectTelemetry();\n emit<TelemetryState>(state, renderTelemetryState, ctx, rc);\n return 0;\n }\n case 'balance': {\n const data = await getBalance({\n profile: stringFlag(parsed.flags.profile),\n signal: rc.signal,\n });\n emit<BalanceData>(data, renderBalance, ctx, rc);\n return 0;\n }\n case 'brand-model.list': {\n const models = await listBrandModels({\n profile: stringFlag(parsed.flags.profile),\n signal: rc.signal,\n });\n emit<BrandModelSummary[]>(models, renderBrandModelsList, ctx, rc);\n return 0;\n }\n default:\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Unknown command: ${parsed.command.join(' ')}. Run \\`clickraft --help\\` for available commands.`,\n { retryable: false },\n );\n }\n}\n\nasync function loginCommand(parsed: ParsedArgs, rc: RunContext): Promise<LoginResult> {\n const noOpen = parsed.flags['open-browser'] === false;\n let spinner: ReturnType<typeof startPollingSpinner> | undefined;\n\n try {\n return await login({\n profile: stringFlag(parsed.flags.profile),\n apiBaseUrl: stringFlag(parsed.flags['api-base-url']),\n scope: stringFlag(parsed.flags.scope),\n forceReauth: parsed.flags['force-reauth'] === true,\n openBrowser: !noOpen,\n signal: rc.signal,\n onUserCode: (info) => {\n if (rc.uiHooks?.onUserCode) {\n rc.uiHooks.onUserCode(info);\n return;\n }\n if (!rc.jsonMode) {\n renderUserCodePrompt(info, rc.stderr);\n if (!noOpen) openBrowser(info.verificationUriComplete);\n spinner = startPollingSpinner(undefined, rc.stderr as NodeJS.WriteStream);\n }\n },\n onPoll: () => {\n rc.uiHooks?.onPoll?.();\n },\n // Always warn, including in --json mode, and always on stderr: the login\n // succeeded, so the JSON envelope on stdout stays a clean success, but the\n // token is quietly less capable than the one that was asked for. Silence\n // here is how a user ends up debugging a scope error days later.\n onScopeDowngrade: (info) => {\n rc.stderr.write(\n `Warning: the server refused one or more requested scopes${\n info.description ? ` (${info.description})` : ''\n }.\\n` +\n ` Retrying with the required scopes only. This token will not be able to ` +\n `use commands that need the refused scopes.\\n` +\n ` Re-run \\`clickraft login --force-reauth\\` once the server grants them.\\n`,\n );\n },\n });\n } finally {\n spinner?.stop();\n }\n}\n\nasync function logoutCommand(parsed: ParsedArgs, rc: RunContext): Promise<LogoutResult> {\n return logout({\n profile: stringFlag(parsed.flags.profile),\n all: parsed.flags.all === true,\n revoke: parsed.flags.revoke !== false,\n signal: rc.signal,\n warn: rc.jsonMode ? () => {} : undefined,\n });\n}\n\nfunction emit<T>(\n result: T,\n human: (result: T, stream: NodeJS.WritableStream) => void,\n ctx: EnvelopeContext,\n rc: RunContext,\n): void {\n // Race window: a SIGINT delivered after the command's awaited work\n // resolves but before this render runs must produce exit 130, not\n // exit 0 with a success line. Throwing routes to dispatch's outer\n // isAbortedError handler, which writes the cancellation line.\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n human(result, rc.stdout);\n}\n\nfunction stringFlag(value: string | boolean | undefined): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n// Per-command flag schema. Unknown flags and missing string-flag values\n// reject with INPUT_INVALID_FORMAT (exit 2). Boolean flags accept either\n// `true` (set) or `false` (via `--no-<flag>`); string flags require an\n// explicit value.\nconst COMMAND_FLAGS: Record<string, Record<string, 'string' | 'boolean'>> = {\n login: {\n profile: 'string',\n 'api-base-url': 'string',\n scope: 'string',\n 'force-reauth': 'boolean',\n 'open-browser': 'boolean',\n json: 'boolean',\n },\n logout: { profile: 'string', all: 'boolean', revoke: 'boolean', json: 'boolean' },\n 'tokens.list': { profile: 'string', json: 'boolean' },\n 'telemetry.inspect': { json: 'boolean' },\n balance: { profile: 'string', json: 'boolean' },\n 'brand-model.list': { profile: 'string', json: 'boolean' },\n};\n\nfunction validateFlags(parsed: ParsedArgs): void {\n const allowed = COMMAND_FLAGS[parsed.command.join('.')];\n // Unknown command: let runCommand's default arm throw the unknown-command\n // error so the user sees that, not a flag complaint.\n if (!allowed) return;\n for (const [name, value] of Object.entries(parsed.flags)) {\n const kind = allowed[name];\n if (!kind) {\n throw new ApiError('INPUT_INVALID_FORMAT', `Unknown flag: --${name}.`, { retryable: false });\n }\n if (kind === 'string' && typeof value !== 'string') {\n throw new ApiError('INPUT_INVALID_FORMAT', `Flag --${name} requires a value.`, {\n retryable: false,\n });\n }\n }\n}\n\nfunction isAbortedError(err: unknown, signal?: AbortSignal): boolean {\n if (signal?.aborted) return true;\n if (err instanceof AuthError && err.code === 'AUTH_FLOW_CANCELLED') return true;\n return false;\n}\n\nfunction extractCode(err: unknown): AllErrorCode {\n if (err && typeof err === 'object' && 'code' in err) {\n const code = (err as { code?: unknown }).code;\n if (typeof code === 'string' && code in EXIT_CODE_MAP) {\n return code as AllErrorCode;\n }\n }\n return 'INTERNAL_ERROR';\n}\n\nfunction renderRootHelp(version: string): string {\n return [\n `clickraft v${version} — the Clickraft CLI`,\n '',\n 'Usage: clickraft <command> [options]',\n '',\n 'Commands:',\n ' login Authenticate via OAuth device flow',\n ' logout Remove credentials (optional server-side revoke)',\n \" tokens list List the caller's API tokens\",\n ' balance Show credit balance and rate limits',\n ' brand-model list List available brand models',\n ' product list List products in your organization',\n ' product create Create a product from uploaded assets',\n ' models list List available AI models',\n ' nodes list List available workflow node types',\n \" nodes describe Describe a node type's ports and fields\",\n ' telemetry inspect Show current telemetry state and payload shape',\n ' template list List available templates',\n ' template get Fetch a template by ID',\n ' template find Search templates by keyword',\n ' generate create Submit a generation job and wait for completion',\n ' generate wait Wait for an existing job to reach a terminal state',\n ' generate get Fetch the current state of a job',\n ' jobs wait Alias of `generate wait`',\n ' workflow create Create a new empty workflow',\n ' workflow list List workflows in your organization',\n ' workflow get Fetch a workflow snapshot by ID',\n ' workflow apply Apply operations to a workflow (canvas mutation)',\n ' upload <file> Upload a local file and return its public URL',\n '',\n 'Options:',\n ' -v, --version Show version',\n ' -h, --help Show help',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n}\n\nfunction renderCommandHelp(command: string[]): string {\n const path = command.join(' ');\n switch (path) {\n case 'login':\n return [\n 'Usage: clickraft login [options]',\n '',\n 'Options:',\n ' --profile <name> Write to a specific profile (default: \"default\")',\n ' --api-base-url <url> Override the API base URL',\n ` --scope <s> Space-separated scope list (default: all ${DEFAULT_SCOPES.length})`,\n ' --force-reauth Re-authenticate even if a valid token exists',\n ' --no-open-browser Do not auto-open the verification URL',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'logout':\n return [\n 'Usage: clickraft logout [options]',\n '',\n 'Options:',\n ' --profile <name> Remove a specific profile (default: \"default\")',\n ' --all Remove every profile (delete the credentials file)',\n ' --no-revoke Skip the server-side revoke call',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'tokens list':\n return [\n 'Usage: clickraft tokens list [options]',\n '',\n 'Options:',\n ' --profile <name> Read credentials from a specific profile',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'balance':\n return [\n 'Usage: clickraft balance [options]',\n '',\n 'Options:',\n ' --profile <name> Read credentials from a specific profile',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'brand-model':\n return [\n 'Usage: clickraft brand-model <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available brand models',\n '',\n ].join('\\n');\n case 'brand-model list':\n return [\n 'Usage: clickraft brand-model list [options]',\n '',\n 'Options:',\n ' --profile <name> Read credentials from a specific profile',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'product':\n return [\n 'Usage: clickraft product <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List products in your organization',\n ' create Create a product from uploaded assets',\n '',\n ].join('\\n');\n case 'product list':\n return [\n 'Usage: clickraft product list [options]',\n '',\n 'List products in your organization. Supports cursor-based pagination.',\n '',\n 'Options:',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --limit <n> Max results per page (1-100, default: 50)',\n ' --sync-status <s> Filter by sync status (synced, pending, stale, error, deleted_upstream)',\n ' --source-type <s> Filter by source type (manual, csv, shopify, etsy, etc.)',\n ' --search <q> Free-text search query',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'product create':\n return [\n 'Usage: clickraft product create --name <name> --image <assetId>[:<altText>] [options]',\n '',\n 'Create a product from images already uploaded to your Clickraft library.',\n 'Upload them first with `clickraft upload`, which prints the assetId to use here.',\n '',\n 'Options:',\n ' --name <name> Product name (required, max 200 chars)',\n ' --image <spec> <assetId>[:<altText>] (repeatable, 1-10 images, required)',\n ' --description <text> Product description (max 5000 chars)',\n ' --primary <assetId> Mark this image primary (default: the first --image)',\n ' --idempotency-key <key> Reuse a key to make a retry safe across invocations',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n 'Examples:',\n ' clickraft product create --name \"Ceramic Mug\" \\\\',\n ' --image 1f7c1e8e-2a4b-4c9d-8e5f-3b2a1c0d9e8f',\n '',\n ' clickraft product create --name \"Ceramic Mug\" \\\\',\n ' --image \"1f7c1e8e-2a4b-4c9d-8e5f-3b2a1c0d9e8f:Front view\" \\\\',\n ' --image \"2a8d2f9f-3b5c-4d0e-9f6a-4c3b2d1e0f9a:Side view\" \\\\',\n ' --primary 2a8d2f9f-3b5c-4d0e-9f6a-4c3b2d1e0f9a',\n '',\n ].join('\\n');\n case 'models':\n return [\n 'Usage: clickraft models <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available AI models',\n '',\n ].join('\\n');\n case 'models list':\n return [\n 'Usage: clickraft models list [options]',\n '',\n 'List AI models available for generation. By default shows a summary table;',\n 'use --json for full details including constraints and llmContext.',\n '',\n 'Options:',\n ' --category <name> Filter by category (image, video, audio, chat, edit)',\n ' --tier <name> Filter by cost tier (standard, pro, premium)',\n ' --type <name> Filter by model type (e.g. text-to-image)',\n ' --featured Show only featured models',\n ' --verbose Show expanded per-model details after the table',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n 'Examples:',\n ' clickraft models list',\n ' clickraft models list --category image --tier pro',\n ' clickraft models list --featured --json',\n '',\n ].join('\\n');\n case 'nodes':\n return [\n 'Usage: clickraft nodes <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available workflow node types',\n \" describe Show a node type's ports and agent-writable fields\",\n '',\n ].join('\\n');\n case 'nodes list':\n return [\n 'Usage: clickraft nodes list [options]',\n '',\n 'Lists the workflow node types available to the API, with port counts.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'nodes describe':\n return [\n 'Usage: clickraft nodes describe <type> [options]',\n '',\n \"Shows a node type's ports (handleId, direction, dataType) and the fields\",\n 'an agent may write. Handle ids are printed verbatim for use in edges.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'telemetry inspect':\n return [\n 'Usage: clickraft telemetry inspect [options]',\n '',\n 'Options:',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'template':\n return [\n 'Usage: clickraft template <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available templates',\n ' get Fetch a template by ID',\n ' find Search templates by keyword',\n '',\n ].join('\\n');\n case 'template list':\n return [\n 'Usage: clickraft template list [options]',\n '',\n 'Options:',\n ' --scope <scope> Filter by scope: own, system, or all (default: all)',\n ' --q <query> Free-text search query',\n ' --tags <tag> Filter by tag (repeatable)',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --limit <n> Max results per page (1-50, default: 20)',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'template get':\n return [\n 'Usage: clickraft template get <id> [options]',\n '',\n 'Fetches a single template by its ID, including declared parameters.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'template find':\n return [\n 'Usage: clickraft template find <query> [options]',\n '',\n 'Searches templates by keyword. Shorthand for `template list --q <query>`.',\n '',\n 'Options:',\n ' --tags <tag> Filter by tag (repeatable)',\n ' --scope <scope> Filter by scope: own, system, or all (default: all)',\n ' --limit <n> Max results per page (1-50, default: 20)',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'generate':\n return [\n 'Usage: clickraft generate <subcommand> [options]',\n '',\n 'Subcommands:',\n ' create Submit a generation job (waits for completion by default)',\n ' wait Long-poll an existing job until terminal',\n ' get Fetch the current state of a job (no polling)',\n '',\n ].join('\\n');\n case 'generate create':\n return [\n 'Usage: clickraft generate create [prompt] --model-slug <slug> [options]',\n '',\n 'Submits a generation job. By default the command waits up to 120s for the',\n 'job to reach a terminal state via the server long-poll (?wait=30) rounds.',\n '',\n 'Options:',\n ' --prompt <text> Text prompt (or pass as the positional argument)',\n ' --model-slug <slug> Required model identifier',\n ' --brand-model <spec> Brand Model reference (repeatable, max 3)',\n ' Format: <uuid> or <uuid>:<pose>',\n ' Poses: front, 3/4-right, right, left, 3/4-left, back, approved',\n ' --product <spec> Product reference (repeatable)',\n ' Format: <uuid> or <uuid>:<imageId>',\n ' Server enforces reference cap per model',\n ' --reference-image <v> Reference image: URL or local path (repeatable, max 8)',\n ' --start-frame <v> Image-to-video start frame: URL or local path',\n ' --aspect-ratio <a:b> e.g. 16:9',\n ' --resolution <size> e.g. 1024x768, 720p, 1K',\n ' --duration-seconds <n> For video/audio models (1-60)',\n ' --quality <tier> e.g. low, medium, high (valid values depend on the model)',\n ' --workflow-id <uuid> Attach to an existing workflow',\n ' --node-id <id> Attach to a specific node',\n ' --no-wait, --async Return immediately with the jobId',\n ' --timeout <seconds> Override the 120s default wait',\n ' --profile <name> Credentials profile name',\n ' --api-base-url <url> Override the API base URL',\n ' --token <token> Override the access token',\n ' --json Emit a JSON envelope instead of human output',\n ' -h, --help Show help',\n '',\n ].join('\\n');\n case 'generate wait':\n return [\n 'Usage: clickraft generate wait <jobId> [options]',\n '',\n 'Long-polls an existing job until it reaches a terminal state (completed,',\n 'failed, or cancelled) or the timeout elapses.',\n '',\n 'Options:',\n ' --timeout <seconds> Overall wait deadline (default: 120)',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'generate get':\n return [\n 'Usage: clickraft generate get <jobId> [options]',\n '',\n 'Fetches the current state of a generation job without polling.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'jobs':\n return [\n 'Usage: clickraft jobs <subcommand> [options]',\n '',\n 'Subcommands:',\n ' wait Long-poll a job until terminal (alias of `generate wait`)',\n '',\n ].join('\\n');\n case 'jobs wait':\n return [\n 'Usage: clickraft jobs wait <jobId> [options]',\n '',\n 'Alias of `clickraft generate wait`. See `clickraft generate wait --help`.',\n '',\n ].join('\\n');\n case 'upload':\n return [\n 'Usage: clickraft upload <file-path> [options]',\n '',\n 'Uploads a local file (up to 15MB) to the Agents API. The CLI computes a',\n 'sha256 of the contents and uses it as the idempotency key, so uploading',\n 'the same file twice within the same scope reuses the original asset.',\n '',\n 'Options:',\n ' --scope <name> Namespace for idempotency dedup (default: user-uploads)',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow':\n return [\n 'Usage: clickraft workflow <subcommand> [options]',\n '',\n 'Subcommands:',\n ' create Create a new empty workflow',\n ' list List workflows in your organization',\n ' get Fetch a workflow snapshot by ID',\n ' apply Apply operations to a workflow (canvas mutation)',\n '',\n ].join('\\n');\n case 'workflow create':\n return [\n 'Usage: clickraft workflow create --name <name> [options]',\n '',\n 'Creates a new empty workflow.',\n '',\n 'Options:',\n ' --name <name> Workflow name (required unless --from-file)',\n ' --description <text> Optional description',\n ' --tags <tag> Tag (repeatable)',\n ' --from-file <path> Read the full create payload as JSON from a file',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow list':\n return [\n 'Usage: clickraft workflow list [options]',\n '',\n 'Lists workflows in your organization. Supports cursor-based pagination.',\n '',\n 'Options:',\n ' --tags <csv> Filter by tags (comma-separated)',\n ' --has-param <key> Filter to workflows that declare this param',\n ' --limit <n> Max results per page (1-100, default: 20)',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow get':\n return [\n 'Usage: clickraft workflow get <id> [options]',\n '',\n 'Fetches a workflow snapshot including nodes and edges.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow apply':\n return [\n 'Usage: clickraft workflow apply <id> [options]',\n '',\n 'Applies mutation operations to a workflow. Requires --canvas-rev or --auto-rev.',\n '',\n 'Options:',\n ' --from-file <path> JSON file with operations (array or { canvas_rev, operations })',\n ' --op <json> Single operation as JSON string (repeatable)',\n ' --canvas-rev <n> The canvas_rev preconditioning the mutation',\n ' --auto-rev Fetch current canvas_rev first; retry once on 409',\n ' --idempotency-key <key> Override the auto-generated idempotency key',\n ' --dry-run Print the request payload without sending it',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n default:\n return `Unknown command: ${path}\\nRun \\`clickraft --help\\` for available commands.\\n`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// PR #4 commands (generate / jobs / upload)\n//\n// These take positional arguments and repeatable flags that the lean\n// parse-args used above can't represent. They reuse dispatch's outer\n// envelope/error/SIGINT semantics but parse argv themselves via args.ts.\n// ---------------------------------------------------------------------------\n\ntype NewCommandPath =\n | 'generate.create'\n | 'generate.wait'\n | 'generate.get'\n | 'jobs.wait'\n | 'upload'\n | 'template.list'\n | 'template.get'\n | 'template.find'\n | 'product.list'\n | 'product.create'\n | 'models.list'\n | 'nodes.list'\n | 'nodes.describe'\n | 'workflow.create'\n | 'workflow.list'\n | 'workflow.get'\n | 'workflow.apply';\n\ntype NewCommandMatch =\n | { kind: 'cmd'; path: NewCommandPath; verbTokenCount: 1 | 2 }\n | {\n kind: 'sub-help';\n verb: 'generate' | 'jobs' | 'template' | 'product' | 'models' | 'nodes' | 'workflow';\n }\n | {\n kind: 'unknown-sub';\n verb: 'generate' | 'jobs' | 'template' | 'product' | 'models' | 'nodes' | 'workflow';\n sub: string;\n };\n\nfunction matchNewCommand(argv: readonly string[]): NewCommandMatch | null {\n if (argv.length === 0) return null;\n const verb = argv[0];\n\n if (verb === 'upload') {\n return { kind: 'cmd', path: 'upload', verbTokenCount: 1 };\n }\n\n if (verb === 'generate') {\n const sub = argv[1];\n if (sub === 'create') return { kind: 'cmd', path: 'generate.create', verbTokenCount: 2 };\n if (sub === 'wait') return { kind: 'cmd', path: 'generate.wait', verbTokenCount: 2 };\n if (sub === 'get') return { kind: 'cmd', path: 'generate.get', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'generate' };\n return { kind: 'unknown-sub', verb: 'generate', sub };\n }\n\n if (verb === 'jobs') {\n const sub = argv[1];\n if (sub === 'wait') return { kind: 'cmd', path: 'jobs.wait', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'jobs' };\n return { kind: 'unknown-sub', verb: 'jobs', sub };\n }\n\n if (verb === 'template') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'template.list', verbTokenCount: 2 };\n if (sub === 'get') return { kind: 'cmd', path: 'template.get', verbTokenCount: 2 };\n if (sub === 'find') return { kind: 'cmd', path: 'template.find', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'template' };\n return { kind: 'unknown-sub', verb: 'template', sub };\n }\n\n if (verb === 'product') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'product.list', verbTokenCount: 2 };\n if (sub === 'create') return { kind: 'cmd', path: 'product.create', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'product' };\n return { kind: 'unknown-sub', verb: 'product', sub };\n }\n\n if (verb === 'models') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'models.list', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'models' };\n return { kind: 'unknown-sub', verb: 'models', sub };\n }\n\n if (verb === 'nodes') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'nodes.list', verbTokenCount: 2 };\n if (sub === 'describe') return { kind: 'cmd', path: 'nodes.describe', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'nodes' };\n return { kind: 'unknown-sub', verb: 'nodes', sub };\n }\n\n if (verb === 'workflow') {\n const sub = argv[1];\n if (sub === 'create') return { kind: 'cmd', path: 'workflow.create', verbTokenCount: 2 };\n if (sub === 'list') return { kind: 'cmd', path: 'workflow.list', verbTokenCount: 2 };\n if (sub === 'get') return { kind: 'cmd', path: 'workflow.get', verbTokenCount: 2 };\n if (sub === 'apply') return { kind: 'cmd', path: 'workflow.apply', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'workflow' };\n return { kind: 'unknown-sub', verb: 'workflow', sub };\n }\n\n return null;\n}\n\ninterface NewRunContext {\n stdout: NodeJS.WritableStream;\n stderr: NodeJS.WritableStream;\n jsonMode: boolean;\n signal?: AbortSignal;\n}\n\nasync function runNewCommand(\n newCmd: NewCommandMatch,\n options: DispatchOptions,\n stdout: NodeJS.WritableStream,\n stderr: NodeJS.WritableStream,\n): Promise<ExitCode> {\n if (newCmd.kind === 'sub-help') {\n stdout.write(renderCommandHelp([newCmd.verb]));\n return 0;\n }\n\n if (newCmd.kind === 'unknown-sub') {\n const err = new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Unknown ${newCmd.verb} subcommand: ${newCmd.sub}. Run \\`clickraft ${newCmd.verb} --help\\` for available subcommands.`,\n { retryable: false },\n );\n const ctx: EnvelopeContext = {\n startMs: Date.now(),\n command: newCmd.verb,\n version: options.version,\n };\n if (options.argv.includes('--json')) {\n stdout.write(formatJsonError(err, ctx) + '\\n');\n } else {\n stderr.write(formatHumanError(err) + '\\n');\n }\n return 2;\n }\n\n const path = newCmd.path;\n const argvAfterVerb = options.argv.slice(newCmd.verbTokenCount);\n const jsonMode = argvAfterVerb.includes('--json');\n\n if (argvAfterVerb.includes('--help') || argvAfterVerb.includes('-h')) {\n stdout.write(renderCommandHelp(path.split('.')));\n return 0;\n }\n\n const ctx: EnvelopeContext = {\n startMs: Date.now(),\n command: path,\n version: options.version,\n };\n\n const rc: NewRunContext = { stdout, stderr, jsonMode, signal: options.signal };\n\n try {\n switch (path) {\n case 'generate.create':\n return await runGenerateCreate(argvAfterVerb, ctx, rc);\n case 'generate.wait':\n return await runGenerateWait(argvAfterVerb, ctx, rc);\n case 'generate.get':\n return await runGenerateGet(argvAfterVerb, ctx, rc);\n case 'jobs.wait':\n return await runJobsWait(argvAfterVerb, ctx, rc);\n case 'upload':\n return await runUploadCmd(argvAfterVerb, ctx, rc);\n case 'template.list':\n return await runTemplateList(argvAfterVerb, ctx, rc);\n case 'template.get':\n return await runTemplateGet(argvAfterVerb, ctx, rc);\n case 'template.find':\n return await runTemplateFind(argvAfterVerb, ctx, rc);\n case 'product.list':\n return await runProductList(argvAfterVerb, ctx, rc);\n case 'product.create':\n return await runProductCreate(argvAfterVerb, ctx, rc);\n case 'models.list':\n return await runModelsList(argvAfterVerb, ctx, rc);\n case 'nodes.list':\n return await runNodesList(argvAfterVerb, ctx, rc);\n case 'nodes.describe':\n return await runNodesDescribe(argvAfterVerb, ctx, rc);\n case 'workflow.create':\n return await runWorkflowCreate(argvAfterVerb, ctx, rc);\n case 'workflow.list':\n return await runWorkflowList(argvAfterVerb, ctx, rc);\n case 'workflow.get':\n return await runWorkflowGet(argvAfterVerb, ctx, rc);\n case 'workflow.apply':\n return await runWorkflowApply(argvAfterVerb, ctx, rc);\n }\n } catch (err) {\n if (isAbortedError(err, options.signal)) {\n if (jsonMode) {\n stdout.write(\n formatJsonError(new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.'), ctx) + '\\n',\n );\n } else {\n stderr.write('Cancelled.\\n');\n }\n return SIGINT_EXIT_CODE;\n }\n\n const mapped =\n err instanceof ArgError\n ? new ApiError('INPUT_INVALID_FORMAT', err.message, { retryable: false })\n : err;\n\n const code = extractCode(mapped);\n if (jsonMode) {\n stdout.write(formatJsonError(mapped, ctx) + '\\n');\n } else {\n stderr.write(formatHumanError(mapped) + '\\n');\n }\n return getExitCode(code);\n }\n}\n\nconst COMMON_RICH_STRING_FLAGS = ['profile', 'api-base-url', 'token'] as const;\nconst COMMON_RICH_BOOL_FLAGS = ['json', 'help'] as const;\n\nasync function runGenerateCreate(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [\n ...COMMON_RICH_STRING_FLAGS,\n 'prompt',\n 'model-slug',\n 'start-frame',\n 'aspect-ratio',\n 'resolution',\n 'duration-seconds',\n 'quality',\n 'workflow-id',\n 'node-id',\n 'timeout',\n ],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'wait', 'async'],\n array: ['reference-image', 'brand-model', 'product'],\n });\n\n const modelSlug = parsed.string['model-slug'];\n if (!modelSlug) throw new ArgError('--model-slug is required.');\n\n const rawBrandModels = parsed.array['brand-model'] ?? [];\n const brandModels =\n rawBrandModels.length > 0 ? rawBrandModels.map(parseBrandModelSpec) : undefined;\n if (brandModels) validateBrandModelSpecs(brandModels);\n\n const rawProducts = parsed.array['product'] ?? [];\n const products = rawProducts.length > 0 ? rawProducts.map(parseProductSpec) : undefined;\n if (products) validateProductSpecs(products);\n\n const result = await generateCreate({\n prompt: parsed.string.prompt ?? parsed.positional[0],\n modelSlug,\n referenceImages: parsed.array['reference-image'],\n startFrame: parsed.string['start-frame'],\n aspectRatio: parsed.string['aspect-ratio'],\n resolution: parsed.string.resolution,\n durationSeconds: optionalInt(parsed.string['duration-seconds'], 'duration-seconds'),\n quality: parsed.string.quality,\n brandModels,\n products,\n workflowId: parsed.string['workflow-id'],\n nodeId: parsed.string['node-id'],\n wait: computeWaitFlag(parsed),\n timeoutSeconds: optionalInt(parsed.string.timeout, 'timeout'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitJob(result, ctx, rc);\n return exitCodeForResult(result);\n}\n\nasync function runGenerateWait(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'timeout'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const jobId = parsed.positional[0];\n if (!jobId) throw new ArgError('Missing required <jobId> argument.');\n\n const result = await generateWait({\n jobId,\n timeoutSeconds: optionalInt(parsed.string.timeout, 'timeout'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n emitJob(result, ctx, rc);\n return exitCodeForResult(result);\n}\n\nasync function runGenerateGet(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const jobId = parsed.positional[0];\n if (!jobId) throw new ArgError('Missing required <jobId> argument.');\n\n const result = await generateGet({\n jobId,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n emitJob(result, ctx, rc);\n return exitCodeForResult(result);\n}\n\nasync function runJobsWait(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'timeout'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const jobId = parsed.positional[0];\n if (!jobId) throw new ArgError('Missing required <jobId> argument.');\n\n const result = await jobsWait({\n jobId,\n timeoutSeconds: optionalInt(parsed.string.timeout, 'timeout'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n emitJob(result, ctx, rc);\n return exitCodeForResult(result);\n}\n\nasync function runUploadCmd(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'scope'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const filePath = parsed.positional[0];\n if (!filePath) throw new ArgError('Missing required <file-path> argument.');\n\n const result = await uploadFile({\n filePath,\n scope: parsed.string.scope,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n emitUpload(result, ctx, rc);\n return 0;\n}\n\nfunction emitJob(result: GenerationResult, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n rc.stdout.write(renderGenerationResult(result) + '\\n');\n}\n\nfunction emitUpload(result: UploadResult, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n rc.stdout.write(renderUploadResult(result) + '\\n');\n}\n\nfunction renderGenerationResult(r: GenerationResult): string {\n const lines: string[] = [`Job ID: ${r.jobId}`, `Status: ${r.status}`, `Model: ${r.modelSlug}`];\n if (r.resultUrl) lines.push(`Result URL: ${r.resultUrl}`);\n if (r.thumbnailUrl) lines.push(`Thumbnail: ${r.thumbnailUrl}`);\n lines.push(`Credits charged: ${r.creditsCharged}`);\n if (r.creditsRefunded) lines.push('Credits refunded: yes');\n if (r.errorCode || r.errorMessage) {\n lines.push(`Error: ${r.errorCode ?? 'unknown'}${r.errorMessage ? ` — ${r.errorMessage}` : ''}`);\n }\n return lines.join('\\n');\n}\n\nfunction renderUploadResult(r: UploadResult): string {\n return [\n `Uploaded: ${r.publicUrl}`,\n `Asset ID: ${r.assetId}`,\n `Bytes: ${r.bytes}`,\n `Deduplicated: ${r.deduplicated}`,\n ].join('\\n');\n}\n\nfunction computeWaitFlag(parsed: ParsedArgsRich): boolean {\n // `--async` is shorthand for \"don't wait\"; an explicit `--wait` /\n // `--no-wait` takes precedence when present.\n if (typeof parsed.boolean.wait === 'boolean') return parsed.boolean.wait;\n if (parsed.boolean.async === true) return false;\n return true;\n}\n\nfunction optionalInt(value: string | undefined, label: string): number | undefined {\n if (value === undefined) return undefined;\n const n = Number.parseInt(value, 10);\n if (!Number.isFinite(n) || n < 0 || String(n) !== value) {\n throw new ArgError(`--${label} must be a non-negative integer.`);\n }\n return n;\n}\n\nfunction exitCodeForResult(result: GenerationResult): ExitCode {\n if (result.status === 'completed') return 0;\n if (result.status === 'failed' || result.status === 'cancelled') {\n if (result.errorCode) return getExitCode(result.errorCode as AllErrorCode);\n return 1;\n }\n return 0;\n}\n\nexport function splitCsvArray(values: string[] | undefined): string[] | undefined {\n if (!values || values.length === 0) return undefined;\n const result = values.flatMap((v) =>\n v\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean),\n );\n return result.length > 0 ? result : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Template commands\n// ---------------------------------------------------------------------------\n\nasync function runTemplateList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'scope', 'q', 'cursor', 'limit'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['tags'],\n });\n\n const result = await listTemplates({\n q: parsed.string.q,\n tags: splitCsvArray(parsed.array.tags),\n scope: parsed.string.scope as 'own' | 'system' | 'all' | undefined,\n cursor: parsed.string.cursor,\n limit: optionalInt(parsed.string.limit, 'limit'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n ctx.nextCursor = result.cursor ?? undefined;\n emitTemplateList(result, ctx, rc);\n return 0;\n}\n\nasync function runTemplateGet(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const id = parsed.positional[0];\n if (!id) throw new ArgError('Missing required <id> argument.');\n\n const detail = await getTemplate({\n id,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitTemplateDetail(detail, ctx, rc);\n return 0;\n}\n\nasync function runTemplateFind(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'scope', 'cursor', 'limit'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['tags'],\n });\n const query = parsed.positional[0];\n if (!query) throw new ArgError('Missing required <query> argument.');\n\n const result = await findTemplates({\n query,\n tags: splitCsvArray(parsed.array.tags),\n scope: parsed.string.scope as 'own' | 'system' | 'all' | undefined,\n cursor: parsed.string.cursor,\n limit: optionalInt(parsed.string.limit, 'limit'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n ctx.nextCursor = result.cursor ?? undefined;\n emitTemplateList(result, ctx, rc);\n return 0;\n}\n\nfunction emitTemplateList(\n result: TemplateListResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderTemplatesList(result, rc.stdout);\n}\n\nfunction emitTemplateDetail(detail: TemplateDetail, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(detail, ctx)) + '\\n');\n return;\n }\n renderTemplateDetail(detail, rc.stdout);\n}\n\n// ---------------------------------------------------------------------------\n// Product commands\n// ---------------------------------------------------------------------------\n\n// Curated remedy for a 403 caused by a missing scope.\n//\n// `--force-reauth` is not optional wording. `login()` REFUSES when the profile\n// holds a valid unexpired token (commands/login.ts), and every user who reaches\n// a scope error has exactly that, so a bare `clickraft login` sends them\n// straight into a second error telling them to pass the flag. The previous hint\n// said `clickraft login`, which was wrong for the only situation it appears in.\n//\n// Parameterized rather than duplicated per scope: the string is identical apart\n// from the scope name, and two copies would drift the moment one is reworded.\nexport function scopeHintFor(scope: string): string {\n return `Your CLI token doesn't include ${scope}. Run \\`clickraft login --force-reauth\\` to re-authenticate with the new scope.`;\n}\n\n// Re-raise an insufficient-scope failure carrying the curated hint, leaving\n// every other error untouched. `err.meta` is spread so status/requestId/details\n// survive; only `hint` is added.\nasync function withScopeHint<T>(scope: string, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof ApiError && err.code === 'AUTH_TOKEN_SCOPE_INSUFFICIENT') {\n const hint = scopeHintFor(scope);\n throw new ApiError(err.code, hint, { ...err.meta, hint }, err.cause);\n }\n throw err;\n }\n}\n\nasync function runProductList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [\n ...COMMON_RICH_STRING_FLAGS,\n 'cursor',\n 'limit',\n 'sync-status',\n 'source-type',\n 'search',\n ],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n\n const limit = optionalInt(parsed.string.limit, 'limit');\n if (limit !== undefined && (limit < 1 || limit > 100)) {\n throw new ArgError('--limit must be between 1 and 100.');\n }\n\n const result = await withScopeHint('products:read', () =>\n listProducts({\n cursor: parsed.string.cursor,\n limit,\n syncStatus: parsed.string['sync-status'],\n sourceType: parsed.string['source-type'],\n search: parsed.string.search,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n }),\n );\n\n ctx.nextCursor = result.nextCursor ?? undefined;\n emitProductList(result, ctx, rc);\n return 0;\n}\n\n// Curated replacements for two server answers whose default CLI rendering is\n// actively misleading on this route.\nconst PRODUCT_CREATE_NOT_ENABLED =\n 'Product creation is not enabled on this deployment yet. ' +\n 'The endpoint answers 404 while the feature flag is off.';\n\nfunction remapProductCreateError(err: unknown): unknown {\n if (!(err instanceof ApiError)) return err;\n\n // The route 404s when AGENTS_PRODUCTS_WRITE_ENABLED is off, AFTER auth. The\n // generic mapping renders that as \"Resource not found.\", which reads as \"your\n // asset ids are wrong\" and sends the user hunting through their library.\n if (err.code === 'NOT_FOUND') {\n return new ApiError(\n err.code,\n PRODUCT_CREATE_NOT_ENABLED,\n { ...err.meta, hint: PRODUCT_CREATE_NOT_ENABLED },\n err.cause,\n );\n }\n\n // One code, two very different causes, and the remedies are opposites: a\n // body mismatch means \"use a new key\", a cross-token replay means \"this key\n // is not yours\". The server's message distinguishes them, so key off it\n // rather than inventing a third state. Deliberately NOT retried with a fresh\n // key — that is precisely how the duplicate product this key prevents gets\n // created.\n if (err.code === 'IDEMPOTENCY_KEY_CONFLICT') {\n const hint = /different token/i.test(err.message)\n ? 'This idempotency key was used by a different token. Use a key of your own.'\n : 'This idempotency key was already used with a different request body. Use a new key.';\n return new ApiError(err.code, err.message, { ...err.meta, hint }, err.cause);\n }\n\n return err;\n}\n\nasync function runProductCreate(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'name', 'description', 'primary', 'idempotency-key'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['image'],\n });\n\n const name = parsed.string.name;\n if (!name) throw new ArgError('--name is required.');\n\n const rawImages = parsed.array['image'] ?? [];\n if (rawImages.length === 0) throw new ArgError('At least one --image is required.');\n const images = rawImages.map(parseImageSpec);\n\n try {\n const product = await withScopeHint('products:write', () =>\n createProduct({\n name,\n description: parsed.string.description,\n images,\n primary: parsed.string.primary,\n idempotencyKey: parsed.string['idempotency-key'],\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n scopeHint: scopeHintFor('products:write'),\n }),\n );\n\n emitProductCreate(product, ctx, rc);\n return 0;\n } catch (err) {\n throw remapProductCreateError(err);\n }\n}\n\nfunction emitProductCreate(product: ProductSummary, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(product, ctx)) + '\\n');\n return;\n }\n renderProductCreateResult(product, rc.stdout);\n}\n\nfunction emitProductList(result: ProductListResult, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderProductsList(result, rc.stdout);\n}\n\n// ---------------------------------------------------------------------------\n// Models commands\n// ---------------------------------------------------------------------------\n\nasync function runModelsList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'category', 'tier', 'type'],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'featured', 'verbose'],\n });\n\n const result = await listModels({\n category: parsed.string.category,\n tier: parsed.string.tier,\n type: parsed.string.type,\n featured: parsed.boolean.featured,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitModelsList(result, ctx, rc, parsed);\n return 0;\n}\n\nfunction emitModelsList(\n result: ModelListResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n parsed: ParsedArgsRich,\n): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderModelsList(result, rc.stdout, {\n verbose: parsed.boolean.verbose === true,\n filters: {\n category: parsed.string.category ?? '',\n tier: parsed.string.tier ?? '',\n type: parsed.string.type ?? '',\n featured: parsed.boolean.featured !== undefined ? String(parsed.boolean.featured) : '',\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Nodes commands\n// ---------------------------------------------------------------------------\n\nasync function runNodesList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n\n const result = await listNodes({\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitNodesList(result, ctx, rc);\n return 0;\n}\n\nasync function runNodesDescribe(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const type = parsed.positional[0];\n if (!type) throw new ArgError('Missing required <type> argument.');\n\n const detail = await describeNode({\n type,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitNodeDetail(detail, ctx, rc);\n return 0;\n}\n\nfunction emitNodesList(result: NodesListResult, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderNodesList(result, rc.stdout);\n}\n\nfunction emitNodeDetail(detail: NodeTypeDetail, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(detail, ctx)) + '\\n');\n return;\n }\n renderNodeDetail(detail, rc.stdout);\n}\n\n// ---------------------------------------------------------------------------\n// Workflow commands\n// ---------------------------------------------------------------------------\n\nasync function runWorkflowCreate(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'name', 'description', 'from-file'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['tags'],\n });\n\n let name = parsed.string.name;\n let description = parsed.string.description;\n let tags = splitCsvArray(parsed.array.tags);\n let declaredParams: Record<string, unknown> | Array<Record<string, unknown>> | undefined;\n\n if (parsed.string['from-file']) {\n const raw = await readJsonFile(parsed.string['from-file']);\n if (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) {\n const obj = raw as Record<string, unknown>;\n name = name ?? (typeof obj.name === 'string' ? obj.name : undefined);\n description =\n description ?? (typeof obj.description === 'string' ? obj.description : undefined);\n if (!tags && Array.isArray(obj.tags)) tags = obj.tags as string[];\n if (obj.declared_params != null && typeof obj.declared_params === 'object') {\n declaredParams = obj.declared_params as\n | Record<string, unknown>\n | Array<Record<string, unknown>>;\n }\n }\n }\n\n if (!name) throw new ArgError('--name is required (or provide it in --from-file).');\n\n const result = await createWorkflow({\n name,\n description,\n tags,\n declaredParams,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitWorkflowCreate(result, ctx, rc);\n return 0;\n}\n\nasync function runWorkflowList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'tags', 'has-param', 'cursor', 'limit'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n\n const limit = optionalInt(parsed.string.limit, 'limit');\n if (limit !== undefined && (limit < 1 || limit > 100)) {\n throw new ArgError('--limit must be between 1 and 100.');\n }\n\n const result = await listWorkflows({\n cursor: parsed.string.cursor,\n limit,\n tags: parsed.string.tags\n ? parsed.string.tags\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n : undefined,\n declaredParamsHasKey: parsed.string['has-param'],\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n ctx.nextCursor = result.nextCursor ?? undefined;\n emitWorkflowList(result, ctx, rc);\n return 0;\n}\n\nasync function runWorkflowGet(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const id = parsed.positional[0];\n if (!id) throw new ArgError('Missing required <id> argument.');\n\n const detail = await getWorkflow({\n id,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitWorkflowDetail(detail, ctx, rc);\n return 0;\n}\n\nasync function runWorkflowApply(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'canvas-rev', 'from-file', 'idempotency-key'],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'auto-rev', 'dry-run'],\n array: ['op'],\n });\n\n const id = parsed.positional[0];\n if (!id) throw new ArgError('Missing required <id> argument.');\n\n let operations: Record<string, unknown>[] = [];\n let fileCanvasRev: number | undefined;\n\n if (parsed.string['from-file']) {\n const raw = await readJsonFile(parsed.string['from-file']);\n if (Array.isArray(raw)) {\n operations = raw as Record<string, unknown>[];\n } else if (typeof raw === 'object' && raw !== null && 'operations' in raw) {\n const obj = raw as Record<string, unknown>;\n operations = obj.operations as Record<string, unknown>[];\n if (typeof obj.canvas_rev === 'number') fileCanvasRev = obj.canvas_rev;\n } else {\n throw new ArgError(\n '--from-file must contain a JSON array or an object with an \"operations\" key.',\n );\n }\n }\n\n if (parsed.array.op) {\n for (const opStr of parsed.array.op) {\n try {\n operations.push(JSON.parse(opStr) as Record<string, unknown>);\n } catch {\n throw new ArgError(`Invalid JSON in --op: ${opStr}`);\n }\n }\n }\n\n if (operations.length === 0) {\n throw new ArgError('No operations provided. Use --from-file or --op.');\n }\n if (operations.length > 100) {\n throw new ArgError('At most 100 operations per request.');\n }\n\n const autoRev = parsed.boolean['auto-rev'] === true;\n let canvasRev: number;\n\n if (parsed.string['canvas-rev'] !== undefined) {\n const n = optionalInt(parsed.string['canvas-rev'], 'canvas-rev');\n if (n === undefined) throw new ArgError('--canvas-rev must be a non-negative integer.');\n canvasRev = n;\n } else if (autoRev) {\n const snapshot = await getWorkflow({\n id,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n canvasRev = snapshot.canvas_rev;\n } else if (fileCanvasRev !== undefined) {\n canvasRev = fileCanvasRev;\n } else {\n throw new ArgError(\n 'Must provide --canvas-rev, use --auto-rev, or include canvas_rev in --from-file.',\n );\n }\n\n if (parsed.boolean['dry-run'] === true) {\n const payload = { canvas_rev: canvasRev, operations };\n rc.stdout.write(JSON.stringify(payload, null, 2) + '\\n');\n return 0;\n }\n\n const result = await applyWorkflow({\n id,\n canvasRev,\n operations,\n idempotencyKey: parsed.string['idempotency-key'],\n autoRev,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitWorkflowApply(result, ctx, rc);\n return 0;\n}\n\nfunction emitWorkflowCreate(\n result: WorkflowCreateResponse,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderWorkflowCreateResult(result, rc.stdout);\n}\n\nfunction emitWorkflowList(\n result: WorkflowListResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderWorkflowsList(result, rc.stdout);\n}\n\nfunction emitWorkflowDetail(detail: WorkflowDetail, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(detail, ctx)) + '\\n');\n return;\n }\n renderWorkflowDetail(detail, rc.stdout);\n}\n\nfunction emitWorkflowApply(\n result: WorkflowApplyResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderWorkflowApplyResult(result, rc.stdout);\n}\n\nasync function readJsonFile(filePath: string): Promise<unknown> {\n const { readFile } = await import('node:fs/promises');\n let text: string;\n try {\n text = await readFile(filePath, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') throw new ArgError(`File not found: ${filePath}`);\n if (code === 'EACCES') throw new ArgError(`Permission denied: ${filePath}`);\n throw new ArgError(`Failed to read file: ${filePath}`);\n }\n try {\n return JSON.parse(text);\n } catch {\n throw new ArgError(`File is not valid JSON: ${filePath}`);\n }\n}\n"],"mappings":"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","names":["dirname","join","z","createHash","undiciRequest","request","onWarning","delayMs","z","readFile","stat","stat","readFile","UUID_RE","UUID_RE","isAbortError","profile","z","buildRequestBody","parseArgs","parseArgs","ctx","readFile","__filename","__dirname","dirname","join"]}
1
+ {"version":3,"sources":["../src/index.ts","../../sdk/src/redact.ts","../../sdk/src/contracts/balance.ts","../../sdk/src/contracts/brand-model.ts","../../sdk/src/contracts/product.ts","../../sdk/src/errors/api-error.ts","../../sdk/src/errors/schema-mismatch.ts","../../sdk/src/contracts/tokens.ts","../../sdk/src/contracts/templates.ts","../../sdk/src/contracts/jobs.ts","../../sdk/src/contracts/assets.ts","../../sdk/src/contracts/node-types.ts","../../sdk/src/contracts/workflows.ts","../../sdk/src/errors/codes.ts","../../sdk/src/long-poll.ts","../../sdk/src/http/client.ts","../../sdk/src/http/idempotency.ts","../../sdk/src/http/retry.ts","../../sdk/src/http/types.ts","../../sdk/src/orchestration/workflow-apply.ts","../../sdk/src/orchestration/upload.ts","../../sdk/src/orchestration/create-and-wait.ts","../src/errors/codes.ts","../src/api/client.ts","../src/auth/errors.ts","../src/api/envelope.ts","../src/auth/credentials.ts","../src/config/paths.ts","../src/auth/types.ts","../src/config/loader.ts","../src/commands/balance.ts","../src/commands/brand-model/list.ts","../src/commands/upload.ts","../src/commands/generate/internal.ts","../src/commands/generate/wait.ts","../src/commands/generate/create.ts","../src/commands/generate/download.ts","../src/commands/generate/estimate.ts","../src/commands/generate/get.ts","../src/commands/generate/list.ts","../src/cli/args.ts","../src/commands/generate/parse-brand-model-spec.ts","../src/commands/generate/parse-product-spec.ts","../src/auth/device-flow.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/schemas/models.ts","../src/commands/models/internal.ts","../src/commands/models/list.ts","../src/commands/nodes/internal.ts","../src/commands/nodes/describe.ts","../src/commands/nodes/list.ts","../src/auth/scopes.ts","../src/commands/product/create.ts","../src/commands/product/list.ts","../src/commands/product/parse-image-spec.ts","../src/telemetry/detect.ts","../src/commands/telemetry/inspect.ts","../src/commands/template/internal.ts","../src/commands/template/list.ts","../src/commands/template/find.ts","../src/commands/template/get.ts","../src/commands/tokens/list.ts","../src/commands/workflow/internal.ts","../src/commands/workflow/apply.ts","../src/commands/workflow/create.ts","../src/commands/workflow/get.ts","../src/commands/workflow/list.ts","../src/errors/format.ts","../src/cli/parse-args.ts","../src/cli/progress.ts","../src/cli/render.ts","../src/cli/dispatch.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { dispatch } from './cli/dispatch.js';\nimport { type ExitCode } from './errors/codes.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf8')) as {\n version: string;\n};\n\nexport async function run(args: string[], signal?: AbortSignal): Promise<ExitCode> {\n return dispatch({\n argv: args,\n version: pkg.version,\n signal,\n });\n}\n","// Token-shaped patterns that must never reach stderr or audit logs.\n//\n// `TOKEN_FIELD_PATTERN` targets the JSON-encoded form `\"<field>\":\"<value>\"`\n// so it matches verbatim server response bodies without first parsing them.\n// `BARE_TOKEN_PATTERN` covers tokens inlined in plain text (e.g. a server\n// error message like `token ck_live_xxx rejected`) that the JSON pattern\n// would miss.\nconst TOKEN_FIELD_PATTERN =\n /\"(access_token|refresh_token|device_code|user_code|code_verifier|client_secret)\"\\s*:\\s*\"[^\"]*\"/gi;\nconst BARE_TOKEN_PATTERN = /\\bck_(?:live|dev|test)_[A-Za-z0-9_-]+/gi;\n\nexport function redactTokenLikeFields(input: string): string {\n return input\n .replace(TOKEN_FIELD_PATTERN, '\"$1\":\"[REDACTED]\"')\n .replace(BARE_TOKEN_PATTERN, '[REDACTED]');\n}\n\nexport function redactTokenLikeValue(token: string | undefined): string {\n if (!token) return '<empty>';\n if (token.length <= 12) return '[REDACTED]';\n return `${token.slice(0, 8)}...[REDACTED]`;\n}\n","import { z } from 'zod';\n\nexport const BalanceResponseSchema = z\n .object({\n totalCredits: z.number(),\n subscriptionCredits: z.number(),\n purchasedCredits: z.number(),\n promotionalCredits: z.number(),\n rateLimit: z\n .object({\n apiBurstPerMinute: z.number(),\n })\n .strict(),\n })\n .strict();\n\nexport type BalanceData = z.infer<typeof BalanceResponseSchema>;\n","import { z } from 'zod';\n\nexport const BrandModelSummarySchema = z\n .object({\n id: z.string().uuid(),\n source: z.enum(['system', 'user']),\n slug: z.string().nullable(),\n name: z.string(),\n description: z.string().nullable(),\n thumbnailUrl: z.string().nullable(),\n tags: z.array(z.string()),\n category: z.string().nullable(),\n isPremium: z.boolean().nullable(),\n isFeatured: z.boolean().nullable(),\n badgeText: z.string().nullable(),\n usageCount: z.number().nullable(),\n createdAt: z.string(),\n })\n .strict();\n\nexport const BrandModelsListResponseSchema = z\n .object({\n brandModels: z.array(BrandModelSummarySchema),\n })\n .strict();\n\nexport type BrandModelSummary = z.infer<typeof BrandModelSummarySchema>;\n","import { z } from 'zod';\n\nimport { ApiError } from '../errors/api-error.js';\nimport { formatSchemaIssues } from '../errors/schema-mismatch.js';\n\n/**\n * RFC 9562 UUID. The source of truth is the vendored golden's published\n * `pattern` for `\"format\": \"uuid\"` fields, NOT Zod's built-in `.uuid()`.\n *\n * This package is on Zod 3 and the server validates with Zod 4. Zod 3's\n * `.uuid()` constrains neither the version nibble nor the variant nibble, so it\n * accepts ids the server rejects — `...-0794-...` and `...-c543-...` both pass\n * here and 400 on the wire. That turns a local, well-worded failure into a\n * round trip and defeats the point of mirroring the schema at all.\n *\n * Kept as a literal rather than read from the golden at runtime: the golden is\n * ~38 KB and this package is bundled (tsup `noExternal`) into both the CLI and\n * the MCP server, so importing it would ship 38 KB twice to compile one regex.\n * The literal is PINNED BY TEST instead (`product.test.ts`, \"UUID_RE matches the\n * golden\"), which reads the golden offline exactly as `contract-checker.test.ts`\n * does. The nightly refresh updates the golden; CI then fails here. Checked,\n * not copied.\n *\n * No flags. The character classes are explicit about case, and adding `i` would\n * widen the pattern without changing `.source`, which would defeat the pin.\n */\nexport const UUID_RE =\n /^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/;\n\n/** A UUID string field validated against {@link UUID_RE}, not Zod's `.uuid()`. */\nexport const uuidString = (): z.ZodString => z.string().regex(UUID_RE, 'Must be a UUID.');\n\nexport const ProductImageSummarySchema = z.object({\n id: z.string().uuid(),\n url: z.string(),\n altText: z.string().nullable(),\n isPrimary: z.boolean(),\n sortOrder: z.number().int(),\n});\n\nexport const ProductSummarySchema = z.object({\n id: z.string().uuid(),\n title: z.string(),\n sourceType: z.string(),\n syncStatus: z.enum(['synced', 'pending', 'stale', 'error', 'deleted_upstream']).nullable(),\n vendor: z.string().nullable(),\n productType: z.string().nullable(),\n tags: z.array(z.string()),\n images: z.array(ProductImageSummarySchema),\n});\n\nexport const ProductsListResponseSchema = z.object({\n items: z.array(ProductSummarySchema),\n nextCursor: z.string().nullable(),\n});\n\nexport type ProductImageSummary = z.infer<typeof ProductImageSummarySchema>;\nexport type ProductSummary = z.infer<typeof ProductSummarySchema>;\n\n// ─── POST /api/agents/v1/products ────────────────────────────────────────────\n//\n// Mirrors `lib/agents/schemas/products.ts` in the app repo, including `.strict()`.\n// The response side needs nothing new: the HTTP client unwraps the `{ data }`\n// envelope, so `responseSchema` is `ProductSummarySchema` above.\n\n/** Per-request image cap. Shared by the schema, both callers and their tests. */\nexport const MAX_PRODUCT_IMAGES = 10;\n\n/**\n * Request-body cap. The server enforces this by READING the stream, not by\n * trusting Content-Length, so the client must measure the same thing: UTF-8\n * bytes of the exact JSON it will send.\n */\nexport const MAX_PRODUCT_CREATE_BODY_BYTES = 32 * 1024;\n\nexport const ProductCreateImageSchema = z\n .object({\n /**\n * An image `library_items.id`. Uploads via `POST /assets` are one source;\n * rows of kind 'generation' are equally admissible.\n */\n assetId: uuidString(),\n altText: z.string().trim().max(500).optional(),\n isPrimary: z.boolean().optional(),\n })\n .strict();\n\n/**\n * `.strict()` IS the guardrail, not a style choice. `variants`, `sourceType`,\n * `integrationId`, `status`, `tags` and `sku` are absent from this schema, so\n * sending any of them is a rejection rather than a silent drop — matching the\n * server, which answers 400 for exactly that reason.\n *\n * `sortOrder` is not on the wire either: it is the array index.\n */\nexport const ProductCreateRequestSchema = z\n .object({\n name: z.string().trim().min(1).max(200),\n description: z.string().trim().max(5000).optional(),\n images: z.array(ProductCreateImageSchema).min(1).max(MAX_PRODUCT_IMAGES),\n })\n .strict()\n .superRefine((v, ctx) => {\n if (v.images.filter((i) => i.isPrimary).length > 1) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: ['images'],\n message: 'At most one image may be marked isPrimary.',\n });\n }\n });\n\nexport type ProductCreateImage = z.infer<typeof ProductCreateImageSchema>;\nexport type ProductCreateRequest = z.infer<typeof ProductCreateRequestSchema>;\n\n/**\n * The one owner of client-side product-create validation.\n *\n * Both the CLI command and the MCP tool call this, so the two surfaces cannot\n * drift on which payloads they reject locally. Returns the normalized request,\n * ready to hand straight to `client.request({ body })`.\n *\n * Three checks the schema alone cannot express:\n * - duplicate `assetId`, which the server answers with\n * PRODUCT_IMAGE_ASSET_DUPLICATE. Caught here so it costs no round trip.\n * - the 32 KiB body cap, measured in UTF-8 BYTES of the serialized body. A\n * description of multibyte characters can sit under the cap by `.length`\n * and over it on the wire, so `.length` would let exactly the interesting\n * case through.\n * - at-most-one-`isPrimary`, which lives in the schema's superRefine above\n * but is only reachable through this function on the MCP path.\n *\n * Throws ApiError('INPUT_INVALID_FORMAT'), never a raw ZodError, so both\n * surfaces get their existing formatting: the CLI maps it to exit 2 and the MCP\n * tool renders it through `toToolError`.\n */\nexport function parseProductCreateRequest(input: unknown): ProductCreateRequest {\n const parsed = ProductCreateRequestSchema.safeParse(input);\n if (!parsed.success) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Invalid product create request: ${formatSchemaIssues(parsed.error)}`,\n // `issues` is an array of { path, code, message }, which is the shape the\n // MCP server's summarizeValidationDetails recognizes and renders.\n { retryable: false, details: parsed.error.issues },\n );\n }\n\n const request = parsed.data;\n\n const seen = new Set<string>();\n const duplicates = new Set<string>();\n for (const img of request.images) {\n if (seen.has(img.assetId)) duplicates.add(img.assetId);\n seen.add(img.assetId);\n }\n if (duplicates.size > 0) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `The same assetId appears more than once in images: ${[...duplicates].join(', ')}.`,\n { retryable: false },\n );\n }\n\n // Measured on the SAME string the client will send: `client.request` does\n // `JSON.stringify(body)` on this exact object, so the two cannot disagree.\n const bytes = Buffer.byteLength(JSON.stringify(request), 'utf8');\n if (bytes > MAX_PRODUCT_CREATE_BODY_BYTES) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Request body is ${bytes} bytes; the endpoint caps at ${MAX_PRODUCT_CREATE_BODY_BYTES}.`,\n { retryable: false },\n );\n }\n\n return request;\n}\n","// The error type the Clickraft HTTP client raises for every non-success path:\n// server-returned errors, network failures, parse/schema mismatches, and\n// aborts/timeouts. `code` is narrowed to `ApiErrorCode` (Server | Client) — the\n// CLI's auth/credential codes are surfaced via AuthError/CredentialsError and\n// are never carried by ApiError.\n\nimport type { ApiErrorCode } from './codes.js';\n\nexport interface ApiErrorMeta {\n status?: number;\n requestId?: string;\n retryable: boolean;\n retryAfterMs?: number;\n redactedBody?: string;\n details?: unknown;\n hint?: string;\n}\n\nexport class ApiError extends Error {\n public readonly code: ApiErrorCode;\n public readonly meta: ApiErrorMeta;\n public override readonly cause?: unknown;\n\n constructor(code: ApiErrorCode, message: string, meta: ApiErrorMeta, cause?: unknown) {\n super(message);\n this.name = 'ApiError';\n this.code = code;\n this.meta = meta;\n this.cause = cause;\n }\n}\n","// Formats a Zod validation failure into a one-line, human-readable summary\n// suitable for inclusion in the E_SCHEMA_MISMATCH error message. The summary\n// names the offending path(s), the zod issue code, and (when available) the\n// expected vs received types — enough to diagnose drift without having to\n// re-run with --debug or inspect the raw response.\n\nimport type { ZodError, ZodIssue } from 'zod';\n\nconst MAX_ISSUES = 5;\n\nexport function formatSchemaIssues(error: ZodError): string {\n const issues = error.issues;\n const shown = issues.slice(0, MAX_ISSUES).map(formatIssue);\n const remaining = issues.length - shown.length;\n const joined = shown.join('; ');\n return remaining > 0 ? `${joined} (+${remaining} more)` : joined;\n}\n\nfunction formatIssue(issue: ZodIssue): string {\n const path = formatPath(issue.path);\n if (issue.code === 'invalid_type') {\n return `${path}: ${issue.code} (expected ${issue.expected}, received ${issue.received})`;\n }\n if (issue.code === 'invalid_string') {\n const validation =\n typeof issue.validation === 'string'\n ? issue.validation\n : (Object.keys(issue.validation)[0] ?? 'string');\n return `${path}: ${issue.code} (${validation})`;\n }\n return `${path}: ${issue.code}`;\n}\n\nfunction formatPath(path: ReadonlyArray<string | number>): string {\n if (path.length === 0) return '(root)';\n return path.map(String).join('.');\n}\n","import { z } from 'zod';\n\nexport const TokenRowSchema = z\n .object({\n id: z.string().uuid(),\n organizationId: z.string().uuid(),\n userId: z.string().uuid(),\n clientId: z.string().nullable(),\n tokenPrefix: z.string(),\n name: z.string().nullable(),\n scopes: z.array(z.string()),\n lastUsedAt: z.string().nullable(),\n expiresAt: z.string(),\n createdAt: z.string(),\n })\n .strict();\n\nexport const TokensListResponseSchema = z.array(TokenRowSchema);\n\nexport type TokenRow = z.infer<typeof TokenRowSchema>;\n","import { z } from 'zod';\n\nexport const DeclaredParamSchema = z\n .object({\n name: z.string(),\n type: z.string(),\n required: z.boolean().optional(),\n defaultValue: z.unknown().optional(),\n enumValues: z.array(z.string()).nullable().optional(),\n description: z.string().nullable().optional(),\n })\n .strict();\n\nexport const TemplateSummarySchema = z\n .object({\n id: z.string().uuid(),\n source: z.enum(['own', 'system']),\n name: z.string(),\n description: z.string().nullable(),\n category: z.string().nullable(),\n thumbnailUrl: z.string().nullable(),\n tags: z.array(z.string()),\n createdAt: z.string(),\n })\n .strict();\n\nexport const TemplateDetailSchema = TemplateSummarySchema.extend({\n declaredParams: z.array(DeclaredParamSchema),\n timesUsed: z.number(),\n}).strict();\n\nexport const TemplatesListResponseSchema = z\n .object({\n templates: z.array(TemplateSummarySchema),\n cursor: z.string().nullable(),\n hasMore: z.boolean(),\n })\n .strict();\n\nexport type DeclaredParam = z.infer<typeof DeclaredParamSchema>;\nexport type TemplateSummary = z.infer<typeof TemplateSummarySchema>;\nexport type TemplateDetail = z.infer<typeof TemplateDetailSchema>;\nexport type TemplatesListResponse = z.infer<typeof TemplatesListResponseSchema>;\n","// Zod schemas for the generation-job endpoints documented in\n// `docs-internal/agents/01-day1-rfc/01-tool-surface.md` §4.3 (generate create)\n// and §4.4 (generate wait/get).\n//\n// Object schemas are .strict() so unexpected fields surface as SCHEMA_MISMATCH\n// during development rather than silently passing through.\n//\n// §4.3 reference images: the canonical wire shape for `referenceImages` is the\n// object array `{ url, label? }[]`. The server still tolerates legacy bare\n// strings and canonicalizes them to `{ url }`, but this contract emits/accepts\n// objects only. `referenceImageUrl` (the single-image field) remains a bare\n// string on both server and client.\n\nimport { z } from 'zod';\n\n// §4.3 — POST /api/agents/v1/jobs\nconst ProductReferenceSchema = z\n .object({\n id: z.string().uuid(),\n imageId: z.string().uuid().optional(),\n })\n .strict();\n\n// Canonical per-reference shape. `label` mirrors the server's optional caption\n// (max 80 chars); it is part of the contract but not yet exposed as CLI/MCP input.\nconst ReferenceImageSchema = z\n .object({\n url: z.string().url(),\n label: z.string().max(80).optional(),\n })\n .strict();\n\nexport type ReferenceImage = z.infer<typeof ReferenceImageSchema>;\n\nexport const GenerateCreateRequestSchema = z\n .object({\n modelSlug: z.string().min(1).max(100),\n input: z\n .object({\n prompt: z.string().max(10000).optional(),\n referenceImageUrl: z.string().url().optional(),\n referenceImages: z.array(ReferenceImageSchema).max(8).optional(),\n aspectRatio: z\n .string()\n .regex(/^\\d+:\\d+$/)\n .optional(),\n resolution: z\n .string()\n .regex(\n /^(\\d+x\\d+|\\d{2,4}p|\\d+[Kk])$/,\n 'resolution must match WxH (e.g. 1280x720), p-token (e.g. 720p), or K-token (e.g. 1K)',\n )\n .optional(),\n durationSeconds: z.number().int().min(1).max(60).optional(),\n // The model's quality tier (e.g. 'low' | 'medium' | 'high'). The valid set is\n // per model, so it is checked server-side: an unoffered value returns 400\n // INPUT_INVALID_FORMAT with the supported options in `details.allowed`.\n quality: z.string().min(1).max(40).optional(),\n width: z.number().int().min(64).max(8192).optional(),\n height: z.number().int().min(64).max(8192).optional(),\n providerParams: z.record(z.string(), z.unknown()).optional(),\n })\n .strict(),\n options: z\n .object({\n workflowId: z.string().uuid().optional(),\n nodeId: z.string().optional(),\n })\n .strict()\n .optional(),\n products: z.array(ProductReferenceSchema).min(1).max(10).optional(),\n })\n .strict();\n\nexport type GenerateCreateRequest = z.infer<typeof GenerateCreateRequestSchema>;\n\n// §4.3 — create response (4 states; no `uploading` or `cancelled` at create time)\nexport const GenerateCreateResponseSchema = z\n .object({\n jobId: z.string().uuid(),\n status: z.enum(['queued', 'processing', 'completed', 'failed']),\n estimatedSeconds: z.number().int().nonnegative().nullable(),\n creditsCharged: z.number().int().nonnegative(),\n })\n .strict();\n\nexport type GenerateCreateResponse = z.infer<typeof GenerateCreateResponseSchema>;\n\n// §4.4 — GET /api/agents/v1/jobs/:id?wait=0-30\n//\n// The full result schema returned by `generate wait` / `generate get`. `wait`\n// accepts 0–30 seconds; 0 means no long-poll, N means the server holds the\n// request up to N seconds before responding with the latest state.\nexport const GenerationStatusSchema = z.enum([\n 'queued',\n 'processing',\n 'uploading',\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\nexport type GenerationStatus = z.infer<typeof GenerationStatusSchema>;\n\nexport const TERMINAL_STATUSES: ReadonlySet<GenerationStatus> = new Set<GenerationStatus>([\n 'completed',\n 'failed',\n 'cancelled',\n]);\n\nexport function isTerminalStatus(status: GenerationStatus): boolean {\n return TERMINAL_STATUSES.has(status);\n}\n\nexport const GenerationResultSchema = z\n .object({\n jobId: z.string().uuid(),\n status: GenerationStatusSchema,\n modelSlug: z.string(),\n resultUrl: z.string().url().nullable(),\n thumbnailUrl: z.string().url().nullable(),\n errorCode: z.string().nullable(),\n errorMessage: z.string().nullable(),\n creditsCharged: z.number().int().nonnegative(),\n creditsRefunded: z.boolean(),\n startedAt: z.string().nullable(),\n completedAt: z.string().nullable(),\n })\n .strict();\n\nexport type GenerationResult = z.infer<typeof GenerationResultSchema>;\n\n// GET /api/agents/v1/jobs — the calling token's user's generation history in\n// the org, newest first, keyset-paginated (opaque `cursor`). Mirrors the\n// server's GenerateListResponseSchema.\nexport const GenerationListItemSchema = z\n .object({\n jobId: z.string().uuid(),\n status: GenerationStatusSchema,\n modelSlug: z.string().nullable(),\n contentType: z.enum(['image', 'video', 'audio']),\n prompt: z.string().nullable(),\n resultUrl: z.string().nullable(),\n thumbnailUrl: z.string().nullable(),\n errorCode: z.string().nullable(),\n errorMessage: z.string().nullable(),\n creditsCharged: z.number().int().nonnegative(),\n creditsRefunded: z.boolean(),\n createdAt: z.string(),\n completedAt: z.string().nullable(),\n })\n .strict();\n\nexport type GenerationListItem = z.infer<typeof GenerationListItemSchema>;\n\nexport const GenerationListResponseSchema = z\n .object({\n jobs: z.array(GenerationListItemSchema),\n cursor: z.string().nullable(),\n hasMore: z.boolean(),\n })\n .strict();\n\nexport type GenerationListResponse = z.infer<typeof GenerationListResponseSchema>;\n\n// POST /api/agents/v1/jobs/estimate — what POST /jobs would charge for the SAME\n// body, and whether it would accept it now. Nothing is created or deducted.\n// `blockedReason` is null when POST /jobs would accept; `balance` is null when\n// the server's entitlement gate did not read it.\nexport const GenerateEstimateResponseSchema = z\n .object({\n modelSlug: z.string(),\n creditCost: z.number().int().nonnegative(),\n estimatedSeconds: z.number().int().nonnegative().nullable(),\n balance: z.number().nullable(),\n affordable: z.boolean(),\n blockedReason: z\n .enum(['insufficient_credits', 'feature_disabled', 'subscription_required', 'past_due'])\n .nullable(),\n })\n .strict();\n\nexport type GenerateEstimateResponse = z.infer<typeof GenerateEstimateResponseSchema>;\n","// Zod schemas for the upload endpoint documented in\n// `docs-internal/agents/01-day1-rfc/01-tool-surface.md` §4.6.\n//\n// The endpoint is two-step: the client POSTs file metadata + a sha256\n// content hash, the server returns a 5-minute signed GCS upload URL, and the\n// client PUTs the bytes to that URL. §7.1 #2 covers partial-upload retry:\n// the client retries with the same contentHash and the server either signals\n// `deduplicated: true` (bytes already landed) or issues a fresh signed URL.\n\nimport { z } from 'zod';\n\nexport const MAX_UPLOAD_SIZE_BYTES = 15 * 1024 * 1024;\n\nexport const UploadRequestSchema = z\n .object({\n filename: z.string().min(1).max(255),\n contentType: z.string().regex(/^[\\w-]+\\/[\\w+.-]+$/),\n sizeBytes: z.number().int().positive().max(MAX_UPLOAD_SIZE_BYTES),\n contentHash: z.string().regex(/^sha256:[0-9a-f]{64}$/),\n })\n .strict();\n\nexport type UploadRequest = z.infer<typeof UploadRequestSchema>;\n\nexport const UploadResponseSchema = z\n .object({\n assetId: z.string().uuid(),\n // `z.string()` (not `.url()`): the server emits `uploadUrl: ''` on the\n // dedup branch (`deduplicated: true`) — see server `assets.ts` comment.\n uploadUrl: z.string(),\n publicUrl: z.string().url(),\n deduplicated: z.boolean(),\n })\n .strict();\n\nexport type UploadResponse = z.infer<typeof UploadResponseSchema>;\n","import { z } from 'zod';\n\nexport const NodeTypeSummarySchema = z\n .object({\n type: z.string(),\n portCount: z.number(),\n })\n .strict();\n\nexport const NodeTypePortSchema = z\n .object({\n handleId: z.string(),\n direction: z.enum(['input', 'output']),\n dataType: z.string(),\n })\n .strict();\n\nexport const NodeTypeDetailSchema = z\n .object({\n type: z.string(),\n ports: z.array(NodeTypePortSchema),\n agentWritableFields: z.array(z.string()),\n })\n .strict();\n\nexport const NodeTypesListResponseSchema = z\n .object({\n nodeTypes: z.array(NodeTypeSummarySchema),\n })\n .strict();\n\nexport type NodeTypeSummary = z.infer<typeof NodeTypeSummarySchema>;\nexport type NodeTypePort = z.infer<typeof NodeTypePortSchema>;\nexport type NodeTypeDetail = z.infer<typeof NodeTypeDetailSchema>;\nexport type NodeTypesListResponse = z.infer<typeof NodeTypesListResponseSchema>;\n","import { z } from 'zod';\n\nexport const WorkflowDeclaredParamSchema = z\n .object({\n name: z.string(),\n type: z.string(),\n required: z.boolean().optional(),\n defaultValue: z.unknown().optional(),\n description: z.unknown().optional(),\n })\n .passthrough();\n\nexport const WorkflowSummarySchema = z\n .object({\n id: z.string().uuid(),\n name: z.string(),\n tags: z.array(z.string()),\n declared_params: z.array(WorkflowDeclaredParamSchema).nullable().default([]),\n canvas_rev: z.number().int().nonnegative(),\n updated_at: z.string(),\n })\n .strict();\n\nexport const WorkflowsListResponseSchema = z\n .object({\n items: z.array(WorkflowSummarySchema),\n nextCursor: z.string().nullable(),\n })\n .strict();\n\nexport const WorkflowDetailSchema = z\n .object({\n id: z.string().uuid(),\n name: z.string(),\n description: z.string().nullable(),\n tags: z.array(z.string()),\n declared_params: z.array(WorkflowDeclaredParamSchema).nullable().default([]),\n canvas_rev: z.number().int().nonnegative(),\n nodes: z.array(z.unknown()),\n edges: z.array(z.unknown()),\n created_at: z.string(),\n updated_at: z.string(),\n })\n .strict();\n\nexport const WorkflowCreateResponseSchema = z\n .object({\n id: z.string().uuid(),\n name: z.string(),\n description: z.string().nullable(),\n tags: z.array(z.string()),\n declared_params: z.array(WorkflowDeclaredParamSchema).nullable().default([]),\n canvas_rev: z.number().int().nonnegative(),\n created_at: z.string(),\n updated_at: z.string(),\n })\n .strict();\n\nexport const WorkflowMutateResponseSchema = z\n .object({\n canvas_rev: z.number().int().nonnegative(),\n applied: z.number().int().nonnegative(),\n workflow: WorkflowDetailSchema,\n })\n .strict();\n\nexport type WorkflowDeclaredParam = z.infer<typeof WorkflowDeclaredParamSchema>;\nexport type WorkflowSummary = z.infer<typeof WorkflowSummarySchema>;\nexport type WorkflowsListResponse = z.infer<typeof WorkflowsListResponseSchema>;\nexport type WorkflowDetail = z.infer<typeof WorkflowDetailSchema>;\nexport type WorkflowCreateResponse = z.infer<typeof WorkflowCreateResponseSchema>;\nexport type WorkflowMutateResponse = z.infer<typeof WorkflowMutateResponseSchema>;\n","// Error-code taxonomy: the set of machine-readable codes the Agents API can\n// surface. These are pure string-literal unions with no exit-code/hint policy\n// attached — that policy (the EXIT_CODE_MAP and friends) stays on the CLI side.\n//\n// The server codes come from `docs-internal/agents/01-day1-rfc/01-tool-surface.md`\n// §5 and `02-oauth.md` §2.6. The client codes cover failure modes only the\n// client can observe (network errors after retries exhausted, abort timeouts,\n// parse failures, schema mismatches).\n\n// The 61 server error codes, as a runtime array. `ServerErrorCode` (the type)\n// is DERIVED from this array so the two can never drift — adding a code in one\n// place without the other is a compile error. `KNOWN_SERVER_CODES` (the\n// allow-list the HTTP client trusts from the server) is also built from it.\nexport const SERVER_ERROR_CODES = [\n 'AUTH_TOKEN_MISSING',\n 'AUTH_TOKEN_INVALID',\n 'AUTH_TOKEN_EXPIRED',\n 'AUTH_TOKEN_REVOKED',\n 'AUTH_TOKEN_SCOPE_INSUFFICIENT',\n 'AUTH_ORG_MISMATCH',\n 'AUTH_DEVICE_CODE_PENDING',\n 'AUTH_DEVICE_CODE_EXPIRED',\n 'AUTH_DEVICE_CODE_SLOW_DOWN',\n 'IDEMPOTENCY_KEY_MISSING',\n 'IDEMPOTENCY_KEY_CONFLICT',\n 'PLAN_FEATURE_LOCKED',\n 'PLAN_QUOTA_EXCEEDED',\n 'INSUFFICIENT_CREDITS',\n 'CREDIT_DEDUCTION_FAILED',\n 'RATE_LIMITED',\n 'INPUT_INVALID_FORMAT',\n 'INPUT_TOO_LONG',\n 'WORKFLOW_VALIDATION_FAILED',\n 'WORKFLOW_NODE_TYPE_UNKNOWN',\n 'CANVAS_REV_MISMATCH',\n 'CANVAS_REV_REQUIRED',\n 'WORKER_UNREACHABLE',\n 'IDEMPOTENCY_IN_PROGRESS',\n 'TOKEN_NAME_INVALID',\n 'WORKFLOW_NOT_FOUND',\n 'NOT_FOUND',\n 'NODE_TYPE_NOT_FOUND',\n 'FEATURE_DISABLED',\n 'FORBIDDEN',\n 'MODEL_NOT_FOUND',\n 'PROVIDER_UNAVAILABLE',\n 'STORAGE_UPLOAD_FAILED',\n 'STORAGE_QUOTA_EXCEEDED',\n 'GEN_CONTENT_REFUSAL',\n 'GEN_OUTPUT_SCHEMA_MISMATCH',\n 'GEN_EMPTY_OUTPUT',\n 'GEN_ITEM_COUNT_MISMATCH',\n 'AGENT_FINGERPRINT_REJECTED',\n 'INTERNAL_ERROR',\n 'BRAND_MODEL_NOT_FOUND',\n 'BRAND_MODEL_NOT_A_MODEL',\n 'BRAND_MODEL_NOT_ACTIVE',\n 'BRAND_MODEL_NO_REFERENCES',\n 'BRAND_MODEL_POSE_NOT_FOUND',\n 'BRAND_MODEL_DUPLICATE_ID',\n 'MODEL_DOES_NOT_SUPPORT_REFERENCES',\n 'REFERENCE_LIMIT_EXCEEDED',\n 'PRODUCT_NOT_FOUND',\n 'PRODUCT_DUPLICATE_REFERENCE',\n 'PRODUCT_IMAGE_NOT_FOUND',\n 'PRODUCT_IMAGE_MISMATCH',\n 'PRODUCT_SYNC_ERROR',\n 'PRODUCT_DELETED_UPSTREAM',\n 'PRODUCT_NO_PRIMARY_IMAGE',\n 'PRODUCT_SOURCE_MANAGED',\n // Product create (`POST /api/agents/v1/products`). Without these five in the\n // allow-list the HTTP client folds each one into INTERNAL_ERROR, which loses\n // the server's message, the actionable `details.assetIds`, and the CLI exit\n // code the failure should map to. STORAGE_UNAVAILABLE additionally loses its\n // retryability, turning a transient 503 the server marked retryable into a\n // one-shot failure.\n 'PRODUCT_IMAGE_ASSET_DUPLICATE',\n 'PRODUCT_IMAGE_ASSET_NOT_FOUND',\n 'PRODUCT_IMAGE_ASSET_NOT_IMAGE',\n 'PRODUCT_IMAGE_ASSET_INCOMPLETE',\n 'STORAGE_UNAVAILABLE',\n] as const;\n\nexport type ServerErrorCode = (typeof SERVER_ERROR_CODES)[number];\n\nexport type ClientErrorCode = 'NETWORK_ERROR' | 'TIMEOUT' | 'PARSE_ERROR' | 'SCHEMA_MISMATCH';\n\n// The codes `ApiError` can actually carry: every error the HTTP client either\n// receives from the server (ServerErrorCode) or synthesizes itself\n// (ClientErrorCode). Deliberately NOT the CLI's `AllErrorCode` — auth/credential\n// codes are surfaced via AuthError/CredentialsError, never via ApiError.\nexport type ApiErrorCode = ServerErrorCode | ClientErrorCode;\n\n// Allow-list of codes the HTTP client is willing to accept from the server.\n// Anything outside this set is mapped to INTERNAL_ERROR so the strict-Zod\n// guarantees aren't bypassed by a typo or future server addition. Derived from\n// SERVER_ERROR_CODES so it is exactly the server taxonomy — the CLI-only client\n// codes are never valid as a server-supplied `error.code`.\nexport const KNOWN_SERVER_CODES: ReadonlySet<string> = new Set(SERVER_ERROR_CODES);\n","// Generic long-poll helper for the `wait` commands. Each `fetcher()` call is\n// expected to already encode a server-side hold (e.g. `?wait=30` per RFC §4.4),\n// so the helper does NOT impose a client-side interval — it just loops back-to-\n// back until the result is terminal or the overall deadline expires.\n//\n// Phase 8 Q9 of `wave-1-investigation.md` settled the wait UX: default overall\n// timeout 120s, server long-poll rounds 30s, no exponential backoff.\n\nimport { ApiError } from './errors/api-error.js';\n\nexport interface LongPollOptions<T> {\n // One round of the long-poll. Should carry the server `?wait=N` query so\n // each call holds for up to N seconds before returning the latest state.\n // The helper passes an iteration AbortSignal composed from `opts.signal`\n // and the remaining-time deadline; fetchers SHOULD forward it to the HTTP\n // request so e.g. `--timeout 1` doesn't get blocked by a 30s server hold.\n // The args parameter is optional to keep existing test fetchers compatible.\n fetcher: (args?: { signal?: AbortSignal }) => Promise<T>;\n // Returns true when `result` represents a terminal state and the loop\n // should stop. Caller decides what constitutes terminal (e.g. completed\n // ∪ failed ∪ cancelled for generation jobs).\n isTerminal: (result: T) => boolean;\n // Overall hard deadline in milliseconds. Once elapsed >= timeoutMs the\n // helper throws ApiError('TIMEOUT', ...).\n timeoutMs: number;\n // Optional abort signal. If it fires the helper throws ApiError('TIMEOUT',\n // ...) to keep all \"we gave up\" paths under a single exit-code category.\n signal?: AbortSignal;\n // Test-only clock seam. Defaults to Date.now.\n now?: () => number;\n}\n\nexport async function longPoll<T>(opts: LongPollOptions<T>): Promise<T> {\n const now = opts.now ?? Date.now;\n const started = now();\n\n for (;;) {\n if (opts.signal?.aborted) {\n throw new ApiError('TIMEOUT', 'Wait was aborted.', { retryable: true });\n }\n\n // Pre-fetch deadline check — must come BEFORE the fetcher so we never\n // begin a fresh server hold once we've already blown past the user's\n // overall timeout.\n const elapsedBefore = now() - started;\n if (elapsedBefore >= opts.timeoutMs) {\n throw new ApiError(\n 'TIMEOUT',\n `Wait exceeded ${opts.timeoutMs}ms without reaching a terminal state.`,\n { retryable: true },\n );\n }\n\n const remainingMs = opts.timeoutMs - elapsedBefore;\n const iterationSignal = composeIterationSignal(opts.signal, remainingMs);\n\n let result: T;\n try {\n result = await opts.fetcher({ signal: iterationSignal });\n } catch (err) {\n // The fetcher rejects (typically AbortError) when the composed iteration\n // signal aborts — either the overall deadline elapsed (AbortSignal.timeout)\n // or the caller aborted (opts.signal). Both are \"we gave up\" → ApiError\n // TIMEOUT, sharing one exit-code category. Classify from the signal's\n // already-settled aborted state, NOT a wall-clock re-read: the timer and\n // Date.now() can disagree by ~1ms, which used to rethrow the raw AbortError.\n if (iterationSignal.aborted) {\n throw new ApiError(\n 'TIMEOUT',\n opts.signal?.aborted\n ? 'Wait was aborted.'\n : `Wait exceeded ${opts.timeoutMs}ms without reaching a terminal state.`,\n { retryable: true },\n );\n }\n // Genuine non-abort fetcher error — propagate verbatim.\n throw err;\n }\n\n if (opts.signal?.aborted) {\n throw new ApiError('TIMEOUT', 'Wait was aborted.', { retryable: true });\n }\n\n // Post-fetch deadline check — a fetcher that resolves AT or AFTER the\n // overall deadline must not be allowed to satisfy the wait. We do this\n // BEFORE the terminal check so terminal-arrived-too-late still surfaces\n // as TIMEOUT (the contract is \"give an answer within timeoutMs\").\n const elapsedAfter = now() - started;\n if (elapsedAfter >= opts.timeoutMs) {\n throw new ApiError(\n 'TIMEOUT',\n `Wait exceeded ${opts.timeoutMs}ms without reaching a terminal state.`,\n { retryable: true },\n );\n }\n\n if (opts.isTerminal(result)) {\n return result;\n }\n }\n}\n\nfunction composeIterationSignal(\n userSignal: AbortSignal | undefined,\n remainingMs: number,\n): AbortSignal {\n const deadlineSignal = AbortSignal.timeout(Math.max(remainingMs, 0));\n return userSignal ? AbortSignal.any([userSignal, deadlineSignal]) : deadlineSignal;\n}\n","// HTTP client for the Clickraft Agents API. Wraps `undici.request` with:\n//\n// - Bearer auth + User-Agent + Idempotency-Key headers\n// - JSON body serialization + JSON response parsing\n// - Strict Zod schema validation on success payloads\n// - Exponential-backoff retry that honors `Retry-After` and the\n// `error.retryAfter` field per RFC §4.1 / Phase 8 Q7\n// - AbortSignal composition (client signal + per-request signal)\n// - Token redaction on every error body via redactTokenLikeFields from 1A.1\n//\n// Retryability of server error codes and warning emission are CLI policy and\n// are injected via `ApiClientOptions.isRetryableServerCode` / `.onWarning`; this\n// module never reads the CLI's exit-code policy table. See plan-file for the contract.\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\nimport { z } from 'zod';\n\nimport type { CloudflareAccessCredentials } from '../config-types.js';\nimport { ApiError } from '../errors/api-error.js';\nimport { KNOWN_SERVER_CODES, type ServerErrorCode } from '../errors/codes.js';\nimport { formatSchemaIssues } from '../errors/schema-mismatch.js';\nimport { redactTokenLikeFields } from '../redact.js';\n\nimport { generateIdempotencyKey } from './idempotency.js';\nimport { DEFAULT_RETRY_OPTIONS, decideRetry, sleep, type RetryOptions } from './retry.js';\nimport { ServerErrorBodySchema, ServerSuccessSchema, type ServerErrorBody } from './types.js';\n\nexport interface ApiClientOptions {\n apiBaseUrl: string;\n accessToken: string | null;\n userAgent?: string;\n signal?: AbortSignal;\n dispatcher?: Dispatcher;\n retryDefaults?: Partial<RetryOptions>;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n // Sink for non-fatal warnings (unknown server code, Retry-After clipping).\n // Injected by the CLI to forward to stderr; absent ⇒ silent.\n onWarning?: (msg: string) => void;\n // Decides whether a known server error code is retryable. Injected by the CLI\n // (backed by its exit-code policy, the single source of retryability truth).\n // When absent, the client falls back to the HTTP-status heuristic below.\n isRetryableServerCode?: (code: ServerErrorCode) => boolean;\n}\n\nexport type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';\n\nexport interface RequestOptions<TSchema extends z.ZodTypeAny = z.ZodTypeAny> {\n method: HttpMethod;\n path: string;\n body?: unknown;\n query?: Record<string, string | number | string[] | undefined>;\n idempotencyKey?: string;\n retry?: Partial<RetryOptions>;\n responseSchema?: TSchema;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\nconst REDACT_BODY_LIMIT = 1024;\n// Cap the input to redaction so the regex doesn't traverse pathologically\n// large bodies. Anything past this is dropped before truncation; the trade-\n// off vs. token leakage is documented in plan-wobbly-floyd.md (C2).\nconst REDACT_INPUT_CAP = 100 * 1024;\nconst DEFAULT_USER_AGENT = 'clickraft-cli';\n\nexport class ApiClient {\n private readonly options: ApiClientOptions;\n private readonly retryDefaults: RetryOptions;\n\n constructor(options: ApiClientOptions) {\n this.options = options;\n this.retryDefaults = {\n ...DEFAULT_RETRY_OPTIONS,\n ...options.retryDefaults,\n };\n }\n\n // Issues a request with built-in retry, Zod validation, and token redaction.\n //\n // Non-GET requests get an auto-generated UUIDv4 `X-Idempotency-Key` per\n // Phase 8 Q8 of the wave-1 investigation. The key is computed once and\n // reused across every retry attempt so the server can deduplicate. Callers\n // may pass `opts.idempotencyKey` to override the default — the upload\n // command uses this to derive the key from the content's SHA-256.\n async request<TData = unknown, TSchema extends z.ZodTypeAny = z.ZodTypeAny>(\n opts: RequestOptions<TSchema>,\n ): Promise<TData> {\n const retry: RetryOptions = {\n ...this.retryDefaults,\n ...opts.retry,\n };\n const signal = composeSignals([this.options.signal, opts.signal, retry.signal]);\n const url = buildUrl(this.options.apiBaseUrl, opts.path, opts.query);\n const effectiveIdempotencyKey =\n opts.method === 'GET'\n ? opts.idempotencyKey\n : (opts.idempotencyKey ?? generateIdempotencyKey());\n const headers = this.buildHeaders({ ...opts, idempotencyKey: effectiveIdempotencyKey });\n const bodyText = serializeBody(opts);\n\n let attempt = 0;\n let lastError: ApiError | undefined;\n\n // First attempt is attempt=1; we retry up to retry.maxAttempts total.\n while (attempt < retry.maxAttempts) {\n attempt += 1;\n if (signal.aborted) {\n throw toAbortApiError(signal);\n }\n\n try {\n return await this.singleAttempt<TData>({\n url,\n method: opts.method,\n headers,\n bodyText,\n signal,\n responseSchema: opts.responseSchema,\n });\n } catch (err) {\n if (!(err instanceof ApiError)) throw err;\n lastError = err;\n\n const isNetworkError = err.code === 'NETWORK_ERROR';\n const isRetryable = err.meta.retryable;\n const decision = decideRetry({\n attempt,\n options: { ...retry, signal },\n serverRetryAfterMs: err.meta.retryAfterMs,\n isNetworkError,\n isRetryable,\n onWarning: this.options.onWarning,\n });\n\n if (!decision.shouldRetry) throw err;\n try {\n await sleep(decision.delayMs, signal);\n } catch (sleepErr) {\n throw toAbortApiError(signal, sleepErr);\n }\n }\n }\n\n // Loop only exits via return or throw above, but TS needs a fallback.\n throw (\n lastError ??\n new ApiError('INTERNAL_ERROR', 'Retry loop terminated unexpectedly.', {\n retryable: false,\n })\n );\n }\n\n private buildHeaders(opts: RequestOptions): Record<string, string> {\n const h: Record<string, string> = {\n accept: 'application/json',\n 'user-agent': this.options.userAgent ?? DEFAULT_USER_AGENT,\n };\n if (this.options.accessToken) {\n h.authorization = `Bearer ${this.options.accessToken}`;\n }\n if (this.options.cloudflareAccess) {\n h['cf-access-client-id'] = this.options.cloudflareAccess.clientId;\n h['cf-access-client-secret'] = this.options.cloudflareAccess.clientSecret;\n }\n if (opts.body !== undefined && opts.method !== 'GET' && opts.method !== 'DELETE') {\n h['content-type'] = 'application/json';\n }\n if (opts.idempotencyKey) {\n h['x-idempotency-key'] = opts.idempotencyKey;\n }\n if (opts.headers) {\n for (const [k, v] of Object.entries(opts.headers)) {\n h[k.toLowerCase()] = v;\n }\n }\n return h;\n }\n\n private async singleAttempt<TData>(args: {\n url: string;\n method: HttpMethod;\n headers: Record<string, string>;\n bodyText?: string;\n signal: AbortSignal;\n responseSchema?: z.ZodTypeAny;\n }): Promise<TData> {\n let response: Dispatcher.ResponseData;\n try {\n response = await undiciRequest(args.url, {\n method: args.method,\n headers: args.headers,\n body: args.bodyText,\n signal: args.signal,\n dispatcher: this.options.dispatcher,\n });\n } catch (err) {\n if (isAbortError(err)) {\n throw toAbortApiError(args.signal, err);\n }\n throw new ApiError(\n 'NETWORK_ERROR',\n `Network request failed: ${errorMessage(err)}`,\n { retryable: true },\n err,\n );\n }\n\n const { statusCode, headers: responseHeaders, body } = response;\n let bodyText: string;\n try {\n bodyText = await body.text();\n } catch (err) {\n if (isAbortError(err)) {\n throw toAbortApiError(args.signal, err);\n }\n throw new ApiError(\n 'NETWORK_ERROR',\n `Failed to read response body: ${errorMessage(err)}`,\n { status: statusCode, retryable: true },\n err,\n );\n }\n\n const requestId = pickHeader(responseHeaders, 'x-correlation-id');\n\n if (statusCode >= 200 && statusCode < 300) {\n return parseSuccessBody<TData>({\n bodyText,\n statusCode,\n requestId,\n responseSchema: args.responseSchema,\n });\n }\n\n throw parseErrorBody({\n bodyText,\n statusCode,\n requestId,\n retryAfterHeader: pickHeader(responseHeaders, 'retry-after'),\n onWarning: this.options.onWarning,\n isRetryableServerCode: this.options.isRetryableServerCode,\n });\n }\n}\n\n// Constructs an ApiClient from resolved options. The factory exists so callers\n// (and the CLI's policy-injecting wrapper) have a single, stable entry point\n// that does not depend on the class shape.\nexport function createClient(options: ApiClientOptions): ApiClient {\n return new ApiClient(options);\n}\n\nfunction parseSuccessBody<TData>(args: {\n bodyText: string;\n statusCode: number;\n requestId?: string;\n responseSchema?: z.ZodTypeAny;\n}): TData {\n let parsed: unknown;\n try {\n parsed = JSON.parse(args.bodyText);\n } catch (err) {\n throw new ApiError(\n 'PARSE_ERROR',\n 'Server returned a non-JSON response.',\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: false,\n redactedBody: redactAndTruncate(args.bodyText),\n },\n err,\n );\n }\n\n const envelope = ServerSuccessSchema(args.responseSchema ?? z.unknown()).safeParse(parsed);\n if (!envelope.success) {\n const issues = formatSchemaIssues(envelope.error);\n throw new ApiError(\n 'SCHEMA_MISMATCH',\n `Server response did not match the expected schema. Issues: ${issues}`,\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: false,\n redactedBody: redactAndTruncate(args.bodyText),\n },\n );\n }\n return envelope.data.data as TData;\n}\n\nfunction parseErrorBody(args: {\n bodyText: string;\n statusCode: number;\n requestId?: string;\n retryAfterHeader?: string;\n onWarning?: (msg: string) => void;\n isRetryableServerCode?: (code: ServerErrorCode) => boolean;\n}): ApiError {\n const redactedBody = redactAndTruncate(args.bodyText);\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(args.bodyText);\n } catch {\n return new ApiError(\n 'PARSE_ERROR',\n `Server returned a ${args.statusCode} response with a non-JSON body.`,\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: args.statusCode >= 500,\n redactedBody,\n },\n );\n }\n\n const envelope = ServerErrorBodySchema.safeParse(parsed);\n if (!envelope.success) {\n return new ApiError(\n 'PARSE_ERROR',\n `Server returned ${args.statusCode} but body did not match the error envelope.`,\n {\n status: args.statusCode,\n requestId: args.requestId,\n retryable: args.statusCode >= 500,\n redactedBody,\n },\n );\n }\n\n return apiErrorFromServerBody({\n body: envelope.data,\n statusCode: args.statusCode,\n requestId: args.requestId,\n retryAfterHeader: args.retryAfterHeader,\n redactedBody,\n onWarning: args.onWarning,\n isRetryableServerCode: args.isRetryableServerCode,\n });\n}\n\nfunction apiErrorFromServerBody(args: {\n body: ServerErrorBody;\n statusCode: number;\n requestId?: string;\n retryAfterHeader?: string;\n redactedBody?: string;\n onWarning?: (msg: string) => void;\n isRetryableServerCode?: (code: ServerErrorCode) => boolean;\n}): ApiError {\n const { error } = args.body;\n\n // S1 — reject unknown codes so a server typo or future addition cannot\n // bypass the strict mapping. Unknown codes are folded into INTERNAL_ERROR\n // with a warning; the raw code is redacted before logging in case the\n // server (or an attacker) embedded a token in it.\n let code: ServerErrorCode;\n let safeMessage: string;\n if (KNOWN_SERVER_CODES.has(error.code)) {\n code = error.code as ServerErrorCode;\n // C3 — server-provided messages can echo tokens. Strip them before the\n // string reaches ApiError.message (which surfaces via stderr, JSON\n // envelope, and any default Error stringification).\n safeMessage = redactTokenLikeFields(error.message);\n } else {\n const redactedRawCode = redactTokenLikeFields(error.code);\n args.onWarning?.(`Unknown server error code: ${redactedRawCode}. Treating as INTERNAL_ERROR.`);\n code = 'INTERNAL_ERROR';\n safeMessage = `Unknown server error code: ${redactedRawCode}.`;\n }\n\n // Retryability is CLI policy, injected as `isRetryableServerCode` (backed by\n // the CLI's exit-code policy). The status heuristic is the fallback when no\n // predicate is injected — it lives here because the predicate has no access to\n // statusCode.\n const retryable =\n args.isRetryableServerCode?.(code) ?? (args.statusCode >= 500 || args.statusCode === 429);\n\n // Prefer the structured `error.retryAfter` field (seconds) over the\n // Retry-After header per Phase 8 Q7 & the RFC §4.1 error envelope.\n const retryAfterMs =\n typeof error.retryAfter === 'number'\n ? error.retryAfter * 1000\n : parseRetryAfterHeader(args.retryAfterHeader);\n\n return new ApiError(code, safeMessage, {\n status: args.statusCode,\n requestId: error.correlationId ?? args.requestId,\n retryable,\n retryAfterMs,\n redactedBody: args.redactedBody,\n details: error.details,\n });\n}\n\n// Parses a Retry-After HTTP header. Per RFC 7231 §7.1.3 the value is either\n// a non-negative integer number of seconds OR an HTTP-date. We are strict\n// here because `parseInt(\"2garbage\")` would otherwise return `2` and the\n// CLI would sleep for an attacker- or proxy-chosen window.\nexport function parseRetryAfterHeader(headerValue: string | undefined): number | undefined {\n if (!headerValue) return undefined;\n const trimmed = headerValue.trim();\n if (/^\\d+$/.test(trimmed)) {\n return Number.parseInt(trimmed, 10) * 1000;\n }\n // Only fall through to HTTP-date if the input actually looks like one\n // (i.e. contains letters). `Date.parse(\"2.5\")` accidentally parses on V8.\n if (/[A-Za-z]/.test(trimmed)) {\n const parsed = Date.parse(trimmed);\n if (!Number.isNaN(parsed)) {\n return Math.max(0, parsed - Date.now());\n }\n }\n return undefined;\n}\n\nfunction buildUrl(\n baseUrl: string,\n path: string,\n query?: Record<string, string | number | string[] | undefined>,\n): string {\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n const relative = path.startsWith('/') ? path.slice(1) : path;\n const url = new URL(relative, base);\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n if (value === undefined) continue;\n if (Array.isArray(value)) {\n for (const item of value) url.searchParams.append(key, item);\n continue;\n }\n url.searchParams.append(key, String(value));\n }\n }\n return url.toString();\n}\n\nfunction serializeBody(opts: RequestOptions): string | undefined {\n if (opts.body === undefined) return undefined;\n if (opts.method === 'GET') return undefined;\n return JSON.stringify(opts.body);\n}\n\nfunction composeSignals(signals: Array<AbortSignal | undefined>): AbortSignal {\n const present = signals.filter((s): s is AbortSignal => s !== undefined);\n if (present.length === 0) return new AbortController().signal;\n if (present.length === 1) return present[0]!;\n\n // `AbortSignal.any` landed in Node 20.3; the project's `engines.node` floor\n // is 20.0, so fall back to a hand-rolled merger when it's not available.\n type AbortSignalCtor = typeof AbortSignal & { any?: (signals: AbortSignal[]) => AbortSignal };\n const any = (AbortSignal as AbortSignalCtor).any;\n if (typeof any === 'function') return any(present);\n\n const ctrl = new AbortController();\n for (const s of present) {\n if (s.aborted) {\n ctrl.abort(s.reason);\n break;\n }\n s.addEventListener('abort', () => ctrl.abort(s.reason), { once: true });\n }\n return ctrl.signal;\n}\n\nfunction pickHeader(\n headers: Record<string, string | string[] | undefined>,\n name: string,\n): string | undefined {\n const value = headers[name] ?? headers[name.toLowerCase()];\n if (Array.isArray(value)) return value[0];\n return value;\n}\n\n// Redact token-shaped JSON fields, THEN truncate to REDACT_BODY_LIMIT. The\n// order matters: the redact regex requires a closing quote, so truncating\n// first can slice mid-string and leak the token's prefix into the survivor.\nfunction redactAndTruncate(body: string): string {\n const input = body.length > REDACT_INPUT_CAP ? body.slice(0, REDACT_INPUT_CAP) : body;\n const redacted = redactTokenLikeFields(input);\n return redacted.length > REDACT_BODY_LIMIT\n ? `${redacted.slice(0, REDACT_BODY_LIMIT)}…`\n : redacted;\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (!(err instanceof Error)) return false;\n return err.name === 'AbortError' || /aborted/i.test(err.message);\n}\n\nfunction toAbortApiError(signal: AbortSignal, cause?: unknown): ApiError {\n const reasonMessage =\n signal.reason instanceof Error ? signal.reason.message : 'Request was aborted.';\n return new ApiError('TIMEOUT', reasonMessage, { retryable: true }, cause);\n}\n\nfunction errorMessage(err: unknown): string {\n if (err instanceof Error) return err.message;\n return String(err);\n}\n","// Idempotency-Key generation per Phase 8 Q8 of `wave-1-investigation.md`.\n//\n// Default: crypto.randomUUID() returns an RFC 4122 v4 UUID — generated once\n// per command invocation and reused across automatic retries within that\n// invocation. Memory-only; no on-disk cache.\n//\n// Exception: upload uses sha256(content) + scope per\n// `01-tool-surface.md` §7.1 edge case 2, so identical content uploaded twice\n// hits the server's content-hash dedup path and surfaces as\n// `deduplicated: true` with no duplicate charge.\n\nimport { createHash, randomUUID } from 'node:crypto';\n\nexport function generateIdempotencyKey(): string {\n return randomUUID();\n}\n\nexport function generateUploadIdempotencyKey(content: Buffer | Uint8Array, scope: string): string {\n const hash = createHash('sha256').update(content).digest('hex');\n return `upload-${scope}-${hash}`;\n}\n","// Retry policy used by the HTTP client. Exponential backoff with jitter,\n// capped at maxDelayMs. `decideRetry` is pure so the client's retry loop is\n// easy to test in isolation.\n\nexport interface RetryOptions {\n maxAttempts: number;\n baseDelayMs: number;\n maxDelayMs: number;\n jitterFraction: number;\n signal?: AbortSignal;\n}\n\nexport const DEFAULT_RETRY_OPTIONS: Omit<RetryOptions, 'signal'> = {\n maxAttempts: 3,\n baseDelayMs: 200,\n maxDelayMs: 10_000,\n jitterFraction: 0.25,\n};\n\nexport type RetryReason =\n | 'retryable_error'\n | 'network_failure'\n | 'rate_limited'\n | 'aborted'\n | 'max_attempts'\n | 'not_retryable';\n\nexport interface RetryDecision {\n shouldRetry: boolean;\n delayMs: number;\n reason: RetryReason;\n}\n\n// Absolute upper bound on server-supplied Retry-After. A misconfigured server\n// or buggy proxy could send an unreasonably large value; we clip it here to\n// avoid stalling the CLI for hours.\nexport const ABSOLUTE_MAX_RETRY_AFTER_MS = 5 * 60 * 1000;\n\nexport function computeBackoffMs(\n attempt: number,\n baseDelayMs: number,\n maxDelayMs: number,\n jitterFraction: number,\n): number {\n const exp = Math.min(baseDelayMs * 2 ** Math.max(0, attempt - 1), maxDelayMs);\n const jitter = exp * jitterFraction * (Math.random() * 2 - 1);\n return Math.max(0, Math.round(exp + jitter));\n}\n\n// Decides whether to retry and how long to wait. Server-supplied\n// Retry-After overrides `maxDelayMs` — clamping it would let the CLI retry\n// faster than the server requested, which defeats the rate-limit signal.\n// An absolute safety cap (`ABSOLUTE_MAX_RETRY_AFTER_MS`) bounds pathological\n// values; the optional `onWarning` sink is notified when clipping occurs.\nexport function decideRetry(params: {\n attempt: number;\n options: RetryOptions;\n serverRetryAfterMs?: number;\n isNetworkError: boolean;\n isRetryable: boolean;\n onWarning?: (msg: string) => void;\n}): RetryDecision {\n const { attempt, options, serverRetryAfterMs, isNetworkError, isRetryable, onWarning } = params;\n\n if (options.signal?.aborted) {\n return { shouldRetry: false, delayMs: 0, reason: 'aborted' };\n }\n if (attempt >= options.maxAttempts) {\n return { shouldRetry: false, delayMs: 0, reason: 'max_attempts' };\n }\n if (!isNetworkError && !isRetryable) {\n return { shouldRetry: false, delayMs: 0, reason: 'not_retryable' };\n }\n\n if (typeof serverRetryAfterMs === 'number' && serverRetryAfterMs >= 0) {\n let delayMs = serverRetryAfterMs;\n if (delayMs > ABSOLUTE_MAX_RETRY_AFTER_MS) {\n onWarning?.(`Server Retry-After exceeded ${ABSOLUTE_MAX_RETRY_AFTER_MS}ms; clipping.`);\n delayMs = ABSOLUTE_MAX_RETRY_AFTER_MS;\n }\n return { shouldRetry: true, delayMs, reason: 'rate_limited' };\n }\n\n const delayMs = computeBackoffMs(\n attempt,\n options.baseDelayMs,\n options.maxDelayMs,\n options.jitterFraction,\n );\n return {\n shouldRetry: true,\n delayMs,\n reason: isNetworkError ? 'network_failure' : 'retryable_error',\n };\n}\n\n// Abortable sleep. Resolves at `delayMs`; rejects with an AbortError-shaped\n// DOMException if the signal aborts first.\nexport async function sleep(delayMs: number, signal?: AbortSignal): Promise<void> {\n if (signal?.aborted) {\n throw signalToAbortError(signal);\n }\n await new Promise<void>((resolve, reject) => {\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, delayMs);\n const onAbort = (): void => {\n clearTimeout(timer);\n reject(signalToAbortError(signal));\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nfunction signalToAbortError(signal: AbortSignal | undefined): Error {\n const reason = signal?.reason;\n if (reason instanceof Error) return reason;\n const err = new Error('The operation was aborted.');\n err.name = 'AbortError';\n return err;\n}\n","// Zod schemas for the server response envelopes documented in\n// `docs-internal/agents/01-day1-rfc/01-tool-surface.md` §3.7 and §4.1.\n//\n// All schemas use `.strict()` per 1A.1 convention — unknown fields fail\n// validation loudly rather than passing through silently.\n\nimport { z } from 'zod';\n\nexport const ServerSuccessSchema = <T extends z.ZodTypeAny>(payload: T) =>\n z.object({ data: payload }).strict();\n\n// Match what the server emits: code/message/optional correlationId, retryAfter\n// (seconds), and free-form details. Keep the schema strict so unexpected fields\n// surface as PARSE_ERROR during development rather than silently dropping.\nexport const ServerErrorBodySchema = z\n .object({\n error: z\n .object({\n code: z.string().min(1),\n message: z.string(),\n correlationId: z.string().optional(),\n retryAfter: z.number().int().nonnegative().optional(),\n details: z.unknown().optional(),\n })\n .strict(),\n })\n .strict();\n\nexport type ServerErrorBody = z.infer<typeof ServerErrorBodySchema>;\n","// Workflow-apply orchestration (Phase 4a). The auto-rev-retry algorithm that\n// wraps PATCH /workflows/{id}: try → on a canvas-rev conflict re-fetch the\n// current rev and retry the PATCH once with a fresh idempotency key.\n//\n// This is the pilot for the Phase 4 orchestration-injection pattern: the\n// function takes a REQUIRED ApiClient and the response schemas it needs\n// INJECTED (the SDK stays domain-agnostic and never imports cli/schemas). It is\n// UX-free and disk-free — config resolution, rendering, and exit codes stay in\n// the CLI. See docs-internal/decisions/sdk-orchestration-injection-pattern.md.\n\nimport type { ZodTypeAny } from 'zod';\n\nimport { ApiError } from '../errors/api-error.js';\nimport type { ApiClient } from '../http/client.js';\n\n// Minimal shapes the algorithm reads. The CLI injects richer schemas whose\n// inferred types extend these; the generics carry the precise types back to the\n// caller without the SDK importing any domain schema.\nexport interface MutateResponseShape {\n canvas_rev: number;\n applied: number;\n workflow: unknown;\n}\n\nexport interface DetailRevShape {\n canvas_rev: number;\n}\n\nexport interface ApplyWorkflowWithRetryParams {\n // REQUIRED — there is no config fallback in the SDK. The CLI resolves config\n // and constructs the client before calling.\n client: ApiClient;\n id: string;\n canvasRev: number;\n operations: Record<string, unknown>[];\n idempotencyKey?: string;\n autoRev?: boolean;\n signal?: AbortSignal;\n // Injected by the CLI. Typed ZodTypeAny to match client.request's own\n // responseSchema param (the response data types are carried by the\n // <TMutate>/<TDetail> generics on applyWorkflowWithRetry, not by the schemas).\n schemas: { mutate: ZodTypeAny; detail: ZodTypeAny };\n}\n\nexport interface ApplyWorkflowWithRetryResult<TMutate extends MutateResponseShape> {\n canvasRev: number;\n applied: number;\n workflow: TMutate['workflow'];\n retriedWithRev?: number;\n}\n\nexport async function applyWorkflowWithRetry<\n TMutate extends MutateResponseShape,\n TDetail extends DetailRevShape,\n>(params: ApplyWorkflowWithRetryParams): Promise<ApplyWorkflowWithRetryResult<TMutate>> {\n try {\n return await patch<TMutate>(params);\n } catch (err) {\n if (!(err instanceof ApiError)) throw err;\n\n const isRevConflict =\n err.code === 'CANVAS_REV_MISMATCH' || (err.meta.status === 409 && err.meta.details != null);\n\n if (!isRevConflict || !params.autoRev) throw err;\n\n const snapshot = await params.client.request<TDetail>({\n method: 'GET',\n path: `/workflows/${encodeURIComponent(params.id)}`,\n responseSchema: params.schemas.detail,\n signal: params.signal,\n });\n\n const retryResult = await patch<TMutate>({\n ...params,\n canvasRev: snapshot.canvas_rev,\n // Fresh key — the body changed (different canvas_rev), so reusing the\n // caller's key would trigger IDEMPOTENCY_KEY_CONFLICT.\n idempotencyKey: undefined,\n });\n\n return { ...retryResult, retriedWithRev: snapshot.canvas_rev };\n }\n}\n\nasync function patch<TMutate extends MutateResponseShape>(\n params: ApplyWorkflowWithRetryParams,\n): Promise<ApplyWorkflowWithRetryResult<TMutate>> {\n const data = await params.client.request<TMutate>({\n method: 'PATCH',\n path: `/workflows/${encodeURIComponent(params.id)}`,\n body: {\n canvas_rev: params.canvasRev,\n operations: params.operations,\n },\n idempotencyKey: params.idempotencyKey,\n responseSchema: params.schemas.mutate,\n signal: params.signal,\n });\n\n return {\n canvasRev: data.canvas_rev,\n applied: data.applied,\n workflow: data.workflow,\n };\n}\n","// Upload orchestration (Phase 4b). The buffer-onward half of the two-step asset\n// upload: derive metadata (content-type, sha256, content-hash idempotency key),\n// POST /assets, then PUT the bytes to the signed GCS URL with retry-once.\n//\n// Follows the Phase-4 orchestration-injection pattern: a REQUIRED ApiClient and\n// the response schema INJECTED, UX-free and DISK-free — the bytes arrive as an\n// already-read Buffer (the CLI owns all filesystem I/O). See\n// docs-internal/decisions/sdk-orchestration-injection-pattern.md.\n\nimport { createHash } from 'node:crypto';\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\nimport type { ZodTypeAny } from 'zod';\n\nimport { ApiError } from '../errors/api-error.js';\nimport type { ApiClient } from '../http/client.js';\nimport { generateUploadIdempotencyKey } from '../http/idempotency.js';\n\n// Minimal POST /assets response shape the orchestration reads. The CLI injects\n// the real (strict) UploadResponseSchema; the SDK validates against it and only\n// reads these fields.\nexport interface UploadResponseShape {\n assetId: string;\n uploadUrl: string;\n publicUrl: string;\n deduplicated: boolean;\n}\n\nexport interface UploadAssetParams {\n // REQUIRED — there is no config fallback in the SDK. The CLI resolves config\n // and constructs the client before calling.\n client: ApiClient;\n // INJECTED — the SDK never reads disk. The CLI reads the file and passes bytes.\n content: Buffer;\n // basename, computed CLI-side (a pure string — no filesystem semantics here).\n filename: string;\n // Resolved CLI-side (default `user-uploads`); drives the content-hash key.\n scope: string;\n signal?: AbortSignal;\n // Test seam for the raw GCS PUT (MockAgent), threaded from the CLI.\n putDispatcher?: Dispatcher;\n // Injected UploadResponseSchema (assets.ts stays in the CLI).\n schema: ZodTypeAny;\n}\n\nexport interface UploadAssetResult {\n assetId: string;\n publicUrl: string;\n deduplicated: boolean;\n bytes: number;\n contentHash: string;\n}\n\nexport async function uploadAsset(params: UploadAssetParams): Promise<UploadAssetResult> {\n const contentType = detectContentType(params.filename, params.content);\n const sha = sha256Hex(params.content);\n const contentHash = `sha256:${sha}`;\n const idempotencyKey = generateUploadIdempotencyKey(params.content, params.scope);\n\n // HTTP step 1 — POST /assets via the ApiClient (auth, envelope, schema, retry).\n const response = await params.client.request<UploadResponseShape>({\n method: 'POST',\n path: '/assets',\n body: {\n filename: params.filename,\n contentType,\n sizeBytes: params.content.length,\n contentHash,\n },\n idempotencyKey,\n responseSchema: params.schema,\n signal: params.signal,\n });\n\n if (!response.deduplicated) {\n // §7.1 #2 — On PUT failure we retry once against the SAME signed URL with\n // the SAME bytes. We do NOT re-POST to /assets on PUT failure: if partial\n // bytes already landed, a fresh POST may report `deduplicated:true` and we\n // would skip the PUT entirely, surfacing a publicUrl backed by corrupt or\n // truncated data.\n const first = await tryPut({\n uploadUrl: response.uploadUrl,\n content: params.content,\n contentType,\n signal: params.signal,\n dispatcher: params.putDispatcher,\n });\n if (!first.ok) {\n if (first.kind === 'fatal') {\n throw new ApiError(\n 'STORAGE_UPLOAD_FAILED',\n `Upload to signed URL failed for ${params.filename} (HTTP ${first.status ?? 'unknown'}).`,\n { retryable: false },\n );\n }\n const retry = await tryPut({\n uploadUrl: response.uploadUrl,\n content: params.content,\n contentType,\n signal: params.signal,\n dispatcher: params.putDispatcher,\n });\n if (!retry.ok) {\n throw new ApiError(\n 'STORAGE_UPLOAD_FAILED',\n `Upload to signed URL failed for ${params.filename} after one retry.`,\n { retryable: true },\n );\n }\n }\n }\n\n return {\n assetId: response.assetId,\n publicUrl: response.publicUrl,\n deduplicated: response.deduplicated,\n bytes: params.content.length,\n contentHash,\n };\n}\n\ntype PutOutcome = { ok: true } | { ok: false; kind: 'retryable' | 'fatal'; status?: number };\n\n// HTTP step 2 — raw undici PUT to the signed GCS URL (no auth, no envelope, no\n// zod; GCS returns an empty body on success and a small XML doc on failure).\nasync function tryPut(args: {\n uploadUrl: string;\n content: Buffer;\n contentType: string;\n signal?: AbortSignal;\n dispatcher?: Dispatcher;\n}): Promise<PutOutcome> {\n try {\n const response = await undiciRequest(args.uploadUrl, {\n method: 'PUT',\n body: args.content,\n headers: {\n 'content-type': args.contentType,\n 'content-length': String(args.content.length),\n },\n signal: args.signal,\n dispatcher: args.dispatcher,\n });\n // Drain the body so the connection can be released; ignore the contents.\n await response.body.text();\n const status = response.statusCode;\n if (status >= 200 && status < 300) return { ok: true };\n // 4xx — signed URL is dead (expired, malformed, auth). Re-POSTing risks a\n // deduplicated:true echo that hides corrupt partial bytes, so we surface\n // STORAGE_UPLOAD_FAILED and let the user re-run upload to mint a fresh URL.\n if (status >= 400 && status < 500) return { ok: false, kind: 'fatal', status };\n // 5xx / 3xx — transient; safe to retry against the same URL.\n return { ok: false, kind: 'retryable', status };\n } catch {\n // Network error, socket reset, abort — retryable.\n return { ok: false, kind: 'retryable' };\n }\n}\n\nfunction sha256Hex(content: Buffer): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\n// Magic-number sniffing for the formats Wave 1 care about. Falls back to the\n// extension and then to application/octet-stream. We deliberately do NOT pull\n// in a `mime-types` dependency for one helper.\n//\n// GIF and MP4 are handled inline in detectContentType because they need\n// offset-aware or exact-length checks that don't fit the fixed-prefix model.\nconst MAGIC_NUMBERS: Array<{ contentType: string; prefix: number[] }> = [\n { contentType: 'image/png', prefix: [0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a] },\n { contentType: 'image/jpeg', prefix: [0xff, 0xd8, 0xff] },\n { contentType: 'image/webp', prefix: [0x52, 0x49, 0x46, 0x46] }, // also matches WAV — disambiguated below\n];\n\nconst EXTENSION_FALLBACK: Record<string, string> = {\n png: 'image/png',\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n gif: 'image/gif',\n webp: 'image/webp',\n mp4: 'video/mp4',\n mov: 'video/quicktime',\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n pdf: 'application/pdf',\n txt: 'text/plain',\n json: 'application/json',\n};\n\n// Derives the content type from the bytes (and the filename, used only as a\n// string for the extension fallback — no filesystem access).\nexport function detectContentType(filename: string, content: Buffer): string {\n // GIF: require an exact 6-byte signature so files that merely begin with\n // \"GIF8\" don't get mistyped as image/gif.\n if (content.length >= 6) {\n const head = content.subarray(0, 6).toString('ascii');\n if (head === 'GIF87a' || head === 'GIF89a') return 'image/gif';\n }\n // MP4 / ISO BMFF: the \"ftyp\" box sits at offset 4-8.\n if (content.length >= 12 && content.subarray(4, 8).toString('ascii') === 'ftyp') {\n return 'video/mp4';\n }\n for (const { contentType, prefix } of MAGIC_NUMBERS) {\n if (matchesPrefix(content, prefix)) {\n if (contentType === 'image/webp') {\n // RIFF container — disambiguate WEBP vs WAV via the 4-byte format ID.\n const formatId = content.subarray(8, 12).toString('ascii');\n if (formatId === 'WEBP') return 'image/webp';\n if (formatId === 'WAVE') return 'audio/wav';\n // Unknown RIFF — fall through to extension.\n break;\n }\n return contentType;\n }\n }\n const ext = filename.toLowerCase().split('.').pop();\n if (ext && EXTENSION_FALLBACK[ext]) {\n return EXTENSION_FALLBACK[ext];\n }\n return 'application/octet-stream';\n}\n\nfunction matchesPrefix(content: Buffer, prefix: number[]): boolean {\n if (content.length < prefix.length) return false;\n for (let i = 0; i < prefix.length; i++) {\n if (content[i] !== prefix[i]) return false;\n }\n return true;\n}\n","// Generation create→wait→result orchestration (Phase 4c). The transport control\n// flow that wraps the generate job lifecycle: POST /jobs, then (if waiting)\n// longPoll the job until it reaches a terminal state, else project the create\n// response into a result.\n//\n// Follows the Phase-4 orchestration-injection pattern: a REQUIRED ApiClient, the\n// response schemas + terminal predicate + create-projection INJECTED, UX-free\n// and DISK-free. Reference-image resolution and request-body shaping stay in the\n// CLI; the SDK receives an already-built body. See\n// docs-internal/decisions/sdk-orchestration-injection-pattern.md.\n\nimport type { ZodTypeAny } from 'zod';\n\nimport type { ApiClient } from '../http/client.js';\nimport { longPoll } from '../long-poll.js';\n\nexport interface WaitForGenerationParams<TResult> {\n client: ApiClient;\n jobId: string;\n timeoutMs: number;\n // Per-round server hold in seconds (the CLI passes SERVER_LONG_POLL_SECONDS).\n serverWaitSeconds: number;\n signal?: AbortSignal;\n // Injected GenerationResultSchema (jobs.ts stays in the CLI).\n resultSchema: ZodTypeAny;\n // Injected; the CLI passes (r) => isTerminalStatus(r.status).\n isTerminal: (result: TResult) => boolean;\n}\n\n// Long-polls GET /jobs/{id}?wait=N until the injected predicate reports terminal\n// (or the overall deadline / abort fires — handled inside longPoll).\nexport function waitForGeneration<TResult>(\n params: WaitForGenerationParams<TResult>,\n): Promise<TResult> {\n return longPoll<TResult>({\n // Forward the iteration signal so the in-flight server hold is aborted as\n // soon as the overall deadline expires — otherwise `--timeout 1` would still\n // block for the full server long-poll round.\n fetcher: (args) =>\n params.client.request<TResult>({\n method: 'GET',\n path: `/jobs/${encodeURIComponent(params.jobId)}`,\n query: { wait: params.serverWaitSeconds },\n responseSchema: params.resultSchema,\n signal: args?.signal,\n }),\n isTerminal: params.isTerminal,\n timeoutMs: params.timeoutMs,\n signal: params.signal,\n });\n}\n\nexport interface CreateGenerationParams<TCreate extends { jobId: string }, TResult> {\n // REQUIRED — there is no config fallback in the SDK. The CLI resolves config\n // and constructs the client before calling.\n client: ApiClient;\n // Already built + validated by the CLI (buildRequestBody) — the SDK never\n // shapes or validates the request, and never resolves reference images.\n body: unknown;\n modelSlug: string;\n wait: boolean;\n timeoutMs: number;\n serverWaitSeconds: number;\n signal?: AbortSignal;\n // Injected GenerateCreateResponseSchema.\n createSchema: ZodTypeAny;\n // Injected GenerationResultSchema (for the wait path).\n resultSchema: ZodTypeAny;\n isTerminal: (result: TResult) => boolean;\n // Injected projection of the create response → result, for the no-wait branch.\n projectCreated: (created: TCreate, modelSlug: string) => TResult;\n // Optional caller-chosen idempotency key for POST /jobs. Omitted, the client\n // mints a fresh one per invocation (reused across its own automatic retries).\n // Supplying the SAME key on a later invocation makes the server replay the\n // original job instead of creating — and charging for — a second one.\n idempotencyKey?: string;\n}\n\nexport async function createGeneration<TCreate extends { jobId: string }, TResult>(\n params: CreateGenerationParams<TCreate, TResult>,\n): Promise<TResult> {\n const created = await params.client.request<TCreate>({\n method: 'POST',\n path: '/jobs',\n body: params.body,\n responseSchema: params.createSchema,\n signal: params.signal,\n idempotencyKey: params.idempotencyKey,\n });\n\n if (!params.wait) {\n return params.projectCreated(created, params.modelSlug);\n }\n\n return waitForGeneration<TResult>({\n client: params.client,\n jobId: created.jobId,\n timeoutMs: params.timeoutMs,\n serverWaitSeconds: params.serverWaitSeconds,\n signal: params.signal,\n resultSchema: params.resultSchema,\n isTerminal: params.isTerminal,\n });\n}\n","// Sparse exit-code mapping for every error the CLI can surface.\n//\n// The 37 RFC codes come from `docs-internal/agents/01-day1-rfc/01-tool-surface.md`\n// §5 (35 server codes) and `02-oauth.md` §2.6 (CREDENTIALS_LOCKED,\n// CREDENTIALS_PERMISSIONS_LOOSE), remapped per Phase 8 Q7 of\n// `wave-1-investigation.md`.\n//\n// 1A.1 introduced five additional codes beyond Q7 — they are mapped here using\n// the same Q7 category semantics: auth (3), permission (4), quota (5),\n// network (6), conflict (7), runtime (1), usage (2), signal (130), success (0).\n//\n// Four CLI-synthetic codes cover failure modes only the client can observe\n// (network errors after retries exhausted, abort timeouts, parse failures,\n// schema mismatches).\n\nimport type { ApiErrorCode } from '@clickraft/sdk';\n\nimport type { AuthErrorCode } from '../auth/errors.js';\n\n// The server/client error-code taxonomy now lives in @clickraft/sdk. Re-export\n// both so existing `from '../errors/codes.js'` importers keep resolving.\n// AllErrorCode stays CLI-side (AuthErrorCode is CLI-only); it composes the SDK's\n// ApiErrorCode (= ServerErrorCode | ClientErrorCode) with the auth codes,\n// preserving the exact same membership as the previous three-way union.\nexport type { ClientErrorCode, ServerErrorCode } from '@clickraft/sdk';\n\nexport type AllErrorCode = ApiErrorCode | AuthErrorCode;\n\nexport type ExitCode = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 130;\n\nexport type ErrorCategory =\n | 'success'\n | 'runtime'\n | 'usage'\n | 'auth'\n | 'permission'\n | 'quota'\n | 'network'\n | 'conflict'\n | 'signal';\n\nexport interface ExitCodeMapping {\n exitCode: ExitCode;\n category: ErrorCategory;\n retryable: boolean;\n hint?: string;\n}\n\nconst LOGIN_HINT = 'Run `clickraft login` to authenticate.';\nconst RELOGIN_HINT = 'Run `clickraft login` to refresh.';\n\nexport const EXIT_CODE_MAP: Record<AllErrorCode, ExitCodeMapping> = {\n // --- 37 Phase 8 Q7 codes ----------------------------------------------------\n AUTH_TOKEN_MISSING: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Set `CLICKRAFT_TOKEN` or run `clickraft login`.',\n },\n AUTH_TOKEN_INVALID: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'The token is malformed or unknown. Run `clickraft login`.',\n },\n AUTH_TOKEN_EXPIRED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: RELOGIN_HINT,\n },\n AUTH_TOKEN_REVOKED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Token was revoked. Run `clickraft login` to mint a new one.',\n },\n AUTH_TOKEN_SCOPE_INSUFFICIENT: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'This token does not have the required scope. Re-run `clickraft login` selecting the needed scopes.',\n },\n AUTH_ORG_MISMATCH: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: \"This token's org no longer exists or you have been removed.\",\n },\n AUTH_DEVICE_CODE_PENDING: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Continue polling.',\n },\n AUTH_DEVICE_CODE_EXPIRED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Device code expired. Re-run `clickraft login`.',\n },\n AUTH_DEVICE_CODE_SLOW_DOWN: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Increase polling interval (Retry-After).',\n },\n IDEMPOTENCY_KEY_MISSING: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Add `X-Idempotency-Key` header (or `--idempotency-key`).',\n },\n IDEMPOTENCY_KEY_CONFLICT: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'Same key was used with a different request body. Use a new key.',\n },\n PLAN_FEATURE_LOCKED: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'API access is not enabled on your plan. Visit billing settings.',\n },\n PLAN_QUOTA_EXCEEDED: {\n exitCode: 5,\n category: 'quota',\n retryable: false,\n hint: 'Daily API quota exhausted. Wait, or upgrade your plan.',\n },\n INSUFFICIENT_CREDITS: {\n exitCode: 5,\n category: 'quota',\n retryable: false,\n hint: 'Top up credits to retry.',\n },\n CREDIT_DEDUCTION_FAILED: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Could not charge credits. Retry; no charge was made.',\n },\n RATE_LIMITED: {\n exitCode: 5,\n category: 'quota',\n retryable: true,\n hint: 'Slow down. Honor Retry-After.',\n },\n INPUT_INVALID_FORMAT: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Check input format and try again.',\n },\n INPUT_TOO_LONG: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Field exceeded max length.',\n },\n WORKFLOW_VALIDATION_FAILED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Run `workflow validate` for the full list of errors.',\n },\n WORKFLOW_NODE_TYPE_UNKNOWN: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Run `clickraft nodes list` for the current set of node types.',\n },\n CANVAS_REV_MISMATCH: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'The workflow was updated elsewhere. Re-fetch and retry with the current canvas_rev.',\n },\n CANVAS_REV_REQUIRED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Include --canvas-rev or use --auto-rev.',\n },\n WORKER_UNREACHABLE: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Collaboration service temporarily unavailable. Retry.',\n },\n IDEMPOTENCY_IN_PROGRESS: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'A request with this idempotency key is currently in-flight. Retry in a moment.',\n },\n TOKEN_NAME_INVALID: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Agent token name is malformed.',\n },\n WORKFLOW_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'No workflow with that ID in your org.',\n },\n NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Resource not found.',\n },\n NODE_TYPE_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Run `clickraft nodes list` for the current set of node types.',\n },\n FEATURE_DISABLED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'This endpoint is not enabled. Contact support if you believe this is in error.',\n },\n FORBIDDEN: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'Your role does not permit this action.',\n },\n MODEL_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Unknown `modelSlug`. Run `brand-model list` for the current set.',\n },\n PROVIDER_UNAVAILABLE: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Provider is temporarily unavailable. Retry shortly.',\n },\n STORAGE_UPLOAD_FAILED: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Upload failed mid-stream. Retry.',\n },\n STORAGE_QUOTA_EXCEEDED: {\n exitCode: 5,\n category: 'quota',\n retryable: false,\n hint: 'Org storage quota exceeded. Free space or upgrade.',\n },\n GEN_CONTENT_REFUSAL: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'The model declined the request via safety policy.',\n },\n GEN_OUTPUT_SCHEMA_MISMATCH: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Provider returned malformed output. Full refund issued. Retry.',\n },\n GEN_EMPTY_OUTPUT: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Provider returned no usable output. Full refund issued. Retry.',\n },\n GEN_ITEM_COUNT_MISMATCH: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Partial output kept; no refund.',\n },\n AGENT_FINGERPRINT_REJECTED: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'This client identification is not permitted. Contact support.',\n },\n INTERNAL_ERROR: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Server error. Retry; if it persists, contact support with the request ID.',\n },\n CREDENTIALS_LOCKED: {\n exitCode: 1,\n category: 'runtime',\n retryable: true,\n hint: 'Another CLI invocation holds the credentials lock. Retry shortly.',\n },\n CREDENTIALS_PERMISSIONS_LOOSE: {\n exitCode: 0,\n category: 'success',\n retryable: false,\n hint: 'Credentials file mode is wider than 0600; continuing.',\n },\n\n // --- 5 additional codes introduced by 1A.1 ---------------------------------\n AUTH_ACCESS_DENIED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'You denied the OAuth grant. Re-run `clickraft login` to retry.',\n },\n AUTH_FLOW_CANCELLED: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: 'Authentication was cancelled. Re-run `clickraft login`.',\n },\n CREDENTIALS_CORRUPT: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Credentials file is unreadable. Remove it and run `clickraft login`.',\n },\n CREDENTIALS_NOT_FOUND: {\n exitCode: 3,\n category: 'auth',\n retryable: false,\n hint: LOGIN_HINT,\n },\n CREDENTIALS_PROFILE_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'No such profile. Use `clickraft auth profiles` to list available profiles.',\n },\n\n // --- 8 brand model resolution codes -----------------------------------------\n BRAND_MODEL_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'No brand model with that ID. Run `clickraft brand-model list`.',\n },\n BRAND_MODEL_NOT_A_MODEL: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'The specified asset is not a brand model.',\n },\n BRAND_MODEL_NOT_ACTIVE: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Brand model is not active. Check its status in the dashboard.',\n },\n BRAND_MODEL_NO_REFERENCES: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Brand model has no reference images. Upload references first.',\n },\n BRAND_MODEL_POSE_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Requested pose not found. Valid: front, 3/4-right, right, left, 3/4-left, back, approved.',\n },\n BRAND_MODEL_DUPLICATE_ID: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Same brand model ID appears more than once.',\n },\n MODEL_DOES_NOT_SUPPORT_REFERENCES: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'This model does not support brand model references.',\n },\n REFERENCE_LIMIT_EXCEEDED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Too many reference images. Check model limits.',\n },\n\n // --- 8 product reference resolver codes -------------------------------------\n PRODUCT_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'No product with that ID in your org. Run `clickraft product list`.',\n },\n PRODUCT_DUPLICATE_REFERENCE: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Same (productId, imageId) tuple appears twice in the request.',\n },\n PRODUCT_IMAGE_NOT_FOUND: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'imageId does not exist in the product images.',\n },\n PRODUCT_IMAGE_MISMATCH: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'imageId belongs to a different product.',\n },\n PRODUCT_SYNC_ERROR: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: \"Product sync status is 'error'. Re-sync or use a different product.\",\n },\n PRODUCT_DELETED_UPSTREAM: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Product was deleted upstream. Remove it or re-sync.',\n },\n PRODUCT_NO_PRIMARY_IMAGE: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Product has no primary image. Specify --product <id>:<imageId> explicitly.',\n },\n PRODUCT_SOURCE_MANAGED: {\n exitCode: 4,\n category: 'permission',\n retryable: false,\n hint: 'Product is managed by an external integration.',\n },\n\n // --- 5 product create codes (`POST /products`) ------------------------------\n //\n // `lib/errors/app-error.ts` in the app repo annotates the four asset codes\n // \"CLI exit 7\". That is wrong and the app repo is being corrected: exit 7 is\n // the `conflict` category, reserved here for idempotency and canvas-rev\n // conflicts, and none of these are conflicts. Exit-code policy is CLI-side by\n // design (see the SDK's `errors/codes.ts` header), so the mapping below is the\n // authority.\n //\n // The three `usage` codes are all \"the caller named something unusable\", which\n // is exit 2 for MODEL_NOT_FOUND and WORKFLOW_NOT_FOUND already.\n PRODUCT_IMAGE_ASSET_DUPLICATE: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'The same asset id appears more than once in the images list.',\n },\n PRODUCT_IMAGE_ASSET_NOT_FOUND: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'One or more asset ids do not exist in your organization. Upload them first, or check the ids.',\n },\n PRODUCT_IMAGE_ASSET_NOT_IMAGE: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'One or more referenced assets are not images.',\n },\n // Deliberately NOT `usage`. The asset row exists and belongs to the caller;\n // its bytes never landed, which is an upload that half-completed on our side.\n // Retrying the create cannot help — the asset has to be uploaded again — so\n // this is runtime/non-retryable rather than a caller mistake.\n PRODUCT_IMAGE_ASSET_INCOMPLETE: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'An asset has no uploaded bytes. Re-run `clickraft upload` for it, then retry.',\n },\n // `retryable: true` is load-bearing, not decorative: this table is the single\n // source of retryability for the SDK client via `isRetryableServerCode`, so\n // flipping it to false makes the CLI ignore a 503 the server explicitly marked\n // retryable and sent a Retry-After for.\n STORAGE_UNAVAILABLE: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Object storage is temporarily unavailable. Retry with the same idempotency key.',\n },\n\n // --- 4 CLI-synthetic codes --------------------------------------------------\n NETWORK_ERROR: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Network connection failed. Check connectivity and retry.',\n },\n TIMEOUT: {\n exitCode: 6,\n category: 'network',\n retryable: true,\n hint: 'Request timed out. Retry; consider increasing the timeout.',\n },\n PARSE_ERROR: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Server returned an unexpected response. Contact support with the request ID.',\n },\n SCHEMA_MISMATCH: {\n exitCode: 1,\n category: 'runtime',\n retryable: false,\n hint: 'Server response did not match the expected schema. Update the CLI.',\n },\n};\n\n// KNOWN_SERVER_CODES (the allow-list the HTTP client trusts from the server)\n// now lives in @clickraft/sdk, derived from SERVER_ERROR_CODES. It is the\n// server taxonomy exactly — the four CLI-only client codes (NETWORK_ERROR,\n// TIMEOUT, PARSE_ERROR, SCHEMA_MISMATCH) are never valid server `error.code`s.\n\nexport function getMapping(code: AllErrorCode): ExitCodeMapping | undefined {\n return EXIT_CODE_MAP[code];\n}\n\nexport function getExitCode(code: AllErrorCode): ExitCode {\n return EXIT_CODE_MAP[code]?.exitCode ?? 1;\n}\n\nexport function getHint(code: AllErrorCode): string | undefined {\n return EXIT_CODE_MAP[code]?.hint;\n}\n\nexport function isRetryable(code: AllErrorCode): boolean {\n return EXIT_CODE_MAP[code]?.retryable ?? false;\n}\n\n// Phase 8 Q10 — envelope error codes are `E_*` prefixed. Idempotent against\n// already-prefixed input so an upstream caller cannot accidentally produce\n// `E_E_FOO`. Param is widened to `string` because unknown server codes flow\n// through here before being mapped to INTERNAL_ERROR (see S1).\nexport function toEnvelopeCode(code: string): string {\n return code.startsWith('E_') ? code : `E_${code}`;\n}\n\n// SIGINT is delivered as a process signal, not as an AllErrorCode. CLIs map it\n// to exit 130 (POSIX 128 + 2). Kept here as a named constant so callers don't\n// hard-code the number.\nexport const SIGINT_EXIT_CODE: ExitCode = 130;\n","// The HTTP client now lives in @clickraft/sdk (Phase 3). This module re-exports\n// it from its historical path so existing `from '../api/client.js'` importers\n// keep resolving unchanged, and adds the CLI's policy-injecting factory.\n//\n// Retryability and warning emission are CLI policy: the SDK client takes them as\n// injected callbacks. `createApiClient` wires `EXIT_CODE_MAP` (the single source\n// of retryability truth, which stays in the CLI) and a console.warn sink.\n\nimport {\n createClient,\n type ApiClient,\n type CloudflareAccessCredentials,\n type ServerErrorCode,\n} from '@clickraft/sdk';\n\nimport { EXIT_CODE_MAP } from '../errors/codes.js';\n\nexport { ApiClient, ApiError, createClient, parseRetryAfterHeader } from '@clickraft/sdk';\nexport type {\n ApiClientOptions,\n ApiErrorMeta,\n HttpMethod,\n RequestOptions,\n ServerErrorCode,\n} from '@clickraft/sdk';\n\n// SINGLE source of truth for retryability is the CLI's EXIT_CODE_MAP. `code` is\n// always a known ServerErrorCode at the call site (unknown codes are folded to\n// INTERNAL_ERROR before this runs), so the index is total. The HTTP-status\n// fallback for the no-predicate path lives in the SDK client, which has the\n// statusCode this predicate signature deliberately does not.\nexport const isRetryableServerCode = (code: ServerErrorCode): boolean =>\n EXIT_CODE_MAP[code].retryable;\n\nexport const onWarning = (msg: string): void => {\n console.warn(msg);\n};\n\n// Single CLI entry point for constructing a client: maps the resolved config\n// fields onto ApiClientOptions and injects the two policy callbacks. All\n// production construction sites go through this.\nexport function createApiClient(opts: {\n apiBaseUrl: string;\n accessToken: string | null;\n signal?: AbortSignal;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n}): ApiClient {\n return createClient({ ...opts, onWarning, isRetryableServerCode });\n}\n","// Auth + credentials error codes used by 1A.1. The full 37-code map and the\n// mapping to sparse exit codes (0-7, 130) lands in 1A.2 — see\n// wave-1-investigation.md Phase 8 Q7.\n//\n// AUTH_FLOW_CANCELLED extends the catalog in 02-oauth.md §6.1 to cover\n// AbortSignal-driven cancellation of the device-flow loop.\nexport type AuthErrorCode =\n | 'AUTH_TOKEN_MISSING'\n | 'AUTH_TOKEN_INVALID'\n | 'AUTH_TOKEN_EXPIRED'\n | 'AUTH_TOKEN_REVOKED'\n | 'AUTH_DEVICE_CODE_PENDING'\n | 'AUTH_DEVICE_CODE_EXPIRED'\n | 'AUTH_DEVICE_CODE_SLOW_DOWN'\n | 'AUTH_ACCESS_DENIED'\n | 'AUTH_FLOW_CANCELLED'\n | 'CREDENTIALS_LOCKED'\n | 'CREDENTIALS_PERMISSIONS_LOOSE'\n | 'CREDENTIALS_CORRUPT'\n | 'CREDENTIALS_NOT_FOUND'\n | 'CREDENTIALS_PROFILE_NOT_FOUND';\n\nexport type CredentialsErrorCode = Extract<AuthErrorCode, `CREDENTIALS_${string}`>;\n\nexport class AuthError extends Error {\n public readonly code: AuthErrorCode;\n public override readonly cause?: unknown;\n\n constructor(code: AuthErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'AuthError';\n this.code = code;\n this.cause = cause;\n }\n}\n\nexport class CredentialsError extends Error {\n public readonly code: CredentialsErrorCode;\n public override readonly cause?: unknown;\n\n constructor(code: CredentialsErrorCode, message: string, cause?: unknown) {\n super(message);\n this.name = 'CredentialsError';\n this.code = code;\n this.cause = cause;\n }\n}\n","// CLI-side {ok,data,error,meta} envelope per Phase 8 Q6 of\n// `wave-1-investigation.md`. The envelope is applied only at the `--json`\n// output layer — server endpoints continue to return `{ data: T }` /\n// `{ error: { ... } }` per `01-tool-surface.md` §3.7.\n//\n// Envelope error codes carry the `E_*` prefix per Phase 8 Q10 (\"Stable\n// E_* codes are public API\"). `retry_after_ms` lives inside `error`, not\n// `meta`, per the Phase 8 Q6 example.\n\nimport { AuthError, CredentialsError, type AuthErrorCode } from '../auth/errors.js';\nimport { EXIT_CODE_MAP, toEnvelopeCode, type AllErrorCode } from '../errors/codes.js';\n\nimport { ApiError } from './client.js';\n\nexport interface EnvelopeMeta {\n request_id?: string;\n command: string;\n version: string;\n duration_ms: number;\n next_cursor?: string;\n}\n\nexport interface SuccessEnvelope<T> {\n ok: true;\n data: T;\n error: null;\n meta: EnvelopeMeta;\n}\n\nexport interface EnvelopeErrorPayload {\n code: string;\n message: string;\n retryable: boolean;\n retry_after_ms?: number;\n request_id?: string;\n hint?: string;\n details?: unknown;\n}\n\nexport interface ErrorEnvelope {\n ok: false;\n data: null;\n error: EnvelopeErrorPayload;\n meta: EnvelopeMeta;\n}\n\nexport type Envelope<T> = SuccessEnvelope<T> | ErrorEnvelope;\n\nexport interface EnvelopeContext {\n startMs: number;\n command: string;\n version: string;\n requestId?: string;\n nextCursor?: string;\n}\n\nexport function wrapSuccess<T>(data: T, ctx: EnvelopeContext): SuccessEnvelope<T> {\n const meta: EnvelopeMeta = {\n command: ctx.command,\n version: ctx.version,\n duration_ms: Math.max(0, Date.now() - ctx.startMs),\n };\n if (ctx.requestId) meta.request_id = ctx.requestId;\n if (ctx.nextCursor) meta.next_cursor = ctx.nextCursor;\n return { ok: true, data, error: null, meta };\n}\n\nexport function wrapError(err: unknown, ctx: EnvelopeContext): ErrorEnvelope {\n const payload = errorToEnvelopePayload(err);\n const meta: EnvelopeMeta = {\n command: ctx.command,\n version: ctx.version,\n duration_ms: Math.max(0, Date.now() - ctx.startMs),\n };\n if (payload.request_id ?? ctx.requestId) {\n meta.request_id = payload.request_id ?? ctx.requestId;\n }\n return { ok: false, data: null, error: payload, meta };\n}\n\nfunction errorToEnvelopePayload(err: unknown): EnvelopeErrorPayload {\n if (err instanceof ApiError) {\n return buildPayload({\n code: err.code,\n message: err.message,\n retryable: err.meta.retryable,\n retryAfterMs: err.meta.retryAfterMs,\n requestId: err.meta.requestId,\n details: err.meta.details,\n hint: err.meta.hint,\n });\n }\n if (err instanceof AuthError || err instanceof CredentialsError) {\n const code = err.code as AuthErrorCode;\n const mapping = EXIT_CODE_MAP[code];\n return buildPayload({\n code,\n message: err.message,\n retryable: mapping?.retryable ?? false,\n });\n }\n // Unknown error — fall back to INTERNAL_ERROR.\n const message = err instanceof Error ? err.message : String(err);\n return buildPayload({\n code: 'INTERNAL_ERROR' as AllErrorCode,\n message,\n retryable: false,\n });\n}\n\nfunction buildPayload(args: {\n code: AllErrorCode;\n message: string;\n retryable: boolean;\n retryAfterMs?: number;\n requestId?: string;\n details?: unknown;\n hint?: string;\n}): EnvelopeErrorPayload {\n const mapping = EXIT_CODE_MAP[args.code];\n const payload: EnvelopeErrorPayload = {\n code: toEnvelopeCode(args.code),\n message: args.message,\n retryable: args.retryable,\n };\n if (typeof args.retryAfterMs === 'number') payload.retry_after_ms = args.retryAfterMs;\n if (args.requestId) payload.request_id = args.requestId;\n const resolvedHint = args.hint ?? mapping?.hint;\n if (resolvedHint) payload.hint = resolvedHint;\n if (args.details != null) payload.details = args.details;\n return payload;\n}\n","import {\n access,\n chmod,\n mkdir,\n readFile,\n rename,\n rm,\n stat,\n unlink,\n writeFile,\n} from 'node:fs/promises';\nimport { dirname } from 'node:path';\n\nimport * as lockfile from 'proper-lockfile';\n\nimport { getCredentialsPath } from '../config/paths.js';\n\nimport { CredentialsError } from './errors.js';\nimport {\n CredentialsFileSchema,\n CredentialsProfileSchema,\n type CredentialsFile,\n type CredentialsProfile,\n} from './types.js';\n\n// proper-lockfile substitutes for the POSIX flock contract described in\n// 02-oauth.md §2.6. It uses mkdir-based locking (a `<path>.lock/` directory\n// adjacent to the target) rather than fcntl/flock, which makes it work\n// uniformly across Linux, macOS, and Windows. The functional outcome —\n// mutual exclusion + atomic-rename writes — is preserved.\n//\n// `realpath: false` is required so we can lock a not-yet-existent file\n// during first write (proper-lockfile's default resolves realpath and\n// fails on ENOENT). Retry budget caps at ~3.8s, well under the 5s\n// CREDENTIALS_LOCKED threshold.\n//\n// `stale: 5000` matches the spec's ≤5s lock-acquisition budget — a holder\n// killed mid-write (SIGKILL / OOM) won't strand the lock for 10s (default).\n// `update: 2000` makes live holders refresh their lock mtime every 2s, well\n// inside the stale window, so a healthy process is never mistaken for dead.\nconst LOCK_OPTS = {\n retries: { retries: 10, factor: 1.5, minTimeout: 100, maxTimeout: 500 },\n realpath: false,\n stale: 5000,\n update: 2000,\n} as const;\n\nconst IS_WINDOWS = process.platform === 'win32';\n\nexport async function readCredentials(path?: string): Promise<CredentialsFile | null> {\n const target = path ?? getCredentialsPath();\n\n try {\n await access(target);\n } catch {\n return null;\n }\n\n if (!IS_WINDOWS) {\n try {\n const s = await stat(target);\n if ((s.mode & 0o077) !== 0) {\n const modeStr = (s.mode & 0o777).toString(8).padStart(3, '0');\n console.warn(\n `[clickraft] credentials file at ${target} has loose permissions (mode ${modeStr}). ` +\n `Run \\`chmod 600 ${target}\\` to restrict it.`,\n );\n }\n } catch {\n // stat failure shouldn't block reading\n }\n }\n\n return parseCredentialsFile(await readFile(target, 'utf8'), target);\n}\n\nexport async function writeCredentials(file: CredentialsFile, path?: string): Promise<void> {\n const target = path ?? getCredentialsPath();\n const validated = validateFile(file);\n await withLock(target, async () => {\n await writeAtomic(target, serialize(validated));\n });\n}\n\nexport async function setProfile(\n name: string,\n profile: CredentialsProfile,\n path?: string,\n): Promise<void> {\n const target = path ?? getCredentialsPath();\n const validatedProfile = validateProfile(profile);\n await withLock(target, async () => {\n const current = (await readUnderLock(target)) ?? {\n version: 1 as const,\n defaultProfile: name,\n profiles: {},\n };\n current.profiles[name] = validatedProfile;\n await writeAtomic(target, serialize(current));\n });\n}\n\nexport async function removeProfile(name: string, path?: string): Promise<void> {\n const target = path ?? getCredentialsPath();\n await withLock(target, async () => {\n const current = await readUnderLock(target);\n if (!current) {\n throw new CredentialsError(\n 'CREDENTIALS_NOT_FOUND',\n `No credentials file at ${target}; nothing to remove.`,\n );\n }\n if (!(name in current.profiles)) {\n throw new CredentialsError(\n 'CREDENTIALS_PROFILE_NOT_FOUND',\n `Profile \"${name}\" not found in credentials file.`,\n );\n }\n delete current.profiles[name];\n if (current.defaultProfile === name) {\n const remaining = Object.keys(current.profiles);\n current.defaultProfile = remaining[0] ?? '';\n }\n await writeAtomic(target, serialize(current));\n });\n}\n\nexport async function deleteCredentials(path?: string): Promise<void> {\n const target = path ?? getCredentialsPath();\n await withLock(target, async () => {\n try {\n await rm(target);\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n }\n });\n}\n\nasync function withLock<T>(target: string, fn: () => Promise<T>): Promise<T> {\n await ensureDir(dirname(target));\n let release: () => Promise<void>;\n try {\n release = await lockfile.lock(target, LOCK_OPTS);\n } catch (err) {\n throw new CredentialsError(\n 'CREDENTIALS_LOCKED',\n `Failed to acquire exclusive lock on ${target}. ` +\n `Another clickraft process may be holding it; retry shortly.`,\n err,\n );\n }\n try {\n return await fn();\n } finally {\n try {\n await release();\n } catch {\n // best-effort release; the lock dir will be cleaned up by proper-lockfile's stale detection\n }\n }\n}\n\nasync function readUnderLock(target: string): Promise<CredentialsFile | null> {\n try {\n await access(target);\n } catch {\n return null;\n }\n return parseCredentialsFile(await readFile(target, 'utf8'), target);\n}\n\nfunction validateFile(file: CredentialsFile): CredentialsFile {\n const result = CredentialsFileSchema.safeParse(file);\n if (!result.success) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n 'Refusing to write credentials file: input failed schema validation.',\n result.error,\n );\n }\n return result.data;\n}\n\nfunction validateProfile(profile: CredentialsProfile): CredentialsProfile {\n const result = CredentialsProfileSchema.safeParse(profile);\n if (!result.success) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n 'Refusing to write credentials profile: input failed schema validation.',\n result.error,\n );\n }\n return result.data;\n}\n\nfunction parseCredentialsFile(raw: string, target: string): CredentialsFile {\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n `credentials file at ${target} is not valid JSON. Run \\`clickraft login\\` to re-authenticate.`,\n err,\n );\n }\n const result = CredentialsFileSchema.safeParse(parsed);\n if (!result.success) {\n throw new CredentialsError(\n 'CREDENTIALS_CORRUPT',\n `credentials file at ${target} has an unexpected shape. Run \\`clickraft login\\` to re-authenticate.`,\n result.error,\n );\n }\n return result.data;\n}\n\nasync function ensureDir(dir: string): Promise<void> {\n const opts = IS_WINDOWS ? { recursive: true } : { recursive: true, mode: 0o700 };\n await mkdir(dir, opts);\n}\n\nasync function writeAtomic(target: string, payload: string): Promise<void> {\n const tmp = `${target}.tmp`;\n const writeOpts = IS_WINDOWS\n ? { encoding: 'utf8' as const }\n : { encoding: 'utf8' as const, mode: 0o600 };\n await writeFile(tmp, payload, writeOpts);\n try {\n if (!IS_WINDOWS) {\n // chmod is idempotent and guards against umask-induced mode drift\n // on filesystems where the writeFile mode flag is advisory only.\n await chmod(tmp, 0o600);\n }\n await rename(tmp, target);\n } catch (err) {\n try {\n await unlink(tmp);\n } catch {\n // best-effort cleanup\n }\n throw err;\n }\n}\n\nfunction serialize(file: CredentialsFile): string {\n return JSON.stringify(file, null, 2) + '\\n';\n}\n","import { homedir } from 'node:os';\nimport { join } from 'node:path';\n\n// Resolved per 02-oauth.md §2.6 + XDG Base Directory Specification.\n// 1. XDG_CONFIG_HOME (if set) → $XDG_CONFIG_HOME/clickraft\n// 2. Windows → %APPDATA%/clickraft (fallback: <home>/AppData/Roaming/clickraft)\n// 3. Otherwise (Linux/macOS) → ~/.config/clickraft\n\nexport interface PathResolutionContext {\n env?: NodeJS.ProcessEnv;\n platform?: NodeJS.Platform;\n home?: string;\n}\n\nconst CREDENTIALS_FILE = 'credentials.json';\nconst APP_DIR = 'clickraft';\n\nexport function getConfigDir(ctx: PathResolutionContext = {}): string {\n const env = ctx.env ?? process.env;\n const platform = ctx.platform ?? process.platform;\n const home = ctx.home ?? homedir();\n\n const xdg = env.XDG_CONFIG_HOME;\n if (xdg && xdg.length > 0) {\n return join(xdg, APP_DIR);\n }\n\n if (platform === 'win32') {\n const appData = env.APPDATA;\n if (appData && appData.length > 0) {\n return join(appData, APP_DIR);\n }\n return join(home, 'AppData', 'Roaming', APP_DIR);\n }\n\n return join(home, '.config', APP_DIR);\n}\n\nexport function getCredentialsPath(ctx: PathResolutionContext = {}): string {\n return join(getConfigDir(ctx), CREDENTIALS_FILE);\n}\n","import { z } from 'zod';\n\n// OAuth 2.0 Device Authorization Grant (RFC 8628) request/response shapes.\n// Source of truth: 02-oauth.md §3.1.\n\nexport const DeviceAuthorizationRequestSchema = z.object({\n client_id: z.string(),\n scope: z.string(),\n});\nexport type DeviceAuthorizationRequest = z.infer<typeof DeviceAuthorizationRequestSchema>;\n\n// `verification_uri_complete` is OPTIONAL per RFC 8628 §3.2; `interval`\n// defaults to 5 seconds when absent per §3.5. `user_code` is intentionally\n// unstructured: RFC 8628 §6.1 leaves the format to the server, so the CLI\n// only checks it is non-empty.\nexport const DeviceAuthorizationResponseSchema = z.object({\n device_code: z.string(),\n user_code: z.string().min(1),\n verification_uri: z.string().url(),\n verification_uri_complete: z.string().url().optional(),\n expires_in: z.number().int().positive(),\n interval: z.number().int().positive().default(5),\n});\nexport type DeviceAuthorizationResponse = z.infer<typeof DeviceAuthorizationResponseSchema>;\n\nexport const DeviceTokenPollRequestSchema = z.object({\n client_id: z.string(),\n device_code: z.string(),\n grant_type: z.literal('urn:ietf:params:oauth:grant-type:device_code'),\n});\nexport type DeviceTokenPollRequest = z.infer<typeof DeviceTokenPollRequestSchema>;\n\nexport const TokenResponseSchema = z.object({\n access_token: z.string(),\n token_type: z.literal('Bearer'),\n expires_in: z.number().int().positive(),\n scope: z.string(),\n});\nexport type TokenResponse = z.infer<typeof TokenResponseSchema>;\n\nexport const DeviceTokenPollErrorCodeSchema = z.enum([\n 'authorization_pending',\n 'slow_down',\n 'access_denied',\n 'expired_token',\n 'invalid_client',\n 'invalid_grant',\n 'unauthorized_client',\n 'unsupported_grant_type',\n 'invalid_scope',\n]);\nexport type DeviceTokenPollErrorCode = z.infer<typeof DeviceTokenPollErrorCodeSchema>;\n\nexport const DeviceTokenPollErrorSchema = z.object({\n error: DeviceTokenPollErrorCodeSchema,\n error_description: z.string().optional(),\n});\nexport type DeviceTokenPollError = z.infer<typeof DeviceTokenPollErrorSchema>;\n\n// Credentials file shape. Source of truth: 02-oauth.md §2.6.\n// No refreshToken field — 90-day access tokens only per 02-oauth.md §2.5.\n\nexport const CredentialsProfileSchema = z\n .object({\n apiBaseUrl: z.string().url(),\n accessToken: z.string(),\n tokenType: z.literal('Bearer'),\n tokenPrefix: z.string(),\n organizationId: z.string().uuid(),\n organizationSlug: z.string(),\n userId: z.string().uuid(),\n scopes: z.array(z.string()),\n expiresAt: z.string().datetime(),\n issuedAt: z.string().datetime(),\n clientId: z.string(),\n })\n .strict();\nexport type CredentialsProfile = z.infer<typeof CredentialsProfileSchema>;\n\nexport const CredentialsFileSchema = z\n .object({\n version: z.literal(1),\n defaultProfile: z.string(),\n profiles: z.record(z.string(), CredentialsProfileSchema),\n })\n .strict();\nexport type CredentialsFile = z.infer<typeof CredentialsFileSchema>;\n","import type { CloudflareAccessCredentials } from '@clickraft/sdk';\n\nimport { ApiError } from '../api/client.js';\nimport { readCredentials } from '../auth/credentials.js';\n\nimport { getCredentialsPath } from './paths.js';\n\n// Per-field precedence ladder per wave-1-investigation.md Phase 8 Q4:\n// accessToken : --token → CLICKRAFT_TOKEN → profile.accessToken → null\n// profileName : --profile → CLICKRAFT_PROFILE → file.defaultProfile → \"default\"\n// apiBaseUrl : --api-base-url → CLICKRAFT_API_BASE_URL → profile.apiBaseUrl → DEFAULT_API_BASE_URL\n//\n// The credentials file is read only when at least one field still needs to\n// resolve from it after flag/env are applied.\n\nexport const DEFAULT_API_BASE_URL = 'https://clickraft.ai/api/agents/v1';\nexport const DEFAULT_PROFILE_NAME = 'default';\n\nexport const TOKEN_ENV_VAR = 'CLICKRAFT_TOKEN';\nexport const PROFILE_ENV_VAR = 'CLICKRAFT_PROFILE';\nexport const API_BASE_URL_ENV_VAR = 'CLICKRAFT_API_BASE_URL';\n// Telemetry implementation lands in 1A.3+; the var name is fixed here so all\n// modules import the same constant. Source: PR #104 S1 fix.\nexport const TELEMETRY_DISABLE_ENV_VAR = 'CLICKRAFT_DISABLE_TELEMETRY';\n\nexport const CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR = 'CLOUDFLARE_ACCESS_CLIENT_ID';\nexport const CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR = 'CLOUDFLARE_ACCESS_CLIENT_SECRET';\n\nexport interface ConfigLoaderOptions {\n flagToken?: string;\n flagProfile?: string;\n flagApiBaseUrl?: string;\n env?: NodeJS.ProcessEnv;\n credentialsPath?: string;\n}\n\nexport interface ResolvedConfig {\n accessToken: string | null;\n profileName: string;\n apiBaseUrl: string;\n cloudflareAccess: CloudflareAccessCredentials | null;\n /**\n * Scopes recorded when THIS token was minted, or `null` when unknown.\n *\n * Populated only when `accessToken` came from the credentials file. A token\n * supplied via `--token` or `CLICKRAFT_TOKEN` has no recorded scopes, and\n * pairing it with the file profile's scopes would answer a question about one\n * token using facts about a different one — so `null`, and callers must treat\n * that as \"cannot check\" rather than \"has nothing\".\n *\n * This is a SNAPSHOT from login, not live truth: scopes can be revoked or\n * widened server-side afterwards. It is good enough to fail fast before a\n * request, never good enough to authorize one. The server's 403 remains the\n * authority (see `assertScope`).\n */\n scopes: string[] | null;\n}\n\nexport async function loadConfig(options: ConfigLoaderOptions = {}): Promise<ResolvedConfig> {\n const env = options.env ?? process.env;\n\n // Validate Cloudflare Access service-token pair before any other work so\n // a misconfigured env fails fast, before file IO or network.\n const cloudflareAccess = loadCloudflareAccess(env);\n\n const flagToken = trim(options.flagToken);\n const envToken = trim(env[TOKEN_ENV_VAR]);\n const flagProfile = trim(options.flagProfile);\n const envProfile = trim(env[PROFILE_ENV_VAR]);\n const flagApiBaseUrl = trim(options.flagApiBaseUrl);\n const envApiBaseUrl = trim(env[API_BASE_URL_ENV_VAR]);\n\n // Determine profile name first — it gates which profile we read from file.\n const profileName = flagProfile ?? envProfile;\n\n // If every field can resolve without the file, skip the read entirely.\n const tokenFromFlagOrEnv = flagToken ?? envToken;\n const apiBaseFromFlagOrEnv = flagApiBaseUrl ?? envApiBaseUrl;\n const needsFile = !tokenFromFlagOrEnv || !apiBaseFromFlagOrEnv || !profileName;\n\n let fileProfileName: string | undefined;\n let fileAccessToken: string | undefined;\n let fileApiBaseUrl: string | undefined;\n let fileScopes: string[] | undefined;\n\n if (needsFile) {\n const path = options.credentialsPath ?? getCredentialsPath();\n const file = await readCredentials(path);\n if (file) {\n const resolvedName = profileName ?? file.defaultProfile ?? DEFAULT_PROFILE_NAME;\n fileProfileName = file.defaultProfile;\n const profile = file.profiles[resolvedName];\n if (profile) {\n fileAccessToken = profile.accessToken;\n fileApiBaseUrl = profile.apiBaseUrl;\n fileScopes = profile.scopes;\n }\n }\n }\n\n return {\n accessToken: tokenFromFlagOrEnv ?? fileAccessToken ?? null,\n profileName: profileName ?? fileProfileName ?? DEFAULT_PROFILE_NAME,\n apiBaseUrl: apiBaseFromFlagOrEnv ?? fileApiBaseUrl ?? DEFAULT_API_BASE_URL,\n cloudflareAccess,\n // Scopes describe the FILE's token. If the flag/env token won the\n // precedence ladder above, the scopes we happen to have on disk belong to a\n // different credential, so report `null` rather than something plausible\n // and wrong.\n scopes: tokenFromFlagOrEnv ? null : (fileScopes ?? null),\n };\n}\n\nfunction loadCloudflareAccess(env: NodeJS.ProcessEnv): CloudflareAccessCredentials | null {\n const clientId = trim(env[CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR]);\n const clientSecret = trim(env[CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR]);\n\n if (clientId && clientSecret) {\n return { clientId, clientSecret };\n }\n if (!clientId && !clientSecret) {\n return null;\n }\n\n const onlySet = clientId\n ? CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR\n : CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR;\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `${CLOUDFLARE_ACCESS_CLIENT_ID_ENV_VAR} and ${CLOUDFLARE_ACCESS_CLIENT_SECRET_ENV_VAR} must both be set, or neither. Got only ${onlySet}.`,\n { retryable: false },\n );\n}\n\nfunction trim(value: string | undefined): string | undefined {\n if (value === undefined) return undefined;\n const t = value.trim();\n return t.length === 0 ? undefined : t;\n}\n","import { BalanceResponseSchema, type BalanceData } from '@clickraft/sdk';\n\nimport { createApiClient, type ApiClient } from '../api/client.js';\nimport { AuthError } from '../auth/errors.js';\nimport { loadConfig } from '../config/loader.js';\n\nexport interface BalanceOptions {\n profile?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nexport async function getBalance(options: BalanceOptions): Promise<BalanceData> {\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const data = await client.request<BalanceData>({\n method: 'GET',\n path: '/balance',\n responseSchema: BalanceResponseSchema,\n signal: options.signal,\n });\n\n return data;\n}\n","import { BrandModelsListResponseSchema, type BrandModelSummary } from '@clickraft/sdk';\nimport { z } from 'zod';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface BrandModelListOptions {\n profile?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nexport async function listBrandModels(\n options: BrandModelListOptions,\n): Promise<BrandModelSummary[]> {\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const data = await client.request<z.infer<typeof BrandModelsListResponseSchema>>({\n method: 'GET',\n path: '/brand-models',\n responseSchema: BrandModelsListResponseSchema,\n signal: options.signal,\n });\n\n return data.brandModels;\n}\n","// `clickraft upload <file-path>` — uploads a local file to the Agents API.\n//\n// Two-step flow per RFC §4.6 (POST /assets metadata + PUT bytes to the signed\n// GCS URL with retry-once). As of Phase 4b the buffer-onward orchestration lives\n// in @clickraft/sdk (uploadAsset); this module is the thin CLI wrapper that owns\n// the filesystem side: stat → size validation → read → fs-error mapping, then\n// hands the Buffer to the SDK with the client + injected response schema.\n\nimport { readFile, stat } from 'node:fs/promises';\nimport { basename } from 'node:path';\n\nimport { uploadAsset, MAX_UPLOAD_SIZE_BYTES, UploadResponseSchema } from '@clickraft/sdk';\nimport { type Dispatcher } from 'undici';\n\nimport { ApiError, createApiClient, type ApiClient } from '../api/client.js';\nimport { loadConfig } from '../config/loader.js';\n\nexport const DEFAULT_UPLOAD_SCOPE = 'user-uploads';\n\nexport interface UploadOptions {\n filePath: string;\n scope?: string;\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n // Injected when the caller (e.g. `generate create` for path auto-upload)\n // already has an ApiClient; saves a redundant config + client construction.\n client?: ApiClient;\n // Injected for testing the GCS PUT against MockAgent without an extra round\n // of undici plumbing. Threaded through to the SDK upload orchestration.\n putDispatcher?: Dispatcher;\n}\n\nexport interface UploadResult {\n assetId: string;\n publicUrl: string;\n deduplicated: boolean;\n bytes: number;\n contentHash: string;\n}\n\n// Public entry — used by `clickraft upload` (CLI command) and by\n// generate/create's reference-image path auto-upload.\nexport async function uploadFile(opts: UploadOptions): Promise<UploadResult> {\n const scope = opts.scope ?? DEFAULT_UPLOAD_SCOPE;\n // stat() first so oversized files are rejected before we buffer them and\n // so missing/EISDIR/EACCES surface as INPUT_INVALID_FORMAT (exit 2) rather\n // than propagating as INTERNAL_ERROR (exit 1).\n const size = await safeStatSize(opts.filePath);\n validateSize(size);\n const content = await safeReadFile(opts.filePath);\n\n const client = opts.client ?? (await buildClient(opts));\n\n // Disk work is done — hand the bytes to the SDK orchestration (POST /assets +\n // PUT-to-GCS with retry-once). The SDK never reads disk.\n return uploadAsset({\n client,\n content,\n filename: basename(opts.filePath),\n scope,\n signal: opts.signal,\n putDispatcher: opts.putDispatcher,\n schema: UploadResponseSchema,\n });\n}\n\nasync function buildClient(opts: UploadOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n\nasync function safeStatSize(filePath: string): Promise<number> {\n let stats;\n try {\n stats = await stat(filePath);\n } catch (err) {\n throw toFsApiError(err, filePath);\n }\n if (stats.isDirectory()) {\n throw new ApiError('INPUT_INVALID_FORMAT', `Expected a file, got a directory: ${filePath}`, {\n retryable: false,\n });\n }\n if (!stats.isFile()) {\n throw new ApiError('INPUT_INVALID_FORMAT', `Expected a regular file: ${filePath}`, {\n retryable: false,\n });\n }\n return stats.size;\n}\n\nasync function safeReadFile(filePath: string): Promise<Buffer> {\n try {\n return await readFile(filePath);\n } catch (err) {\n throw toFsApiError(err, filePath);\n }\n}\n\nfunction toFsApiError(err: unknown, filePath: string): unknown {\n if (err instanceof Error && 'code' in err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') {\n return new ApiError('INPUT_INVALID_FORMAT', `File not found: ${filePath}`, {\n retryable: false,\n });\n }\n if (code === 'EISDIR') {\n return new ApiError('INPUT_INVALID_FORMAT', `Expected a file, got a directory: ${filePath}`, {\n retryable: false,\n });\n }\n if (code === 'EACCES' || code === 'EPERM') {\n return new ApiError('INPUT_INVALID_FORMAT', `Permission denied: ${filePath}`, {\n retryable: false,\n });\n }\n }\n return err;\n}\n\nfunction validateSize(bytes: number): void {\n if (bytes === 0) {\n throw new ApiError('INPUT_INVALID_FORMAT', 'Refusing to upload an empty file.', {\n retryable: false,\n });\n }\n if (bytes > MAX_UPLOAD_SIZE_BYTES) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `File is ${bytes} bytes; the upload endpoint caps at ${MAX_UPLOAD_SIZE_BYTES} bytes.`,\n { retryable: false },\n );\n }\n}\n","// Shared helpers for the `generate` command family.\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface GenerateClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildGenerateClient(opts: GenerateClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n\n// Returns true for absolute http(s) URLs only. Everything else (ftp://, data:,\n// mailto:, file://, plus all filesystem paths) is treated as a local path and\n// routed through the upload primitive. The server only accepts http(s)\n// reference images, so accepting other schemes here would just defer the\n// failure into the API round-trip.\nexport function isUrlLike(value: string): boolean {\n return value.startsWith('http://') || value.startsWith('https://');\n}\n","// `clickraft generate wait <jobId>` — long-polls until the job reaches a\n// terminal state (completed / failed / cancelled) or the overall timeout\n// elapses.\n//\n// As of Phase 4c the long-poll orchestration lives in @clickraft/sdk\n// (waitForGeneration, built on the SDK longPoll); this module is the thin CLI\n// wrapper that resolves config+client and injects the result schema + terminal\n// predicate. Each wait round is a `?wait=30` request (RFC §4.4 + Phase 8 Q9).\n\nimport {\n waitForGeneration,\n GenerationResultSchema,\n isTerminalStatus,\n type GenerationResult,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildGenerateClient, type GenerateClientOptions } from './internal.js';\n\nexport const DEFAULT_WAIT_TIMEOUT_SECONDS = 120;\nexport const SERVER_LONG_POLL_SECONDS = 30;\n\nexport interface GenerateWaitOptions extends GenerateClientOptions {\n jobId: string;\n timeoutSeconds?: number;\n client?: ApiClient;\n}\n\nexport async function generateWait(opts: GenerateWaitOptions): Promise<GenerationResult> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n return waitForGeneration<GenerationResult>({\n client,\n jobId: opts.jobId,\n timeoutMs: (opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS) * 1000,\n serverWaitSeconds: SERVER_LONG_POLL_SECONDS,\n signal: opts.signal,\n resultSchema: GenerationResultSchema,\n isTerminal: (r) => isTerminalStatus(r.status),\n });\n}\n","// `clickraft generate create` — submits a generation job and (by default)\n// waits up to 120s for completion via the server long-poll mechanism. Per\n// Phase 8 Q9 of `wave-1-investigation.md` and RFC §4.4, each wait round is a\n// `?wait=30` request to the server.\n//\n// Reference images may be supplied as URLs (sent verbatim) or as local paths\n// (auto-uploaded via the upload primitive; the resulting publicUrl is then\n// sent to the API).\n\nimport {\n createGeneration,\n GenerateCreateRequestSchema,\n GenerateCreateResponseSchema,\n GenerationResultSchema,\n isTerminalStatus,\n type GenerateCreateResponse,\n type GenerationResult,\n} from '@clickraft/sdk';\n\nimport { ApiError, type ApiClient } from '../../api/client.js';\nimport { uploadFile, DEFAULT_UPLOAD_SCOPE } from '../upload.js';\n\nimport { buildGenerateClient, isUrlLike, type GenerateClientOptions } from './internal.js';\nimport type { BrandModelSpec } from './parse-brand-model-spec.js';\nimport type { ProductSpec } from './parse-product-spec.js';\nimport { DEFAULT_WAIT_TIMEOUT_SECONDS, SERVER_LONG_POLL_SECONDS } from './wait.js';\n\nexport interface GenerateCreateOptions extends GenerateClientOptions {\n prompt?: string;\n modelSlug: string;\n // RFC §4.3: at most 8 reference images. Each value is either a URL (sent\n // verbatim) or a local filesystem path (auto-uploaded via uploadFile).\n // Always routed to the `referenceImages[]` array (the references category),\n // regardless of count — see buildRequestBody.\n referenceImages?: string[];\n // Image-to-video start frame. Emitted as the scalar `referenceImageUrl`, which\n // the server maps to `start_image` — distinct from the reference images above.\n // A URL (sent verbatim) or a local path (auto-uploaded via uploadFile).\n startFrame?: string;\n aspectRatio?: string;\n resolution?: string;\n durationSeconds?: number;\n // The model's quality tier (e.g. low | medium | high). Checked server-side\n // against the model's options; an unsupported value fails before any charge.\n quality?: string;\n brandModels?: BrandModelSpec[];\n products?: ProductSpec[];\n workflowId?: string;\n nodeId?: string;\n // Defaults to true. When false, returns immediately after the POST with the\n // create response projected into the GenerationResult shape.\n wait?: boolean;\n timeoutSeconds?: number;\n client?: ApiClient;\n}\n\nexport type GenerateCreateOutput = GenerationResult;\n\n// Placeholder URL used during the pre-upload validation pass. We substitute\n// local paths with this sentinel so the strict request schema (which requires\n// `.url()` for reference images) can vet every non-upload field BEFORE we\n// commit any bytes to the network — invalid aspectRatio / prompt length /\n// modelSlug / etc. now fail before we upload, not after.\nconst PREFLIGHT_PLACEHOLDER_URL = 'https://placeholder.invalid/pending-upload';\n\n/**\n * Validate the flags, upload any local reference paths, and build the\n * POST /jobs body. Shared by `generate create` and `generate estimate`, so an\n * estimate prices exactly the body a create would send.\n */\nexport async function prepareCreateBody(\n opts: GenerateCreateOptions,\n client: ApiClient,\n): Promise<unknown> {\n // Preflight: replace each local path with a placeholder URL and run the\n // request schema. Any non-upload validation failure surfaces here, before\n // we read or upload a single byte.\n const preflightRefs = (opts.referenceImages ?? []).map((v) =>\n isUrlLike(v) ? v : PREFLIGHT_PLACEHOLDER_URL,\n );\n const preflightStartFrame =\n opts.startFrame === undefined\n ? undefined\n : isUrlLike(opts.startFrame)\n ? opts.startFrame\n : PREFLIGHT_PLACEHOLDER_URL;\n buildRequestBody({ ...opts, referenceImages: preflightRefs, startFrame: preflightStartFrame });\n\n const referenceImages = await resolveReferenceImages({\n items: opts.referenceImages ?? [],\n client,\n signal: opts.signal,\n });\n // The start frame goes through the same URL/local-path resolution (single item).\n const startFrame =\n opts.startFrame === undefined\n ? undefined\n : (\n await resolveReferenceImages({\n items: [opts.startFrame],\n client,\n signal: opts.signal,\n })\n )[0];\n\n return buildRequestBody({ ...opts, referenceImages, startFrame });\n}\n\nexport async function generateCreate(opts: GenerateCreateOptions): Promise<GenerateCreateOutput> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n const body = await prepareCreateBody(opts, client);\n\n // POST /jobs → (if waiting) longPoll to terminal → project. The orchestration\n // lives in @clickraft/sdk; the CLI injects the schemas, the terminal predicate,\n // and the create-projection, and passes the already-built/validated body.\n return createGeneration<GenerateCreateResponse, GenerationResult>({\n client,\n body,\n modelSlug: opts.modelSlug,\n wait: opts.wait ?? true,\n timeoutMs: (opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS) * 1000,\n serverWaitSeconds: SERVER_LONG_POLL_SECONDS,\n signal: opts.signal,\n createSchema: GenerateCreateResponseSchema,\n resultSchema: GenerationResultSchema,\n isTerminal: (r) => isTerminalStatus(r.status),\n projectCreated: projectCreateToResult,\n });\n}\n\nasync function resolveReferenceImages(args: {\n items: string[];\n client: ApiClient;\n signal?: AbortSignal;\n}): Promise<string[]> {\n const out: string[] = [];\n for (const item of args.items) {\n if (isUrlLike(item)) {\n out.push(item);\n continue;\n }\n const uploaded = await uploadFile({\n filePath: item,\n scope: DEFAULT_UPLOAD_SCOPE,\n client: args.client,\n signal: args.signal,\n });\n out.push(uploaded.publicUrl);\n }\n return out;\n}\n\nfunction buildRequestBody(\n args: GenerateCreateOptions & { referenceImages: string[]; startFrame?: string },\n): unknown {\n const input: Record<string, unknown> = {};\n if (args.prompt !== undefined) input.prompt = args.prompt;\n // --reference-image is ALWAYS a reference (references category), regardless of\n // count. Canonical wire shape: object array { url, label? }[]; we only emit\n // `url` (no label UX yet). Do NOT collapse a single ref to referenceImageUrl —\n // that scalar is the start-frame slot (server start_image). This block must\n // match apps/mcp-server/src/tools/generate.ts exactly.\n if (args.referenceImages.length > 0) {\n input.referenceImages = args.referenceImages.map((url) => ({ url }));\n }\n // --start-frame → scalar referenceImageUrl → server start_image (image-to-video).\n if (args.startFrame !== undefined) {\n input.referenceImageUrl = args.startFrame;\n }\n if (args.aspectRatio !== undefined) input.aspectRatio = args.aspectRatio;\n if (args.resolution !== undefined) input.resolution = args.resolution;\n if (args.durationSeconds !== undefined) input.durationSeconds = args.durationSeconds;\n if (args.quality !== undefined) input.quality = args.quality;\n if (args.brandModels !== undefined && args.brandModels.length > 0) {\n input.providerParams = {\n brandModels: args.brandModels.map((spec) => {\n const entry: Record<string, string> = { id: spec.id };\n if (spec.imageType) entry.imageType = spec.imageType;\n return entry;\n }),\n };\n }\n\n const body: Record<string, unknown> = {\n modelSlug: args.modelSlug,\n input,\n };\n\n if (args.workflowId !== undefined || args.nodeId !== undefined) {\n const options: Record<string, unknown> = {};\n if (args.workflowId !== undefined) options.workflowId = args.workflowId;\n if (args.nodeId !== undefined) options.nodeId = args.nodeId;\n body.options = options;\n }\n\n if (args.products !== undefined && args.products.length > 0) {\n body.products = args.products.map((spec) => {\n const entry: Record<string, string> = { id: spec.id };\n if (spec.imageId) entry.imageId = spec.imageId;\n return entry;\n });\n }\n\n const parsed = GenerateCreateRequestSchema.safeParse(body);\n if (!parsed.success) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Invalid generate create request: ${parsed.error.message}`,\n { retryable: false },\n );\n }\n return parsed.data;\n}\n\nfunction projectCreateToResult(\n response: GenerateCreateResponse,\n modelSlug: string,\n): GenerationResult {\n return {\n jobId: response.jobId,\n status: response.status,\n modelSlug,\n resultUrl: null,\n thumbnailUrl: null,\n errorCode: null,\n errorMessage: null,\n creditsCharged: response.creditsCharged,\n creditsRefunded: false,\n startedAt: null,\n completedAt: null,\n };\n}\n","// `--output <path>` for generate create / wait / get: save a completed job's\n// result to disk.\n//\n// Why it exists: a result URL is only a string to a coding agent. Saved as a\n// local file, the agent can open it (Claude Code's Read shows images), judge\n// the result, and pass the path on — and a human gets a file, not a link.\n//\n// Path rules (curl -o semantics, plus a directory form):\n// - an existing directory, or a path ending in \"/\" → <dir>/<jobId>.<ext>\n// - anything else → written exactly there (parent directories created,\n// an existing file overwritten)\n\nimport { createWriteStream } from 'node:fs';\nimport { mkdir, rename, rm, stat } from 'node:fs/promises';\nimport { basename, dirname, extname, join, resolve, sep } from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\n\nimport { ApiError, type GenerationResult } from '@clickraft/sdk';\nimport { request, type Dispatcher } from 'undici';\n\nconst DOWNLOAD_TIMEOUT_MS = 120_000;\n\nexport interface DownloadOptions {\n signal?: AbortSignal;\n // Test seam, mirroring the upload command's putDispatcher.\n dispatcher?: Dispatcher;\n}\n\nasync function isDirectory(path: string): Promise<boolean> {\n try {\n return (await stat(path)).isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction extensionOf(url: string): string {\n const ext = extname(new URL(url).pathname);\n return /^\\.[a-z0-9]{1,5}$/i.test(ext) ? ext.toLowerCase() : '';\n}\n\n/** Where `--output <output>` puts this job's file. */\nexport async function resolveOutputPath(output: string, result: GenerationResult): Promise<string> {\n if (!result.resultUrl) {\n throw new ApiError('INPUT_INVALID_FORMAT', 'The job has no result to save.', {\n retryable: false,\n });\n }\n const asDir = output.endsWith('/') || output.endsWith(sep) || (await isDirectory(output));\n return asDir\n ? resolve(output, `${result.jobId}${extensionOf(result.resultUrl)}`)\n : resolve(output);\n}\n\n/**\n * Download a completed job's result to `output`; returns the absolute path.\n * Writes to a temporary sibling first and renames, so a failed or interrupted\n * download never leaves a truncated file at the requested path.\n */\nexport async function downloadResult(\n result: GenerationResult,\n output: string,\n options: DownloadOptions = {},\n): Promise<string> {\n if (result.status !== 'completed' || !result.resultUrl) {\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Job ${result.jobId} is ${result.status}; only a completed job can be saved.`,\n { retryable: false },\n );\n }\n const url = result.resultUrl;\n if (!url.startsWith('https://') && !url.startsWith('http://')) {\n throw new ApiError('INPUT_INVALID_FORMAT', `Refusing to download a non-HTTP URL: ${url}`, {\n retryable: false,\n });\n }\n\n const target = await resolveOutputPath(output, result);\n await mkdir(dirname(target), { recursive: true });\n const partial = join(dirname(target), `.${basename(target)}.part`);\n\n const signals = [AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS)];\n if (options.signal) signals.push(options.signal);\n const res = await request(url, {\n method: 'GET',\n signal: AbortSignal.any(signals),\n dispatcher: options.dispatcher,\n });\n if (res.statusCode !== 200) {\n await res.body.dump();\n throw new ApiError('NETWORK_ERROR', `Could not download the result (HTTP ${res.statusCode}).`, {\n retryable: res.statusCode >= 500,\n });\n }\n\n try {\n await pipeline(Readable.from(res.body), createWriteStream(partial));\n await rename(partial, target);\n } catch (err) {\n await rm(partial, { force: true });\n throw err;\n }\n return target;\n}\n","// `clickraft generate estimate` — what `generate create` with the same flags\n// would charge, and whether the account can run it now (POST /jobs/estimate).\n// The body is built by the same prepareCreateBody as create, so the estimate\n// prices exactly what create would send. Nothing is created or charged; local\n// reference paths are still uploaded (content-addressed, free) because the\n// server prices the resolved request.\n\nimport { GenerateEstimateResponseSchema, type GenerateEstimateResponse } from '@clickraft/sdk';\n\nimport { prepareCreateBody, type GenerateCreateOptions } from './create.js';\nimport { buildGenerateClient } from './internal.js';\n\nexport type GenerateEstimateOptions = Omit<GenerateCreateOptions, 'wait' | 'timeoutSeconds'>;\n\nexport async function generateEstimate(\n opts: GenerateEstimateOptions,\n): Promise<GenerateEstimateResponse> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n const body = await prepareCreateBody(opts, client);\n return client.request<GenerateEstimateResponse>({\n method: 'POST',\n path: '/jobs/estimate',\n body,\n responseSchema: GenerateEstimateResponseSchema,\n signal: opts.signal,\n });\n}\n","// `clickraft generate get <jobId>` — fetches the current state of a generation\n// job without holding the request. Returns the full GenerationResult.\n\nimport { GenerationResultSchema, type GenerationResult } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildGenerateClient, type GenerateClientOptions } from './internal.js';\n\nexport interface GenerateGetOptions extends GenerateClientOptions {\n jobId: string;\n client?: ApiClient;\n // Optional server-side hold in seconds (0-30). Defaults to 0 for `generate\n // get` (no hold). The wait command sets this to 30 for each round.\n waitSeconds?: number;\n}\n\nexport async function generateGet(opts: GenerateGetOptions): Promise<GenerationResult> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n return client.request<GenerationResult>({\n method: 'GET',\n path: `/jobs/${encodeURIComponent(opts.jobId)}`,\n query: opts.waitSeconds && opts.waitSeconds > 0 ? { wait: opts.waitSeconds } : undefined,\n responseSchema: GenerationResultSchema,\n signal: opts.signal,\n });\n}\n","// `clickraft generate list` — the user's recent generations (GET /jobs),\n// newest first, one page at a time.\n\nimport { GenerationListResponseSchema, type GenerationListResponse } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildGenerateClient, type GenerateClientOptions } from './internal.js';\n\nexport interface GenerateListOptions extends GenerateClientOptions {\n limit?: number;\n status?: string;\n contentType?: string;\n cursor?: string;\n client?: ApiClient;\n}\n\nexport async function generateList(opts: GenerateListOptions): Promise<GenerationListResponse> {\n const client = opts.client ?? (await buildGenerateClient(opts));\n return client.request<GenerationListResponse>({\n method: 'GET',\n path: '/jobs',\n query: {\n limit: opts.limit,\n status: opts.status,\n contentType: opts.contentType,\n cursor: opts.cursor,\n },\n responseSchema: GenerationListResponseSchema,\n signal: opts.signal,\n });\n}\n","// Minimal flag parser used by the Wave 1 CLI dispatcher. We do not pull in\n// commander/yargs yet — the surface is small enough that a hand-rolled parser\n// avoids the dependency footprint and keeps `clickraft --help` instant.\n//\n// Syntax supported:\n// --flag value -> string : { foo: \"value\" }\n// --flag=value -> string : { foo: \"value\" }\n// --bool -> boolean : { bool: true }\n// --no-bool -> boolean : { bool: false }\n// --repeat a --repeat b -> array : { repeat: [\"a\", \"b\"] }\n// -- -> stop flag parsing (everything after is positional)\n//\n// Anything not matched by `string`, `boolean`, or `array` is treated as\n// positional. Unknown long flags throw a usage error so typos surface loudly.\n\nexport interface FlagSpec {\n string?: readonly string[];\n boolean?: readonly string[];\n array?: readonly string[];\n aliases?: Readonly<Record<string, string>>;\n}\n\nexport interface ParsedArgs {\n positional: string[];\n string: Record<string, string>;\n boolean: Record<string, boolean>;\n array: Record<string, string[]>;\n}\n\nexport class ArgError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ArgError';\n }\n}\n\nexport function parseArgs(argv: readonly string[], spec: FlagSpec): ParsedArgs {\n const result: ParsedArgs = {\n positional: [],\n string: {},\n boolean: {},\n array: {},\n };\n\n const stringFlags = new Set(spec.string ?? []);\n const booleanFlags = new Set(spec.boolean ?? []);\n const arrayFlags = new Set(spec.array ?? []);\n const aliases = spec.aliases ?? {};\n\n let i = 0;\n let stopFlags = false;\n\n while (i < argv.length) {\n const raw = argv[i];\n if (raw === undefined) {\n i += 1;\n continue;\n }\n\n if (stopFlags) {\n result.positional.push(raw);\n i += 1;\n continue;\n }\n\n if (raw === '--') {\n stopFlags = true;\n i += 1;\n continue;\n }\n\n if (!raw.startsWith('--')) {\n result.positional.push(raw);\n i += 1;\n continue;\n }\n\n // --flag or --flag=value or --no-flag\n const eqIdx = raw.indexOf('=');\n const flagToken = eqIdx >= 0 ? raw.slice(2, eqIdx) : raw.slice(2);\n const inlineValue = eqIdx >= 0 ? raw.slice(eqIdx + 1) : undefined;\n const canonical = resolveCanonical(flagToken, { booleanFlags, aliases });\n\n if (booleanFlags.has(canonical)) {\n if (inlineValue !== undefined) {\n result.boolean[canonical] = parseBool(inlineValue);\n } else if (flagToken.startsWith('no-') && booleanFlags.has(flagToken.slice(3))) {\n result.boolean[flagToken.slice(3)] = false;\n } else {\n result.boolean[canonical] = true;\n }\n i += 1;\n continue;\n }\n\n if (stringFlags.has(canonical) || arrayFlags.has(canonical)) {\n let value: string;\n if (inlineValue !== undefined) {\n value = inlineValue;\n } else {\n const next = argv[i + 1];\n if (next === undefined || next.startsWith('--')) {\n throw new ArgError(`Flag --${canonical} requires a value.`);\n }\n value = next;\n i += 1;\n }\n if (arrayFlags.has(canonical)) {\n const existing = result.array[canonical] ?? [];\n existing.push(value);\n result.array[canonical] = existing;\n } else {\n result.string[canonical] = value;\n }\n i += 1;\n continue;\n }\n\n throw new ArgError(`Unknown flag --${flagToken}`);\n }\n\n return result;\n}\n\nfunction resolveCanonical(\n flagToken: string,\n ctx: { booleanFlags: Set<string>; aliases: Readonly<Record<string, string>> },\n): string {\n if (ctx.aliases[flagToken]) return ctx.aliases[flagToken];\n if (flagToken.startsWith('no-') && ctx.booleanFlags.has(flagToken.slice(3))) {\n return flagToken.slice(3);\n }\n return flagToken;\n}\n\nfunction parseBool(value: string): boolean {\n if (value === 'true' || value === '1') return true;\n if (value === 'false' || value === '0') return false;\n throw new ArgError(`Expected boolean value (true/false), got \"${value}\".`);\n}\n","import { ArgError } from '../../cli/args.js';\n\nexport const VALID_POSES = [\n 'front',\n '3/4-right',\n 'right',\n 'left',\n '3/4-left',\n 'back',\n 'approved',\n] as const;\n\nexport type Pose = (typeof VALID_POSES)[number];\n\nexport interface BrandModelSpec {\n id: string;\n imageType?: Pose;\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function parseBrandModelSpec(raw: string): BrandModelSpec {\n if (!raw) throw new ArgError('--brand-model value cannot be empty.');\n\n const colonIdx = raw.indexOf(':');\n const uuid = colonIdx >= 0 ? raw.slice(0, colonIdx) : raw;\n const poseRaw = colonIdx >= 0 ? raw.slice(colonIdx + 1) : undefined;\n\n if (!UUID_RE.test(uuid)) {\n throw new ArgError(\n `Invalid brand model ID: '${uuid}'. Expected a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).`,\n );\n }\n\n if (poseRaw !== undefined) {\n if (!poseRaw) {\n throw new ArgError(\n `Empty pose for brand model ${uuid}. Valid poses: ${VALID_POSES.join(', ')}.`,\n );\n }\n if (!VALID_POSES.includes(poseRaw as Pose)) {\n throw new ArgError(\n `Unknown pose '${poseRaw}' for brand model ${uuid}. Valid poses: ${VALID_POSES.join(', ')}.`,\n );\n }\n return { id: uuid.toLowerCase(), imageType: poseRaw as Pose };\n }\n\n return { id: uuid.toLowerCase() };\n}\n\nexport function validateBrandModelSpecs(specs: BrandModelSpec[]): void {\n if (specs.length > 3) {\n throw new ArgError(`Too many --brand-model flags (${specs.length}). Maximum is 3.`);\n }\n const seen = new Set<string>();\n for (const spec of specs) {\n if (seen.has(spec.id)) {\n throw new ArgError(\n `Duplicate brand model ID: ${spec.id}. Each --brand-model must reference a different model.`,\n );\n }\n seen.add(spec.id);\n }\n}\n","import { ArgError } from '../../cli/args.js';\n\nexport interface ProductSpec {\n id: string;\n imageId?: string;\n}\n\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function parseProductSpec(raw: string): ProductSpec {\n if (!raw) throw new ArgError('--product value cannot be empty.');\n\n const colonIdx = raw.indexOf(':');\n const productId = colonIdx >= 0 ? raw.slice(0, colonIdx) : raw;\n const imageIdRaw = colonIdx >= 0 ? raw.slice(colonIdx + 1) : undefined;\n\n if (!UUID_RE.test(productId)) {\n throw new ArgError(\n `Invalid product ID: '${productId}'. Expected a UUID (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx).`,\n );\n }\n\n if (imageIdRaw !== undefined) {\n if (!imageIdRaw) {\n throw new ArgError(\n `Empty image ID for product ${productId.toLowerCase()}. Omit the colon or provide a valid UUID.`,\n );\n }\n if (!UUID_RE.test(imageIdRaw)) {\n throw new ArgError(\n `Invalid image ID: '${imageIdRaw}' for product ${productId.toLowerCase()}. Expected a UUID.`,\n );\n }\n return { id: productId.toLowerCase(), imageId: imageIdRaw.toLowerCase() };\n }\n\n return { id: productId.toLowerCase() };\n}\n\nexport function validateProductSpecs(specs: ProductSpec[]): void {\n const seen = new Set<string>();\n for (const spec of specs) {\n const key = spec.imageId ? `${spec.id}:${spec.imageId}` : spec.id;\n if (seen.has(key)) {\n throw new ArgError(`Duplicate product reference: ${key}. Each --product must be unique.`);\n }\n seen.add(key);\n }\n}\n","import { setTimeout as delay } from 'node:timers/promises';\n\nimport { redactTokenLikeFields, type CloudflareAccessCredentials } from '@clickraft/sdk';\nimport { request } from 'undici';\n\nimport { ApiError } from '../api/client.js';\n\nimport { AuthError } from './errors.js';\nimport {\n DeviceAuthorizationResponseSchema,\n DeviceTokenPollErrorSchema,\n TokenResponseSchema,\n type DeviceAuthorizationResponse,\n type TokenResponse,\n} from './types.js';\n\n// OAuth 2.0 Device Authorization Grant (RFC 8628) client.\n// Source of truth: 02-oauth.md §3.1 (shapes) and §5.1 (sequence).\n\nconst GRANT_TYPE = 'urn:ietf:params:oauth:grant-type:device_code';\nconst FORM_CONTENT_TYPE = 'application/x-www-form-urlencoded';\n\nexport interface DeviceFlowOptions {\n apiBaseUrl: string;\n clientId: string;\n scope: string;\n /**\n * The subset to fall back to when the server refuses `scope` outright.\n * Required for a downgrade to be possible; absent means no fallback exists.\n */\n requiredScope?: string;\n /**\n * Whether a refusal of `scope` may be retried with `requiredScope`.\n *\n * Passed explicitly by the caller rather than inferred here, because only the\n * caller knows whether `scope` came from its own defaults or from a\n * user-supplied `--scope`. Inferring it would put the decision in the wrong\n * place and make it invisible at the call site.\n */\n allowScopeDowngrade?: boolean;\n /** Fired once, before the retry, so the CLI can warn on stderr. */\n onScopeDowngrade?: (info: {\n requested: string;\n retryingWith: string;\n description: string | undefined;\n }) => void;\n onUserCode?: (info: {\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresAt: Date;\n }) => void;\n onPoll?: (event: {\n iteration: number;\n intervalSeconds: number;\n status: 'pending' | 'slow_down';\n }) => void;\n signal?: AbortSignal;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n}\n\nexport async function runDeviceFlow(opts: DeviceFlowOptions): Promise<TokenResponse> {\n throwIfCancelled(opts.signal);\n\n const authResp = await requestDeviceAuthorization(opts);\n const deadlineMs = Date.now() + authResp.expires_in * 1000;\n\n opts.onUserCode?.({\n userCode: authResp.user_code,\n verificationUri: authResp.verification_uri,\n verificationUriComplete: authResp.verification_uri_complete ?? authResp.verification_uri,\n expiresAt: new Date(deadlineMs),\n });\n\n let intervalSeconds = authResp.interval;\n let iteration = 0;\n let consecutiveNetworkFailures = 0;\n const MAX_CONSECUTIVE_NETWORK_FAILURES = 5;\n\n // RFC 8628 §3.5: the client waits `interval` seconds before each poll.\n // `expires_in` is a hard deadline — we bound each sleep by the remaining\n // time so an expired flow never waits past the cutoff.\n while (true) {\n const sleepMs = Math.min(intervalSeconds * 1000, deadlineMs - Date.now());\n if (sleepMs <= 0) {\n throw new AuthError(\n 'AUTH_DEVICE_CODE_EXPIRED',\n `Device authorization expired after ${authResp.expires_in}s. Run \\`clickraft login\\` again.`,\n );\n }\n await abortableSleep(sleepMs, opts.signal);\n throwIfCancelled(opts.signal);\n\n if (Date.now() >= deadlineMs) {\n throw new AuthError(\n 'AUTH_DEVICE_CODE_EXPIRED',\n `Device authorization expired after ${authResp.expires_in}s. Run \\`clickraft login\\` again.`,\n );\n }\n\n iteration += 1;\n const result = await pollToken({\n apiBaseUrl: opts.apiBaseUrl,\n clientId: opts.clientId,\n deviceCode: authResp.device_code,\n signal: opts.signal,\n cloudflareAccess: opts.cloudflareAccess,\n });\n\n if (result.kind === 'success') {\n return result.token;\n }\n if (result.kind === 'pending') {\n consecutiveNetworkFailures = 0;\n opts.onPoll?.({ iteration, intervalSeconds, status: 'pending' });\n continue;\n }\n if (result.kind === 'slow_down') {\n consecutiveNetworkFailures = 0;\n intervalSeconds *= 2;\n opts.onPoll?.({ iteration, intervalSeconds, status: 'slow_down' });\n continue;\n }\n if (result.kind === 'network_error') {\n consecutiveNetworkFailures += 1;\n if (consecutiveNetworkFailures >= MAX_CONSECUTIVE_NETWORK_FAILURES) {\n throw new ApiError(\n 'NETWORK_ERROR',\n `Network repeatedly failed during polling (${MAX_CONSECUTIVE_NETWORK_FAILURES} consecutive errors).`,\n { retryable: true },\n result.cause,\n );\n }\n intervalSeconds *= 2;\n opts.onPoll?.({ iteration, intervalSeconds, status: 'slow_down' });\n continue;\n }\n throw result.error;\n }\n}\n\n/**\n * Request a device code, degrading once if the server refuses an optional scope.\n *\n * `POST /oauth/device-authorization` validates the requested scope list\n * ATOMICALLY: if any member falls outside the client's `allowed_scopes` it\n * rejects the WHOLE request with `invalid_scope`, rather than intersecting and\n * proceeding. So a CLI that adds one new scope to its request list cannot log\n * in AT ALL against a server that has not granted it yet — the failure is the\n * entire authentication flow, not the one feature the scope was for.\n *\n * Correct release ordering (grant the scope server-side first, ship the client\n * second) should mean this never fires. It exists anyway because the client and\n * the server release independently: this package publishes to npm on every\n * merge, while the grant is a migration in another repo applied by hand, and\n * the window between them is invisible from either side.\n *\n * The retry is deliberately narrow. See `allowScopeDowngrade`.\n */\nasync function requestDeviceAuthorization(\n opts: DeviceFlowOptions,\n): Promise<DeviceAuthorizationResponse> {\n try {\n return await attemptDeviceAuthorization(opts, opts.scope);\n } catch (err) {\n if (!(err instanceof ScopeRefusedError)) throw err;\n\n // An explicit --scope is a WHOLESALE override: the caller stated the exact\n // set they want. Silently substituting a different one hands them a token\n // whose powers they never asked for and would not think to re-check, so\n // refuse instead and name what the server rejected.\n if (!opts.allowScopeDowngrade || opts.requiredScope === undefined) {\n throw new AuthError('AUTH_TOKEN_INVALID', scopeRefusalMessage(err.description));\n }\n\n opts.onScopeDowngrade?.({\n requested: opts.scope,\n retryingWith: opts.requiredScope,\n description: err.description,\n });\n\n try {\n return await attemptDeviceAuthorization(opts, opts.requiredScope);\n } catch (retryErr) {\n // A second refusal means even the required set is not granted, which is\n // a server-side misconfiguration rather than a version skew. One retry,\n // never a loop.\n if (retryErr instanceof ScopeRefusedError) {\n throw new AuthError('AUTH_TOKEN_INVALID', scopeRefusalMessage(retryErr.description));\n }\n throw retryErr;\n }\n }\n}\n\nfunction scopeRefusalMessage(description: string | undefined): string {\n return (\n `The authorization server refused the requested scopes${description ? `: ${description}` : '.'}` +\n ' Re-run `clickraft login` without --scope to request the defaults.'\n );\n}\n\n/** Internal signal that the server answered `invalid_scope`. Never surfaced. */\nclass ScopeRefusedError extends Error {\n constructor(readonly description: string | undefined) {\n super('invalid_scope');\n this.name = 'ScopeRefusedError';\n }\n}\n\nasync function attemptDeviceAuthorization(\n opts: DeviceFlowOptions,\n scope: string,\n): Promise<DeviceAuthorizationResponse> {\n const body = new URLSearchParams({ client_id: opts.clientId, scope }).toString();\n const headers: Record<string, string> = { 'content-type': FORM_CONTENT_TYPE };\n if (opts.cloudflareAccess) {\n headers['cf-access-client-id'] = opts.cloudflareAccess.clientId;\n headers['cf-access-client-secret'] = opts.cloudflareAccess.clientSecret;\n }\n let resp;\n try {\n resp = await request(`${opts.apiBaseUrl}/oauth/device-authorization`, {\n method: 'POST',\n headers,\n body,\n signal: opts.signal,\n });\n } catch (err) {\n if (isAbortError(err) || opts.signal?.aborted) {\n throw new AuthError(\n 'AUTH_FLOW_CANCELLED',\n 'Device flow cancelled during authorization request.',\n err,\n );\n }\n throw new ApiError(\n 'NETWORK_ERROR',\n `Network error contacting authorization endpoint: ${(err as Error).message}`,\n { retryable: true },\n err,\n );\n }\n\n const text = await resp.body.text();\n if (resp.statusCode !== 200) {\n // Classify `invalid_scope` before the generic path so the caller can decide\n // whether a downgrade is permitted. Reuses DeviceTokenPollErrorSchema: the\n // authorization and token endpoints emit the same `{error, error_description}`\n // envelope, and that enum already contains `invalid_scope`.\n if (resp.statusCode === 400) {\n const maybe = DeviceTokenPollErrorSchema.safeParse(safeParseJson(text));\n if (maybe.success && maybe.data.error === 'invalid_scope') {\n throw new ScopeRefusedError(maybe.data.error_description);\n }\n }\n const redacted = redactTokenLikeFields(truncate(text));\n throw new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Authorization endpoint returned HTTP ${resp.statusCode}: ${redacted}`,\n {\n status: resp.statusCode,\n redactedBody: redactTokenLikeFields(text),\n headers: safeHeaders(resp.headers),\n },\n );\n }\n const parsed = parseJson(text, 'authorization');\n const validated = DeviceAuthorizationResponseSchema.safeParse(parsed);\n if (!validated.success) {\n // No token has been issued yet at this point in the flow, so an\n // `AUTH_TOKEN_INVALID` would mislead the user into thinking their saved\n // credentials are bad. Surface a schema mismatch instead (exit 1) per\n // 1A.2 — the CLI is out of sync with the server contract.\n throw new ApiError(\n 'SCHEMA_MISMATCH',\n 'Authorization endpoint response did not match the expected schema.',\n {\n status: resp.statusCode,\n retryable: false,\n redactedBody: redactTokenLikeFields(truncate(text)),\n },\n validated.error,\n );\n }\n return validated.data;\n}\n\ntype PollResult =\n | { kind: 'success'; token: TokenResponse }\n | { kind: 'pending' }\n | { kind: 'slow_down' }\n | { kind: 'network_error'; cause: unknown }\n | { kind: 'error'; error: AuthError | ApiError };\n\n// undici / Node error codes that mean \"the request never reached a server\n// response\" — RFC 8628 §3.5 says these should be treated like slow_down.\nconst TRANSIENT_NETWORK_CODES = new Set([\n 'ECONNRESET',\n 'ECONNREFUSED',\n 'ETIMEDOUT',\n 'EAI_AGAIN',\n 'UND_ERR_SOCKET',\n 'UND_ERR_CONNECT_TIMEOUT',\n 'UND_ERR_HEADERS_TIMEOUT',\n]);\n\nfunction isTransientNetworkError(err: unknown): boolean {\n const code = (err as { code?: unknown }).code;\n return typeof code === 'string' && TRANSIENT_NETWORK_CODES.has(code);\n}\n\nasync function pollToken(args: {\n apiBaseUrl: string;\n clientId: string;\n deviceCode: string;\n signal?: AbortSignal;\n cloudflareAccess?: CloudflareAccessCredentials | null;\n}): Promise<PollResult> {\n const body = new URLSearchParams({\n client_id: args.clientId,\n device_code: args.deviceCode,\n grant_type: GRANT_TYPE,\n }).toString();\n const headers: Record<string, string> = { 'content-type': FORM_CONTENT_TYPE };\n if (args.cloudflareAccess) {\n headers['cf-access-client-id'] = args.cloudflareAccess.clientId;\n headers['cf-access-client-secret'] = args.cloudflareAccess.clientSecret;\n }\n\n let resp;\n try {\n resp = await request(`${args.apiBaseUrl}/oauth/token`, {\n method: 'POST',\n headers,\n body,\n signal: args.signal,\n });\n } catch (err) {\n if (isAbortError(err) || args.signal?.aborted) {\n return {\n kind: 'error',\n error: new AuthError('AUTH_FLOW_CANCELLED', 'Device flow cancelled mid-poll.', err),\n };\n }\n if (isTransientNetworkError(err)) {\n return { kind: 'network_error', cause: err };\n }\n return {\n kind: 'error',\n error: new ApiError(\n 'NETWORK_ERROR',\n `Network error contacting token endpoint: ${(err as Error).message}`,\n { retryable: true },\n err,\n ),\n };\n }\n\n const text = await resp.body.text();\n\n if (resp.statusCode === 200) {\n return parseTokenSuccess(text);\n }\n if (resp.statusCode === 400) {\n return parseTokenError(text);\n }\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Token endpoint returned unexpected HTTP ${resp.statusCode}: ${redactTokenLikeFields(truncate(text))}`,\n {\n status: resp.statusCode,\n redactedBody: redactTokenLikeFields(text),\n headers: safeHeaders(resp.headers),\n },\n ),\n };\n}\n\nfunction parseTokenSuccess(text: string): PollResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n return {\n kind: 'error',\n error: new AuthError('AUTH_TOKEN_INVALID', 'Token endpoint returned invalid JSON.', err),\n };\n }\n const validated = TokenResponseSchema.safeParse(parsed);\n if (!validated.success) {\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n 'Token endpoint success response failed schema validation.',\n validated.error,\n ),\n };\n }\n return { kind: 'success', token: validated.data };\n}\n\nfunction parseTokenError(text: string): PollResult {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch (err) {\n return {\n kind: 'error',\n error: new AuthError('AUTH_TOKEN_INVALID', 'Token error response was not valid JSON.', err),\n };\n }\n const validated = DeviceTokenPollErrorSchema.safeParse(parsed);\n if (!validated.success) {\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n 'Token error response failed schema validation.',\n validated.error,\n ),\n };\n }\n const { error, error_description } = validated.data;\n switch (error) {\n case 'authorization_pending':\n return { kind: 'pending' };\n case 'slow_down':\n return { kind: 'slow_down' };\n case 'access_denied':\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_ACCESS_DENIED',\n error_description ?? 'User denied the device authorization request.',\n ),\n };\n case 'expired_token':\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_DEVICE_CODE_EXPIRED',\n error_description ?? 'Device code has expired. Run `clickraft login` again.',\n ),\n };\n default:\n return {\n kind: 'error',\n error: new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Token endpoint returned error: ${error}${error_description ? ` (${error_description})` : ''}`,\n ),\n };\n }\n}\n\nasync function abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n try {\n await delay(ms, undefined, { signal });\n } catch (err) {\n if (isAbortError(err)) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Device flow cancelled while waiting.', err);\n }\n throw err;\n }\n}\n\nfunction throwIfCancelled(signal?: AbortSignal): void {\n if (signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Device flow cancelled.');\n }\n}\n\nfunction isAbortError(err: unknown): boolean {\n if (err instanceof Error) {\n if (err.name === 'AbortError') return true;\n if ((err as { code?: string }).code === 'ABORT_ERR') return true;\n }\n return false;\n}\n\n/** Parse or give up quietly. Used only for classifying an error body. */\nfunction safeParseJson(text: string): unknown {\n try {\n return JSON.parse(text);\n } catch {\n return undefined;\n }\n}\n\nfunction parseJson(text: string, label: string): unknown {\n try {\n return JSON.parse(text);\n } catch (err) {\n throw new AuthError(\n 'AUTH_TOKEN_INVALID',\n `${label} endpoint returned invalid JSON: ${redactTokenLikeFields(truncate(text))}`,\n err,\n );\n }\n}\n\nfunction truncate(text: string, max = 200): string {\n return text.length > max ? `${text.slice(0, max)}...` : text;\n}\n\nfunction safeHeaders(\n headers: Record<string, string | string[] | undefined>,\n): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(headers)) {\n if (typeof v === 'string') out[k] = v;\n }\n return out;\n}\n","// `clickraft login` — interactive OAuth device flow → credentials on disk.\n//\n// Wave 1 limitation (TODO(wave-2)): the `/oauth/token` response per\n// `02-oauth.md` §3.1 returns only {access_token, token_type, expires_in,\n// scope}. CredentialsProfile requires organizationId / organizationSlug /\n// userId — there is no `/me` endpoint to fetch them and `src/auth/types.ts`\n// is locked. Wave 1 writes placeholder identity (nil UUID + slug \"unknown\"),\n// which validates against the Zod schema but degrades the human display.\n// Wave 2 lifts this by extending the token response to carry identity.\n\nimport { setProfile, readCredentials } from '../auth/credentials.js';\nimport { runDeviceFlow, type DeviceFlowOptions } from '../auth/device-flow.js';\nimport { AuthError } from '../auth/errors.js';\nimport { type CredentialsProfile, type TokenResponse } from '../auth/types.js';\nimport { DEFAULT_API_BASE_URL, DEFAULT_PROFILE_NAME, loadConfig } from '../config/loader.js';\n\nconst PLACEHOLDER_UUID = '00000000-0000-0000-0000-000000000000';\nconst PLACEHOLDER_ORG_SLUG = 'unknown';\nconst CLIENT_ID = 'clickraft-cli';\n\n// Default scopes per `02-oauth.md` §2.4. Reads are not implied by writes.\n//\n// Split into required and optional because the authorization endpoint validates\n// the list ATOMICALLY: one member the server has not granted rejects the whole\n// request with `invalid_scope`, and login fails entirely. Anything added here\n// after the CLI has shipped is therefore a breaking change until the server\n// grants it, and belongs in OPTIONAL_SCOPES so a refusal degrades to a warning\n// instead of locking every user out. See device-flow.ts.\nexport const REQUIRED_SCOPES: readonly string[] = [\n 'templates:read',\n 'generations:write',\n 'generations:read',\n 'workflows:write',\n 'workflows:read',\n 'brand-models:read',\n 'products:read',\n 'models:read',\n 'assets:write',\n 'balance:read',\n];\n\n// `products:write` gates `clickraft product create`. Granted by migration 0075\n// on the first-party OAuth clients; a server without it refuses the whole list.\nexport const OPTIONAL_SCOPES: readonly string[] = ['products:write'];\n\nexport const DEFAULT_SCOPES: readonly string[] = [...REQUIRED_SCOPES, ...OPTIONAL_SCOPES];\n\nexport interface LoginOptions {\n profile?: string;\n apiBaseUrl?: string;\n scope?: string;\n forceReauth: boolean;\n openBrowser: boolean;\n signal?: AbortSignal;\n credentialsPath?: string;\n // UI callbacks — wired to progress.ts by the dispatcher. Pulled out as\n // injectable hooks so tests can drive the flow without touching stderr.\n onUserCode?: DeviceFlowOptions['onUserCode'];\n onPoll?: DeviceFlowOptions['onPoll'];\n onScopeDowngrade?: DeviceFlowOptions['onScopeDowngrade'];\n // Override the device-flow function — only set in tests.\n runDeviceFlow?: typeof runDeviceFlow;\n}\n\nexport interface LoginResult {\n profileName: string;\n tokenPrefix: string;\n expiresAt: string;\n scopes: string[];\n identityKnown: boolean;\n organizationId: string;\n organizationSlug: string;\n userId: string;\n}\n\nexport async function login(options: LoginOptions): Promise<LoginResult> {\n const config = await loadConfig({\n flagProfile: options.profile,\n flagApiBaseUrl: options.apiBaseUrl,\n credentialsPath: options.credentialsPath,\n });\n const profileName = config.profileName || DEFAULT_PROFILE_NAME;\n const apiBaseUrl = options.apiBaseUrl ?? config.apiBaseUrl ?? DEFAULT_API_BASE_URL;\n\n if (!options.forceReauth) {\n const existing = await readCredentials(options.credentialsPath);\n const profile = existing?.profiles[profileName];\n if (profile && !isExpired(profile.expiresAt)) {\n throw new AuthError(\n 'AUTH_TOKEN_INVALID',\n `Profile \"${profileName}\" is already logged in (token valid until ${profile.expiresAt}). ` +\n `Pass --force-reauth to mint a new token.`,\n );\n }\n }\n\n const explicitScope = options.scope?.trim();\n const scope = explicitScope || DEFAULT_SCOPES.join(' ');\n const flow = options.runDeviceFlow ?? runDeviceFlow;\n const token = await flow({\n apiBaseUrl,\n clientId: CLIENT_ID,\n scope,\n requiredScope: REQUIRED_SCOPES.join(' '),\n // ONLY when the list is ours. An explicit --scope is a wholesale override,\n // and quietly requesting a different set than the caller asked for would\n // hand them a token whose powers they never chose and cannot see.\n allowScopeDowngrade: !explicitScope,\n onScopeDowngrade: options.onScopeDowngrade,\n onUserCode: options.onUserCode,\n onPoll: options.onPoll,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n });\n\n const profile = buildCredentialsProfile({ token, apiBaseUrl });\n await setProfile(profileName, profile, options.credentialsPath);\n\n return {\n profileName,\n tokenPrefix: profile.tokenPrefix,\n expiresAt: profile.expiresAt,\n scopes: profile.scopes,\n identityKnown: false,\n organizationId: profile.organizationId,\n organizationSlug: profile.organizationSlug,\n userId: profile.userId,\n };\n}\n\nfunction buildCredentialsProfile(args: {\n token: TokenResponse;\n apiBaseUrl: string;\n}): CredentialsProfile {\n const now = Date.now();\n const issuedAt = new Date(now).toISOString();\n const expiresAt = new Date(now + args.token.expires_in * 1000).toISOString();\n\n // Token prefix is the first 12 chars per `02-oauth.md` §2.3 (\"ck_live_AbCdEf01gH\").\n const tokenPrefix = args.token.access_token.slice(0, 12);\n const scopes = args.token.scope.split(/\\s+/).filter(Boolean);\n\n return {\n apiBaseUrl: args.apiBaseUrl,\n accessToken: args.token.access_token,\n tokenType: args.token.token_type,\n tokenPrefix,\n organizationId: PLACEHOLDER_UUID,\n organizationSlug: PLACEHOLDER_ORG_SLUG,\n userId: PLACEHOLDER_UUID,\n scopes,\n expiresAt,\n issuedAt,\n clientId: CLIENT_ID,\n };\n}\n\nfunction isExpired(expiresAt: string): boolean {\n const t = Date.parse(expiresAt);\n if (Number.isNaN(t)) return true;\n return t <= Date.now();\n}\n","// `clickraft logout` — removes a credentials profile and, by default,\n// revokes the access token server-side via POST /oauth/revoke.\n//\n// Per `02-oauth.md` §3.3 the revoke endpoint always returns 200 (RFC 7009)\n// — but network failures, server outages, or 4xx-on-our-bug do happen.\n// We treat revocation as best-effort: any failure is logged to stderr and\n// the local profile is still removed.\n\nimport { redactTokenLikeFields, redactTokenLikeValue } from '@clickraft/sdk';\n\nimport { createApiClient, type ApiClient } from '../api/client.js';\nimport { deleteCredentials, readCredentials, removeProfile } from '../auth/credentials.js';\nimport { CredentialsError } from '../auth/errors.js';\nimport { DEFAULT_PROFILE_NAME, loadConfig } from '../config/loader.js';\n\nexport interface LogoutOptions {\n profile?: string;\n all: boolean;\n revoke: boolean;\n signal?: AbortSignal;\n credentialsPath?: string;\n // Test seam.\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n // Sink for revoke-failure warnings; defaults to process.stderr. Tests\n // capture this without touching real stderr.\n warn?: (line: string) => void;\n}\n\nexport interface LogoutResult {\n profilesRemoved: string[];\n serverRevoked: boolean;\n revokeFailureMessage?: string;\n}\n\nexport async function logout(options: LogoutOptions): Promise<LogoutResult> {\n if (options.all) {\n await deleteCredentials(options.credentialsPath);\n return { profilesRemoved: ['*'], serverRevoked: false };\n }\n\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n const profileName = config.profileName || DEFAULT_PROFILE_NAME;\n\n const file = await readCredentials(options.credentialsPath);\n const profile = file?.profiles[profileName];\n if (!profile) {\n throw new CredentialsError(\n 'CREDENTIALS_PROFILE_NOT_FOUND',\n `Profile \"${profileName}\" not found. Use \\`clickraft logout --all\\` to clear all credentials.`,\n );\n }\n\n let serverRevoked = false;\n let revokeFailureMessage: string | undefined;\n\n if (options.revoke) {\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(profile.apiBaseUrl, profile.accessToken);\n try {\n // The server returns 200 with empty/JSON body per RFC 7009. ApiClient\n // requires a JSON envelope on 200 — supply z.unknown() so any body\n // shape passes. If the server returns 2xx with non-JSON, parseSuccessBody\n // throws PARSE_ERROR which we then catch and downgrade to a warning.\n await client.request({\n method: 'POST',\n path: '/oauth/revoke',\n body: { token: profile.accessToken },\n });\n serverRevoked = true;\n } catch (err) {\n revokeFailureMessage = formatRevokeFailure(err, profile.accessToken);\n const sink = options.warn ?? ((line: string) => process.stderr.write(`${line}\\n`));\n sink(revokeFailureMessage);\n }\n }\n\n await removeProfile(profileName, options.credentialsPath);\n\n return {\n profilesRemoved: [profileName],\n serverRevoked,\n ...(revokeFailureMessage ? { revokeFailureMessage } : {}),\n };\n}\n\nfunction formatRevokeFailure(err: unknown, token: string): string {\n const reason = redactTokenLikeFields(err instanceof Error ? err.message : String(err));\n return (\n `warning: server-side revoke failed (${reason}). ` +\n `Local profile removed; token ${redactTokenLikeValue(token)} remains server-valid until expiry.`\n );\n}\n","import { z } from 'zod';\n\nexport const ModelSummarySchema = z\n .object({\n id: z.string().uuid(),\n slug: z.string(),\n displayName: z.string(),\n description: z.string().nullable(),\n shortDescription: z.string().nullable(),\n providerSlug: z.string(),\n providerName: z.string(),\n modelType: z.string(),\n category: z.string(),\n costTier: z.string(),\n creditCost: z.number(),\n pricingStrategy: z.string(),\n estimatedSeconds: z\n .object({\n typical: z.number(),\n range: z.array(z.number()),\n })\n .passthrough()\n .nullable(),\n status: z.string(),\n modalities: z\n .object({\n input: z.array(z.string()),\n output: z.array(z.string()),\n })\n .passthrough()\n .nullable(),\n bestFor: z.array(z.string()),\n badges: z.array(\n z\n .object({\n type: z.string(),\n label: z.string(),\n color: z.string(),\n expires_at: z.string().nullable().optional(),\n })\n .strict(),\n ),\n isFeatured: z.boolean(),\n isDefault: z.boolean(),\n docsUrl: z.string().nullable(),\n llmContext: z.string().nullable(),\n // Server (AgentModelSchema) types constraints as any-typed (anyOf[{}, null]); mirror it with\n // z.unknown().nullable() rather than narrowing to object|null, so a non-object emit is accepted.\n constraints: z.unknown().nullable(),\n modelFamily: z.string().nullable(),\n isFamilyPrimary: z.boolean().nullable(),\n // Optional lifecycle fields the server emits (string|null, absent when not set).\n deprecatedAt: z.string().nullable().optional(),\n sunsetAt: z.string().nullable().optional(),\n successorSlug: z.string().nullable().optional(),\n })\n .strict();\n\nexport const ModelsListResponseSchema = z\n .object({\n models: z.array(ModelSummarySchema),\n })\n .strict();\n\nexport type ModelSummary = z.infer<typeof ModelSummarySchema>;\nexport type ModelsListResponse = z.infer<typeof ModelsListResponseSchema>;\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface ModelClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildModelClient(opts: ModelClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import type { ApiClient } from '../../api/client.js';\nimport {\n ModelsListResponseSchema,\n type ModelSummary,\n type ModelsListResponse,\n} from '../../schemas/models.js';\n\nimport { buildModelClient, type ModelClientOptions } from './internal.js';\n\nexport interface ModelListOptions extends ModelClientOptions {\n category?: string;\n tier?: string;\n type?: string;\n featured?: boolean;\n client?: ApiClient;\n}\n\nexport interface ModelListResult {\n models: ModelSummary[];\n}\n\nexport async function listModels(opts: ModelListOptions): Promise<ModelListResult> {\n const client = opts.client ?? (await buildModelClient(opts));\n\n const data = await client.request<ModelsListResponse>({\n method: 'GET',\n path: '/models',\n query: {\n category: opts.category,\n tier: opts.tier,\n type: opts.type,\n featured: opts.featured !== undefined ? String(opts.featured) : undefined,\n },\n responseSchema: ModelsListResponseSchema,\n signal: opts.signal,\n });\n\n return data;\n}\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface NodesClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildNodesClient(opts: NodesClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import { NodeTypeDetailSchema, type NodeTypeDetail } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildNodesClient, type NodesClientOptions } from './internal.js';\n\nexport interface NodesDescribeOptions extends NodesClientOptions {\n type: string;\n client?: ApiClient;\n}\n\nexport async function describeNode(opts: NodesDescribeOptions): Promise<NodeTypeDetail> {\n const client = opts.client ?? (await buildNodesClient(opts));\n return client.request<NodeTypeDetail>({\n method: 'GET',\n path: `/node-types/${encodeURIComponent(opts.type)}`,\n responseSchema: NodeTypeDetailSchema,\n signal: opts.signal,\n });\n}\n","import {\n NodeTypesListResponseSchema,\n type NodeTypeSummary,\n type NodeTypesListResponse,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildNodesClient, type NodesClientOptions } from './internal.js';\n\nexport interface NodesListOptions extends NodesClientOptions {\n client?: ApiClient;\n}\n\nexport interface NodesListResult {\n nodeTypes: NodeTypeSummary[];\n}\n\nexport async function listNodes(opts: NodesListOptions): Promise<NodesListResult> {\n const client = opts.client ?? (await buildNodesClient(opts));\n\n const data = await client.request<NodeTypesListResponse>({\n method: 'GET',\n path: '/node-types',\n responseSchema: NodeTypesListResponseSchema,\n signal: opts.signal,\n });\n\n return data;\n}\n","// Client-side scope pre-flight.\n//\n// A token minted before a scope existed cannot use the endpoints that require\n// it, and the server's answer is a bare 403 that says nothing about re-login\n// being the fix. This module turns the scopes recorded at login into a fast,\n// offline failure with an actionable remedy.\n//\n// IT IS NOT AUTHORIZATION. The recorded scopes are a snapshot from login, and\n// they can be revoked or widened server-side afterwards, so this check is\n// necessarily both incomplete and potentially stale:\n//\n// - stale-permissive: a scope was revoked after login. The check passes and\n// the server still 403s, which is why the curated server-response mapping\n// in dispatch.ts stays armed regardless of what happens here.\n// - unknowable: the token came from --token or CLICKRAFT_TOKEN, so there are\n// no recorded scopes at all. The check must then do NOTHING. Failing closed\n// on an unknown would break every CI caller that supplies a token by env\n// var, and those are exactly the callers most likely to hold a fresh token.\n//\n// So: a fast path over an authority that always runs, never a replacement.\n\nimport { ApiError } from '../api/client.js';\nimport type { ResolvedConfig } from '../config/loader.js';\n\nexport const PRODUCTS_WRITE_SCOPE = 'products:write';\n\n/**\n * Throw when the recorded scopes are known and do not include `scope`.\n *\n * No-op when `config.scopes` is null (unknown), which is the flag/env-token\n * case. `hint` matches what the server-response mapping produces for the same\n * failure, so the user sees one consistent remedy whichever path reports it.\n */\nexport function assertScope(config: ResolvedConfig, scope: string, hint: string): void {\n if (config.scopes === null) return;\n if (config.scopes.includes(scope)) return;\n\n throw new ApiError('AUTH_TOKEN_SCOPE_INSUFFICIENT', hint, { retryable: false, hint });\n}\n","import {\n ProductSummarySchema,\n parseProductCreateRequest,\n type ProductCreateImage,\n type ProductSummary,\n} from '@clickraft/sdk';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { PRODUCTS_WRITE_SCOPE, assertScope } from '../../auth/scopes.js';\nimport { ArgError } from '../../cli/args.js';\nimport { loadConfig } from '../../config/loader.js';\n\nimport type { ParsedImageSpec } from './parse-image-spec.js';\n\nexport interface ProductCreateOptions {\n name: string;\n description?: string;\n images: ParsedImageSpec[];\n /** assetId of the image to mark primary. Must be one of `images`. */\n primary?: string;\n /**\n * Overrides the SDK's per-invocation UUID. The only way to get idempotency\n * ACROSS process invocations, which a shell script wrapping the CLI in its\n * own retry loop needs.\n */\n idempotencyKey?: string;\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n scopeHint: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nconst IDEMPOTENCY_KEY_MAX = 255;\n\nexport async function createProduct(options: ProductCreateOptions): Promise<ProductSummary> {\n if (options.idempotencyKey !== undefined) {\n const len = options.idempotencyKey.length;\n if (len < 1 || len > IDEMPOTENCY_KEY_MAX) {\n throw new ArgError(`--idempotency-key must be 1..${IDEMPOTENCY_KEY_MAX} characters.`);\n }\n }\n\n const config = await loadConfig({\n flagProfile: options.profile,\n flagApiBaseUrl: options.apiBaseUrl,\n flagToken: options.token,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n // Before the client is even built: a token that provably lacks the scope\n // cannot succeed, and a wasted round trip buys nothing but a worse message.\n // Silent when the scopes are unknown — see auth/scopes.ts.\n assertScope(config, PRODUCTS_WRITE_SCOPE, options.scopeHint);\n\n const body = buildRequestBody(options);\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n // `responseSchema` is the INNER shape: the SDK client unwraps `{ data }`\n // before validating, so this is ProductSummarySchema and not a wrapper.\n //\n // No `idempotencyKey` passed means the SDK mints a UUIDv4 once, outside its\n // retry loop, so every attempt of THIS call carries the same key. That is what\n // makes the 503 STORAGE_UNAVAILABLE retry replay instead of double-creating.\n return client.request<ProductSummary>({\n method: 'POST',\n path: '/products',\n body,\n idempotencyKey: options.idempotencyKey,\n responseSchema: ProductSummarySchema,\n signal: options.signal,\n });\n}\n\n/**\n * Assemble and validate the request body.\n *\n * `--primary` is resolved here rather than defaulted: when it is absent no\n * `isPrimary` is sent at all and the SERVER decides (index 0 becomes primary).\n * Duplicating that rule client-side would create a second place for it to drift.\n */\nfunction buildRequestBody(options: ProductCreateOptions): unknown {\n if (options.images.length === 0) {\n throw new ArgError('At least one --image is required.');\n }\n\n if (options.primary !== undefined) {\n const known = options.images.some((img) => img.assetId === options.primary);\n if (!known) {\n throw new ArgError(`--primary ${options.primary} is not among the --image assets provided.`);\n }\n }\n\n const images: ProductCreateImage[] = options.images.map((img) => {\n const entry: ProductCreateImage = { assetId: img.assetId };\n if (img.altText !== undefined) entry.altText = img.altText;\n // Only the chosen image carries the flag. The others omit it rather than\n // sending `false`: same server branch, smaller body, and it keeps \"the\n // caller expressed no preference\" distinguishable in the payload.\n if (options.primary === img.assetId) entry.isPrimary = true;\n return entry;\n });\n\n const raw: Record<string, unknown> = { name: options.name, images };\n if (options.description !== undefined) raw.description = options.description;\n\n // The SDK owns duplicate-detection, the image cap, field bounds and the byte\n // cap, so the CLI and the MCP tool reject exactly the same payloads.\n return parseProductCreateRequest(raw);\n}\n","// TODO: brand-model/list.ts and template schemas use .strict() on response\n// schemas, causing SCHEMA_MISMATCH when the server adds fields. Audit and\n// relax those separately — out of scope for this PR.\n\nimport { ProductsListResponseSchema, type ProductSummary } from '@clickraft/sdk';\nimport { z } from 'zod';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface ProductListOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n cursor?: string;\n limit?: number;\n syncStatus?: string;\n sourceType?: string;\n search?: string;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nconst DEFAULT_LIMIT = 50;\n\nexport interface ProductListResult {\n products: ProductSummary[];\n nextCursor: string | null;\n hasMore: boolean;\n}\n\nexport async function listProducts(options: ProductListOptions): Promise<ProductListResult> {\n const config = await loadConfig({\n flagProfile: options.profile,\n flagApiBaseUrl: options.apiBaseUrl,\n flagToken: options.token,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const query: Record<string, string | number | undefined> = {\n limit: options.limit ?? DEFAULT_LIMIT,\n };\n if (options.cursor) query.cursor = options.cursor;\n if (options.syncStatus) query.syncStatus = options.syncStatus;\n if (options.sourceType) query.sourceType = options.sourceType;\n if (options.search) query.search = options.search;\n\n const data = await client.request<z.infer<typeof ProductsListResponseSchema>>({\n method: 'GET',\n path: '/products',\n query,\n responseSchema: ProductsListResponseSchema,\n signal: options.signal,\n });\n\n return {\n products: data.items,\n nextCursor: data.nextCursor,\n hasMore: data.nextCursor !== null,\n };\n}\n","// Parses a `--image` spec into a product-create image entry.\n//\n// Shape: `<assetId>[:<altText>]`, matching the colon-spec idiom already used by\n// `--product` and `--brand-model`.\n\nimport { UUID_RE } from '@clickraft/sdk';\n\nimport { ArgError } from '../../cli/args.js';\n\nexport interface ParsedImageSpec {\n assetId: string;\n altText?: string;\n}\n\n/**\n * Split on the FIRST colon only, so alt text may contain colons\n * (`--image \"<uuid>:Mug: the sequel\"`). That is unambiguous because the left\n * side must be a UUID, which never contains one.\n *\n * `UUID_RE` comes from the SDK rather than a local regex on purpose: it is\n * pinned to the server's own published pattern, and a second copy here would be\n * the drift this CLI just spent a commit eliminating.\n */\nexport function parseImageSpec(spec: string): ParsedImageSpec {\n const trimmed = spec.trim();\n if (trimmed.length === 0) {\n throw new ArgError('--image requires a value of the form <assetId>[:<altText>].');\n }\n\n const colon = trimmed.indexOf(':');\n // Both sides are trimmed independently: trimming only the whole spec leaves\n // `<uuid> : alt` with a trailing space on the id, which then fails UUID_RE\n // with a confusing \"not a UUID\" message about a string that plainly is one.\n const assetId = (colon === -1 ? trimmed : trimmed.slice(0, colon)).trim();\n const rawAlt = colon === -1 ? undefined : trimmed.slice(colon + 1).trim();\n\n if (!UUID_RE.test(assetId)) {\n throw new ArgError(\n `--image expects an asset id (UUID) before the colon, got \"${assetId}\". ` +\n 'Use the assetId returned by `clickraft upload`.',\n );\n }\n\n // `<uuid>:` with nothing after it means no alt text, not empty alt text: the\n // server would reject \"\" against `.min(1)`-less but trimmed semantics, and an\n // empty string is never what the caller meant.\n return rawAlt ? { assetId, altText: rawAlt } : { assetId };\n}\n","// Agent / CI environment detection. Source: 04-fingerprinting.md §2.1–§2.4\n// and wave-1-investigation.md Phase 8 Q3 (\"default OFF in non-interactive /\n// CI / agent contexts\"). The detection here is read-only — telemetry SDKs\n// will consult `detectAgents(process.env).detected` before initializing.\n\nexport interface DetectedAgents {\n detected: string[];\n signals: Record<string, string>;\n}\n\n// `signal → agent label` lookup. The order does not matter; signals are\n// independent. If multiple variables for the same agent are set, the agent\n// appears once in `detected` and every triggered env var lands in `signals`.\nconst AGENT_SIGNALS: ReadonlyArray<{ envVar: string; agent: string }> = [\n { envVar: 'CLAUDE_CODE_SESSION_ID', agent: 'claude-code' },\n { envVar: 'CLAUDECODE', agent: 'claude-code' },\n { envVar: 'CURSOR_SESSION', agent: 'cursor' },\n { envVar: 'CURSOR_TRACE_ID', agent: 'cursor' },\n { envVar: 'OPENAI_CODEX_ENV', agent: 'codex' },\n { envVar: 'CODEX_CLI', agent: 'codex' },\n { envVar: 'CI', agent: 'ci' },\n];\n\nexport function detectAgents(env: NodeJS.ProcessEnv = process.env): DetectedAgents {\n const detected = new Set<string>();\n const signals: Record<string, string> = {};\n\n for (const { envVar, agent } of AGENT_SIGNALS) {\n const value = env[envVar];\n if (value !== undefined && value !== '' && value !== '0') {\n detected.add(agent);\n signals[envVar] = agent;\n }\n }\n\n return { detected: [...detected].sort(), signals };\n}\n","// `clickraft telemetry inspect` — transparency surface per Phase 8 Q3.\n//\n// Wave 1: no telemetry SDK is wired in (Sentry crash SDK is planned for the\n// Wave 1 release pipeline, PostHog product-analytics SDK is deferred to\n// Wave 2 per `wave-1-investigation.md` line 484). This command reports the\n// current opt-in/opt-out state, what would be sent, and which agent-detection\n// signals are tripping.\n\nimport { TELEMETRY_DISABLE_ENV_VAR } from '../../config/loader.js';\nimport { detectAgents } from '../../telemetry/detect.js';\n\nexport type CrashReportsReason = 'default' | 'env-disabled' | 'opt-out';\nexport type ProductAnalyticsReason = 'opt-in-pending' | 'opt-in-active';\n\nexport interface TelemetryState {\n crashReports: {\n enabled: boolean;\n reason: CrashReportsReason;\n sdkShipped: boolean;\n };\n productAnalytics: {\n enabled: boolean;\n reason: ProductAnalyticsReason;\n sdkShipped: boolean;\n };\n agentDetection: {\n enabled: boolean;\n signals: Record<string, string>;\n detected: string[];\n };\n envOverrides: {\n CLICKRAFT_DISABLE_TELEMETRY: boolean;\n DO_NOT_TRACK: boolean;\n };\n payloadShape: {\n crashReports: Record<string, unknown>;\n productAnalytics: Record<string, unknown>;\n };\n}\n\nexport interface InspectOptions {\n env?: NodeJS.ProcessEnv;\n}\n\nexport function inspectTelemetry(options: InspectOptions = {}): TelemetryState {\n const env = options.env ?? process.env;\n const optedOut = env[TELEMETRY_DISABLE_ENV_VAR] === '1' || env.DO_NOT_TRACK === '1';\n const agents = detectAgents(env);\n\n // SDK shipped status — currently both false in Wave 1.\n const crashSdkShipped = false;\n const productSdkShipped = false;\n\n return {\n crashReports: {\n enabled: false, // SDK not shipped → not enabled regardless of opt-out flags\n reason: optedOut ? 'env-disabled' : 'default',\n sdkShipped: crashSdkShipped,\n },\n productAnalytics: {\n enabled: false,\n reason: 'opt-in-pending',\n sdkShipped: productSdkShipped,\n },\n agentDetection: {\n enabled: agents.detected.length > 0,\n signals: agents.signals,\n detected: agents.detected,\n },\n envOverrides: {\n CLICKRAFT_DISABLE_TELEMETRY: env[TELEMETRY_DISABLE_ENV_VAR] === '1',\n DO_NOT_TRACK: env.DO_NOT_TRACK === '1',\n },\n payloadShape: {\n crashReports: {\n event: 'unhandled_exception',\n error_type: 'string',\n error_message: 'string (token-redacted)',\n stack_redacted: 'string',\n cli_version: 'string',\n node_version: 'string',\n platform: 'string',\n agents_detected: 'string[]',\n },\n productAnalytics: {\n event: 'command_completed',\n command: 'string (e.g. \"tokens.list\")',\n exit_code: 'number',\n duration_ms: 'number',\n cli_version: 'string',\n agents_detected: 'string[]',\n },\n },\n };\n}\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface TemplateClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildTemplateClient(opts: TemplateClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import {\n TemplatesListResponseSchema,\n type TemplateSummary,\n type TemplatesListResponse,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildTemplateClient, type TemplateClientOptions } from './internal.js';\n\nexport interface TemplateListOptions extends TemplateClientOptions {\n q?: string;\n tags?: string[];\n scope?: 'own' | 'system' | 'all';\n cursor?: string;\n limit?: number;\n client?: ApiClient;\n}\n\nexport interface TemplateListResult {\n templates: TemplateSummary[];\n cursor: string | null;\n hasMore: boolean;\n}\n\nexport async function listTemplates(opts: TemplateListOptions): Promise<TemplateListResult> {\n const client = opts.client ?? (await buildTemplateClient(opts));\n\n const data = await client.request<TemplatesListResponse>({\n method: 'GET',\n path: '/templates',\n query: {\n q: opts.q,\n tags: opts.tags,\n scope: opts.scope,\n cursor: opts.cursor,\n limit: opts.limit,\n },\n responseSchema: TemplatesListResponseSchema,\n signal: opts.signal,\n });\n\n return data;\n}\n","import type { ApiClient } from '../../api/client.js';\n\nimport { type TemplateClientOptions } from './internal.js';\nimport { listTemplates, type TemplateListResult } from './list.js';\n\nexport interface TemplateFindOptions extends TemplateClientOptions {\n query: string;\n tags?: string[];\n scope?: 'own' | 'system' | 'all';\n limit?: number;\n cursor?: string;\n client?: ApiClient;\n}\n\nexport async function findTemplates(opts: TemplateFindOptions): Promise<TemplateListResult> {\n return listTemplates({\n q: opts.query,\n tags: opts.tags,\n scope: opts.scope,\n limit: opts.limit,\n cursor: opts.cursor,\n profile: opts.profile,\n apiBaseUrl: opts.apiBaseUrl,\n token: opts.token,\n signal: opts.signal,\n client: opts.client,\n });\n}\n","import { TemplateDetailSchema, type TemplateDetail } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildTemplateClient, type TemplateClientOptions } from './internal.js';\n\nexport interface TemplateGetOptions extends TemplateClientOptions {\n id: string;\n client?: ApiClient;\n}\n\nexport async function getTemplate(opts: TemplateGetOptions): Promise<TemplateDetail> {\n const client = opts.client ?? (await buildTemplateClient(opts));\n return client.request<TemplateDetail>({\n method: 'GET',\n path: `/templates/${encodeURIComponent(opts.id)}`,\n responseSchema: TemplateDetailSchema,\n signal: opts.signal,\n });\n}\n","// `clickraft tokens list` — GET /api/agents/v1/tokens.\n//\n// The RFC names the endpoint (`01-tool-surface.md` §7.2, `02-oauth.md` §7)\n// but does not pin the per-row shape. The per-row contract (now in\n// @clickraft/sdk) is the CLI's assumption; if the server diverges the\n// integration test will surface it via SCHEMA_MISMATCH from ApiClient's\n// strict Zod validation.\n\nimport { TokensListResponseSchema, type TokenRow } from '@clickraft/sdk';\nimport { z } from 'zod';\n\nimport { createApiClient, type ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface TokensListOptions {\n profile?: string;\n signal?: AbortSignal;\n credentialsPath?: string;\n apiClientFactory?: (apiBaseUrl: string, accessToken: string) => ApiClient;\n}\n\nexport async function listTokens(options: TokensListOptions): Promise<TokenRow[]> {\n const config = await loadConfig({\n flagProfile: options.profile,\n credentialsPath: options.credentialsPath,\n });\n if (!config.accessToken) {\n throw new AuthError('AUTH_TOKEN_MISSING', `Not authenticated. Run \\`clickraft login\\` first.`);\n }\n\n const factory =\n options.apiClientFactory ??\n ((apiBaseUrl: string, accessToken: string): ApiClient =>\n createApiClient({\n apiBaseUrl,\n accessToken,\n signal: options.signal,\n cloudflareAccess: config.cloudflareAccess,\n }));\n const client = factory(config.apiBaseUrl, config.accessToken);\n\n const data = await client.request<z.infer<typeof TokensListResponseSchema>>({\n method: 'GET',\n path: '/tokens',\n responseSchema: TokensListResponseSchema,\n signal: options.signal,\n });\n\n return data;\n}\n","import { createApiClient, type ApiClient } from '../../api/client.js';\nimport { loadConfig } from '../../config/loader.js';\n\nexport interface WorkflowClientOptions {\n profile?: string;\n apiBaseUrl?: string;\n token?: string;\n signal?: AbortSignal;\n}\n\nexport async function buildWorkflowClient(opts: WorkflowClientOptions): Promise<ApiClient> {\n const cfg = await loadConfig({\n flagProfile: opts.profile,\n flagApiBaseUrl: opts.apiBaseUrl,\n flagToken: opts.token,\n });\n return createApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import {\n applyWorkflowWithRetry,\n WorkflowDetailSchema,\n WorkflowMutateResponseSchema,\n type ApiClient,\n type WorkflowDetail,\n type WorkflowMutateResponse,\n} from '@clickraft/sdk';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowApplyOptions extends WorkflowClientOptions {\n id: string;\n canvasRev: number;\n operations: Record<string, unknown>[];\n idempotencyKey?: string;\n autoRev?: boolean;\n client?: ApiClient;\n}\n\nexport interface WorkflowApplyResult {\n canvasRev: number;\n applied: number;\n workflow: WorkflowDetail;\n retriedWithRev?: number;\n}\n\n// Thin CLI wrapper around the SDK orchestration (Phase 4a). The CLI resolves\n// config + builds the client, then injects the real response schemas; the\n// auto-rev-retry algorithm itself lives in @clickraft/sdk and is UX-free /\n// disk-free. Rendering and exit codes stay in the dispatcher.\nexport async function applyWorkflow(opts: WorkflowApplyOptions): Promise<WorkflowApplyResult> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n return applyWorkflowWithRetry<WorkflowMutateResponse, WorkflowDetail>({\n client,\n id: opts.id,\n canvasRev: opts.canvasRev,\n operations: opts.operations,\n idempotencyKey: opts.idempotencyKey,\n autoRev: opts.autoRev,\n signal: opts.signal,\n schemas: { mutate: WorkflowMutateResponseSchema, detail: WorkflowDetailSchema },\n });\n}\n","import { WorkflowCreateResponseSchema, type WorkflowCreateResponse } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\nimport { ArgError } from '../../cli/args.js';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowCreateOptions extends WorkflowClientOptions {\n name: string;\n description?: string;\n tags?: string[];\n declaredParams?: Record<string, unknown> | Array<Record<string, unknown>>;\n client?: ApiClient;\n}\n\nfunction toParamArray(\n input: Record<string, unknown> | Array<Record<string, unknown>>,\n): Array<Record<string, unknown>> {\n if (Array.isArray(input)) return input;\n return Object.entries(input).map(([key, val]) => {\n const def = typeof val === 'object' && val !== null ? (val as Record<string, unknown>) : {};\n if (def.name !== undefined && def.name !== key) {\n throw new ArgError(\n `declared_params key '${key}' conflicts with inner name '${String(def.name)}'.`,\n );\n }\n return { name: key, ...def };\n });\n}\n\nexport async function createWorkflow(opts: WorkflowCreateOptions): Promise<WorkflowCreateResponse> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n const body: Record<string, unknown> = { name: opts.name };\n if (opts.description !== undefined) body.description = opts.description;\n if (opts.tags !== undefined && opts.tags.length > 0) body.tags = opts.tags;\n if (opts.declaredParams !== undefined) body.declared_params = toParamArray(opts.declaredParams);\n\n return client.request<WorkflowCreateResponse>({\n method: 'POST',\n path: '/workflows',\n body,\n responseSchema: WorkflowCreateResponseSchema,\n signal: opts.signal,\n });\n}\n","import { WorkflowDetailSchema, type WorkflowDetail } from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowGetOptions extends WorkflowClientOptions {\n id: string;\n client?: ApiClient;\n}\n\nexport async function getWorkflow(opts: WorkflowGetOptions): Promise<WorkflowDetail> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n return client.request<WorkflowDetail>({\n method: 'GET',\n path: `/workflows/${encodeURIComponent(opts.id)}`,\n responseSchema: WorkflowDetailSchema,\n signal: opts.signal,\n });\n}\n","import {\n WorkflowsListResponseSchema,\n type WorkflowSummary,\n type WorkflowsListResponse,\n} from '@clickraft/sdk';\n\nimport type { ApiClient } from '../../api/client.js';\n\nimport { buildWorkflowClient, type WorkflowClientOptions } from './internal.js';\n\nexport interface WorkflowListOptions extends WorkflowClientOptions {\n cursor?: string;\n limit?: number;\n tags?: string[];\n declaredParamsHasKey?: string;\n client?: ApiClient;\n}\n\nexport interface WorkflowListResult {\n items: WorkflowSummary[];\n nextCursor: string | null;\n hasMore: boolean;\n}\n\nexport async function listWorkflows(opts: WorkflowListOptions): Promise<WorkflowListResult> {\n const client = opts.client ?? (await buildWorkflowClient(opts));\n\n const data = await client.request<WorkflowsListResponse>({\n method: 'GET',\n path: '/workflows',\n query: {\n cursor: opts.cursor,\n limit: opts.limit,\n tags: opts.tags?.join(','),\n declared_params_has_key: opts.declaredParamsHasKey,\n },\n responseSchema: WorkflowsListResponseSchema,\n signal: opts.signal,\n });\n\n return {\n items: data.items,\n nextCursor: data.nextCursor,\n hasMore: data.nextCursor !== null,\n };\n}\n","// Dual error format per Phase 8 Q10 of `wave-1-investigation.md`.\n//\n// Human (stderr): 4-line template\n// Error: <message>\n// Code: E_<CODE>\n// Try: <hint or fallback>\n// Request ID: <id or 'n/a'>\n//\n// JSON (stdout): full envelope via wrapError.\n\nimport { ApiError } from '../api/client.js';\nimport { wrapError, type EnvelopeContext } from '../api/envelope.js';\nimport { AuthError, CredentialsError } from '../auth/errors.js';\n\nimport { EXIT_CODE_MAP, toEnvelopeCode, type AllErrorCode } from './codes.js';\n\nconst FALLBACK_HINT = 'See `clickraft --help` or contact support.';\n\nexport function formatHumanError(err: unknown): string {\n const view = errorToView(err);\n const lines = [\n `Error: ${view.message}`,\n `Code: ${view.code}`,\n `Try: ${view.hint}`,\n `Request ID: ${view.requestId ?? 'n/a'}`,\n ];\n if (view.details) lines.push(`Details: ${view.details}`);\n return lines.join('\\n');\n}\n\nexport function formatJsonError(err: unknown, ctx: EnvelopeContext): string {\n return JSON.stringify(wrapError(err, ctx));\n}\n\ninterface ErrorView {\n code: string;\n message: string;\n hint: string;\n requestId?: string;\n details?: string;\n}\n\nfunction formatDetails(details: unknown): string | undefined {\n if (details == null) return undefined;\n if (typeof details !== 'object') return String(details);\n const entries = Object.entries(details as Record<string, unknown>);\n if (entries.length === 0) return undefined;\n return entries.map(([k, v]) => `${k}=${v}`).join(', ');\n}\n\nfunction errorToView(err: unknown): ErrorView {\n if (err instanceof ApiError) {\n return {\n code: toEnvelopeCode(err.code),\n message: err.message,\n hint: err.meta.hint ?? EXIT_CODE_MAP[err.code]?.hint ?? FALLBACK_HINT,\n requestId: err.meta.requestId,\n details: formatDetails(err.meta.details),\n };\n }\n if (err instanceof AuthError || err instanceof CredentialsError) {\n const code = err.code as AllErrorCode;\n return {\n code: toEnvelopeCode(code),\n message: err.message,\n hint: EXIT_CODE_MAP[code]?.hint ?? FALLBACK_HINT,\n };\n }\n return {\n code: toEnvelopeCode('INTERNAL_ERROR'),\n message: err instanceof Error ? err.message : String(err),\n hint: FALLBACK_HINT,\n };\n}\n","// Minimal argv parser for the Wave 1 command surface. 0-dep state machine.\n//\n// Surface today: subcommand path + flags only (no positional args until 1A.4\n// introduces `upload <file>` and `generate get <id>`). If the surface outgrows\n// this, swap to `commander@^12` at that point.\n\nexport interface ParsedArgs {\n command: string[];\n flags: Record<string, string | boolean | undefined>;\n positional: string[];\n}\n\nconst SHORT_ALIASES: Record<string, string> = {\n h: 'help',\n v: 'version',\n};\n\n// Long flags whose value follows in the next argv token (`--profile staging`\n// vs `--profile=staging`). Anything not in this set is treated as a boolean\n// switch — keeps `--json` and friends from greedily eating the next arg.\nconst VALUE_FLAGS: ReadonlySet<string> = new Set(['profile', 'api-base-url', 'scope', 'token']);\n\nexport function parseArgs(argv: string[]): ParsedArgs {\n const flags: Record<string, string | boolean | undefined> = {};\n const positional: string[] = [];\n const command: string[] = [];\n let commandLocked = false;\n\n let i = 0;\n while (i < argv.length) {\n const raw = argv[i]!;\n\n if (raw === '--') {\n // Everything after `--` is positional, no flag parsing.\n for (let j = i + 1; j < argv.length; j += 1) positional.push(argv[j]!);\n break;\n }\n\n if (raw.startsWith('--')) {\n const eq = raw.indexOf('=');\n const name = eq === -1 ? raw.slice(2) : raw.slice(2, eq);\n const inline = eq === -1 ? undefined : raw.slice(eq + 1);\n\n if (name.startsWith('no-')) {\n flags[name.slice(3)] = false;\n i += 1;\n commandLocked = true;\n continue;\n }\n\n if (VALUE_FLAGS.has(name)) {\n if (inline !== undefined) {\n flags[name] = inline;\n } else {\n const next = argv[i + 1];\n if (next === undefined || next.startsWith('-')) {\n // Missing value — leave as boolean true so the command handler\n // can surface a clear \"flag requires a value\" error.\n flags[name] = true;\n } else {\n flags[name] = next;\n i += 1;\n }\n }\n } else {\n flags[name] = inline ?? true;\n }\n i += 1;\n commandLocked = true;\n continue;\n }\n\n if (raw.startsWith('-') && raw.length > 1) {\n // Short flags: only -h / -v are recognized; everything else falls\n // through as a positional so error messages can point at it.\n const short = raw.slice(1);\n const aliased = SHORT_ALIASES[short];\n if (aliased) {\n flags[aliased] = true;\n i += 1;\n commandLocked = true;\n continue;\n }\n positional.push(raw);\n i += 1;\n commandLocked = true;\n continue;\n }\n\n if (!commandLocked) {\n command.push(raw);\n } else {\n positional.push(raw);\n }\n i += 1;\n }\n\n return { command, flags, positional };\n}\n","// User-facing progress UI for `clickraft login`. All output goes to stderr so\n// stdout stays clean for `--json` consumers and shell redirection.\n\nimport { spawn } from 'node:child_process';\n\nexport interface UserCodePromptInfo {\n userCode: string;\n verificationUri: string;\n verificationUriComplete: string;\n expiresAt: Date;\n}\n\nexport function renderUserCodePrompt(\n info: UserCodePromptInfo,\n stream: NodeJS.WritableStream = process.stderr,\n): void {\n const lines = [\n '',\n 'To complete login, visit:',\n ` ${info.verificationUriComplete}`,\n '',\n `And enter the code: ${info.userCode}`,\n `Code expires at: ${info.expiresAt.toISOString()}`,\n '',\n ];\n stream.write(lines.join('\\n'));\n}\n\n// Best-effort browser open. Returns true if a spawn was issued. Never throws —\n// a failure here is a UX degradation, not a flow-blocking error.\nexport function openBrowser(url: string): boolean {\n if (!process.stderr.isTTY) return false;\n\n const command = pickBrowserCommand();\n if (!command) return false;\n\n try {\n const child = spawn(command.bin, [...command.args, url], {\n stdio: 'ignore',\n detached: true,\n });\n child.on('error', () => {\n // Swallow — caller has already printed the URL.\n });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n\nfunction pickBrowserCommand(): { bin: string; args: string[] } | undefined {\n if (process.platform === 'darwin') return { bin: 'open', args: [] };\n if (process.platform === 'win32') return { bin: 'cmd', args: ['/c', 'start', ''] };\n if (process.platform === 'linux') return { bin: 'xdg-open', args: [] };\n return undefined;\n}\n\nconst SPINNER_FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];\nconst SPINNER_INTERVAL_MS = 80;\n\nexport interface Spinner {\n stop(): void;\n}\n\nexport function startPollingSpinner(\n label = 'Waiting for authorization…',\n stream: NodeJS.WriteStream = process.stderr,\n): Spinner {\n if (!stream.isTTY) {\n return { stop() {} };\n }\n\n let frame = 0;\n const handle = setInterval(() => {\n stream.write(`\\r${SPINNER_FRAMES[frame]!} ${label}`);\n frame = (frame + 1) % SPINNER_FRAMES.length;\n }, SPINNER_INTERVAL_MS);\n\n return {\n stop(): void {\n clearInterval(handle);\n // Erase the spinner line so subsequent output starts clean.\n stream.write(`\\r${' '.repeat(label.length + 4)}\\r`);\n },\n };\n}\n","// Human-mode result renderers. JSON mode uses wrapSuccess directly from the\n// dispatcher — this module only deals with the friendly stdout/stderr output\n// shown to a terminal user.\n\nimport type {\n BalanceData,\n BrandModelSummary,\n NodeTypeDetail,\n ProductSummary,\n TemplateDetail,\n TokenRow,\n WorkflowCreateResponse,\n WorkflowDetail,\n} from '@clickraft/sdk';\n\nimport { type LoginResult } from '../commands/login.js';\nimport { type LogoutResult } from '../commands/logout.js';\nimport { type ModelListResult } from '../commands/models/list.js';\nimport { type NodesListResult } from '../commands/nodes/list.js';\nimport { type ProductListResult } from '../commands/product/list.js';\nimport { type TelemetryState } from '../commands/telemetry/inspect.js';\nimport { type TemplateListResult } from '../commands/template/list.js';\nimport { type WorkflowApplyResult } from '../commands/workflow/apply.js';\nimport { type WorkflowListResult } from '../commands/workflow/list.js';\nimport { type ModelSummary } from '../schemas/models.js';\n\nexport function renderLoginResult(result: LoginResult, out: NodeJS.WritableStream): void {\n const expiresHuman = formatExpiresAt(result.expiresAt);\n const lines = [\n `✓ Logged in (profile: ${result.profileName}).`,\n ` Token prefix: ${result.tokenPrefix}`,\n ` Expires: ${expiresHuman}`,\n ` Scopes: ${result.scopes.join(' ')}`,\n ];\n if (!result.identityKnown) {\n // Surface the Wave 1 limitation so the user knows organizationSlug /\n // userId in the credentials file are placeholders. Quiet enough not to\n // alarm; specific enough to be auditable.\n lines.push(\n ` Note: Identity not populated (Wave 1 server-response gap, see PR description).`,\n );\n }\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderLogoutResult(result: LogoutResult, out: NodeJS.WritableStream): void {\n if (result.profilesRemoved[0] === '*') {\n out.write('✓ Removed all profiles.\\n');\n return;\n }\n const name = result.profilesRemoved[0] ?? '(unknown)';\n if (result.serverRevoked) {\n out.write(`✓ Logged out of profile \"${name}\" (server-side token revoked).\\n`);\n } else if (result.revokeFailureMessage) {\n out.write(`✓ Logged out of profile \"${name}\" locally; server-side revoke failed.\\n`);\n } else {\n out.write(`✓ Logged out of profile \"${name}\" (local only).\\n`);\n }\n}\n\nexport function renderTokensList(rows: TokenRow[], out: NodeJS.WritableStream): void {\n if (rows.length === 0) {\n out.write('No tokens.\\n');\n return;\n }\n\n const headers = ['PREFIX', 'NAME', 'SCOPES', 'LAST USED', 'EXPIRES'];\n const data = rows.map((row) => [\n row.tokenPrefix,\n row.name ?? '—',\n row.scopes.join(',') || '—',\n row.lastUsedAt ?? 'never',\n row.expiresAt,\n ]);\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n}\n\nexport function renderTelemetryState(state: TelemetryState, out: NodeJS.WritableStream): void {\n const crash = state.crashReports;\n const product = state.productAnalytics;\n const agents = state.agentDetection;\n\n const lines = [\n 'Telemetry state:',\n '',\n ` Crash reports: ${crash.enabled ? 'ON' : 'OFF'} (${crash.reason}${crash.sdkShipped ? '' : ', SDK not shipped'})`,\n ` Product analytics: ${product.enabled ? 'ON' : 'OFF'} (${product.reason}${product.sdkShipped ? '' : ', SDK not shipped'})`,\n ` Agent detection: ${agents.enabled ? 'ON' : 'OFF'}`,\n ` Detected agents: ${agents.detected.length === 0 ? '(none)' : agents.detected.join(', ')}`,\n '',\n 'Env overrides:',\n ` CLICKRAFT_DISABLE_TELEMETRY=${state.envOverrides.CLICKRAFT_DISABLE_TELEMETRY ? '1' : '0'}`,\n ` DO_NOT_TRACK=${state.envOverrides.DO_NOT_TRACK ? '1' : '0'}`,\n '',\n 'Payload shape (illustrative — no data is currently sent):',\n ` ${JSON.stringify(state.payloadShape, null, 2).split('\\n').join('\\n ')}`,\n ];\n out.write(lines.join('\\n') + '\\n');\n}\n\nconst fmtNum = new Intl.NumberFormat('en-US');\n\nexport function renderBalance(data: BalanceData, out: NodeJS.WritableStream): void {\n const pad = 22;\n const lines = [\n `${'Total credits:'.padEnd(pad)}${fmtNum.format(data.totalCredits).padStart(12)}`,\n `${'├─ Subscription:'.padEnd(pad)}${fmtNum.format(data.subscriptionCredits).padStart(12)}`,\n `${'├─ Purchased:'.padEnd(pad)}${fmtNum.format(data.purchasedCredits).padStart(12)}`,\n `${'└─ Promotional:'.padEnd(pad)}${fmtNum.format(data.promotionalCredits).padStart(12)}`,\n '',\n `${'Rate limit:'.padEnd(pad)}${fmtNum.format(data.rateLimit.apiBurstPerMinute).padStart(12)} req/min`,\n ];\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderBrandModelsList(\n models: BrandModelSummary[],\n out: NodeJS.WritableStream,\n): void {\n if (models.length === 0) {\n out.write('No brand models.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['SOURCE', 'NAME', 'SLUG', 'CATEGORY', 'TAGS'];\n const data = models.map((m) => {\n const shown = m.tags.slice(0, MAX_TAGS).join(', ');\n const extra = m.tags.length > MAX_TAGS ? ` +${m.tags.length - MAX_TAGS} more` : '';\n return [\n m.source,\n m.name,\n m.slug ?? '—',\n m.category ?? '—',\n m.tags.length > 0 ? shown + extra : '—',\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n}\n\nexport function renderProductsList(result: ProductListResult, out: NodeJS.WritableStream): void {\n const { products } = result;\n if (products.length === 0) {\n out.write('No products.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['ID', 'TITLE', 'SOURCE', 'SYNC', 'IMAGES', 'PRIMARY IMAGE', 'VENDOR', 'TAGS'];\n const data = products.map((p) => {\n const shown = p.tags.slice(0, MAX_TAGS).join(', ');\n const extra = p.tags.length > MAX_TAGS ? ` +${p.tags.length - MAX_TAGS} more` : '';\n const primary =\n p.images.find((img) => img.isPrimary) ?? p.images.find((img) => img.sortOrder === 0);\n return [\n p.id,\n p.title,\n p.sourceType,\n p.syncStatus ?? '—',\n String(p.images.length),\n primary?.id ?? '—',\n p.vendor ?? '—',\n p.tags.length > 0 ? shown + extra : '—',\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n if (result.hasMore) {\n out.write('\\nMore results available. Use --cursor to fetch the next page.\\n');\n }\n}\n\nexport function renderProductCreateResult(\n product: ProductSummary,\n out: NodeJS.WritableStream,\n): void {\n const lines = [\n `Created product \"${product.title}\"`,\n ` ID: ${product.id}`,\n ` Source: ${product.sourceType}`,\n ` Images: ${product.images.length}`,\n ];\n for (const img of product.images) {\n // The primary marker matters downstream: `generate create --product <id>`\n // resolves the primary image when no imageId is given, so which one it is\n // decides what a later generation actually references.\n lines.push(\n ` ${img.isPrimary ? '*' : '-'} ${img.id}${img.altText ? ` ${img.altText}` : ''}`,\n );\n }\n lines.push('', `Use it with: clickraft generate create --product ${product.id} ...`);\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderTemplatesList(result: TemplateListResult, out: NodeJS.WritableStream): void {\n const { templates } = result;\n if (templates.length === 0) {\n out.write('No templates.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['SOURCE', 'NAME', 'CATEGORY', 'TAGS', 'CREATED'];\n const data = templates.map((t) => {\n const shown = t.tags.slice(0, MAX_TAGS).join(', ');\n const extra = t.tags.length > MAX_TAGS ? ` +${t.tags.length - MAX_TAGS} more` : '';\n return [\n t.source,\n t.name,\n t.category ?? '—',\n t.tags.length > 0 ? shown + extra : '—',\n t.createdAt.slice(0, 10),\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n if (result.hasMore) {\n out.write('\\nMore results available. Use --cursor to fetch the next page.\\n');\n }\n}\n\nexport function renderTemplateDetail(detail: TemplateDetail, out: NodeJS.WritableStream): void {\n const pad = 17;\n const lines = [\n detail.name,\n `${'ID:'.padEnd(pad)}${detail.id}`,\n `${'Source:'.padEnd(pad)}${detail.source}`,\n `${'Category:'.padEnd(pad)}${detail.category ?? '—'}`,\n `${'Tags:'.padEnd(pad)}${detail.tags.length > 0 ? detail.tags.join(', ') : '—'}`,\n `${'Created:'.padEnd(pad)}${detail.createdAt.slice(0, 10)}`,\n `${'Times used:'.padEnd(pad)}${detail.timesUsed}`,\n ];\n\n if (detail.description) {\n lines.push('', detail.description);\n }\n\n lines.push('', 'Declared parameters:');\n if (detail.declaredParams.length === 0) {\n lines.push(' (none)');\n } else {\n for (const p of detail.declaredParams) {\n const req = p.required ? 'required' : 'optional';\n const desc = p.description ? `: ${p.description}` : '';\n lines.push(` - ${p.name} (${p.type}, ${req})${desc}`);\n }\n }\n\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderNodesList(result: NodesListResult, out: NodeJS.WritableStream): void {\n const { nodeTypes } = result;\n if (nodeTypes.length === 0) {\n out.write('No node types.\\n');\n return;\n }\n\n const headers = ['TYPE', 'PORTS'];\n const data = nodeTypes.map((n) => [n.type, String(n.portCount)]);\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n}\n\nexport function renderNodeDetail(detail: NodeTypeDetail, out: NodeJS.WritableStream): void {\n const lines = [detail.type, '', 'Ports:'];\n if (detail.ports.length === 0) {\n lines.push(' (none)');\n } else {\n // handleId is the canonical edge identifier — print it verbatim, never\n // renamed or prettified, so an agent can copy it to build edges.\n for (const p of detail.ports) {\n lines.push(` - ${p.handleId} (${p.direction}, ${p.dataType})`);\n }\n }\n\n lines.push('', 'Agent-writable fields:');\n if (detail.agentWritableFields.length === 0) {\n lines.push(' (none)');\n } else {\n for (const field of detail.agentWritableFields) {\n lines.push(` - ${field}`);\n }\n }\n\n out.write(lines.join('\\n') + '\\n');\n}\n\nconst TIER_ORDER: Record<string, number> = { premium: 0, pro: 1, standard: 2 };\n\nexport interface RenderModelsListOptions {\n verbose?: boolean;\n filters?: Record<string, string>;\n}\n\nexport function renderModelsList(\n result: ModelListResult,\n out: NodeJS.WritableStream,\n options?: RenderModelsListOptions,\n): void {\n const { models } = result;\n if (models.length === 0) {\n out.write('No models match your filters.\\n');\n return;\n }\n\n const sorted = [...models].sort((a: ModelSummary, b: ModelSummary) => {\n const catCmp = a.category.localeCompare(b.category);\n if (catCmp !== 0) return catCmp;\n const tierA = TIER_ORDER[a.costTier] ?? 99;\n const tierB = TIER_ORDER[b.costTier] ?? 99;\n if (tierA !== tierB) return tierA - tierB;\n return a.slug.localeCompare(b.slug);\n });\n\n const filterParts: string[] = [];\n if (options?.filters) {\n for (const [k, v] of Object.entries(options.filters)) {\n if (v) filterParts.push(`${k}=${v}`);\n }\n }\n const filterSuffix = filterParts.length > 0 ? ` (filters: ${filterParts.join(', ')})` : '';\n out.write(`${sorted.length} models${filterSuffix}\\n\\n`);\n\n const MAX_BADGES = 3;\n const headers = ['SLUG', 'NAME', 'CATEGORY', 'TIER', 'CREDITS', 'DEFAULT', 'BADGES'];\n const data = sorted.map((m) => {\n const labels = m.badges.map((b) => b.label);\n const shown = labels.slice(0, MAX_BADGES).join(', ');\n const extra = labels.length > MAX_BADGES ? ` +${labels.length - MAX_BADGES} more` : '';\n return [\n m.slug,\n m.displayName,\n m.category,\n m.costTier,\n String(m.creditCost),\n m.isDefault ? '✓' : '',\n labels.length > 0 ? shown + extra : '—',\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n out.write(\n `\\nShowing all ${sorted.length} models. Use --json for full details including constraints.\\n`,\n );\n\n if (options?.verbose) {\n out.write('\\n');\n for (const m of sorted) {\n const pad = 16;\n out.write(`${m.slug} (${m.displayName})\\n`);\n out.write(`${' Provider:'.padEnd(pad)}${m.providerName}\\n`);\n out.write(`${' Category:'.padEnd(pad)}${m.category} / ${m.modelType}\\n`);\n out.write(`${' Tier:'.padEnd(pad)}${m.costTier} (${m.creditCost} credits)\\n`);\n if (m.llmContext) {\n const ctx = m.llmContext.length > 100 ? m.llmContext.slice(0, 100) + '...' : m.llmContext;\n out.write(`${' Context:'.padEnd(pad)}${ctx}\\n`);\n }\n out.write('\\n');\n }\n }\n}\n\nfunction formatExpiresAt(iso: string): string {\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return iso;\n const date = new Date(ms);\n const days = Math.round((ms - Date.now()) / (24 * 60 * 60 * 1000));\n return `${date.toISOString()} (~${days}d)`;\n}\n\n// ---------------------------------------------------------------------------\n// Workflow renderers\n// ---------------------------------------------------------------------------\n\nexport function renderWorkflowCreateResult(\n result: WorkflowCreateResponse,\n out: NodeJS.WritableStream,\n): void {\n const lines = [\n `Created workflow \"${result.name}\"`,\n ` ID: ${result.id}`,\n ` Canvas rev: ${result.canvas_rev}`,\n ` Created: ${result.created_at.slice(0, 19)}`,\n ];\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderWorkflowsList(result: WorkflowListResult, out: NodeJS.WritableStream): void {\n const { items } = result;\n if (items.length === 0) {\n out.write('No workflows.\\n');\n return;\n }\n\n const MAX_TAGS = 3;\n const headers = ['ID', 'NAME', 'TAGS', 'REV', 'UPDATED'];\n const data = items.map((w) => {\n const shown = w.tags.slice(0, MAX_TAGS).join(', ');\n const extra = w.tags.length > MAX_TAGS ? ` +${w.tags.length - MAX_TAGS} more` : '';\n return [\n w.id.slice(0, 8),\n w.name,\n w.tags.length > 0 ? shown + extra : '—',\n String(w.canvas_rev),\n w.updated_at.slice(0, 10),\n ];\n });\n\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n\n out.write(padRow(headers) + '\\n');\n for (const cells of data) out.write(padRow(cells) + '\\n');\n\n if (result.hasMore) {\n out.write('\\nMore results available. Use --cursor to fetch the next page.\\n');\n }\n}\n\nexport function renderWorkflowDetail(detail: WorkflowDetail, out: NodeJS.WritableStream): void {\n const pad = 17;\n const lines = [\n detail.name,\n `${'ID:'.padEnd(pad)}${detail.id}`,\n `${'Canvas rev:'.padEnd(pad)}${detail.canvas_rev}`,\n `${'Tags:'.padEnd(pad)}${detail.tags.length > 0 ? detail.tags.join(', ') : '—'}`,\n `${'Created:'.padEnd(pad)}${detail.created_at.slice(0, 19)}`,\n `${'Updated:'.padEnd(pad)}${detail.updated_at.slice(0, 19)}`,\n `${'Nodes:'.padEnd(pad)}${detail.nodes.length}`,\n `${'Edges:'.padEnd(pad)}${detail.edges.length}`,\n ];\n\n if (detail.description) {\n lines.push('', detail.description);\n }\n\n const params = detail.declared_params;\n lines.push('', 'Declared parameters:');\n if (!params || params.length === 0) {\n lines.push(' (none)');\n } else {\n for (const p of params) {\n const req = p.required ? 'required' : 'optional';\n const desc = p.description ? `: ${p.description}` : '';\n lines.push(` - ${p.name} (${p.type}, ${req})${desc}`);\n }\n }\n\n out.write(lines.join('\\n') + '\\n');\n}\n\nexport function renderWorkflowApplyResult(\n result: WorkflowApplyResult,\n out: NodeJS.WritableStream,\n): void {\n const lines = [\n `Applied ${result.applied} operation${result.applied === 1 ? '' : 's'}. New canvas_rev: ${result.canvasRev}`,\n ];\n if (result.retriedWithRev !== undefined) {\n lines.push(` (auto-rev: resolved conflict, retried with canvas_rev ${result.retriedWithRev})`);\n }\n out.write(lines.join('\\n') + '\\n');\n}\n","// Maps a ParsedArgs into a command handler, builds the EnvelopeContext,\n// renders output in human vs --json mode, and converts thrown errors into\n// the right exit code per Phase 8 Q7 / Q10.\n\nimport type {\n BalanceData,\n BrandModelSummary,\n GenerateEstimateResponse,\n GenerationListResponse,\n GenerationResult,\n NodeTypeDetail,\n ProductSummary,\n TemplateDetail,\n TokenRow,\n WorkflowCreateResponse,\n WorkflowDetail,\n} from '@clickraft/sdk';\n\nimport { ApiError } from '../api/client.js';\nimport { wrapSuccess, type EnvelopeContext } from '../api/envelope.js';\nimport { AuthError } from '../auth/errors.js';\nimport { getBalance } from '../commands/balance.js';\nimport { listBrandModels } from '../commands/brand-model/list.js';\nimport { generateCreate } from '../commands/generate/create.js';\nimport { downloadResult } from '../commands/generate/download.js';\nimport { generateEstimate } from '../commands/generate/estimate.js';\nimport { generateGet } from '../commands/generate/get.js';\nimport { generateList } from '../commands/generate/list.js';\nimport {\n parseBrandModelSpec,\n validateBrandModelSpecs,\n} from '../commands/generate/parse-brand-model-spec.js';\nimport { parseProductSpec, validateProductSpecs } from '../commands/generate/parse-product-spec.js';\nimport { generateWait } from '../commands/generate/wait.js';\nimport { jobsWait } from '../commands/jobs/wait.js';\nimport { DEFAULT_SCOPES, login, type LoginResult } from '../commands/login.js';\nimport { logout, type LogoutResult } from '../commands/logout.js';\nimport { listModels, type ModelListResult } from '../commands/models/list.js';\nimport { describeNode } from '../commands/nodes/describe.js';\nimport { listNodes, type NodesListResult } from '../commands/nodes/list.js';\nimport { createProduct } from '../commands/product/create.js';\nimport { listProducts, type ProductListResult } from '../commands/product/list.js';\nimport { parseImageSpec } from '../commands/product/parse-image-spec.js';\nimport { inspectTelemetry, type TelemetryState } from '../commands/telemetry/inspect.js';\nimport { findTemplates } from '../commands/template/find.js';\nimport { getTemplate } from '../commands/template/get.js';\nimport { listTemplates, type TemplateListResult } from '../commands/template/list.js';\nimport { listTokens } from '../commands/tokens/list.js';\nimport { uploadFile, type UploadResult } from '../commands/upload.js';\nimport { applyWorkflow, type WorkflowApplyResult } from '../commands/workflow/apply.js';\nimport { createWorkflow } from '../commands/workflow/create.js';\nimport { getWorkflow } from '../commands/workflow/get.js';\nimport { listWorkflows, type WorkflowListResult } from '../commands/workflow/list.js';\nimport {\n EXIT_CODE_MAP,\n getExitCode,\n SIGINT_EXIT_CODE,\n type AllErrorCode,\n type ExitCode,\n} from '../errors/codes.js';\nimport { formatHumanError, formatJsonError } from '../errors/format.js';\n\nimport { ArgError, parseArgs as parseArgsRich, type ParsedArgs as ParsedArgsRich } from './args.js';\nimport { parseArgs, type ParsedArgs } from './parse-args.js';\nimport { openBrowser, renderUserCodePrompt, startPollingSpinner } from './progress.js';\nimport {\n renderBalance,\n renderBrandModelsList,\n renderLoginResult,\n renderLogoutResult,\n renderModelsList,\n renderNodeDetail,\n renderNodesList,\n renderProductCreateResult,\n renderProductsList,\n renderTelemetryState,\n renderTemplateDetail,\n renderTemplatesList,\n renderTokensList,\n renderWorkflowApplyResult,\n renderWorkflowCreateResult,\n renderWorkflowDetail,\n renderWorkflowsList,\n} from './render.js';\n\nexport interface DispatchOptions {\n argv: string[];\n version: string;\n stdout?: NodeJS.WritableStream;\n stderr?: NodeJS.WritableStream;\n signal?: AbortSignal;\n // Test seam: skip the real browser-open / spinner UI.\n uiHooks?: {\n onUserCode?: (info: Parameters<typeof renderUserCodePrompt>[0]) => void;\n onPoll?: () => void;\n };\n}\n\nexport async function dispatch(options: DispatchOptions): Promise<ExitCode> {\n const stdout = options.stdout ?? process.stdout;\n const stderr = options.stderr ?? process.stderr;\n\n // PR #4 commands (generate / jobs / upload) take positional arguments and\n // repeatable flags, which `./parse-args.ts` does not support. Route them to\n // a separate handler that uses the richer parser in `./args.ts`, before the\n // shared parser greedily folds positionals into the command path.\n const newCmd = matchNewCommand(options.argv);\n if (newCmd !== null) {\n return runNewCommand(newCmd, options, stdout, stderr);\n }\n\n const parsed = parseArgs(options.argv);\n const jsonMode = parsed.flags.json === true;\n\n // Top-level --version / --help short-circuit BEFORE dispatch.\n if (parsed.flags.version === true) {\n stdout.write(`${options.version}\\n`);\n return 0;\n }\n\n if (parsed.command.length === 0 || parsed.flags.help === true) {\n if (parsed.command.length === 0) {\n stdout.write(renderRootHelp(options.version));\n } else {\n stdout.write(renderCommandHelp(parsed.command));\n }\n return 0;\n }\n\n const commandName = parsed.command.join('.');\n const ctx: EnvelopeContext = {\n startMs: Date.now(),\n command: commandName,\n version: options.version,\n };\n\n try {\n validateFlags(parsed);\n return await runCommand(parsed, ctx, {\n stdout,\n stderr,\n jsonMode,\n version: options.version,\n signal: options.signal,\n uiHooks: options.uiHooks,\n });\n } catch (err) {\n if (isAbortedError(err, options.signal)) {\n if (jsonMode) {\n // Synthesize an AUTH_FLOW_CANCELLED-shaped envelope so JSON consumers\n // get a structured response on SIGINT.\n stdout.write(\n formatJsonError(new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.'), ctx) + '\\n',\n );\n } else {\n stderr.write('Cancelled.\\n');\n }\n return SIGINT_EXIT_CODE;\n }\n\n const code = extractCode(err);\n if (jsonMode) {\n stdout.write(formatJsonError(err, ctx) + '\\n');\n } else {\n stderr.write(formatHumanError(err) + '\\n');\n }\n return getExitCode(code);\n }\n}\n\ninterface RunContext {\n stdout: NodeJS.WritableStream;\n stderr: NodeJS.WritableStream;\n jsonMode: boolean;\n version: string;\n signal?: AbortSignal;\n uiHooks?: DispatchOptions['uiHooks'];\n}\n\nasync function runCommand(\n parsed: ParsedArgs,\n ctx: EnvelopeContext,\n rc: RunContext,\n): Promise<ExitCode> {\n const path = parsed.command.join('.');\n\n switch (path) {\n case 'login': {\n const result = await loginCommand(parsed, rc);\n emit(result, renderLoginResult, ctx, rc);\n return 0;\n }\n case 'logout': {\n const result = await logoutCommand(parsed, rc);\n emit(result, renderLogoutResult, ctx, rc);\n return 0;\n }\n case 'tokens.list': {\n const rows = await listTokens({\n profile: stringFlag(parsed.flags.profile),\n signal: rc.signal,\n });\n emit<TokenRow[]>(rows, renderTokensList, ctx, rc);\n return 0;\n }\n case 'telemetry.inspect': {\n const state = inspectTelemetry();\n emit<TelemetryState>(state, renderTelemetryState, ctx, rc);\n return 0;\n }\n case 'balance': {\n const data = await getBalance({\n profile: stringFlag(parsed.flags.profile),\n signal: rc.signal,\n });\n emit<BalanceData>(data, renderBalance, ctx, rc);\n return 0;\n }\n case 'brand-model.list': {\n const models = await listBrandModels({\n profile: stringFlag(parsed.flags.profile),\n signal: rc.signal,\n });\n emit<BrandModelSummary[]>(models, renderBrandModelsList, ctx, rc);\n return 0;\n }\n default:\n throw new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Unknown command: ${parsed.command.join(' ')}. Run \\`clickraft --help\\` for available commands.`,\n { retryable: false },\n );\n }\n}\n\nasync function loginCommand(parsed: ParsedArgs, rc: RunContext): Promise<LoginResult> {\n const noOpen = parsed.flags['open-browser'] === false;\n let spinner: ReturnType<typeof startPollingSpinner> | undefined;\n\n try {\n return await login({\n profile: stringFlag(parsed.flags.profile),\n apiBaseUrl: stringFlag(parsed.flags['api-base-url']),\n scope: stringFlag(parsed.flags.scope),\n forceReauth: parsed.flags['force-reauth'] === true,\n openBrowser: !noOpen,\n signal: rc.signal,\n onUserCode: (info) => {\n if (rc.uiHooks?.onUserCode) {\n rc.uiHooks.onUserCode(info);\n return;\n }\n if (!rc.jsonMode) {\n renderUserCodePrompt(info, rc.stderr);\n if (!noOpen) openBrowser(info.verificationUriComplete);\n spinner = startPollingSpinner(undefined, rc.stderr as NodeJS.WriteStream);\n }\n },\n onPoll: () => {\n rc.uiHooks?.onPoll?.();\n },\n // Always warn, including in --json mode, and always on stderr: the login\n // succeeded, so the JSON envelope on stdout stays a clean success, but the\n // token is quietly less capable than the one that was asked for. Silence\n // here is how a user ends up debugging a scope error days later.\n onScopeDowngrade: (info) => {\n rc.stderr.write(\n `Warning: the server refused one or more requested scopes${\n info.description ? ` (${info.description})` : ''\n }.\\n` +\n ` Retrying with the required scopes only. This token will not be able to ` +\n `use commands that need the refused scopes.\\n` +\n ` Re-run \\`clickraft login --force-reauth\\` once the server grants them.\\n`,\n );\n },\n });\n } finally {\n spinner?.stop();\n }\n}\n\nasync function logoutCommand(parsed: ParsedArgs, rc: RunContext): Promise<LogoutResult> {\n return logout({\n profile: stringFlag(parsed.flags.profile),\n all: parsed.flags.all === true,\n revoke: parsed.flags.revoke !== false,\n signal: rc.signal,\n warn: rc.jsonMode ? () => {} : undefined,\n });\n}\n\nfunction emit<T>(\n result: T,\n human: (result: T, stream: NodeJS.WritableStream) => void,\n ctx: EnvelopeContext,\n rc: RunContext,\n): void {\n // Race window: a SIGINT delivered after the command's awaited work\n // resolves but before this render runs must produce exit 130, not\n // exit 0 with a success line. Throwing routes to dispatch's outer\n // isAbortedError handler, which writes the cancellation line.\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n human(result, rc.stdout);\n}\n\nfunction stringFlag(value: string | boolean | undefined): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined;\n}\n\n// Per-command flag schema. Unknown flags and missing string-flag values\n// reject with INPUT_INVALID_FORMAT (exit 2). Boolean flags accept either\n// `true` (set) or `false` (via `--no-<flag>`); string flags require an\n// explicit value.\nconst COMMAND_FLAGS: Record<string, Record<string, 'string' | 'boolean'>> = {\n login: {\n profile: 'string',\n 'api-base-url': 'string',\n scope: 'string',\n 'force-reauth': 'boolean',\n 'open-browser': 'boolean',\n json: 'boolean',\n },\n logout: { profile: 'string', all: 'boolean', revoke: 'boolean', json: 'boolean' },\n 'tokens.list': { profile: 'string', json: 'boolean' },\n 'telemetry.inspect': { json: 'boolean' },\n balance: { profile: 'string', json: 'boolean' },\n 'brand-model.list': { profile: 'string', json: 'boolean' },\n};\n\nfunction validateFlags(parsed: ParsedArgs): void {\n const allowed = COMMAND_FLAGS[parsed.command.join('.')];\n // Unknown command: let runCommand's default arm throw the unknown-command\n // error so the user sees that, not a flag complaint.\n if (!allowed) return;\n for (const [name, value] of Object.entries(parsed.flags)) {\n const kind = allowed[name];\n if (!kind) {\n throw new ApiError('INPUT_INVALID_FORMAT', `Unknown flag: --${name}.`, { retryable: false });\n }\n if (kind === 'string' && typeof value !== 'string') {\n throw new ApiError('INPUT_INVALID_FORMAT', `Flag --${name} requires a value.`, {\n retryable: false,\n });\n }\n }\n}\n\nfunction isAbortedError(err: unknown, signal?: AbortSignal): boolean {\n if (signal?.aborted) return true;\n if (err instanceof AuthError && err.code === 'AUTH_FLOW_CANCELLED') return true;\n return false;\n}\n\nfunction extractCode(err: unknown): AllErrorCode {\n if (err && typeof err === 'object' && 'code' in err) {\n const code = (err as { code?: unknown }).code;\n if (typeof code === 'string' && code in EXIT_CODE_MAP) {\n return code as AllErrorCode;\n }\n }\n return 'INTERNAL_ERROR';\n}\n\nfunction renderRootHelp(version: string): string {\n return [\n `clickraft v${version} — the Clickraft CLI`,\n '',\n 'Usage: clickraft <command> [options]',\n '',\n 'Commands:',\n ' login Authenticate via OAuth device flow',\n ' logout Remove credentials (optional server-side revoke)',\n \" tokens list List the caller's API tokens\",\n ' balance Show credit balance and rate limits',\n ' brand-model list List available brand models',\n ' product list List products in your organization',\n ' product create Create a product from uploaded assets',\n ' models list List available AI models',\n ' nodes list List available workflow node types',\n \" nodes describe Describe a node type's ports and fields\",\n ' telemetry inspect Show current telemetry state and payload shape',\n ' template list List available templates',\n ' template get Fetch a template by ID',\n ' template find Search templates by keyword',\n ' generate create Submit a generation job and wait for completion',\n ' generate wait Wait for an existing job to reach a terminal state',\n ' generate get Fetch the current state of a job',\n ' generate list List your recent generations, newest first',\n ' generate estimate Price a generation without running it',\n ' jobs wait Alias of `generate wait`',\n ' workflow create Create a new empty workflow',\n ' workflow list List workflows in your organization',\n ' workflow get Fetch a workflow snapshot by ID',\n ' workflow apply Apply operations to a workflow (canvas mutation)',\n ' upload <file> Upload a local file and return its public URL',\n '',\n 'Options:',\n ' -v, --version Show version',\n ' -h, --help Show help',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n}\n\nfunction renderCommandHelp(command: string[]): string {\n const path = command.join(' ');\n switch (path) {\n case 'login':\n return [\n 'Usage: clickraft login [options]',\n '',\n 'Options:',\n ' --profile <name> Write to a specific profile (default: \"default\")',\n ' --api-base-url <url> Override the API base URL',\n ` --scope <s> Space-separated scope list (default: all ${DEFAULT_SCOPES.length})`,\n ' --force-reauth Re-authenticate even if a valid token exists',\n ' --no-open-browser Do not auto-open the verification URL',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'logout':\n return [\n 'Usage: clickraft logout [options]',\n '',\n 'Options:',\n ' --profile <name> Remove a specific profile (default: \"default\")',\n ' --all Remove every profile (delete the credentials file)',\n ' --no-revoke Skip the server-side revoke call',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'tokens list':\n return [\n 'Usage: clickraft tokens list [options]',\n '',\n 'Options:',\n ' --profile <name> Read credentials from a specific profile',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'balance':\n return [\n 'Usage: clickraft balance [options]',\n '',\n 'Options:',\n ' --profile <name> Read credentials from a specific profile',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'brand-model':\n return [\n 'Usage: clickraft brand-model <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available brand models',\n '',\n ].join('\\n');\n case 'brand-model list':\n return [\n 'Usage: clickraft brand-model list [options]',\n '',\n 'Options:',\n ' --profile <name> Read credentials from a specific profile',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'product':\n return [\n 'Usage: clickraft product <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List products in your organization',\n ' create Create a product from uploaded assets',\n '',\n ].join('\\n');\n case 'product list':\n return [\n 'Usage: clickraft product list [options]',\n '',\n 'List products in your organization. Supports cursor-based pagination.',\n '',\n 'Options:',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --limit <n> Max results per page (1-100, default: 50)',\n ' --sync-status <s> Filter by sync status (synced, pending, stale, error, deleted_upstream)',\n ' --source-type <s> Filter by source type (manual, csv, shopify, etsy, etc.)',\n ' --search <q> Free-text search query',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'product create':\n return [\n 'Usage: clickraft product create --name <name> --image <assetId>[:<altText>] [options]',\n '',\n 'Create a product from images already uploaded to your Clickraft library.',\n 'Upload them first with `clickraft upload`, which prints the assetId to use here.',\n '',\n 'Options:',\n ' --name <name> Product name (required, max 200 chars)',\n ' --image <spec> <assetId>[:<altText>] (repeatable, 1-10 images, required)',\n ' --description <text> Product description (max 5000 chars)',\n ' --primary <assetId> Mark this image primary (default: the first --image)',\n ' --idempotency-key <key> Reuse a key to make a retry safe across invocations',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n 'Examples:',\n ' clickraft product create --name \"Ceramic Mug\" \\\\',\n ' --image 1f7c1e8e-2a4b-4c9d-8e5f-3b2a1c0d9e8f',\n '',\n ' clickraft product create --name \"Ceramic Mug\" \\\\',\n ' --image \"1f7c1e8e-2a4b-4c9d-8e5f-3b2a1c0d9e8f:Front view\" \\\\',\n ' --image \"2a8d2f9f-3b5c-4d0e-9f6a-4c3b2d1e0f9a:Side view\" \\\\',\n ' --primary 2a8d2f9f-3b5c-4d0e-9f6a-4c3b2d1e0f9a',\n '',\n ].join('\\n');\n case 'models':\n return [\n 'Usage: clickraft models <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available AI models',\n '',\n ].join('\\n');\n case 'models list':\n return [\n 'Usage: clickraft models list [options]',\n '',\n 'List AI models available for generation. By default shows a summary table;',\n 'use --json for full details including constraints and llmContext.',\n '',\n 'Options:',\n ' --category <name> Filter by category (image, video, audio, chat, edit)',\n ' --tier <name> Filter by cost tier (standard, pro, premium)',\n ' --type <name> Filter by model type (e.g. text-to-image)',\n ' --featured Show only featured models',\n ' --verbose Show expanded per-model details after the table',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n 'Examples:',\n ' clickraft models list',\n ' clickraft models list --category image --tier pro',\n ' clickraft models list --featured --json',\n '',\n ].join('\\n');\n case 'nodes':\n return [\n 'Usage: clickraft nodes <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available workflow node types',\n \" describe Show a node type's ports and agent-writable fields\",\n '',\n ].join('\\n');\n case 'nodes list':\n return [\n 'Usage: clickraft nodes list [options]',\n '',\n 'Lists the workflow node types available to the API, with port counts.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'nodes describe':\n return [\n 'Usage: clickraft nodes describe <type> [options]',\n '',\n \"Shows a node type's ports (handleId, direction, dataType) and the fields\",\n 'an agent may write. Handle ids are printed verbatim for use in edges.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'telemetry inspect':\n return [\n 'Usage: clickraft telemetry inspect [options]',\n '',\n 'Options:',\n ' --json Emit JSON envelope instead of human output',\n '',\n ].join('\\n');\n case 'template':\n return [\n 'Usage: clickraft template <subcommand> [options]',\n '',\n 'Subcommands:',\n ' list List available templates',\n ' get Fetch a template by ID',\n ' find Search templates by keyword',\n '',\n ].join('\\n');\n case 'template list':\n return [\n 'Usage: clickraft template list [options]',\n '',\n 'Options:',\n ' --scope <scope> Filter by scope: own, system, or all (default: all)',\n ' --q <query> Free-text search query',\n ' --tags <tag> Filter by tag (repeatable)',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --limit <n> Max results per page (1-50, default: 20)',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'template get':\n return [\n 'Usage: clickraft template get <id> [options]',\n '',\n 'Fetches a single template by its ID, including declared parameters.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'template find':\n return [\n 'Usage: clickraft template find <query> [options]',\n '',\n 'Searches templates by keyword. Shorthand for `template list --q <query>`.',\n '',\n 'Options:',\n ' --tags <tag> Filter by tag (repeatable)',\n ' --scope <scope> Filter by scope: own, system, or all (default: all)',\n ' --limit <n> Max results per page (1-50, default: 20)',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'generate':\n return [\n 'Usage: clickraft generate <subcommand> [options]',\n '',\n 'Subcommands:',\n ' create Submit a generation job (waits for completion by default)',\n ' wait Long-poll an existing job until terminal',\n ' get Fetch the current state of a job (no polling)',\n ' list List your recent generations, newest first',\n ' estimate Price a generation without running it (same flags as create)',\n '',\n ].join('\\n');\n case 'generate create':\n return [\n 'Usage: clickraft generate create [prompt] --model-slug <slug> [options]',\n '',\n 'Submits a generation job. By default the command waits up to 120s for the',\n 'job to reach a terminal state via the server long-poll (?wait=30) rounds.',\n '',\n 'Options:',\n ' --prompt <text> Text prompt (or pass as the positional argument)',\n ' --model-slug <slug> Required model identifier',\n ' --brand-model <spec> Brand Model reference (repeatable, max 3)',\n ' Format: <uuid> or <uuid>:<pose>',\n ' Poses: front, 3/4-right, right, left, 3/4-left, back, approved',\n ' --product <spec> Product reference (repeatable)',\n ' Format: <uuid> or <uuid>:<imageId>',\n ' Server enforces reference cap per model',\n ' --reference-image <v> Reference image: URL or local path (repeatable, max 8)',\n ' --start-frame <v> Image-to-video start frame: URL or local path',\n ' --aspect-ratio <a:b> e.g. 16:9',\n ' --resolution <size> e.g. 1024x768, 720p, 1K',\n ' --duration-seconds <n> For video/audio models (1-60)',\n ' --quality <tier> e.g. low, medium, high (valid values depend on the model)',\n ' --workflow-id <uuid> Attach to an existing workflow',\n ' --node-id <id> Attach to a specific node',\n ' --no-wait, --async Return immediately with the jobId',\n ' --timeout <seconds> Override the 120s default wait',\n ' --output <path> Save the completed result to a file, or into a',\n ' directory as <jobId>.<ext>',\n ' --profile <name> Credentials profile name',\n ' --api-base-url <url> Override the API base URL',\n ' --token <token> Override the access token',\n ' --json Emit a JSON envelope instead of human output',\n ' -h, --help Show help',\n '',\n ].join('\\n');\n case 'generate wait':\n return [\n 'Usage: clickraft generate wait <jobId> [options]',\n '',\n 'Long-polls an existing job until it reaches a terminal state (completed,',\n 'failed, or cancelled) or the timeout elapses.',\n '',\n 'Options:',\n ' --timeout <seconds> Overall wait deadline (default: 120)',\n ' --output <path> Save the completed result (file, or directory → <jobId>.<ext>)',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'generate list':\n return [\n 'Usage: clickraft generate list [options]',\n '',\n 'Lists your recent generations in the organization, newest first.',\n '',\n 'Options:',\n ' --limit <n> Results per page (1-50, default: 20)',\n ' --status <status> queued, processing, uploading, completed, failed, cancelled',\n ' --content-type <type> image, video, or audio',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'generate estimate':\n return [\n 'Usage: clickraft generate estimate [prompt] --model-slug <slug> [options]',\n '',\n 'Prices exactly what `generate create` with the same flags would charge, and',\n 'says whether the account can run it now. Nothing is created or charged.',\n 'Accepts the same generation flags as `generate create` (--prompt,',\n '--model-slug, --reference-image, --start-frame, --aspect-ratio, --resolution,',\n '--duration-seconds, --quality, --brand-model, --product, --workflow-id,',\n '--node-id). Local reference paths are uploaded first, as with create.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'generate get':\n return [\n 'Usage: clickraft generate get <jobId> [options]',\n '',\n 'Fetches the current state of a generation job without polling.',\n '',\n 'Options:',\n ' --output <path> Save the completed result (file, or directory → <jobId>.<ext>)',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'jobs':\n return [\n 'Usage: clickraft jobs <subcommand> [options]',\n '',\n 'Subcommands:',\n ' wait Long-poll a job until terminal (alias of `generate wait`)',\n '',\n ].join('\\n');\n case 'jobs wait':\n return [\n 'Usage: clickraft jobs wait <jobId> [options]',\n '',\n 'Alias of `clickraft generate wait`. See `clickraft generate wait --help`.',\n '',\n ].join('\\n');\n case 'upload':\n return [\n 'Usage: clickraft upload <file-path> [options]',\n '',\n 'Uploads a local file (up to 15MB) to the Agents API. The CLI computes a',\n 'sha256 of the contents and uses it as the idempotency key, so uploading',\n 'the same file twice within the same scope reuses the original asset.',\n '',\n 'Options:',\n ' --scope <name> Namespace for idempotency dedup (default: user-uploads)',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow':\n return [\n 'Usage: clickraft workflow <subcommand> [options]',\n '',\n 'Subcommands:',\n ' create Create a new empty workflow',\n ' list List workflows in your organization',\n ' get Fetch a workflow snapshot by ID',\n ' apply Apply operations to a workflow (canvas mutation)',\n '',\n ].join('\\n');\n case 'workflow create':\n return [\n 'Usage: clickraft workflow create --name <name> [options]',\n '',\n 'Creates a new empty workflow.',\n '',\n 'Options:',\n ' --name <name> Workflow name (required unless --from-file)',\n ' --description <text> Optional description',\n ' --tags <tag> Tag (repeatable)',\n ' --from-file <path> Read the full create payload as JSON from a file',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow list':\n return [\n 'Usage: clickraft workflow list [options]',\n '',\n 'Lists workflows in your organization. Supports cursor-based pagination.',\n '',\n 'Options:',\n ' --tags <csv> Filter by tags (comma-separated)',\n ' --has-param <key> Filter to workflows that declare this param',\n ' --limit <n> Max results per page (1-100, default: 20)',\n ' --cursor <token> Pagination cursor from a previous response',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow get':\n return [\n 'Usage: clickraft workflow get <id> [options]',\n '',\n 'Fetches a workflow snapshot including nodes and edges.',\n '',\n 'Options:',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n case 'workflow apply':\n return [\n 'Usage: clickraft workflow apply <id> [options]',\n '',\n 'Applies mutation operations to a workflow. Requires --canvas-rev or --auto-rev.',\n '',\n 'Options:',\n ' --from-file <path> JSON file with operations (array or { canvas_rev, operations })',\n ' --op <json> Single operation as JSON string (repeatable)',\n ' --canvas-rev <n> The canvas_rev preconditioning the mutation',\n ' --auto-rev Fetch current canvas_rev first; retry once on 409',\n ' --idempotency-key <key> Override the auto-generated idempotency key',\n ' --dry-run Print the request payload without sending it',\n ' --profile <name>',\n ' --api-base-url <url>',\n ' --token <token>',\n ' --json',\n '',\n ].join('\\n');\n default:\n return `Unknown command: ${path}\\nRun \\`clickraft --help\\` for available commands.\\n`;\n }\n}\n\n// ---------------------------------------------------------------------------\n// PR #4 commands (generate / jobs / upload)\n//\n// These take positional arguments and repeatable flags that the lean\n// parse-args used above can't represent. They reuse dispatch's outer\n// envelope/error/SIGINT semantics but parse argv themselves via args.ts.\n// ---------------------------------------------------------------------------\n\ntype NewCommandPath =\n | 'generate.create'\n | 'generate.wait'\n | 'generate.get'\n | 'generate.list'\n | 'generate.estimate'\n | 'jobs.wait'\n | 'upload'\n | 'template.list'\n | 'template.get'\n | 'template.find'\n | 'product.list'\n | 'product.create'\n | 'models.list'\n | 'nodes.list'\n | 'nodes.describe'\n | 'workflow.create'\n | 'workflow.list'\n | 'workflow.get'\n | 'workflow.apply';\n\ntype NewCommandMatch =\n | { kind: 'cmd'; path: NewCommandPath; verbTokenCount: 1 | 2 }\n | {\n kind: 'sub-help';\n verb: 'generate' | 'jobs' | 'template' | 'product' | 'models' | 'nodes' | 'workflow';\n }\n | {\n kind: 'unknown-sub';\n verb: 'generate' | 'jobs' | 'template' | 'product' | 'models' | 'nodes' | 'workflow';\n sub: string;\n };\n\nfunction matchNewCommand(argv: readonly string[]): NewCommandMatch | null {\n if (argv.length === 0) return null;\n const verb = argv[0];\n\n if (verb === 'upload') {\n return { kind: 'cmd', path: 'upload', verbTokenCount: 1 };\n }\n\n if (verb === 'generate') {\n const sub = argv[1];\n if (sub === 'create') return { kind: 'cmd', path: 'generate.create', verbTokenCount: 2 };\n if (sub === 'wait') return { kind: 'cmd', path: 'generate.wait', verbTokenCount: 2 };\n if (sub === 'get') return { kind: 'cmd', path: 'generate.get', verbTokenCount: 2 };\n if (sub === 'list') return { kind: 'cmd', path: 'generate.list', verbTokenCount: 2 };\n if (sub === 'estimate') return { kind: 'cmd', path: 'generate.estimate', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'generate' };\n return { kind: 'unknown-sub', verb: 'generate', sub };\n }\n\n if (verb === 'jobs') {\n const sub = argv[1];\n if (sub === 'wait') return { kind: 'cmd', path: 'jobs.wait', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'jobs' };\n return { kind: 'unknown-sub', verb: 'jobs', sub };\n }\n\n if (verb === 'template') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'template.list', verbTokenCount: 2 };\n if (sub === 'get') return { kind: 'cmd', path: 'template.get', verbTokenCount: 2 };\n if (sub === 'find') return { kind: 'cmd', path: 'template.find', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'template' };\n return { kind: 'unknown-sub', verb: 'template', sub };\n }\n\n if (verb === 'product') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'product.list', verbTokenCount: 2 };\n if (sub === 'create') return { kind: 'cmd', path: 'product.create', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'product' };\n return { kind: 'unknown-sub', verb: 'product', sub };\n }\n\n if (verb === 'models') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'models.list', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'models' };\n return { kind: 'unknown-sub', verb: 'models', sub };\n }\n\n if (verb === 'nodes') {\n const sub = argv[1];\n if (sub === 'list') return { kind: 'cmd', path: 'nodes.list', verbTokenCount: 2 };\n if (sub === 'describe') return { kind: 'cmd', path: 'nodes.describe', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'nodes' };\n return { kind: 'unknown-sub', verb: 'nodes', sub };\n }\n\n if (verb === 'workflow') {\n const sub = argv[1];\n if (sub === 'create') return { kind: 'cmd', path: 'workflow.create', verbTokenCount: 2 };\n if (sub === 'list') return { kind: 'cmd', path: 'workflow.list', verbTokenCount: 2 };\n if (sub === 'get') return { kind: 'cmd', path: 'workflow.get', verbTokenCount: 2 };\n if (sub === 'apply') return { kind: 'cmd', path: 'workflow.apply', verbTokenCount: 2 };\n if (sub === undefined || sub.startsWith('-')) return { kind: 'sub-help', verb: 'workflow' };\n return { kind: 'unknown-sub', verb: 'workflow', sub };\n }\n\n return null;\n}\n\ninterface NewRunContext {\n stdout: NodeJS.WritableStream;\n stderr: NodeJS.WritableStream;\n jsonMode: boolean;\n signal?: AbortSignal;\n}\n\nasync function runNewCommand(\n newCmd: NewCommandMatch,\n options: DispatchOptions,\n stdout: NodeJS.WritableStream,\n stderr: NodeJS.WritableStream,\n): Promise<ExitCode> {\n if (newCmd.kind === 'sub-help') {\n stdout.write(renderCommandHelp([newCmd.verb]));\n return 0;\n }\n\n if (newCmd.kind === 'unknown-sub') {\n const err = new ApiError(\n 'INPUT_INVALID_FORMAT',\n `Unknown ${newCmd.verb} subcommand: ${newCmd.sub}. Run \\`clickraft ${newCmd.verb} --help\\` for available subcommands.`,\n { retryable: false },\n );\n const ctx: EnvelopeContext = {\n startMs: Date.now(),\n command: newCmd.verb,\n version: options.version,\n };\n if (options.argv.includes('--json')) {\n stdout.write(formatJsonError(err, ctx) + '\\n');\n } else {\n stderr.write(formatHumanError(err) + '\\n');\n }\n return 2;\n }\n\n const path = newCmd.path;\n const argvAfterVerb = options.argv.slice(newCmd.verbTokenCount);\n const jsonMode = argvAfterVerb.includes('--json');\n\n if (argvAfterVerb.includes('--help') || argvAfterVerb.includes('-h')) {\n stdout.write(renderCommandHelp(path.split('.')));\n return 0;\n }\n\n const ctx: EnvelopeContext = {\n startMs: Date.now(),\n command: path,\n version: options.version,\n };\n\n const rc: NewRunContext = { stdout, stderr, jsonMode, signal: options.signal };\n\n try {\n switch (path) {\n case 'generate.create':\n return await runGenerateCreate(argvAfterVerb, ctx, rc);\n case 'generate.wait':\n return await runGenerateWait(argvAfterVerb, ctx, rc);\n case 'generate.get':\n return await runGenerateGet(argvAfterVerb, ctx, rc);\n case 'generate.list':\n return await runGenerateList(argvAfterVerb, ctx, rc);\n case 'generate.estimate':\n return await runGenerateEstimate(argvAfterVerb, ctx, rc);\n case 'jobs.wait':\n return await runJobsWait(argvAfterVerb, ctx, rc);\n case 'upload':\n return await runUploadCmd(argvAfterVerb, ctx, rc);\n case 'template.list':\n return await runTemplateList(argvAfterVerb, ctx, rc);\n case 'template.get':\n return await runTemplateGet(argvAfterVerb, ctx, rc);\n case 'template.find':\n return await runTemplateFind(argvAfterVerb, ctx, rc);\n case 'product.list':\n return await runProductList(argvAfterVerb, ctx, rc);\n case 'product.create':\n return await runProductCreate(argvAfterVerb, ctx, rc);\n case 'models.list':\n return await runModelsList(argvAfterVerb, ctx, rc);\n case 'nodes.list':\n return await runNodesList(argvAfterVerb, ctx, rc);\n case 'nodes.describe':\n return await runNodesDescribe(argvAfterVerb, ctx, rc);\n case 'workflow.create':\n return await runWorkflowCreate(argvAfterVerb, ctx, rc);\n case 'workflow.list':\n return await runWorkflowList(argvAfterVerb, ctx, rc);\n case 'workflow.get':\n return await runWorkflowGet(argvAfterVerb, ctx, rc);\n case 'workflow.apply':\n return await runWorkflowApply(argvAfterVerb, ctx, rc);\n }\n } catch (err) {\n if (isAbortedError(err, options.signal)) {\n if (jsonMode) {\n stdout.write(\n formatJsonError(new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.'), ctx) + '\\n',\n );\n } else {\n stderr.write('Cancelled.\\n');\n }\n return SIGINT_EXIT_CODE;\n }\n\n const mapped =\n err instanceof ArgError\n ? new ApiError('INPUT_INVALID_FORMAT', err.message, { retryable: false })\n : err;\n\n const code = extractCode(mapped);\n if (jsonMode) {\n stdout.write(formatJsonError(mapped, ctx) + '\\n');\n } else {\n stderr.write(formatHumanError(mapped) + '\\n');\n }\n return getExitCode(code);\n }\n}\n\nconst COMMON_RICH_STRING_FLAGS = ['profile', 'api-base-url', 'token'] as const;\nconst COMMON_RICH_BOOL_FLAGS = ['json', 'help'] as const;\n\nasync function runGenerateCreate(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [\n ...COMMON_RICH_STRING_FLAGS,\n 'prompt',\n 'model-slug',\n 'start-frame',\n 'aspect-ratio',\n 'resolution',\n 'duration-seconds',\n 'quality',\n 'workflow-id',\n 'node-id',\n 'timeout',\n 'output',\n ],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'wait', 'async'],\n array: ['reference-image', 'brand-model', 'product'],\n });\n\n const modelSlug = parsed.string['model-slug'];\n if (!modelSlug) throw new ArgError('--model-slug is required.');\n\n const rawBrandModels = parsed.array['brand-model'] ?? [];\n const brandModels =\n rawBrandModels.length > 0 ? rawBrandModels.map(parseBrandModelSpec) : undefined;\n if (brandModels) validateBrandModelSpecs(brandModels);\n\n const rawProducts = parsed.array['product'] ?? [];\n const products = rawProducts.length > 0 ? rawProducts.map(parseProductSpec) : undefined;\n if (products) validateProductSpecs(products);\n\n const result = await generateCreate({\n prompt: parsed.string.prompt ?? parsed.positional[0],\n modelSlug,\n referenceImages: parsed.array['reference-image'],\n startFrame: parsed.string['start-frame'],\n aspectRatio: parsed.string['aspect-ratio'],\n resolution: parsed.string.resolution,\n durationSeconds: optionalInt(parsed.string['duration-seconds'], 'duration-seconds'),\n quality: parsed.string.quality,\n brandModels,\n products,\n workflowId: parsed.string['workflow-id'],\n nodeId: parsed.string['node-id'],\n wait: computeWaitFlag(parsed),\n timeoutSeconds: optionalInt(parsed.string.timeout, 'timeout'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n await emitJob(result, ctx, rc, parsed.string.output);\n return exitCodeForResult(result);\n}\n\nasync function runGenerateWait(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'timeout', 'output'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const jobId = parsed.positional[0];\n if (!jobId) throw new ArgError('Missing required <jobId> argument.');\n\n const result = await generateWait({\n jobId,\n timeoutSeconds: optionalInt(parsed.string.timeout, 'timeout'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n await emitJob(result, ctx, rc, parsed.string.output);\n return exitCodeForResult(result);\n}\n\nasync function runGenerateGet(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'output'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const jobId = parsed.positional[0];\n if (!jobId) throw new ArgError('Missing required <jobId> argument.');\n\n const result = await generateGet({\n jobId,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n await emitJob(result, ctx, rc, parsed.string.output);\n return exitCodeForResult(result);\n}\n\nasync function runGenerateList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'limit', 'status', 'content-type', 'cursor'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const page = await generateList({\n limit: optionalInt(parsed.string.limit, 'limit'),\n status: parsed.string.status,\n contentType: parsed.string['content-type'],\n cursor: parsed.string.cursor,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(page, ctx)) + '\\n');\n return 0;\n }\n rc.stdout.write(renderGenerationList(page) + '\\n');\n return 0;\n}\n\nasync function runGenerateEstimate(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [\n ...COMMON_RICH_STRING_FLAGS,\n 'prompt',\n 'model-slug',\n 'start-frame',\n 'aspect-ratio',\n 'resolution',\n 'duration-seconds',\n 'quality',\n 'workflow-id',\n 'node-id',\n ],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['reference-image', 'brand-model', 'product'],\n });\n\n const modelSlug = parsed.string['model-slug'];\n if (!modelSlug) throw new ArgError('--model-slug is required.');\n\n const rawBrandModels = parsed.array['brand-model'] ?? [];\n const brandModels =\n rawBrandModels.length > 0 ? rawBrandModels.map(parseBrandModelSpec) : undefined;\n if (brandModels) validateBrandModelSpecs(brandModels);\n\n const rawProducts = parsed.array['product'] ?? [];\n const products = rawProducts.length > 0 ? rawProducts.map(parseProductSpec) : undefined;\n if (products) validateProductSpecs(products);\n\n const estimate = await generateEstimate({\n prompt: parsed.string.prompt ?? parsed.positional[0],\n modelSlug,\n referenceImages: parsed.array['reference-image'],\n startFrame: parsed.string['start-frame'],\n aspectRatio: parsed.string['aspect-ratio'],\n resolution: parsed.string.resolution,\n durationSeconds: optionalInt(parsed.string['duration-seconds'], 'duration-seconds'),\n quality: parsed.string.quality,\n brandModels,\n products,\n workflowId: parsed.string['workflow-id'],\n nodeId: parsed.string['node-id'],\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(estimate, ctx)) + '\\n');\n return 0;\n }\n rc.stdout.write(renderEstimate(estimate) + '\\n');\n return 0;\n}\n\nasync function runJobsWait(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'timeout', 'output'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const jobId = parsed.positional[0];\n if (!jobId) throw new ArgError('Missing required <jobId> argument.');\n\n const result = await jobsWait({\n jobId,\n timeoutSeconds: optionalInt(parsed.string.timeout, 'timeout'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n await emitJob(result, ctx, rc, parsed.string.output);\n return exitCodeForResult(result);\n}\n\nasync function runUploadCmd(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'scope'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const filePath = parsed.positional[0];\n if (!filePath) throw new ArgError('Missing required <file-path> argument.');\n\n const result = await uploadFile({\n filePath,\n scope: parsed.string.scope,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n emitUpload(result, ctx, rc);\n return 0;\n}\n\nasync function emitJob(\n result: GenerationResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n output?: string,\n): Promise<void> {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n // --output: save a completed result. A job that did not complete is reported\n // as usual (its exit code already says so) plus a one-line note on stderr.\n let savedPath: string | undefined;\n if (output !== undefined) {\n if (result.status === 'completed' && result.resultUrl) {\n savedPath = await downloadResult(result, output, { signal: rc.signal });\n } else {\n rc.stderr.write(`Not saved: job ${result.jobId} is ${result.status}.\\n`);\n }\n }\n if (rc.jsonMode) {\n const data = savedPath ? { ...result, savedPath } : result;\n rc.stdout.write(JSON.stringify(wrapSuccess(data, ctx)) + '\\n');\n return;\n }\n rc.stdout.write(renderGenerationResult(result) + '\\n');\n if (savedPath) rc.stdout.write(`Saved: ${savedPath}\\n`);\n}\n\nfunction emitUpload(result: UploadResult, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n rc.stdout.write(renderUploadResult(result) + '\\n');\n}\n\nfunction renderGenerationResult(r: GenerationResult): string {\n const lines: string[] = [`Job ID: ${r.jobId}`, `Status: ${r.status}`, `Model: ${r.modelSlug}`];\n if (r.resultUrl) lines.push(`Result URL: ${r.resultUrl}`);\n if (r.thumbnailUrl) lines.push(`Thumbnail: ${r.thumbnailUrl}`);\n lines.push(`Credits charged: ${r.creditsCharged}`);\n if (r.creditsRefunded) lines.push('Credits refunded: yes');\n if (r.errorCode || r.errorMessage) {\n lines.push(`Error: ${r.errorCode ?? 'unknown'}${r.errorMessage ? ` — ${r.errorMessage}` : ''}`);\n }\n return lines.join('\\n');\n}\n\nfunction renderGenerationList(page: GenerationListResponse): string {\n if (page.jobs.length === 0) return 'No generations.';\n const headers = ['JOB ID', 'STATUS', 'MODEL', 'CREATED', 'CREDITS', 'PROMPT'];\n const PROMPT_WIDTH = 48;\n const data = page.jobs.map((job) => {\n const prompt = (job.prompt ?? '—').replace(/\\s+/g, ' ');\n return [\n job.jobId,\n job.status,\n job.modelSlug ?? '—',\n job.createdAt.slice(0, 16),\n String(job.creditsCharged),\n prompt.length > PROMPT_WIDTH ? `${prompt.slice(0, PROMPT_WIDTH - 1)}…` : prompt,\n ];\n });\n const widths = headers.map((header, i) =>\n Math.max(header.length, ...data.map((cells) => cells[i]!.length)),\n );\n const padRow = (cells: string[]): string =>\n cells\n .map((cell, i) => cell.padEnd(widths[i]!))\n .join(' ')\n .trimEnd();\n const lines = [padRow(headers), ...data.map(padRow)];\n if (page.hasMore && page.cursor) lines.push('', `More: --cursor ${page.cursor}`);\n return lines.join('\\n');\n}\n\nfunction renderEstimate(e: GenerateEstimateResponse): string {\n const lines = [`Model: ${e.modelSlug}`, `Estimated cost: ${e.creditCost} credits`];\n if (e.estimatedSeconds !== null) lines.push(`Typical duration: ~${e.estimatedSeconds}s`);\n if (e.balance !== null) lines.push(`Balance: ${e.balance} credits`);\n lines.push(\n e.affordable\n ? 'Can run now: yes'\n : `Can run now: no (${e.blockedReason?.replace(/_/g, ' ') ?? 'blocked'})`,\n );\n return lines.join('\\n');\n}\n\nfunction renderUploadResult(r: UploadResult): string {\n return [\n `Uploaded: ${r.publicUrl}`,\n `Asset ID: ${r.assetId}`,\n `Bytes: ${r.bytes}`,\n `Deduplicated: ${r.deduplicated}`,\n ].join('\\n');\n}\n\nfunction computeWaitFlag(parsed: ParsedArgsRich): boolean {\n // `--async` is shorthand for \"don't wait\"; an explicit `--wait` /\n // `--no-wait` takes precedence when present.\n if (typeof parsed.boolean.wait === 'boolean') return parsed.boolean.wait;\n if (parsed.boolean.async === true) return false;\n return true;\n}\n\nfunction optionalInt(value: string | undefined, label: string): number | undefined {\n if (value === undefined) return undefined;\n const n = Number.parseInt(value, 10);\n if (!Number.isFinite(n) || n < 0 || String(n) !== value) {\n throw new ArgError(`--${label} must be a non-negative integer.`);\n }\n return n;\n}\n\nfunction exitCodeForResult(result: GenerationResult): ExitCode {\n if (result.status === 'completed') return 0;\n if (result.status === 'failed' || result.status === 'cancelled') {\n if (result.errorCode) return getExitCode(result.errorCode as AllErrorCode);\n return 1;\n }\n return 0;\n}\n\nexport function splitCsvArray(values: string[] | undefined): string[] | undefined {\n if (!values || values.length === 0) return undefined;\n const result = values.flatMap((v) =>\n v\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean),\n );\n return result.length > 0 ? result : undefined;\n}\n\n// ---------------------------------------------------------------------------\n// Template commands\n// ---------------------------------------------------------------------------\n\nasync function runTemplateList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'scope', 'q', 'cursor', 'limit'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['tags'],\n });\n\n const result = await listTemplates({\n q: parsed.string.q,\n tags: splitCsvArray(parsed.array.tags),\n scope: parsed.string.scope as 'own' | 'system' | 'all' | undefined,\n cursor: parsed.string.cursor,\n limit: optionalInt(parsed.string.limit, 'limit'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n ctx.nextCursor = result.cursor ?? undefined;\n emitTemplateList(result, ctx, rc);\n return 0;\n}\n\nasync function runTemplateGet(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const id = parsed.positional[0];\n if (!id) throw new ArgError('Missing required <id> argument.');\n\n const detail = await getTemplate({\n id,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitTemplateDetail(detail, ctx, rc);\n return 0;\n}\n\nasync function runTemplateFind(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'scope', 'cursor', 'limit'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['tags'],\n });\n const query = parsed.positional[0];\n if (!query) throw new ArgError('Missing required <query> argument.');\n\n const result = await findTemplates({\n query,\n tags: splitCsvArray(parsed.array.tags),\n scope: parsed.string.scope as 'own' | 'system' | 'all' | undefined,\n cursor: parsed.string.cursor,\n limit: optionalInt(parsed.string.limit, 'limit'),\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n ctx.nextCursor = result.cursor ?? undefined;\n emitTemplateList(result, ctx, rc);\n return 0;\n}\n\nfunction emitTemplateList(\n result: TemplateListResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderTemplatesList(result, rc.stdout);\n}\n\nfunction emitTemplateDetail(detail: TemplateDetail, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(detail, ctx)) + '\\n');\n return;\n }\n renderTemplateDetail(detail, rc.stdout);\n}\n\n// ---------------------------------------------------------------------------\n// Product commands\n// ---------------------------------------------------------------------------\n\n// Curated remedy for a 403 caused by a missing scope.\n//\n// `--force-reauth` is not optional wording. `login()` REFUSES when the profile\n// holds a valid unexpired token (commands/login.ts), and every user who reaches\n// a scope error has exactly that, so a bare `clickraft login` sends them\n// straight into a second error telling them to pass the flag. The previous hint\n// said `clickraft login`, which was wrong for the only situation it appears in.\n//\n// Parameterized rather than duplicated per scope: the string is identical apart\n// from the scope name, and two copies would drift the moment one is reworded.\nexport function scopeHintFor(scope: string): string {\n return `Your CLI token doesn't include ${scope}. Run \\`clickraft login --force-reauth\\` to re-authenticate with the new scope.`;\n}\n\n// Re-raise an insufficient-scope failure carrying the curated hint, leaving\n// every other error untouched. `err.meta` is spread so status/requestId/details\n// survive; only `hint` is added.\nasync function withScopeHint<T>(scope: string, fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof ApiError && err.code === 'AUTH_TOKEN_SCOPE_INSUFFICIENT') {\n const hint = scopeHintFor(scope);\n throw new ApiError(err.code, hint, { ...err.meta, hint }, err.cause);\n }\n throw err;\n }\n}\n\nasync function runProductList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [\n ...COMMON_RICH_STRING_FLAGS,\n 'cursor',\n 'limit',\n 'sync-status',\n 'source-type',\n 'search',\n ],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n\n const limit = optionalInt(parsed.string.limit, 'limit');\n if (limit !== undefined && (limit < 1 || limit > 100)) {\n throw new ArgError('--limit must be between 1 and 100.');\n }\n\n const result = await withScopeHint('products:read', () =>\n listProducts({\n cursor: parsed.string.cursor,\n limit,\n syncStatus: parsed.string['sync-status'],\n sourceType: parsed.string['source-type'],\n search: parsed.string.search,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n }),\n );\n\n ctx.nextCursor = result.nextCursor ?? undefined;\n emitProductList(result, ctx, rc);\n return 0;\n}\n\n// Curated replacements for two server answers whose default CLI rendering is\n// actively misleading on this route.\nconst PRODUCT_CREATE_NOT_ENABLED =\n 'Product creation is not enabled on this deployment yet. ' +\n 'The endpoint answers 404 while the feature flag is off.';\n\nfunction remapProductCreateError(err: unknown): unknown {\n if (!(err instanceof ApiError)) return err;\n\n // The route 404s when AGENTS_PRODUCTS_WRITE_ENABLED is off, AFTER auth. The\n // generic mapping renders that as \"Resource not found.\", which reads as \"your\n // asset ids are wrong\" and sends the user hunting through their library.\n if (err.code === 'NOT_FOUND') {\n return new ApiError(\n err.code,\n PRODUCT_CREATE_NOT_ENABLED,\n { ...err.meta, hint: PRODUCT_CREATE_NOT_ENABLED },\n err.cause,\n );\n }\n\n // One code, two very different causes, and the remedies are opposites: a\n // body mismatch means \"use a new key\", a cross-token replay means \"this key\n // is not yours\". The server's message distinguishes them, so key off it\n // rather than inventing a third state. Deliberately NOT retried with a fresh\n // key — that is precisely how the duplicate product this key prevents gets\n // created.\n if (err.code === 'IDEMPOTENCY_KEY_CONFLICT') {\n const hint = /different token/i.test(err.message)\n ? 'This idempotency key was used by a different token. Use a key of your own.'\n : 'This idempotency key was already used with a different request body. Use a new key.';\n return new ApiError(err.code, err.message, { ...err.meta, hint }, err.cause);\n }\n\n return err;\n}\n\nasync function runProductCreate(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'name', 'description', 'primary', 'idempotency-key'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['image'],\n });\n\n const name = parsed.string.name;\n if (!name) throw new ArgError('--name is required.');\n\n const rawImages = parsed.array['image'] ?? [];\n if (rawImages.length === 0) throw new ArgError('At least one --image is required.');\n const images = rawImages.map(parseImageSpec);\n\n try {\n const product = await withScopeHint('products:write', () =>\n createProduct({\n name,\n description: parsed.string.description,\n images,\n primary: parsed.string.primary,\n idempotencyKey: parsed.string['idempotency-key'],\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n scopeHint: scopeHintFor('products:write'),\n }),\n );\n\n emitProductCreate(product, ctx, rc);\n return 0;\n } catch (err) {\n throw remapProductCreateError(err);\n }\n}\n\nfunction emitProductCreate(product: ProductSummary, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(product, ctx)) + '\\n');\n return;\n }\n renderProductCreateResult(product, rc.stdout);\n}\n\nfunction emitProductList(result: ProductListResult, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderProductsList(result, rc.stdout);\n}\n\n// ---------------------------------------------------------------------------\n// Models commands\n// ---------------------------------------------------------------------------\n\nasync function runModelsList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'category', 'tier', 'type'],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'featured', 'verbose'],\n });\n\n const result = await listModels({\n category: parsed.string.category,\n tier: parsed.string.tier,\n type: parsed.string.type,\n featured: parsed.boolean.featured,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitModelsList(result, ctx, rc, parsed);\n return 0;\n}\n\nfunction emitModelsList(\n result: ModelListResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n parsed: ParsedArgsRich,\n): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderModelsList(result, rc.stdout, {\n verbose: parsed.boolean.verbose === true,\n filters: {\n category: parsed.string.category ?? '',\n tier: parsed.string.tier ?? '',\n type: parsed.string.type ?? '',\n featured: parsed.boolean.featured !== undefined ? String(parsed.boolean.featured) : '',\n },\n });\n}\n\n// ---------------------------------------------------------------------------\n// Nodes commands\n// ---------------------------------------------------------------------------\n\nasync function runNodesList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n\n const result = await listNodes({\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitNodesList(result, ctx, rc);\n return 0;\n}\n\nasync function runNodesDescribe(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const type = parsed.positional[0];\n if (!type) throw new ArgError('Missing required <type> argument.');\n\n const detail = await describeNode({\n type,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitNodeDetail(detail, ctx, rc);\n return 0;\n}\n\nfunction emitNodesList(result: NodesListResult, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderNodesList(result, rc.stdout);\n}\n\nfunction emitNodeDetail(detail: NodeTypeDetail, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) {\n throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n }\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(detail, ctx)) + '\\n');\n return;\n }\n renderNodeDetail(detail, rc.stdout);\n}\n\n// ---------------------------------------------------------------------------\n// Workflow commands\n// ---------------------------------------------------------------------------\n\nasync function runWorkflowCreate(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'name', 'description', 'from-file'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n array: ['tags'],\n });\n\n let name = parsed.string.name;\n let description = parsed.string.description;\n let tags = splitCsvArray(parsed.array.tags);\n let declaredParams: Record<string, unknown> | Array<Record<string, unknown>> | undefined;\n\n if (parsed.string['from-file']) {\n const raw = await readJsonFile(parsed.string['from-file']);\n if (typeof raw === 'object' && raw !== null && !Array.isArray(raw)) {\n const obj = raw as Record<string, unknown>;\n name = name ?? (typeof obj.name === 'string' ? obj.name : undefined);\n description =\n description ?? (typeof obj.description === 'string' ? obj.description : undefined);\n if (!tags && Array.isArray(obj.tags)) tags = obj.tags as string[];\n if (obj.declared_params != null && typeof obj.declared_params === 'object') {\n declaredParams = obj.declared_params as\n | Record<string, unknown>\n | Array<Record<string, unknown>>;\n }\n }\n }\n\n if (!name) throw new ArgError('--name is required (or provide it in --from-file).');\n\n const result = await createWorkflow({\n name,\n description,\n tags,\n declaredParams,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitWorkflowCreate(result, ctx, rc);\n return 0;\n}\n\nasync function runWorkflowList(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'tags', 'has-param', 'cursor', 'limit'],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n\n const limit = optionalInt(parsed.string.limit, 'limit');\n if (limit !== undefined && (limit < 1 || limit > 100)) {\n throw new ArgError('--limit must be between 1 and 100.');\n }\n\n const result = await listWorkflows({\n cursor: parsed.string.cursor,\n limit,\n tags: parsed.string.tags\n ? parsed.string.tags\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean)\n : undefined,\n declaredParamsHasKey: parsed.string['has-param'],\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n ctx.nextCursor = result.nextCursor ?? undefined;\n emitWorkflowList(result, ctx, rc);\n return 0;\n}\n\nasync function runWorkflowGet(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS],\n boolean: [...COMMON_RICH_BOOL_FLAGS],\n });\n const id = parsed.positional[0];\n if (!id) throw new ArgError('Missing required <id> argument.');\n\n const detail = await getWorkflow({\n id,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitWorkflowDetail(detail, ctx, rc);\n return 0;\n}\n\nasync function runWorkflowApply(\n argv: string[],\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): Promise<ExitCode> {\n const parsed = parseArgsRich(argv, {\n string: [...COMMON_RICH_STRING_FLAGS, 'canvas-rev', 'from-file', 'idempotency-key'],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'auto-rev', 'dry-run'],\n array: ['op'],\n });\n\n const id = parsed.positional[0];\n if (!id) throw new ArgError('Missing required <id> argument.');\n\n let operations: Record<string, unknown>[] = [];\n let fileCanvasRev: number | undefined;\n\n if (parsed.string['from-file']) {\n const raw = await readJsonFile(parsed.string['from-file']);\n if (Array.isArray(raw)) {\n operations = raw as Record<string, unknown>[];\n } else if (typeof raw === 'object' && raw !== null && 'operations' in raw) {\n const obj = raw as Record<string, unknown>;\n operations = obj.operations as Record<string, unknown>[];\n if (typeof obj.canvas_rev === 'number') fileCanvasRev = obj.canvas_rev;\n } else {\n throw new ArgError(\n '--from-file must contain a JSON array or an object with an \"operations\" key.',\n );\n }\n }\n\n if (parsed.array.op) {\n for (const opStr of parsed.array.op) {\n try {\n operations.push(JSON.parse(opStr) as Record<string, unknown>);\n } catch {\n throw new ArgError(`Invalid JSON in --op: ${opStr}`);\n }\n }\n }\n\n if (operations.length === 0) {\n throw new ArgError('No operations provided. Use --from-file or --op.');\n }\n if (operations.length > 100) {\n throw new ArgError('At most 100 operations per request.');\n }\n\n const autoRev = parsed.boolean['auto-rev'] === true;\n let canvasRev: number;\n\n if (parsed.string['canvas-rev'] !== undefined) {\n const n = optionalInt(parsed.string['canvas-rev'], 'canvas-rev');\n if (n === undefined) throw new ArgError('--canvas-rev must be a non-negative integer.');\n canvasRev = n;\n } else if (autoRev) {\n const snapshot = await getWorkflow({\n id,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n canvasRev = snapshot.canvas_rev;\n } else if (fileCanvasRev !== undefined) {\n canvasRev = fileCanvasRev;\n } else {\n throw new ArgError(\n 'Must provide --canvas-rev, use --auto-rev, or include canvas_rev in --from-file.',\n );\n }\n\n if (parsed.boolean['dry-run'] === true) {\n const payload = { canvas_rev: canvasRev, operations };\n rc.stdout.write(JSON.stringify(payload, null, 2) + '\\n');\n return 0;\n }\n\n const result = await applyWorkflow({\n id,\n canvasRev,\n operations,\n idempotencyKey: parsed.string['idempotency-key'],\n autoRev,\n profile: parsed.string.profile,\n apiBaseUrl: parsed.string['api-base-url'],\n token: parsed.string.token,\n signal: rc.signal,\n });\n\n emitWorkflowApply(result, ctx, rc);\n return 0;\n}\n\nfunction emitWorkflowCreate(\n result: WorkflowCreateResponse,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderWorkflowCreateResult(result, rc.stdout);\n}\n\nfunction emitWorkflowList(\n result: WorkflowListResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderWorkflowsList(result, rc.stdout);\n}\n\nfunction emitWorkflowDetail(detail: WorkflowDetail, ctx: EnvelopeContext, rc: NewRunContext): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(detail, ctx)) + '\\n');\n return;\n }\n renderWorkflowDetail(detail, rc.stdout);\n}\n\nfunction emitWorkflowApply(\n result: WorkflowApplyResult,\n ctx: EnvelopeContext,\n rc: NewRunContext,\n): void {\n if (rc.signal?.aborted) throw new AuthError('AUTH_FLOW_CANCELLED', 'Cancelled.');\n if (rc.jsonMode) {\n rc.stdout.write(JSON.stringify(wrapSuccess(result, ctx)) + '\\n');\n return;\n }\n renderWorkflowApplyResult(result, rc.stdout);\n}\n\nasync function readJsonFile(filePath: string): Promise<unknown> {\n const { readFile } = await import('node:fs/promises');\n let text: string;\n try {\n text = await readFile(filePath, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ENOENT') throw new ArgError(`File not found: ${filePath}`);\n if (code === 'EACCES') throw new ArgError(`Permission denied: ${filePath}`);\n throw new ArgError(`Failed to read file: ${filePath}`);\n }\n try {\n return JSON.parse(text);\n } catch {\n throw new ArgError(`File is not valid JSON: ${filePath}`);\n }\n}\n"],"mappings":"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","names":["dirname","join","z","createHash","undiciRequest","request","onWarning","delayMs","resolve","z","readFile","stat","stat","readFile","mkdir","rename","rm","stat","basename","dirname","join","stat","mkdir","dirname","join","basename","rename","rm","UUID_RE","UUID_RE","request","request","isAbortError","profile","z","buildRequestBody","parseArgs","parseArgs","ctx","readFile","__filename","__dirname","dirname","join"]}