@clickraft/cli 0.2.0 → 0.3.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","../src/api/client.ts","../src/auth/redact.ts","../src/errors/codes.ts","../src/errors/schema-mismatch.ts","../src/api/idempotency.ts","../src/api/retry.ts","../src/api/types.ts","../src/auth/errors.ts","../src/api/envelope.ts","../src/commands/balance.ts","../src/auth/credentials.ts","../src/config/paths.ts","../src/auth/types.ts","../src/config/loader.ts","../src/commands/brand-model/list.ts","../src/schemas/jobs.ts","../src/commands/upload.ts","../src/schemas/assets.ts","../src/commands/generate/internal.ts","../src/cli/long-poll.ts","../src/commands/generate/get.ts","../src/commands/generate/wait.ts","../src/commands/generate/create.ts","../src/auth/device-flow.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/telemetry/detect.ts","../src/commands/telemetry/inspect.ts","../src/commands/tokens/list.ts","../src/errors/format.ts","../src/cli/args.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","// 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// See plan-file for the full behaviour contract.\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\nimport { z } from 'zod';\n\nimport { redactTokenLikeFields } from '../auth/redact.js';\nimport type { CloudflareAccessCredentials } from '../config/loader.js';\nimport {\n EXIT_CODE_MAP,\n KNOWN_SERVER_CODES,\n type AllErrorCode,\n type ServerErrorCode,\n} from '../errors/codes.js';\nimport { formatSchemaIssues } from '../errors/schema-mismatch.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}\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 | undefined>;\n idempotencyKey?: string;\n retry?: Partial<RetryOptions>;\n responseSchema?: TSchema;\n signal?: AbortSignal;\n headers?: Record<string, string>;\n}\n\nexport interface ApiErrorMeta {\n status?: number;\n requestId?: string;\n retryable: boolean;\n retryAfterMs?: number;\n redactedBody?: string;\n}\n\nexport class ApiError extends Error {\n public readonly code: AllErrorCode;\n public readonly meta: ApiErrorMeta;\n public override readonly cause?: unknown;\n\n constructor(code: AllErrorCode, 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\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 });\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 });\n }\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}): 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 });\n}\n\nfunction apiErrorFromServerBody(args: {\n body: ServerErrorBody;\n statusCode: number;\n requestId?: string;\n retryAfterHeader?: string;\n redactedBody?: string;\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: AllErrorCode;\n let safeMessage: string;\n if (KNOWN_SERVER_CODES.has(error.code)) {\n code = error.code as AllErrorCode;\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 console.warn(`Unknown server error code: ${redactedRawCode}. Treating as INTERNAL_ERROR.`);\n code = 'INTERNAL_ERROR';\n safeMessage = `Unknown server error code: ${redactedRawCode}.`;\n }\n\n const mapping = EXIT_CODE_MAP[code];\n const retryable = mapping?.retryable ?? (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 });\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 | 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 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\n// Re-export so callers can narrow on ServerErrorCode when needed.\nexport type { ServerErrorCode };\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","// 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 { AuthErrorCode } from '../auth/errors.js';\n\nexport type ServerErrorCode =\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 | 'WORKFLOW_VERSION_REQUIRED'\n | 'WORKFLOW_VERSION_CONFLICT'\n | 'WORKFLOW_NOT_FOUND'\n | '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\nexport type ClientErrorCode = 'NETWORK_ERROR' | 'TIMEOUT' | 'PARSE_ERROR' | 'SCHEMA_MISMATCH';\n\nexport type AllErrorCode = ServerErrorCode | AuthErrorCode | ClientErrorCode;\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 `node-type list` for the current set of node types.',\n },\n WORKFLOW_VERSION_REQUIRED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Send `If-Match: \"<version>\"` from the last `workflow get` response.',\n },\n WORKFLOW_VERSION_CONFLICT: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'The workflow was updated elsewhere. Re-fetch and retry.',\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 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 // --- 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// Codes that originate only on the CLI side; the server should never emit\n// these as `error.code` values.\nconst CLI_ONLY_CODES: ReadonlySet<string> = new Set([\n 'NETWORK_ERROR',\n 'TIMEOUT',\n 'PARSE_ERROR',\n 'SCHEMA_MISMATCH',\n]);\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.\nexport const KNOWN_SERVER_CODES: ReadonlySet<string> = new Set(\n Object.keys(EXIT_CODE_MAP).filter((k) => !CLI_ONLY_CODES.has(k)),\n);\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","// 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","// 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.\nexport function decideRetry(params: {\n attempt: number;\n options: RetryOptions;\n serverRetryAfterMs?: number;\n isNetworkError: boolean;\n isRetryable: boolean;\n}): RetryDecision {\n const { attempt, options, serverRetryAfterMs, isNetworkError, isRetryable } = 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 console.warn(`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","// 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}\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 });\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}): 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 if (mapping?.hint) payload.hint = mapping.hint;\n return payload;\n}\n","import { z } from 'zod';\n\nimport { ApiClient } from '../api/client.js';\nimport { AuthError } from '../auth/errors.js';\nimport { loadConfig } from '../config/loader.js';\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\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 new ApiClient({\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 {\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 { 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 CloudflareAccessCredentials {\n clientId: string;\n clientSecret: string;\n}\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\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\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 }\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 };\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 { z } from 'zod';\n\nimport { ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\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\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 new ApiClient({\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","// 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\nimport { z } from 'zod';\n\n// §4.3 — POST /api/agents/v1/jobs\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(z.string().url()).max(8).optional(),\n aspectRatio: z\n .string()\n .regex(/^\\d+:\\d+$/)\n .optional(),\n resolution: z\n .string()\n .regex(/^\\d+x\\d+$/)\n .optional(),\n durationSeconds: z.number().int().min(1).max(60).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 })\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","// `clickraft upload <file-path>` — uploads a local file to the Agents API.\n//\n// Two-step flow per RFC §4.6:\n// 1. POST /api/agents/v1/assets with file metadata + sha256(content).\n// The idempotency key is derived from the content hash + scope so\n// identical bytes uploaded twice (in CI, in retries) reuse the\n// original asset without a second charge.\n// 2. PUT the bytes to the signed GCS upload URL the server returned. On a\n// retryable PUT failure (5xx / network) we retry once against the SAME\n// URL with the SAME bytes. On 4xx we fail with STORAGE_UPLOAD_FAILED —\n// re-POSTing risks a `deduplicated:true` echo that hides corrupt\n// partial bytes.\n\nimport { createHash } from 'node:crypto';\nimport { readFile, stat } from 'node:fs/promises';\nimport { basename } from 'node:path';\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\n\nimport { ApiClient, ApiError } from '../api/client.js';\nimport { generateUploadIdempotencyKey } from '../api/idempotency.js';\nimport { loadConfig } from '../config/loader.js';\nimport {\n MAX_UPLOAD_SIZE_BYTES,\n UploadResponseSchema,\n type UploadResponse,\n} from '../schemas/assets.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.\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 contentType = detectContentType(opts.filePath, content);\n const sha = sha256Hex(content);\n const contentHash = `sha256:${sha}`;\n const filename = basename(opts.filePath);\n const idempotencyKey = generateUploadIdempotencyKey(content, scope);\n\n const client = opts.client ?? (await buildClient(opts));\n\n const response = await postAssetMetadata({\n client,\n filename,\n contentType,\n sizeBytes: content.length,\n contentHash,\n idempotencyKey,\n signal: opts.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,\n contentType,\n signal: opts.signal,\n dispatcher: opts.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 ${filename} (HTTP ${first.status ?? 'unknown'}).`,\n { retryable: false },\n );\n }\n const retry = await tryPut({\n uploadUrl: response.uploadUrl,\n content,\n contentType,\n signal: opts.signal,\n dispatcher: opts.putDispatcher,\n });\n if (!retry.ok) {\n throw new ApiError(\n 'STORAGE_UPLOAD_FAILED',\n `Upload to signed URL failed for ${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: content.length,\n contentHash,\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 new ApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n\nasync function postAssetMetadata(args: {\n client: ApiClient;\n filename: string;\n contentType: string;\n sizeBytes: number;\n contentHash: string;\n idempotencyKey: string;\n signal?: AbortSignal;\n}): Promise<UploadResponse> {\n return args.client.request<UploadResponse>({\n method: 'POST',\n path: '/assets',\n body: {\n filename: args.filename,\n contentType: args.contentType,\n sizeBytes: args.sizeBytes,\n contentHash: args.contentHash,\n },\n idempotencyKey: args.idempotencyKey,\n responseSchema: UploadResponseSchema,\n signal: args.signal,\n });\n}\n\ntype PutOutcome = { ok: true } | { ok: false; kind: 'retryable' | 'fatal'; status?: number };\n\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 // (GCS returns an empty body on success and a small XML doc on failure).\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\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\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\nexport function detectContentType(filePath: 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 = filePath.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","// 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 uploadUrl: z.string().url(),\n publicUrl: z.string().url(),\n deduplicated: z.boolean(),\n })\n .strict();\n\nexport type UploadResponse = z.infer<typeof UploadResponseSchema>;\n","// Shared helpers for the `generate` command family.\n\nimport { 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 new ApiClient({\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","// 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 '../api/client.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 // If the abort/deadline fired while the fetcher was in flight, the\n // fetcher typically throws AbortError. Surface that as TIMEOUT so all\n // \"we gave up\" paths share the same exit-code category. Other errors\n // propagate verbatim.\n if (opts.signal?.aborted || now() - started >= 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 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","// `clickraft generate get <jobId>` — fetches the current state of a generation\n// job without holding the request. Returns the full GenerationResult.\n\nimport type { ApiClient } from '../../api/client.js';\nimport { GenerationResultSchema, type GenerationResult } from '../../schemas/jobs.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 wait <jobId>` — long-polls until the job reaches a\n// terminal state (completed / failed / cancelled) or the overall timeout\n// elapses.\n//\n// Implementation: server long-poll rounds via `?wait=30` (RFC §4.4 + Phase 8\n// Q9) inside a generic longPoll loop that enforces the overall deadline and\n// honors the abort signal.\n\nimport type { ApiClient } from '../../api/client.js';\nimport { longPoll } from '../../cli/long-poll.js';\nimport { isTerminalStatus, type GenerationResult } from '../../schemas/jobs.js';\n\nimport { generateGet } from './get.js';\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 const timeoutSeconds = opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS;\n\n return longPoll<GenerationResult>({\n // Forward the iteration signal so the in-flight server hold is aborted\n // as soon as the overall deadline expires — otherwise `--timeout 1` would\n // still block for the full 30s server long-poll round.\n fetcher: (args) =>\n generateGet({\n jobId: opts.jobId,\n waitSeconds: SERVER_LONG_POLL_SECONDS,\n client,\n signal: args?.signal,\n }),\n isTerminal: (r) => isTerminalStatus(r.status),\n timeoutMs: timeoutSeconds * 1000,\n signal: opts.signal,\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 { ApiError, type ApiClient } from '../../api/client.js';\nimport {\n GenerateCreateRequestSchema,\n GenerateCreateResponseSchema,\n type GenerateCreateResponse,\n type GenerationResult,\n} from '../../schemas/jobs.js';\nimport { uploadFile, DEFAULT_UPLOAD_SCOPE } from '../upload.js';\n\nimport { buildGenerateClient, isUrlLike, type GenerateClientOptions } from './internal.js';\nimport { generateWait, DEFAULT_WAIT_TIMEOUT_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 referenceImages?: string[];\n aspectRatio?: string;\n resolution?: string;\n durationSeconds?: number;\n // Forwarded as `input.providerParams.brandModelId` per RFC §4.3.\n brandModel?: string;\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 buildRequestBody({ ...opts, referenceImages: preflightRefs });\n\n const referenceImages = await resolveReferenceImages({\n items: opts.referenceImages ?? [],\n client,\n signal: opts.signal,\n });\n\n const body = buildRequestBody({ ...opts, referenceImages });\n\n const created = await client.request<GenerateCreateResponse>({\n method: 'POST',\n path: '/jobs',\n body,\n responseSchema: GenerateCreateResponseSchema,\n signal: opts.signal,\n });\n\n const wait = opts.wait ?? true;\n if (!wait) {\n return projectCreateToResult(created, opts.modelSlug);\n }\n\n return generateWait({\n jobId: created.jobId,\n timeoutSeconds: opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS,\n client,\n signal: opts.signal,\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(args: GenerateCreateOptions & { referenceImages: string[] }): unknown {\n const input: Record<string, unknown> = {};\n if (args.prompt !== undefined) input.prompt = args.prompt;\n if (args.referenceImages.length === 1) {\n input.referenceImageUrl = args.referenceImages[0];\n } else if (args.referenceImages.length > 1) {\n input.referenceImages = args.referenceImages;\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.brandModel !== undefined) input.providerParams = { brandModelId: args.brandModel };\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 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","import { setTimeout as delay } from 'node:timers/promises';\n\nimport { request } from 'undici';\n\nimport { ApiError } from '../api/client.js';\nimport type { CloudflareAccessCredentials } from '../config/loader.js';\n\nimport { AuthError } from './errors.js';\nimport { redactTokenLikeFields } from './redact.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 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\nasync function requestDeviceAuthorization(\n opts: DeviceFlowOptions,\n): Promise<DeviceAuthorizationResponse> {\n const body = new URLSearchParams({ client_id: opts.clientId, scope: opts.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 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\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// All eight scopes per `02-oauth.md` §2.4. Reads are not implied by writes.\nexport const DEFAULT_SCOPES: readonly string[] = [\n 'templates:read',\n 'generations:write',\n 'generations:read',\n 'workflows:write',\n 'workflows:read',\n 'brand-models:read',\n 'assets:write',\n 'balance:read',\n];\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 // 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 scope = options.scope?.trim() || DEFAULT_SCOPES.join(' ');\n const flow = options.runDeviceFlow ?? runDeviceFlow;\n const token = await flow({\n apiBaseUrl,\n clientId: CLIENT_ID,\n scope,\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 { ApiClient } from '../api/client.js';\nimport { deleteCredentials, readCredentials, removeProfile } from '../auth/credentials.js';\nimport { CredentialsError } from '../auth/errors.js';\nimport { redactTokenLikeFields, redactTokenLikeValue } from '../auth/redact.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 new ApiClient({\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","// 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","// `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 schema below is the CLI's\n// assumption; if the server diverges the integration test will surface it\n// via SCHEMA_MISMATCH from ApiClient's strict Zod validation.\n\nimport { z } from 'zod';\n\nimport { ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\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\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 new ApiClient({\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","// 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 return [\n `Error: ${view.message}`,\n `Code: ${view.code}`,\n `Try: ${view.hint}`,\n `Request ID: ${view.requestId ?? 'n/a'}`,\n ].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}\n\nfunction errorToView(err: unknown): ErrorView {\n if (err instanceof ApiError) {\n return {\n code: toEnvelopeCode(err.code),\n message: err.message,\n hint: EXIT_CODE_MAP[err.code]?.hint ?? FALLBACK_HINT,\n requestId: err.meta.requestId,\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 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","// 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 BalanceData } from '../commands/balance.js';\nimport { type BrandModelSummary } from '../commands/brand-model/list.js';\nimport { type LoginResult } from '../commands/login.js';\nimport { type LogoutResult } from '../commands/logout.js';\nimport { type TelemetryState } from '../commands/telemetry/inspect.js';\nimport { type TokenRow } from '../commands/tokens/list.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\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","// 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 { ApiError } from '../api/client.js';\nimport { wrapSuccess, type EnvelopeContext } from '../api/envelope.js';\nimport { AuthError } from '../auth/errors.js';\nimport { getBalance, type BalanceData } from '../commands/balance.js';\nimport { listBrandModels, type BrandModelSummary } from '../commands/brand-model/list.js';\nimport { generateCreate } from '../commands/generate/create.js';\nimport { generateGet } from '../commands/generate/get.js';\nimport { generateWait } from '../commands/generate/wait.js';\nimport { jobsWait } from '../commands/jobs/wait.js';\nimport { login, type LoginResult } from '../commands/login.js';\nimport { logout, type LogoutResult } from '../commands/logout.js';\nimport { inspectTelemetry, type TelemetryState } from '../commands/telemetry/inspect.js';\nimport { listTokens, type TokenRow } from '../commands/tokens/list.js';\nimport { uploadFile, type UploadResult } from '../commands/upload.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';\nimport type { GenerationResult } from '../schemas/jobs.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 renderTelemetryState,\n renderTokensList,\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 });\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 ' telemetry inspect Show current telemetry state and payload shape',\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 ' 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 8)',\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 '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 '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 <id> Optional Brand Model reference',\n ' --reference-image <v> URL or local path (repeatable, max 8)',\n ' --aspect-ratio <a:b> e.g. 16:9',\n ' --resolution <WxH> e.g. 1024x768',\n ' --duration-seconds <n> For video/audio models (1-60)',\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 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 = 'generate.create' | 'generate.wait' | 'generate.get' | 'jobs.wait' | 'upload';\n\ntype NewCommandMatch =\n | { kind: 'cmd'; path: NewCommandPath; verbTokenCount: 1 | 2 }\n | { kind: 'sub-help'; verb: 'generate' | 'jobs' }\n | { kind: 'unknown-sub'; verb: 'generate' | 'jobs'; sub: string };\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 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 }\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 'brand-model',\n 'aspect-ratio',\n 'resolution',\n 'duration-seconds',\n 'workflow-id',\n 'node-id',\n 'timeout',\n ],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'wait', 'async'],\n array: ['reference-image'],\n });\n\n const modelSlug = parsed.string['model-slug'];\n if (!modelSlug) throw new ArgError('--model-slug is required.');\n\n const result = await generateCreate({\n prompt: parsed.string.prompt ?? parsed.positional[0],\n modelSlug,\n referenceImages: parsed.array['reference-image'],\n aspectRatio: parsed.string['aspect-ratio'],\n resolution: parsed.string.resolution,\n durationSeconds: optionalInt(parsed.string['duration-seconds'], 'duration-seconds'),\n brandModel: parsed.string['brand-model'],\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"],"mappings":"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","names":["dirname","join","z","delayMs","z","z","z","z","z","z","z","createHash","readFile","stat","undiciRequest","z","undiciRequest","stat","readFile","createHash","isAbortError","profile","z","z","parseArgs","parseArgs","ctx","__filename","__dirname","dirname","join"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/api/client.ts","../src/auth/redact.ts","../src/errors/codes.ts","../src/errors/schema-mismatch.ts","../src/api/idempotency.ts","../src/api/retry.ts","../src/api/types.ts","../src/auth/errors.ts","../src/api/envelope.ts","../src/commands/balance.ts","../src/auth/credentials.ts","../src/config/paths.ts","../src/auth/types.ts","../src/config/loader.ts","../src/commands/brand-model/list.ts","../src/schemas/jobs.ts","../src/commands/upload.ts","../src/schemas/assets.ts","../src/commands/generate/internal.ts","../src/cli/long-poll.ts","../src/commands/generate/get.ts","../src/commands/generate/wait.ts","../src/commands/generate/create.ts","../src/auth/device-flow.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/telemetry/detect.ts","../src/commands/telemetry/inspect.ts","../src/commands/template/internal.ts","../src/schemas/templates.ts","../src/commands/template/list.ts","../src/commands/template/find.ts","../src/commands/template/get.ts","../src/commands/tokens/list.ts","../src/errors/format.ts","../src/cli/args.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","// 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// See plan-file for the full behaviour contract.\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\nimport { z } from 'zod';\n\nimport { redactTokenLikeFields } from '../auth/redact.js';\nimport type { CloudflareAccessCredentials } from '../config/loader.js';\nimport {\n EXIT_CODE_MAP,\n KNOWN_SERVER_CODES,\n type AllErrorCode,\n type ServerErrorCode,\n} from '../errors/codes.js';\nimport { formatSchemaIssues } from '../errors/schema-mismatch.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}\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\nexport interface ApiErrorMeta {\n status?: number;\n requestId?: string;\n retryable: boolean;\n retryAfterMs?: number;\n redactedBody?: string;\n}\n\nexport class ApiError extends Error {\n public readonly code: AllErrorCode;\n public readonly meta: ApiErrorMeta;\n public override readonly cause?: unknown;\n\n constructor(code: AllErrorCode, 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\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 });\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 });\n }\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}): 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 });\n}\n\nfunction apiErrorFromServerBody(args: {\n body: ServerErrorBody;\n statusCode: number;\n requestId?: string;\n retryAfterHeader?: string;\n redactedBody?: string;\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: AllErrorCode;\n let safeMessage: string;\n if (KNOWN_SERVER_CODES.has(error.code)) {\n code = error.code as AllErrorCode;\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 console.warn(`Unknown server error code: ${redactedRawCode}. Treating as INTERNAL_ERROR.`);\n code = 'INTERNAL_ERROR';\n safeMessage = `Unknown server error code: ${redactedRawCode}.`;\n }\n\n const mapping = EXIT_CODE_MAP[code];\n const retryable = mapping?.retryable ?? (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 });\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\n// Re-export so callers can narrow on ServerErrorCode when needed.\nexport type { ServerErrorCode };\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","// 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 { AuthErrorCode } from '../auth/errors.js';\n\nexport type ServerErrorCode =\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 | 'WORKFLOW_VERSION_REQUIRED'\n | 'WORKFLOW_VERSION_CONFLICT'\n | 'WORKFLOW_NOT_FOUND'\n | '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\nexport type ClientErrorCode = 'NETWORK_ERROR' | 'TIMEOUT' | 'PARSE_ERROR' | 'SCHEMA_MISMATCH';\n\nexport type AllErrorCode = ServerErrorCode | AuthErrorCode | ClientErrorCode;\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 `node-type list` for the current set of node types.',\n },\n WORKFLOW_VERSION_REQUIRED: {\n exitCode: 2,\n category: 'usage',\n retryable: false,\n hint: 'Send `If-Match: \"<version>\"` from the last `workflow get` response.',\n },\n WORKFLOW_VERSION_CONFLICT: {\n exitCode: 7,\n category: 'conflict',\n retryable: false,\n hint: 'The workflow was updated elsewhere. Re-fetch and retry.',\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 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 // --- 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// Codes that originate only on the CLI side; the server should never emit\n// these as `error.code` values.\nconst CLI_ONLY_CODES: ReadonlySet<string> = new Set([\n 'NETWORK_ERROR',\n 'TIMEOUT',\n 'PARSE_ERROR',\n 'SCHEMA_MISMATCH',\n]);\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.\nexport const KNOWN_SERVER_CODES: ReadonlySet<string> = new Set(\n Object.keys(EXIT_CODE_MAP).filter((k) => !CLI_ONLY_CODES.has(k)),\n);\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","// 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","// 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.\nexport function decideRetry(params: {\n attempt: number;\n options: RetryOptions;\n serverRetryAfterMs?: number;\n isNetworkError: boolean;\n isRetryable: boolean;\n}): RetryDecision {\n const { attempt, options, serverRetryAfterMs, isNetworkError, isRetryable } = 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 console.warn(`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","// 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}\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 });\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}): 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 if (mapping?.hint) payload.hint = mapping.hint;\n return payload;\n}\n","import { z } from 'zod';\n\nimport { ApiClient } from '../api/client.js';\nimport { AuthError } from '../auth/errors.js';\nimport { loadConfig } from '../config/loader.js';\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\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 new ApiClient({\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 {\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 { 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 CloudflareAccessCredentials {\n clientId: string;\n clientSecret: string;\n}\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\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\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 }\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 };\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 { z } from 'zod';\n\nimport { ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\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\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 new ApiClient({\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","// 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\nimport { z } from 'zod';\n\n// §4.3 — POST /api/agents/v1/jobs\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(z.string().url()).max(8).optional(),\n aspectRatio: z\n .string()\n .regex(/^\\d+:\\d+$/)\n .optional(),\n resolution: z\n .string()\n .regex(/^\\d+x\\d+$/)\n .optional(),\n durationSeconds: z.number().int().min(1).max(60).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 })\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","// `clickraft upload <file-path>` — uploads a local file to the Agents API.\n//\n// Two-step flow per RFC §4.6:\n// 1. POST /api/agents/v1/assets with file metadata + sha256(content).\n// The idempotency key is derived from the content hash + scope so\n// identical bytes uploaded twice (in CI, in retries) reuse the\n// original asset without a second charge.\n// 2. PUT the bytes to the signed GCS upload URL the server returned. On a\n// retryable PUT failure (5xx / network) we retry once against the SAME\n// URL with the SAME bytes. On 4xx we fail with STORAGE_UPLOAD_FAILED —\n// re-POSTing risks a `deduplicated:true` echo that hides corrupt\n// partial bytes.\n\nimport { createHash } from 'node:crypto';\nimport { readFile, stat } from 'node:fs/promises';\nimport { basename } from 'node:path';\n\nimport { request as undiciRequest, type Dispatcher } from 'undici';\n\nimport { ApiClient, ApiError } from '../api/client.js';\nimport { generateUploadIdempotencyKey } from '../api/idempotency.js';\nimport { loadConfig } from '../config/loader.js';\nimport {\n MAX_UPLOAD_SIZE_BYTES,\n UploadResponseSchema,\n type UploadResponse,\n} from '../schemas/assets.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.\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 contentType = detectContentType(opts.filePath, content);\n const sha = sha256Hex(content);\n const contentHash = `sha256:${sha}`;\n const filename = basename(opts.filePath);\n const idempotencyKey = generateUploadIdempotencyKey(content, scope);\n\n const client = opts.client ?? (await buildClient(opts));\n\n const response = await postAssetMetadata({\n client,\n filename,\n contentType,\n sizeBytes: content.length,\n contentHash,\n idempotencyKey,\n signal: opts.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,\n contentType,\n signal: opts.signal,\n dispatcher: opts.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 ${filename} (HTTP ${first.status ?? 'unknown'}).`,\n { retryable: false },\n );\n }\n const retry = await tryPut({\n uploadUrl: response.uploadUrl,\n content,\n contentType,\n signal: opts.signal,\n dispatcher: opts.putDispatcher,\n });\n if (!retry.ok) {\n throw new ApiError(\n 'STORAGE_UPLOAD_FAILED',\n `Upload to signed URL failed for ${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: content.length,\n contentHash,\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 new ApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n\nasync function postAssetMetadata(args: {\n client: ApiClient;\n filename: string;\n contentType: string;\n sizeBytes: number;\n contentHash: string;\n idempotencyKey: string;\n signal?: AbortSignal;\n}): Promise<UploadResponse> {\n return args.client.request<UploadResponse>({\n method: 'POST',\n path: '/assets',\n body: {\n filename: args.filename,\n contentType: args.contentType,\n sizeBytes: args.sizeBytes,\n contentHash: args.contentHash,\n },\n idempotencyKey: args.idempotencyKey,\n responseSchema: UploadResponseSchema,\n signal: args.signal,\n });\n}\n\ntype PutOutcome = { ok: true } | { ok: false; kind: 'retryable' | 'fatal'; status?: number };\n\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 // (GCS returns an empty body on success and a small XML doc on failure).\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\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\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\nexport function detectContentType(filePath: 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 = filePath.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","// 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 uploadUrl: z.string().url(),\n publicUrl: z.string().url(),\n deduplicated: z.boolean(),\n })\n .strict();\n\nexport type UploadResponse = z.infer<typeof UploadResponseSchema>;\n","// Shared helpers for the `generate` command family.\n\nimport { 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 new ApiClient({\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","// 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 '../api/client.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 // If the abort/deadline fired while the fetcher was in flight, the\n // fetcher typically throws AbortError. Surface that as TIMEOUT so all\n // \"we gave up\" paths share the same exit-code category. Other errors\n // propagate verbatim.\n if (opts.signal?.aborted || now() - started >= 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 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","// `clickraft generate get <jobId>` — fetches the current state of a generation\n// job without holding the request. Returns the full GenerationResult.\n\nimport type { ApiClient } from '../../api/client.js';\nimport { GenerationResultSchema, type GenerationResult } from '../../schemas/jobs.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 wait <jobId>` — long-polls until the job reaches a\n// terminal state (completed / failed / cancelled) or the overall timeout\n// elapses.\n//\n// Implementation: server long-poll rounds via `?wait=30` (RFC §4.4 + Phase 8\n// Q9) inside a generic longPoll loop that enforces the overall deadline and\n// honors the abort signal.\n\nimport type { ApiClient } from '../../api/client.js';\nimport { longPoll } from '../../cli/long-poll.js';\nimport { isTerminalStatus, type GenerationResult } from '../../schemas/jobs.js';\n\nimport { generateGet } from './get.js';\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 const timeoutSeconds = opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS;\n\n return longPoll<GenerationResult>({\n // Forward the iteration signal so the in-flight server hold is aborted\n // as soon as the overall deadline expires — otherwise `--timeout 1` would\n // still block for the full 30s server long-poll round.\n fetcher: (args) =>\n generateGet({\n jobId: opts.jobId,\n waitSeconds: SERVER_LONG_POLL_SECONDS,\n client,\n signal: args?.signal,\n }),\n isTerminal: (r) => isTerminalStatus(r.status),\n timeoutMs: timeoutSeconds * 1000,\n signal: opts.signal,\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 { ApiError, type ApiClient } from '../../api/client.js';\nimport {\n GenerateCreateRequestSchema,\n GenerateCreateResponseSchema,\n type GenerateCreateResponse,\n type GenerationResult,\n} from '../../schemas/jobs.js';\nimport { uploadFile, DEFAULT_UPLOAD_SCOPE } from '../upload.js';\n\nimport { buildGenerateClient, isUrlLike, type GenerateClientOptions } from './internal.js';\nimport { generateWait, DEFAULT_WAIT_TIMEOUT_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 referenceImages?: string[];\n aspectRatio?: string;\n resolution?: string;\n durationSeconds?: number;\n // Forwarded as `input.providerParams.brandModelId` per RFC §4.3.\n brandModel?: string;\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 buildRequestBody({ ...opts, referenceImages: preflightRefs });\n\n const referenceImages = await resolveReferenceImages({\n items: opts.referenceImages ?? [],\n client,\n signal: opts.signal,\n });\n\n const body = buildRequestBody({ ...opts, referenceImages });\n\n const created = await client.request<GenerateCreateResponse>({\n method: 'POST',\n path: '/jobs',\n body,\n responseSchema: GenerateCreateResponseSchema,\n signal: opts.signal,\n });\n\n const wait = opts.wait ?? true;\n if (!wait) {\n return projectCreateToResult(created, opts.modelSlug);\n }\n\n return generateWait({\n jobId: created.jobId,\n timeoutSeconds: opts.timeoutSeconds ?? DEFAULT_WAIT_TIMEOUT_SECONDS,\n client,\n signal: opts.signal,\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(args: GenerateCreateOptions & { referenceImages: string[] }): unknown {\n const input: Record<string, unknown> = {};\n if (args.prompt !== undefined) input.prompt = args.prompt;\n if (args.referenceImages.length === 1) {\n input.referenceImageUrl = args.referenceImages[0];\n } else if (args.referenceImages.length > 1) {\n input.referenceImages = args.referenceImages;\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.brandModel !== undefined) input.providerParams = { brandModelId: args.brandModel };\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 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","import { setTimeout as delay } from 'node:timers/promises';\n\nimport { request } from 'undici';\n\nimport { ApiError } from '../api/client.js';\nimport type { CloudflareAccessCredentials } from '../config/loader.js';\n\nimport { AuthError } from './errors.js';\nimport { redactTokenLikeFields } from './redact.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 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\nasync function requestDeviceAuthorization(\n opts: DeviceFlowOptions,\n): Promise<DeviceAuthorizationResponse> {\n const body = new URLSearchParams({ client_id: opts.clientId, scope: opts.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 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\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// All eight scopes per `02-oauth.md` §2.4. Reads are not implied by writes.\nexport const DEFAULT_SCOPES: readonly string[] = [\n 'templates:read',\n 'generations:write',\n 'generations:read',\n 'workflows:write',\n 'workflows:read',\n 'brand-models:read',\n 'assets:write',\n 'balance:read',\n];\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 // 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 scope = options.scope?.trim() || DEFAULT_SCOPES.join(' ');\n const flow = options.runDeviceFlow ?? runDeviceFlow;\n const token = await flow({\n apiBaseUrl,\n clientId: CLIENT_ID,\n scope,\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 { ApiClient } from '../api/client.js';\nimport { deleteCredentials, readCredentials, removeProfile } from '../auth/credentials.js';\nimport { CredentialsError } from '../auth/errors.js';\nimport { redactTokenLikeFields, redactTokenLikeValue } from '../auth/redact.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 new ApiClient({\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","// 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 { 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 new ApiClient({\n apiBaseUrl: cfg.apiBaseUrl,\n accessToken: cfg.accessToken,\n signal: opts.signal,\n cloudflareAccess: cfg.cloudflareAccess,\n });\n}\n","import { z } from 'zod';\n\nexport const DeclaredParamSchema = z\n .object({\n name: z.string(),\n type: z.string(),\n required: z.boolean(),\n defaultValue: z.string().nullable().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","import type { ApiClient } from '../../api/client.js';\nimport {\n TemplatesListResponseSchema,\n type TemplateSummary,\n type TemplatesListResponse,\n} from '../../schemas/templates.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 type { ApiClient } from '../../api/client.js';\nimport { TemplateDetailSchema, type TemplateDetail } from '../../schemas/templates.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 schema below is the CLI's\n// assumption; if the server diverges the integration test will surface it\n// via SCHEMA_MISMATCH from ApiClient's strict Zod validation.\n\nimport { z } from 'zod';\n\nimport { ApiClient } from '../../api/client.js';\nimport { AuthError } from '../../auth/errors.js';\nimport { loadConfig } from '../../config/loader.js';\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\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 new ApiClient({\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","// 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 return [\n `Error: ${view.message}`,\n `Code: ${view.code}`,\n `Try: ${view.hint}`,\n `Request ID: ${view.requestId ?? 'n/a'}`,\n ].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}\n\nfunction errorToView(err: unknown): ErrorView {\n if (err instanceof ApiError) {\n return {\n code: toEnvelopeCode(err.code),\n message: err.message,\n hint: EXIT_CODE_MAP[err.code]?.hint ?? FALLBACK_HINT,\n requestId: err.meta.requestId,\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 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","// 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 BalanceData } from '../commands/balance.js';\nimport { type BrandModelSummary } from '../commands/brand-model/list.js';\nimport { type LoginResult } from '../commands/login.js';\nimport { type LogoutResult } from '../commands/logout.js';\nimport { type TelemetryState } from '../commands/telemetry/inspect.js';\nimport { type TemplateListResult } from '../commands/template/list.js';\nimport { type TokenRow } from '../commands/tokens/list.js';\nimport { type TemplateDetail } from '../schemas/templates.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 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\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","// 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 { ApiError } from '../api/client.js';\nimport { wrapSuccess, type EnvelopeContext } from '../api/envelope.js';\nimport { AuthError } from '../auth/errors.js';\nimport { getBalance, type BalanceData } from '../commands/balance.js';\nimport { listBrandModels, type BrandModelSummary } from '../commands/brand-model/list.js';\nimport { generateCreate } from '../commands/generate/create.js';\nimport { generateGet } from '../commands/generate/get.js';\nimport { generateWait } from '../commands/generate/wait.js';\nimport { jobsWait } from '../commands/jobs/wait.js';\nimport { login, type LoginResult } from '../commands/login.js';\nimport { logout, type LogoutResult } from '../commands/logout.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, type TokenRow } from '../commands/tokens/list.js';\nimport { uploadFile, type UploadResult } from '../commands/upload.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';\nimport type { GenerationResult } from '../schemas/jobs.js';\nimport type { TemplateDetail } from '../schemas/templates.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 renderTelemetryState,\n renderTemplateDetail,\n renderTemplatesList,\n renderTokensList,\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 });\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 ' 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 ' 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 8)',\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 '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 <id> Optional Brand Model reference',\n ' --reference-image <v> URL or local path (repeatable, max 8)',\n ' --aspect-ratio <a:b> e.g. 16:9',\n ' --resolution <WxH> e.g. 1024x768',\n ' --duration-seconds <n> For video/audio models (1-60)',\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 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\ntype NewCommandMatch =\n | { kind: 'cmd'; path: NewCommandPath; verbTokenCount: 1 | 2 }\n | { kind: 'sub-help'; verb: 'generate' | 'jobs' | 'template' }\n | { kind: 'unknown-sub'; verb: 'generate' | 'jobs' | 'template'; sub: string };\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 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 }\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 'brand-model',\n 'aspect-ratio',\n 'resolution',\n 'duration-seconds',\n 'workflow-id',\n 'node-id',\n 'timeout',\n ],\n boolean: [...COMMON_RICH_BOOL_FLAGS, 'wait', 'async'],\n array: ['reference-image'],\n });\n\n const modelSlug = parsed.string['model-slug'];\n if (!modelSlug) throw new ArgError('--model-slug is required.');\n\n const result = await generateCreate({\n prompt: parsed.string.prompt ?? parsed.positional[0],\n modelSlug,\n referenceImages: parsed.array['reference-image'],\n aspectRatio: parsed.string['aspect-ratio'],\n resolution: parsed.string.resolution,\n durationSeconds: optionalInt(parsed.string['duration-seconds'], 'duration-seconds'),\n brandModel: parsed.string['brand-model'],\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\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: 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: 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"],"mappings":"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","names":["dirname","join","z","delayMs","z","z","z","z","z","z","z","createHash","readFile","stat","undiciRequest","z","undiciRequest","stat","readFile","createHash","isAbortError","profile","z","z","z","parseArgs","parseArgs","ctx","__filename","__dirname","dirname","join"]}