@apicircle/cli 1.0.7 → 1.0.8

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../package.json","../../src/packageVersion.ts","../../src/commands/mock.ts","../../src/util/loadWorkspace.ts","../../src/util/resolveWorkspace.ts","../../src/commands/mcp.ts","../../src/commands/import.ts","../../src/commands/export.ts","../../src/util/secrets.ts","../../src/util/executionAttachments.ts","../../src/commands/run.ts","../../src/commands/workspaces.ts","../../src/index.ts","../../src/bin/cli.ts","../../src/bin/args.ts"],"sourcesContent":["{\n \"name\": \"@apicircle/cli\",\n \"version\": \"1.0.7\",\n \"private\": false,\n \"type\": \"module\",\n \"description\": \"Command-line interface for API Circle Studio. Run mock servers, drive the MCP server, and import OpenAPI / Postman / Insomnia collections from any terminal.\",\n \"keywords\": [\n \"apicircle\",\n \"api-circle\",\n \"cli\",\n \"command-line\",\n \"api\",\n \"api-client\",\n \"http\",\n \"http-client\",\n \"mock-server\",\n \"mcp\",\n \"mcp-server\",\n \"openapi\",\n \"swagger\",\n \"postman\",\n \"insomnia\",\n \"import\",\n \"workspace\",\n \"headless\"\n ],\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/apicircle/studio.git\",\n \"directory\": \"packages/cli\"\n },\n \"homepage\": \"https://github.com/apicircle/studio#readme\",\n \"bugs\": \"https://github.com/apicircle/studio/issues\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"main\": \"./src/index.ts\",\n \"types\": \"./src/index.ts\",\n \"bin\": {\n \"apicircle\": \"./dist/bin/cli.cjs\"\n },\n \"exports\": {\n \".\": \"./src/index.ts\"\n },\n \"files\": [\n \"dist\"\n ],\n \"publishConfig\": {\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.cts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n }\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"check\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"clean\": \"rm -rf dist node_modules\"\n },\n \"dependencies\": {\n \"@apicircle/core\": \"workspace:*\",\n \"@apicircle/mcp-server\": \"workspace:*\",\n \"@apicircle/mock-server-core\": \"workspace:*\",\n \"@apicircle/shared\": \"workspace:*\",\n \"commander\": \"^12.0.0\",\n \"kleur\": \"^4.1.5\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"tsup\": \"^8.3.0\",\n \"typescript\": \"^5.4.0\",\n \"vitest\": \"^2.0.0\"\n }\n}\n","import packageJson from '../package.json';\n\nexport function readPackageVersion(): string {\n const version = (packageJson as { version?: unknown }).version;\n if (typeof version !== 'string' || version.length === 0) {\n throw new Error('Unable to read @apicircle/cli package version');\n }\n return version;\n}\n\nexport const CLI_PACKAGE_VERSION = readPackageVersion();\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n parseSourceToEndpoints,\n startMockServer,\n type MockServerHandle,\n} from '@apicircle/mock-server-core';\nimport { generateId, type MockServer } from '@apicircle/shared';\n\n// =============================================================================\n// `apicircle mock <spec>` — boot a mock server from an OpenAPI / Postman /\n// Insomnia file. The path's extension chooses the parser; user can override\n// with `--type {openapi,postman,insomnia}`.\n// =============================================================================\n\ninterface MockOptions {\n port?: string;\n host?: string;\n type?: 'openapi' | 'postman' | 'insomnia' | 'auto';\n format?: 'json' | 'yaml' | 'auto';\n cors?: boolean;\n}\n\nexport function registerMockCommand(program: Command): void {\n program\n .command('mock')\n .description('Run a mock server from an OpenAPI / Postman / Insomnia file')\n .argument('<spec>', 'Path to the spec file')\n .option('-p, --port <number>', 'TCP port to bind (defaults to a free port)')\n .option('-h, --host <host>', 'Hostname to bind', '127.0.0.1')\n .option('-t, --type <type>', 'Source type: openapi | postman | insomnia | auto', 'auto')\n .option('-f, --format <format>', 'OpenAPI format: json | yaml | auto', 'auto')\n .option('--cors', 'Enable permissive CORS', true)\n .action(async (spec: string, opts: MockOptions) => {\n const absolute = path.resolve(spec);\n const raw = await fs.readFile(absolute, 'utf-8');\n const type = inferType(absolute, opts.type ?? 'auto');\n const format = type === 'openapi' ? inferFormat(absolute, opts.format ?? 'auto') : 'json';\n\n const source = makeSource(type, format, raw);\n const parsed = await parseSourceToEndpoints(source);\n const mock: MockServer = {\n id: generateId(),\n name: path.basename(absolute),\n source,\n endpoints: parsed.endpoints,\n defaultPort: opts.port ? Number(opts.port) : null,\n cors: { enabled: opts.cors !== false, origins: ['*'] },\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n const handle = await startMockServer(mock, {\n port: opts.port ? Number(opts.port) : undefined,\n host: opts.host,\n });\n process.stdout.write(\n `${kleur.green('Mock server')} listening on ${kleur.cyan(`http://${opts.host}:${handle.port}`)} ` +\n `with ${parsed.endpoints.length} endpoints (type=${type}). Press Ctrl-C to stop.\\n`,\n );\n if (parsed.warnings.length) {\n for (const w of parsed.warnings) {\n process.stderr.write(`${kleur.yellow('warn')}: ${w}\\n`);\n }\n }\n installShutdown(handle);\n });\n}\n\nexport function inferType(\n filePath: string,\n hint: NonNullable<MockOptions['type']>,\n): 'openapi' | 'postman' | 'insomnia' {\n if (hint && hint !== 'auto') return hint;\n const lower = filePath.toLowerCase();\n if (lower.includes('postman')) return 'postman';\n if (lower.includes('insomnia')) return 'insomnia';\n return 'openapi';\n}\n\nexport function inferFormat(\n filePath: string,\n hint: NonNullable<MockOptions['format']>,\n): 'json' | 'yaml' {\n if (hint && hint !== 'auto') return hint;\n const lower = filePath.toLowerCase();\n return lower.endsWith('.yaml') || lower.endsWith('.yml') ? 'yaml' : 'json';\n}\n\nexport function makeSource(\n type: 'openapi' | 'postman' | 'insomnia',\n format: 'json' | 'yaml',\n raw: string,\n): MockServer['source'] {\n switch (type) {\n case 'openapi':\n return { kind: 'openapi', spec: raw, format };\n case 'postman':\n return { kind: 'postman', collection: raw };\n case 'insomnia':\n return { kind: 'insomnia', export: raw };\n }\n}\n\nfunction installShutdown(handle: MockServerHandle): void {\n let closing = false;\n const shutdown = async () => {\n if (closing) return;\n closing = true;\n await handle.close();\n process.exit(0);\n };\n process.on('SIGINT', () => void shutdown());\n process.on('SIGTERM', () => void shutdown());\n}\n","import * as path from 'node:path';\nimport { promises as fs } from 'node:fs';\nimport { loadFromFile, saveToFile } from '@apicircle/core/workspace/file-backed';\nimport type { WorkspaceState } from '@apicircle/core';\nimport { FONT_SIZE_PERCENT_DEFAULT, generateId } from '@apicircle/shared';\n\n// =============================================================================\n// loadWorkspace — small wrapper around `@apicircle/core`'s file-backed\n// helpers that auto-creates an empty workspace on first run so users don't\n// have to seed a workspace.synced.json by hand before invoking commands.\n// =============================================================================\n\nexport async function ensureWorkspace(dir: string): Promise<WorkspaceState> {\n const resolved = path.resolve(dir);\n await fs.mkdir(resolved, { recursive: true });\n const existing = await loadFromFile(resolved, { allowMissing: true });\n if (existing) return existing;\n\n const now = new Date().toISOString();\n const workspaceId = generateId();\n const fresh: WorkspaceState = {\n synced: {\n schemaVersion: 1,\n workspaceId,\n collections: {\n tree: { id: generateId(), type: 'root', children: [] },\n requests: {},\n folders: {},\n },\n environments: { items: {}, activeName: null, priorityOrder: [] },\n linkedWorkspaces: {},\n linkedOverrides: { requests: {}, environmentVars: {} },\n releases: { self: null, perLink: {} },\n globalAssets: { schemas: {}, graphql: {}, files: {} },\n mockServers: {},\n meta: { createdAt: now, updatedAt: now, appVersion: '1.0.0' },\n },\n local: {\n schemaVersion: 1,\n workspaceId,\n executionPlans: {},\n history: { requestRuns: [], planRuns: [] },\n secretIndex: { entries: {} },\n sessions: { github: { workspace: null, links: {} } },\n connectedRepo: null,\n workingBranch: null,\n seededWorkspaceSha: null,\n retiredBranch: null,\n sync: { lastPulledSnapshot: null, lastPulledSha: null, lastPulledAt: null, dirtyKeys: [] },\n linkedCollections: {},\n attachmentCache: {},\n globalContext: {},\n mockRuntime: { active: {} },\n ui: {\n activeRequestId: null,\n sidebarExpandedSections: [],\n themeId: 'one-dark-pro',\n fontId: 'system-sans',\n fontSizePercent: FONT_SIZE_PERCENT_DEFAULT,\n },\n settings: { validateOnSend: true, monacoConsumesWheel: false },\n snapshots: { entries: [], maxBytes: 50 * 1024 * 1024 },\n },\n };\n await saveToFile(resolved, fresh);\n return fresh;\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\nimport { promises as fs } from 'node:fs';\nimport {\n findWorkspaceEntry,\n loadRegistry,\n registerWorkspace,\n saveRegistry,\n workspaceDirFor,\n type WorkspaceRegistry,\n type WorkspaceRegistryEntry,\n} from '@apicircle/core/workspace/registry';\nimport { saveToFile } from '@apicircle/core/workspace/file-backed';\nimport { generateId, type Folder, type Request as ApiRequest } from '@apicircle/shared';\nimport type { WorkspaceState } from '@apicircle/core';\n\n// =============================================================================\n// CLI workspace selector — two explicit flags, no ambiguity.\n//\n// Every command that touches workspace state accepts two mutually-exclusive\n// flags:\n//\n// --workspace-name <name-or-id>\n// A logical handle — case-insensitive name match against the desktop\n// registry, falling back to id match. The common case for humans:\n// `--workspace-name Petstore`. Scripts that need to survive renames\n// can pass the long-form id here too.\n//\n// --workspace-path <dir>\n// A filesystem directory containing `workspace.synced.json`. The\n// back-compat path for CI / one-off flows that aren't registered\n// with the desktop app (e.g. a freshly git-cloned workspace repo).\n//\n// Passing both is an error. When NEITHER is passed:\n//\n// • A registry exists at userData/workspaces/ → use the active workspace.\n// • No registry exists → fall back to cwd (the\n// legacy single-workspace\n// flow CI scripts use).\n//\n// The CLI runs outside Electron, so we reproduce Electron's per-OS `userData`\n// convention here. `APICIRCLE_WORKSPACES_ROOT` overrides it for CI / tests.\n// =============================================================================\n\nconst APP_NAME = '@apicircle';\nconst APP_SUBDIR = 'desktop';\nconst WORKSPACES_DIRNAME = 'workspaces';\nconst LEGACY_WORKSPACE_DIRNAME = 'workspace';\n\nexport interface ResolvedWorkspace {\n /** Absolute directory containing workspace.synced.json + workspace.local.json. */\n dir: string;\n /** Workspace id when resolved via registry; null when resolved by raw path. */\n id: string | null;\n /** Display name when resolved via registry; null otherwise. */\n name: string | null;\n /** Whether the resolver looked at the registry to find this dir. */\n fromRegistry: boolean;\n /** The registry root that was consulted (or null when resolving raw paths). */\n registryRoot: string | null;\n}\n\nexport interface ResolveOptions {\n /** Raw value from `--workspace-name <name-or-id>`. */\n name?: string;\n /** Raw value from `--workspace-path <dir>`. */\n path?: string;\n /** Override for the desktop's `userData/workspaces/` (CI / tests). */\n workspacesRoot?: string;\n /** Override for the desktop's legacy `userData/workspace/`. */\n legacyDir?: string;\n /** When true (the default), missing target dirs raise. Set false for create paths. */\n expectExists?: boolean;\n}\n\n/**\n * Compute the on-disk `workspaces/` root the CLI consults for id / name\n * selectors. Honors `APICIRCLE_WORKSPACES_ROOT` first, then derives from\n * the OS-specific user-data convention used by Electron.\n */\nexport function defaultWorkspacesRoot(): string {\n const override = process.env.APICIRCLE_WORKSPACES_ROOT;\n if (override && override.length > 0) return path.resolve(override);\n return path.join(electronUserDataDir(), WORKSPACES_DIRNAME);\n}\n\nexport function defaultLegacyDir(): string {\n return path.join(electronUserDataDir(), LEGACY_WORKSPACE_DIRNAME);\n}\n\nfunction electronUserDataDir(): string {\n // Match Electron's `app.getPath('userData')` semantics. The desktop\n // package's name is `@apicircle/desktop` — Electron flattens the scope\n // into `@apicircle/desktop` on disk.\n const home = os.homedir();\n switch (process.platform) {\n case 'win32': {\n const appdata = process.env.APPDATA ?? path.join(home, 'AppData', 'Roaming');\n return path.join(appdata, APP_NAME, APP_SUBDIR);\n }\n case 'darwin':\n return path.join(home, 'Library', 'Application Support', APP_NAME, APP_SUBDIR);\n default:\n return path.join(\n process.env.XDG_CONFIG_HOME ?? path.join(home, '.config'),\n APP_NAME,\n APP_SUBDIR,\n );\n }\n}\n\n/**\n * Resolve `--workspace-name` / `--workspace-path` into a concrete on-disk\n * directory. Throws a `WorkspaceResolutionError` with a readable message\n * when no match is found, so callers can surface the failure to the user\n * without an opaque stack trace.\n *\n * Precedence rules:\n *\n * 1. Passing both flags is an error — they're mutually exclusive.\n * 2. `path` (when given) is treated as a literal filesystem directory.\n * The registry isn't consulted; the dir must exist (unless\n * `expectExists: false`).\n * 3. `name` (when given) is matched against the registry: exact id\n * first, then case-insensitive name. Errors with a \"did you run\n * `workspaces list`?\" hint when nothing matches.\n * 4. Neither given → active workspace from the registry, or cwd when\n * no registry exists.\n */\nexport async function resolveWorkspace(opts: ResolveOptions = {}): Promise<ResolvedWorkspace> {\n const root = opts.workspacesRoot ?? defaultWorkspacesRoot();\n const nameSelector = opts.name?.trim();\n const pathSelector = opts.path?.trim();\n const expectExists = opts.expectExists ?? true;\n\n if (nameSelector && pathSelector) {\n throw new WorkspaceResolutionError(\n '--workspace-name and --workspace-path are mutually exclusive. Pass one or neither.',\n 'both-flags',\n );\n }\n\n // Explicit path selector: skip the registry entirely.\n if (pathSelector) {\n const expanded = expandTilde(pathSelector);\n const dir = path.resolve(expanded);\n if (expectExists && !(await dirExists(dir))) {\n throw new WorkspaceResolutionError(`Workspace directory not found: ${dir}`, 'path-missing');\n }\n return { dir, id: null, name: null, fromRegistry: false, registryRoot: null };\n }\n\n const registry = await loadRegistry(root);\n\n if (nameSelector) {\n if (!registry) {\n throw new WorkspaceResolutionError(\n `No workspaces are registered at ${root}. Open the desktop app once to seed the registry, ` +\n `or pass --workspace-path <dir> to point at a workspace directory directly.`,\n 'no-registry',\n );\n }\n const entry = findWorkspaceEntry(registry, nameSelector);\n if (!entry) {\n throw new WorkspaceResolutionError(\n `No workspace named \"${nameSelector}\" in the registry at ${root}. ` +\n `Run \\`apicircle workspaces list\\` to see what's available.`,\n 'not-found',\n );\n }\n return {\n dir: workspaceDirFor(root, entry.id),\n id: entry.id,\n name: entry.name,\n fromRegistry: true,\n registryRoot: root,\n };\n }\n\n // No selector — pick active workspace, or fall back to cwd if no registry.\n if (registry && registry.activeWorkspaceId) {\n const active = registry.workspaces.find((w) => w.id === registry.activeWorkspaceId);\n if (active) {\n return {\n dir: workspaceDirFor(root, active.id),\n id: active.id,\n name: active.name,\n fromRegistry: true,\n registryRoot: root,\n };\n }\n }\n // Cwd fallback — preserves the pre-registry CLI flow for users who\n // organise their own workspace directories outside the desktop app.\n return {\n dir: path.resolve(process.cwd()),\n id: null,\n name: null,\n fromRegistry: false,\n registryRoot: null,\n };\n}\n\n/**\n * Create a new workspace on disk + add it to the registry. Returns the\n * fresh state + its registry entry. Idempotent against the id — if the\n * id is already in the registry, the existing entry is returned and the\n * on-disk files are NOT overwritten.\n */\nexport async function createWorkspaceOnDisk(args: {\n name: string;\n workspacesRoot?: string;\n sampleRequest?: boolean;\n}): Promise<{\n registry: WorkspaceRegistry;\n entry: WorkspaceRegistryEntry;\n state: WorkspaceState;\n dir: string;\n}> {\n const root = args.workspacesRoot ?? defaultWorkspacesRoot();\n const trimmed = args.name.trim();\n if (!trimmed) throw new Error('Workspace name is required');\n const existing = await loadRegistry(root);\n if (existing && existing.workspaces.some((w) => w.name.toLowerCase() === trimmed.toLowerCase())) {\n throw new Error(`A workspace named \"${trimmed}\" already exists`);\n }\n const workspaceId = generateId();\n const now = new Date().toISOString();\n const state = buildEmptyState(workspaceId, now, args.sampleRequest ?? false);\n const dir = workspaceDirFor(root, workspaceId);\n await saveToFile(dir, state);\n const entry: WorkspaceRegistryEntry = {\n id: workspaceId,\n name: trimmed,\n createdAt: now,\n lastOpenedAt: now,\n };\n const registry = await registerWorkspace(root, entry);\n return { registry, entry, state, dir };\n}\n\n/**\n * List every workspace registered on this machine. CLI consumers can call\n * this directly; it returns the empty list (not null) when no registry\n * exists yet, so callers can avoid null-checking.\n */\nexport async function listWorkspacesOnDisk(\n args: {\n workspacesRoot?: string;\n } = {},\n): Promise<{ registry: WorkspaceRegistry; root: string }> {\n const root = args.workspacesRoot ?? defaultWorkspacesRoot();\n const registry = (await loadRegistry(root)) ?? {\n schemaVersion: 1 as const,\n activeWorkspaceId: null,\n workspaces: [],\n };\n return { registry, root };\n}\n\n/**\n * Save the registry. Exposed so CLI commands that mutate the registry\n * (e.g. `workspaces switch`) can persist their changes without each one\n * re-importing from `@apicircle/core/workspace/registry`.\n */\nexport async function saveRegistryToDisk(\n registry: WorkspaceRegistry,\n workspacesRoot?: string,\n): Promise<void> {\n await saveRegistry(workspacesRoot ?? defaultWorkspacesRoot(), registry);\n}\n\nexport type WorkspaceResolutionCode = 'path-missing' | 'no-registry' | 'not-found' | 'both-flags';\n\nexport class WorkspaceResolutionError extends Error {\n readonly code: WorkspaceResolutionCode;\n constructor(message: string, code: WorkspaceResolutionCode) {\n super(message);\n this.name = 'WorkspaceResolutionError';\n this.code = code;\n }\n}\n\n// ---------------------------------------------------------------------------\n// internals\n// ---------------------------------------------------------------------------\n\nfunction expandTilde(value: string): string {\n if (value === '~') return os.homedir();\n if (value.startsWith('~/') || value.startsWith('~\\\\')) {\n return path.join(os.homedir(), value.slice(2));\n }\n return value;\n}\n\nasync function dirExists(p: string): Promise<boolean> {\n try {\n const st = await fs.stat(p);\n return st.isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction buildEmptyState(workspaceId: string, now: string, withSample: boolean): WorkspaceState {\n const sample: ApiRequest | null = withSample\n ? {\n id: generateId(),\n name: 'Sample: GET /anything',\n folderId: null,\n method: 'GET',\n url: 'https://httpbin.org/anything',\n headers: [{ key: 'Accept', value: 'application/json', enabled: true }],\n query: [],\n body: { type: 'none', content: '' },\n auth: { type: 'inherit' },\n contextVars: [],\n extractions: [],\n assertions: [],\n createdAt: now,\n updatedAt: now,\n }\n : null;\n const folders: Record<string, Folder> = {};\n const requests: Record<string, ApiRequest> = sample ? { [sample.id]: sample } : {};\n return {\n synced: {\n schemaVersion: 1,\n workspaceId,\n collections: {\n tree: {\n id: generateId(),\n type: 'root',\n children: sample ? [{ kind: 'request', id: sample.id }] : [],\n },\n requests,\n folders,\n },\n environments: { items: {}, activeName: null, priorityOrder: [] },\n linkedWorkspaces: {},\n linkedOverrides: { requests: {}, environmentVars: {} },\n releases: { self: null, perLink: {} },\n globalAssets: { schemas: {}, graphql: {}, files: {} },\n mockServers: {},\n meta: { createdAt: now, updatedAt: now, appVersion: '1.0.0' },\n },\n local: {\n schemaVersion: 1,\n workspaceId,\n executionPlans: {},\n history: { requestRuns: [], planRuns: [] },\n secretIndex: { entries: {} },\n sessions: { github: { workspace: null, links: {} } },\n connectedRepo: null,\n workingBranch: null,\n seededWorkspaceSha: null,\n retiredBranch: null,\n sync: { lastPulledSnapshot: null, lastPulledSha: null, lastPulledAt: null, dirtyKeys: [] },\n linkedCollections: {},\n attachmentCache: {},\n globalContext: {},\n mockRuntime: { active: {} },\n ui: {\n activeRequestId: sample?.id ?? null,\n sidebarExpandedSections: [],\n themeId: 'one-dark-pro',\n fontId: 'system-sans',\n fontSizePercent: 100,\n },\n settings: { validateOnSend: true, monacoConsumesWheel: false },\n snapshots: { entries: [], maxBytes: 50 * 1024 * 1024 },\n },\n };\n}\n","import type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n createMcpServer,\n FileBackedWorkspaceProvider,\n InProcessMockController,\n} from '@apicircle/mcp-server';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle mcp` — boot the MCP stdio server against a workspace directory.\n// Mirrors `@apicircle/mcp-server`'s `bin/mcp-server.ts` but with friendlier\n// CLI ergonomics (default workspace = cwd, friendly error messages, etc).\n// =============================================================================\n\ninterface McpOptions {\n workspaceName?: string;\n workspacePath?: string;\n}\n\nexport function registerMcpCommand(program: Command): void {\n program\n .command('mcp')\n .description('Run the API Circle MCP server (stdio transport)')\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .action(async (opts: McpOptions) => {\n let dir: string;\n let label: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n dir = resolved.dir;\n label = resolved.fromRegistry ? `${resolved.name ?? resolved.id} (${dir})` : dir;\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n process.stderr.write(`${kleur.red('error')}: ${err.message}\\n`);\n process.exit(2);\n }\n throw err;\n }\n // Touch the workspace so subsequent reads don't fail. Errors here\n // surface to stderr and exit non-zero — the AI client wouldn't be\n // able to use a half-initialised workspace anyway.\n try {\n await ensureWorkspace(dir);\n } catch (err) {\n process.stderr.write(\n `${kleur.red('failed to initialise workspace')} at ${dir}: ${\n err instanceof Error ? err.message : String(err)\n }\\n`,\n );\n process.exit(1);\n }\n\n const workspace = new FileBackedWorkspaceProvider(dir);\n const mock = new InProcessMockController();\n const host = createMcpServer({ workspace, mock });\n process.stderr.write(`${kleur.green('apicircle-mcp')} ready · workspace=${label}\\n`);\n await host.connect();\n });\n}\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport { applyMutation, parseApicircleFolderExport } from '@apicircle/core';\nimport { saveToFile } from '@apicircle/core/workspace/file-backed';\nimport {\n parseInsomniaToEndpoints,\n parseOpenApiToEndpoints,\n parsePostmanToEndpoints,\n} from '@apicircle/mock-server-core';\nimport { generateId, type Request as ApiRequest } from '@apicircle/shared';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle import <type> <spec>` — read an external spec, persist one\n// request per operation into `<workspace>/workspace.synced.json`.\n// =============================================================================\n\ntype ImportType = 'curl' | 'openapi' | 'postman' | 'insomnia' | 'apicircle';\n\ninterface ImportOptions {\n workspaceName?: string;\n workspacePath?: string;\n format?: 'json' | 'yaml';\n}\n\nexport function registerImportCommand(program: Command): void {\n program\n .command('import')\n .description('Import a spec into a workspace folder')\n .argument(\n '<type>',\n 'Source type: openapi | postman | insomnia | curl | apicircle (the apicircle.folder/v1 envelope produced by `apicircle export folder`)',\n )\n .argument('<input>', 'Path to a spec file, or `-` to read from stdin')\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .option('-f, --format <format>', 'OpenAPI format: json | yaml', 'json')\n .action(async (type: ImportType, input: string, opts: ImportOptions) => {\n let dir: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n dir = resolved.dir;\n if (resolved.fromRegistry) {\n process.stderr.write(\n `${kleur.dim('workspace')}: ${kleur.cyan(resolved.name ?? resolved.id ?? '')} ${kleur.dim(`(${dir})`)}\\n`,\n );\n }\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n process.stderr.write(`${kleur.red('error')}: ${err.message}\\n`);\n process.exit(2);\n }\n throw err;\n }\n const raw = await readInput(input);\n const state = await ensureWorkspace(dir);\n let nextSynced = state.synced;\n let nextLocal = state.local;\n const created: string[] = [];\n\n const append = (req: ApiRequest) => {\n const out = applyMutation(\n { synced: nextSynced, local: nextLocal },\n { kind: 'request.create', request: req },\n );\n nextSynced = out.next.synced;\n nextLocal = out.next.local;\n created.push(req.id);\n };\n\n if (type === 'curl') {\n const { parseCurl } = await import('@apicircle/core');\n const parsed = parseCurl(raw);\n append(\n blankRequest({\n name: `cURL ${parsed.method} ${parsed.url}`.slice(0, 80),\n method: parsed.method,\n url: parsed.url,\n headers: parsed.headers,\n query: parsed.query,\n body: parsed.body,\n auth: parsed.auth,\n }),\n );\n } else if (type === 'openapi') {\n const parsed = await parseOpenApiToEndpoints(raw, opts.format ?? 'json');\n for (const ep of parsed.endpoints) {\n append(\n blankRequest({\n name: ep.example ?? `${ep.method} ${ep.pathPattern}`,\n method: ep.method,\n url: ep.pathPattern,\n }),\n );\n }\n } else if (type === 'postman') {\n const parsed = parsePostmanToEndpoints(raw);\n for (const ep of parsed.endpoints) {\n append(\n blankRequest({\n name: ep.example ?? `${ep.method} ${ep.pathPattern}`,\n method: ep.method,\n url: ep.pathPattern,\n }),\n );\n }\n } else if (type === 'insomnia') {\n const parsed = parseInsomniaToEndpoints(raw);\n for (const ep of parsed.endpoints) {\n append(\n blankRequest({\n name: ep.example ?? `${ep.method} ${ep.pathPattern}`,\n method: ep.method,\n url: ep.pathPattern,\n }),\n );\n }\n } else if (type === 'apicircle') {\n // API Circle exchange envelope — graft the folder + subtree +\n // dependencies via the same applyMutation patch the UI / MCP use.\n let parsedEnvelope;\n try {\n parsedEnvelope = parseApicircleFolderExport(raw);\n } catch (err) {\n process.stderr.write(\n `${kleur.red('error')}: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n process.exit(2);\n }\n const out = applyMutation(\n { synced: nextSynced, local: nextLocal },\n { kind: 'folder.import_apicircle', parsed: parsedEnvelope, parentFolderId: null },\n );\n nextSynced = out.next.synced;\n nextLocal = out.next.local;\n // `created` only counts requests in the other import branches —\n // mirror that here so the trailing line stays accurate. Folders\n // get reported separately below.\n for (const r of parsedEnvelope.requests) created.push(r.id);\n for (const w of parsedEnvelope.warnings) {\n process.stderr.write(`${kleur.yellow('warning')}: ${w}\\n`);\n }\n await saveToFile(dir, { synced: nextSynced, local: nextLocal });\n process.stdout.write(\n `${kleur.green('imported')} folder \"${parsedEnvelope.rootFolder.name}\" ` +\n `(${parsedEnvelope.subfolders.length + 1} folders, ${parsedEnvelope.requests.length} requests) into ${dir}\\n`,\n );\n if (parsedEnvelope.dependencies.files.length > 0) {\n process.stderr.write(\n `${kleur.yellow('note')}: ${parsedEnvelope.dependencies.files.length} file asset${parsedEnvelope.dependencies.files.length === 1 ? '' : 's'} ` +\n `landed without bytes — re-attach them inside Global Assets → Global Files.\\n`,\n );\n }\n return;\n } else {\n // The four-branch chain above is exhaustive at the type level, so\n // `type` narrows to `never` here. Cast to string for the error\n // message — at runtime this only fires if a caller bypasses the\n // commander enum and passes garbage like `apicircle import xml ...`.\n process.stderr.write(`${kleur.red('error')}: unknown type '${String(type)}'\\n`);\n process.exit(2);\n }\n\n await saveToFile(dir, { synced: nextSynced, local: nextLocal });\n process.stdout.write(\n `${kleur.green('imported')} ${created.length} request${created.length === 1 ? '' : 's'} into ${dir}\\n`,\n );\n });\n}\n\nasync function readInput(p: string): Promise<string> {\n if (p === '-') {\n return new Promise<string>((resolve, reject) => {\n let data = '';\n process.stdin.setEncoding('utf-8');\n // setEncoding('utf-8') causes `chunk` to arrive as a string at runtime,\n // but Node's types still surface it as `string | Buffer`. Coerce to\n // satisfy `restrict-plus-operands` without changing behaviour.\n process.stdin.on('data', (chunk: string | Buffer) => {\n data += typeof chunk === 'string' ? chunk : chunk.toString('utf-8');\n });\n process.stdin.on('end', () => resolve(data));\n process.stdin.on('error', reject);\n });\n }\n return fs.readFile(path.resolve(p), 'utf-8');\n}\n\nfunction blankRequest(\n partial: Partial<ApiRequest> & {\n name: string;\n method: ApiRequest['method'];\n url: string;\n },\n): ApiRequest {\n const now = new Date().toISOString();\n return {\n id: generateId(),\n folderId: null,\n headers: [],\n query: [],\n body: { type: 'none', content: '' },\n auth: { type: 'none' },\n contextVars: [],\n extractions: [],\n assertions: [],\n createdAt: now,\n updatedAt: now,\n ...partial,\n };\n}\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n collectFolderExport,\n redactFolderExportCredentials,\n serializeFolderExport,\n suggestFolderExportFilename,\n} from '@apicircle/core';\nimport type { Folder } from '@apicircle/shared';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle export folder <name-or-id> [--out file]` — write a single folder's\n// `apicircle.folder/v1` JSON envelope. Suitable for sharing one collection\n// with another teammate or workspace without round-tripping through Git.\n//\n// Auth credentials are REDACTED by default (matches the in-app modal's\n// safe default). Pass `--include-credential <id> [--include-credential ...]`\n// to opt specific fields IN; ids follow the report-side format\n// `<scope>:<ownerId>.<authType>.<field>` — surface them with\n// `apicircle export folder --list-credentials`.\n// =============================================================================\n\ninterface ExportFolderOptions {\n workspaceName?: string;\n workspacePath?: string;\n out?: string;\n includeCredential?: string[];\n listCredentials?: boolean;\n}\n\nexport function registerExportCommand(program: Command): void {\n const exportCmd = program\n .command('export')\n .description('Export workspace entities to portable JSON.');\n\n exportCmd\n .command('folder')\n .description('Export a folder (and its subtree) as an apicircle.folder/v1 JSON envelope.')\n .argument(\n '<folder>',\n 'Folder id, or display name (case-insensitive). Unique within the workspace.',\n )\n .option('-o, --out <path>', 'Write the JSON to this file. Defaults to stdout.')\n .option(\n '--include-credential <id>',\n 'Keep the credential field with this id (repeatable). Use --list-credentials to see ids.',\n (value: string, prev: string[] = []) => [...prev, value],\n [] as string[],\n )\n .option(\n '--list-credentials',\n 'Print the detected credentials + their ids and exit without writing anything.',\n )\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .action(async (folder: string, opts: ExportFolderOptions) => {\n let dir: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n });\n dir = resolved.dir;\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n process.stderr.write(`${kleur.red('error')}: ${err.message}\\n`);\n process.exit(2);\n }\n throw err;\n }\n const state = await ensureWorkspace(dir);\n const folderId = resolveFolderId(state.synced.collections.folders, folder);\n if (!folderId) {\n process.stderr.write(`${kleur.red('error')}: no folder matches \"${folder}\" in ${dir}\\n`);\n process.exit(2);\n }\n const collected = collectFolderExport({ synced: state.synced, folderId });\n if (!collected) {\n // Should not happen — resolveFolderId already proved it exists.\n process.stderr.write(`${kleur.red('error')}: folder \"${folder}\" no longer exists\\n`);\n process.exit(2);\n }\n if (opts.listCredentials) {\n if (collected.report.credentials.length === 0) {\n process.stdout.write('No credential-bearing auth fields detected.\\n');\n return;\n }\n for (const cred of collected.report.credentials) {\n process.stdout.write(`${cred.id}\\t${cred.label}\\t${cred.ownerName}\\n`);\n }\n return;\n }\n const includeIds = new Set<string>(opts.includeCredential ?? []);\n const envelope = redactFolderExportCredentials(collected.envelope, includeIds);\n const json = serializeFolderExport(envelope);\n if (opts.out) {\n const outPath = path.resolve(opts.out);\n await fs.writeFile(outPath, json, 'utf-8');\n process.stderr.write(\n `${kleur.green('exported')} folder \"${collected.report.folderName}\" → ${outPath}\\n`,\n );\n } else {\n process.stdout.write(json);\n process.stdout.write('\\n');\n process.stderr.write(\n `${kleur.green('exported')} folder \"${collected.report.folderName}\" ` +\n `(${collected.report.totalFolderCount} folders, ${collected.report.requestCount} requests, ` +\n `${collected.report.credentials.length - includeIds.size} credentials redacted)\\n`,\n );\n }\n // Surface a suggested filename in the trailing message even when\n // streaming to stdout so consumers piping into a tool have a\n // sensible name to suggest.\n if (!opts.out) {\n process.stderr.write(\n `${kleur.dim('hint')}: save with .apicircle.json, e.g. ${suggestFolderExportFilename(envelope)}\\n`,\n );\n }\n });\n}\n\nfunction resolveFolderId(folders: Record<string, Folder>, query: string): string | null {\n // Direct id match first.\n if (folders[query]) return query;\n // Case-insensitive unique name match — same trimming the editor uses.\n const norm = query.trim().toLowerCase();\n const matches = Object.values(folders).filter((f) => f.name.trim().toLowerCase() === norm);\n if (matches.length === 1) return matches[0].id;\n return null;\n}\n","import * as path from 'node:path';\nimport { promises as fs } from 'node:fs';\nimport type { WorkspaceState } from '@apicircle/core';\n\n// =============================================================================\n// CLI secret provisioning\n//\n// Secret values aren't synced to Git. Workspaces synced from a teammate carry\n// only `secretKeyId` references and a synced labels map (`secretKeys`). The\n// CLI must source the actual values from the runtime environment.\n//\n// Resolution order (later sources override earlier ones):\n// 1. `--secrets <file>.json` — `{ \"<id>\": \"<value>\" }`\n// 2. `APICIRCLE_SECRET_<id>=value` — env vars (prefix configurable)\n//\n// Resolved values feed `buildScope` as the `secrets` layer so `{{NAME}}`\n// references in environment variables (with `secretKeyId`) get expanded\n// at send time. Missing required ids surface as a single-block error before\n// any HTTP request goes out.\n// =============================================================================\n\nexport interface SecretRequirement {\n /** secretKeyId referenced by an env-variable in the workspace. */\n id: string;\n /** Best-known label (from `synced.secretKeys[id].label`) for display. */\n label: string;\n /** Where in the workspace the id is referenced (env name + var key). */\n references: Array<{ envName: string; varKey: string }>;\n}\n\nconst DEFAULT_PREFIX = 'APICIRCLE_SECRET_';\n\nexport interface BuildSecretsOptions {\n secretsFile?: string;\n envPrefix?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface BuildSecretsResult {\n /** id → plaintext value, ready for buildScope. */\n byId: Record<string, string>;\n}\n\nexport async function buildSecretsFromCli(\n options: BuildSecretsOptions = {},\n): Promise<BuildSecretsResult> {\n const env = options.env ?? process.env;\n const prefix = options.envPrefix ?? DEFAULT_PREFIX;\n const byId: Record<string, string> = {};\n\n if (options.secretsFile) {\n const resolved = path.resolve(options.secretsFile);\n const raw = await fs.readFile(resolved, 'utf8');\n const parsed: unknown = JSON.parse(raw);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(\n `--secrets ${options.secretsFile}: expected an object mapping secretKeyId → value`,\n );\n }\n for (const [id, value] of Object.entries(parsed as Record<string, unknown>)) {\n if (typeof value !== 'string') {\n throw new Error(`--secrets ${options.secretsFile}: value for \"${id}\" must be a string`);\n }\n byId[id] = value;\n }\n }\n\n for (const [name, value] of Object.entries(env)) {\n if (!name.startsWith(prefix) || typeof value !== 'string') continue;\n const id = name.slice(prefix.length);\n if (id) byId[id] = value;\n }\n\n return { byId };\n}\n\n/**\n * Walk a workspace and collect every `secretKeyId` referenced by an env\n * variable. Used to validate that the CLI received values for every\n * required id before executing a request.\n */\nexport function collectSecretRequirements(workspace: WorkspaceState): SecretRequirement[] {\n const labels = workspace.synced.secretKeys ?? {};\n const refs = new Map<string, SecretRequirement>();\n for (const [envName, env] of Object.entries(workspace.synced.environments.items)) {\n for (const v of env.variables) {\n if (!v.encrypted || !v.secretKeyId) continue;\n const id = v.secretKeyId;\n const requirement = refs.get(id) ?? {\n id,\n label: labels[id]?.label ?? `(unlabelled ${id.slice(0, 6)}…)`,\n references: [],\n };\n requirement.references.push({ envName, varKey: v.key });\n refs.set(id, requirement);\n }\n }\n return [...refs.values()];\n}\n\n/**\n * Format a missing-secrets error for the CLI. Returns a multi-line string\n * suitable for stderr; callers exit with code 2.\n */\nexport function formatMissingSecretsError(missing: SecretRequirement[]): string {\n const lines = ['Missing secret values for the following keys:'];\n for (const req of missing) {\n const refs = req.references.map((r) => `env \"${r.envName}\" var \"${r.varKey}\"`).join('; ');\n lines.push(` - id \"${req.id}\" (label \"${req.label}\") — referenced by ${refs}`);\n }\n lines.push('');\n lines.push(\n 'Provide values via APICIRCLE_SECRET_<id>=<value> environment variables or --secrets <file>.json.',\n );\n return lines.join('\\n');\n}\n\n/**\n * Convenience: assert every required secret has a value. Throws a CLI-formatted\n * error when anything is missing, otherwise returns the resolved id→value map.\n */\nexport async function resolveSecretsForWorkspace(\n workspace: WorkspaceState,\n options: BuildSecretsOptions = {},\n): Promise<Record<string, string>> {\n const { byId } = await buildSecretsFromCli(options);\n const missing = collectSecretRequirements(workspace).filter((r) => !(r.id in byId));\n if (missing.length > 0) {\n const err = new Error(formatMissingSecretsError(missing));\n (err as Error & { code?: string }).code = 'APICIRCLE_MISSING_SECRETS';\n throw err;\n }\n return byId;\n}\n","import { createHash } from 'node:crypto';\nimport { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport {\n collectAttachmentSlots,\n type AttachmentResolver,\n type WorkspaceState,\n} from '@apicircle/core';\nimport type {\n ExecutionPlan,\n LocalAttachmentCacheEntry,\n RequestBody,\n WorkspaceSynced,\n} from '@apicircle/shared';\n\nexport interface AttachmentPreparationSummary {\n total: number;\n downloaded: number;\n alreadyPresent: number;\n failed: number;\n cacheDir: string;\n entries: Array<{\n slotId: string;\n filename: string;\n localPath: string;\n source: 'workspace' | 'linked-workspace';\n linkedWorkspaceId?: string;\n requiredBy: Array<{ requestId: string; requestName: string }>;\n }>;\n}\n\nexport interface PreparedExecutionAttachments {\n state: WorkspaceState;\n resolveAttachment: AttachmentResolver;\n summary: AttachmentPreparationSummary;\n}\n\ninterface AttachmentRequirement {\n slotId: string;\n sha256?: string;\n filename?: string;\n mimeType?: string;\n size?: number;\n source: 'workspace' | 'linked-workspace';\n linkedWorkspaceId?: string;\n repoFullName?: string;\n branch?: string;\n publicRepo?: boolean;\n requiredBy: Array<{ requestId: string; requestName: string }>;\n}\n\nconst ATTACHMENTS_DIR = path.join('.apicircle', 'attachments');\n\nexport async function prepareExecutionAttachments(\n workspaceDir: string,\n state: WorkspaceState,\n plan?: ExecutionPlan,\n): Promise<PreparedExecutionAttachments> {\n const cacheDir = path.resolve(workspaceDir, ATTACHMENTS_DIR);\n const requirements = collectExecutionAttachmentRequirements(state, plan);\n await fs.mkdir(cacheDir, { recursive: true });\n\n let downloaded = 0;\n let alreadyPresent = 0;\n let failed = 0;\n const cache: Record<string, LocalAttachmentCacheEntry> = {\n ...(state.local.attachmentCache ?? {}),\n };\n const entries: AttachmentPreparationSummary['entries'] = [];\n\n for (const requirement of requirements) {\n const localPath = path.join(cacheDir, encodeURIComponent(requirement.slotId));\n const present = await hasExpectedFile(localPath, requirement.sha256);\n if (present) {\n alreadyPresent++;\n } else {\n try {\n const bytes = await downloadAttachment(requirement);\n if (!bytes) {\n throw new Error(\n `Attachment ${attachmentLabel(requirement)} was not found in ${sourceLabel(requirement)}.`,\n );\n }\n if (requirement.sha256 && sha256Hex(bytes) !== requirement.sha256) {\n throw new Error(\n `Attachment ${attachmentLabel(requirement)} failed checksum verification.`,\n );\n }\n await fs.writeFile(localPath, bytes, { mode: 0o600 });\n downloaded++;\n } catch (err) {\n failed++;\n throw new Error(\n `Attachment ${attachmentLabel(requirement)} is required by ${requiredByLabel(\n requirement,\n )} but could not be downloaded from ${sourceLabel(requirement)}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n\n cache[requirement.slotId] = {\n slotId: requirement.slotId,\n filename: requirement.filename ?? requirement.slotId,\n mimeType: requirement.mimeType ?? 'application/octet-stream',\n size: requirement.size ?? (await fileSize(localPath)),\n sha256: requirement.sha256,\n localPath,\n storage: 'filesystem',\n source: requirement.source,\n ...(requirement.linkedWorkspaceId\n ? { linkedWorkspaceId: requirement.linkedWorkspaceId }\n : {}),\n requiredBy: requirement.requiredBy,\n downloadedAt: new Date().toISOString(),\n };\n entries.push({\n slotId: requirement.slotId,\n filename: requirement.filename ?? requirement.slotId,\n localPath,\n source: requirement.source,\n ...(requirement.linkedWorkspaceId\n ? { linkedWorkspaceId: requirement.linkedWorkspaceId }\n : {}),\n requiredBy: requirement.requiredBy,\n });\n }\n\n const nextState: WorkspaceState = {\n ...state,\n local: {\n ...state.local,\n attachmentCache: cache,\n },\n };\n\n return {\n state: nextState,\n resolveAttachment: createFileAttachmentResolver(nextState),\n summary: {\n total: requirements.length,\n downloaded,\n alreadyPresent,\n failed,\n cacheDir,\n entries,\n },\n };\n}\n\nfunction createFileAttachmentResolver(state: WorkspaceState): AttachmentResolver {\n return async (slotId) => {\n const meta = state.local.attachmentCache?.[slotId];\n if (!meta) return null;\n const bytes = await fs.readFile(meta.localPath);\n const view = new Uint8Array(bytes);\n const body = view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);\n return {\n blob: new Blob([body], { type: meta.mimeType }),\n filename: meta.filename,\n };\n };\n}\n\nfunction collectExecutionAttachmentRequirements(\n state: WorkspaceState,\n plan?: ExecutionPlan,\n): AttachmentRequirement[] {\n const seen = new Map<string, AttachmentRequirement>();\n const localRequestFilter = requestFilterForPlan(plan, null);\n const localCollections = localRequestFilter\n ? {\n ...state.synced.collections,\n requests: Object.fromEntries(\n Object.entries(state.synced.collections.requests).filter(([id]) =>\n localRequestFilter.has(id),\n ),\n ),\n }\n : state.synced.collections;\n const workspaceSlots = collectAttachmentSlots({ ...state.synced, collections: localCollections });\n for (const slot of workspaceSlots) {\n const requiredBy = collectRequiredBy(localCollections.requests, slot.slotId);\n if (requiredBy.length === 0) continue;\n addRequirement(seen, {\n ...slot,\n source: 'workspace',\n repoFullName: state.local.connectedRepo?.fullName ?? undefined,\n branch: state.local.workingBranch?.name ?? undefined,\n publicRepo: state.local.connectedRepo ? !state.local.connectedRepo.isPrivate : false,\n requiredBy,\n });\n }\n\n for (const [linkedWorkspaceId, snapshot] of Object.entries(state.local.linkedCollections)) {\n const link = state.synced.linkedWorkspaces[linkedWorkspaceId];\n if (!link) continue;\n const linkedRequestFilter = requestFilterForPlan(plan, linkedWorkspaceId);\n if (plan && linkedRequestFilter && linkedRequestFilter.size === 0) continue;\n const linkedCollections = linkedRequestFilter\n ? {\n ...snapshot.collections,\n requests: Object.fromEntries(\n Object.entries(snapshot.collections.requests).filter(([id]) =>\n linkedRequestFilter.has(id),\n ),\n ),\n }\n : snapshot.collections;\n const linkedSynced: WorkspaceSynced = {\n ...state.synced,\n collections: linkedCollections,\n environments: snapshot.environments,\n globalAssets: snapshot.globalAssets ?? state.synced.globalAssets,\n };\n for (const slot of collectAttachmentSlots(linkedSynced)) {\n const requiredBy = collectRequiredBy(linkedCollections.requests, slot.slotId);\n if (requiredBy.length === 0) continue;\n addRequirement(seen, {\n ...slot,\n source: 'linked-workspace',\n linkedWorkspaceId,\n repoFullName: link.source.repoFullName,\n branch: link.source.branch,\n publicRepo: link.kind === 'public',\n requiredBy,\n });\n }\n }\n\n return [...seen.values()];\n}\n\nfunction requestFilterForPlan(\n plan: ExecutionPlan | undefined,\n linkedWorkspaceId: string | null,\n): Set<string> | null {\n if (!plan) return null;\n const ids = new Set<string>();\n for (const step of plan.steps) {\n if (step.enabled === false) continue;\n if ((step.linkedWorkspaceId ?? null) === linkedWorkspaceId) ids.add(step.requestId);\n }\n return ids;\n}\n\nfunction addRequirement(\n seen: Map<string, AttachmentRequirement>,\n requirement: AttachmentRequirement,\n): void {\n const existing = seen.get(requirement.slotId);\n if (!existing) {\n seen.set(requirement.slotId, requirement);\n return;\n }\n for (const usage of requirement.requiredBy) {\n if (!existing.requiredBy.some((item) => item.requestId === usage.requestId)) {\n existing.requiredBy.push(usage);\n }\n }\n}\n\nfunction collectRequiredBy(\n requests: WorkspaceSynced['collections']['requests'],\n slotId: string,\n): Array<{ requestId: string; requestName: string }> {\n const requiredBy: Array<{ requestId: string; requestName: string }> = [];\n for (const request of Object.values(requests)) {\n if (bodyReferencesSlot(request.body, slotId)) {\n requiredBy.push({ requestId: request.id, requestName: request.name });\n }\n }\n return requiredBy;\n}\n\nfunction bodyReferencesSlot(body: RequestBody, slotId: string): boolean {\n if (body.type === 'binary') return body.attachment?.slotId === slotId;\n if (body.type !== 'form-data') return false;\n return (body.formRows ?? []).some((row) => row.kind === 'file' && row.slotId === slotId);\n}\n\nasync function hasExpectedFile(localPath: string, sha256?: string): Promise<boolean> {\n try {\n const bytes = await fs.readFile(localPath);\n if (!sha256) return true;\n return sha256Hex(bytes) === sha256;\n } catch {\n return false;\n }\n}\n\nasync function fileSize(localPath: string): Promise<number> {\n try {\n return (await fs.stat(localPath)).size;\n } catch {\n return 0;\n }\n}\n\nasync function downloadAttachment(requirement: AttachmentRequirement): Promise<Uint8Array | null> {\n if (!requirement.repoFullName || !requirement.branch) return null;\n const [owner, repo] = requirement.repoFullName.split('/', 2);\n if (!owner || !repo) return null;\n const token = resolveGitHubToken(requirement);\n if (!token && !requirement.publicRepo) {\n throw new Error(\n 'private linked attachments need a GitHub token (set APICIRCLE_GITHUB_TOKEN or GITHUB_TOKEN)',\n );\n }\n\n const apiPath = ['.apicircle', 'attachments', requirement.slotId]\n .map(encodeURIComponent)\n .join('/');\n const url = `https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(\n repo,\n )}/contents/${apiPath}?ref=${encodeURIComponent(requirement.branch)}`;\n const headers: Record<string, string> = {\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'apicircle-cli',\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(url, { headers, cache: 'no-store' });\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`GitHub returned ${res.status}: ${await res.text()}`);\n }\n const json = (await res.json()) as { type?: string; content?: string; encoding?: string };\n if (json.type !== 'file' || typeof json.content !== 'string') {\n throw new Error('GitHub response was not a file');\n }\n if (json.encoding !== 'base64') {\n throw new Error(`GitHub response used unsupported encoding ${json.encoding ?? '(missing)'}`);\n }\n return new Uint8Array(Buffer.from(json.content.replace(/\\n/g, ''), 'base64'));\n}\n\nfunction resolveGitHubToken(requirement: AttachmentRequirement): string {\n if (requirement.source === 'linked-workspace') {\n return (\n process.env.APICIRCLE_E2E_BOT_PAT_LINK_DEDICATED ??\n process.env.APICIRCLE_GITHUB_TOKEN ??\n process.env.GITHUB_TOKEN ??\n process.env.APICIRCLE_E2E_GITHUB_PAT ??\n process.env.APICIRCLE_E2E_BOT_PAT ??\n ''\n );\n }\n return (\n process.env.APICIRCLE_GITHUB_TOKEN ??\n process.env.GITHUB_TOKEN ??\n process.env.APICIRCLE_E2E_GITHUB_PAT ??\n process.env.APICIRCLE_E2E_BOT_PAT ??\n ''\n );\n}\n\nfunction sha256Hex(bytes: Uint8Array): string {\n return createHash('sha256').update(bytes).digest('hex');\n}\n\nfunction attachmentLabel(requirement: AttachmentRequirement): string {\n return `${requirement.filename ?? requirement.slotId} (${requirement.slotId})`;\n}\n\nfunction sourceLabel(requirement: AttachmentRequirement): string {\n const repo = requirement.repoFullName ?? 'local workspace';\n const branch = requirement.branch ? `@${requirement.branch}` : '';\n return `${repo}${branch}`;\n}\n\nfunction requiredByLabel(requirement: AttachmentRequirement): string {\n return requirement.requiredBy.map((item) => item.requestName).join(', ') || 'a request';\n}\n","import * as os from 'node:os';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n ANONYMOUS_ACTOR,\n PlanRunDeniedError,\n resolvePlanRef,\n runPlan,\n type PlanRunAuthorizationContext,\n type PlanStepResult,\n type RunActor,\n type RunPlanResult,\n} from '@apicircle/core';\nimport { loadFromFile, saveToFile } from '@apicircle/core/workspace/file-backed';\nimport type { ExecutionPlan, WorkspaceLocal } from '@apicircle/shared';\nimport { buildSecretsFromCli } from '../util/secrets';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\nimport {\n prepareExecutionAttachments,\n type AttachmentPreparationSummary,\n type PreparedExecutionAttachments,\n} from '../util/executionAttachments';\n\n// =============================================================================\n// `apicircle run <plan>` — execute a saved execution plan headlessly and print\n// a pass/fail report. Sits alongside `apicircle mock` and `apicircle mcp` as\n// the third runtime entry point. Drives the runtime-agnostic engine in\n// `@apicircle/core` (`runPlan`), so the CLI owns only argument parsing,\n// workspace IO, runner-identity resolution, and report formatting.\n//\n// Exit codes:\n// 0 every executed step passed\n// 1 the plan ran but a step failed (or the run was aborted)\n// 2 usage error — no workspace, unknown plan, bad option\n// 3 the run was denied by the authorization gate\n// =============================================================================\n\nconst REPORTERS = ['text', 'json', 'junit'] as const;\ntype Reporter = (typeof REPORTERS)[number];\n\ninterface RunOptions {\n workspaceName?: string;\n workspacePath?: string;\n /** Commander sets this `false` when `--no-assertions` is passed. */\n assertions?: boolean;\n secrets?: string;\n /** Commander sets this `false` when `--no-save` is passed. */\n save?: boolean;\n reporter?: string;\n bail?: boolean;\n env?: string;\n as?: string;\n}\n\nexport function registerRunCommand(program: Command): void {\n program\n .command('run')\n .description('Run a saved execution plan from a workspace and report the result')\n .argument('<plan>', 'Plan name or id to run')\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .option('--no-assertions', 'Run requests without evaluating their assertions')\n .option('-s, --secrets <file>', 'JSON file mapping secretKeyId → plaintext value')\n .option('--no-save', 'Do not write the plan run to workspace history')\n .option('--reporter <format>', 'Report format: text | json | junit', 'text')\n .option('--bail', 'Stop the run at the first failed step')\n .option('-e, --env <name>', 'Layer a local environment on top of the run')\n .option('--as <actor>', 'Override the recorded runner identity')\n .action(async (planRef: string, opts: RunOptions) => {\n let dir: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n dir = resolved.dir;\n if (resolved.fromRegistry) {\n process.stderr.write(\n `${kleur.dim('workspace')}: ${kleur.cyan(resolved.name ?? resolved.id ?? '')} ${kleur.dim(`(${dir})`)}\\n`,\n );\n }\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n fail(err.message);\n return;\n }\n throw err;\n }\n\n const reporter = opts.reporter ?? 'text';\n if (!isReporter(reporter)) {\n fail(`unknown --reporter \"${reporter}\" (expected: ${REPORTERS.join(', ')})`);\n return;\n }\n\n const state = await loadFromFile(dir, { allowMissing: true });\n if (!state) {\n fail(`no workspace found at ${dir} (expected workspace.synced.json)`);\n return;\n }\n\n const ref = resolvePlanRef(state.synced, planRef);\n if (!ref.ok) {\n fail(ref.error);\n if (ref.available.length > 0) {\n process.stderr.write(`Available plans: ${ref.available.join(', ')}\\n`);\n }\n return;\n }\n\n if (opts.env && !state.synced.environments.items[opts.env]) {\n const names = Object.keys(state.synced.environments.items);\n fail(`no environment named \"${opts.env}\" in this workspace`);\n if (names.length > 0) {\n process.stderr.write(`Available environments: ${names.join(', ')}\\n`);\n }\n return;\n }\n\n let secretsById: Record<string, string>;\n try {\n secretsById = (await buildSecretsFromCli({ secretsFile: opts.secrets })).byId;\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err));\n return;\n }\n\n const actor = resolveActor(state.local, opts.as);\n const withAssertions = opts.assertions !== false;\n const text = reporter === 'text';\n\n // Ctrl+C aborts gracefully between steps (and the in-flight request)\n // rather than killing the process — the partial run is still reported.\n const controller = new AbortController();\n const onSigint = (): void => controller.abort(new Error('aborted by SIGINT'));\n process.on('SIGINT', onSigint);\n\n if (text) process.stdout.write(formatHeader(ref.plan, actor, withAssertions, opts));\n\n let prepared: PreparedExecutionAttachments;\n try {\n prepared = await prepareExecutionAttachments(dir, state, ref.plan);\n } catch (err) {\n process.off('SIGINT', onSigint);\n fail(err instanceof Error ? err.message : String(err), 1, 'attachment');\n return;\n }\n if (text && prepared.summary.total > 0) {\n process.stdout.write(formatAttachmentPreparation(prepared.summary));\n }\n\n let result: RunPlanResult;\n try {\n result = await runPlan(prepared.state, ref.id, {\n withAssertions,\n bail: opts.bail === true,\n env: opts.env,\n secretsById,\n actor,\n signal: controller.signal,\n resolveAttachment: prepared.resolveAttachment,\n authorize: checkRunPermission,\n onStep: text ? (step) => process.stdout.write(formatStepLine(step)) : undefined,\n });\n } catch (err) {\n process.off('SIGINT', onSigint);\n if (err instanceof PlanRunDeniedError) {\n fail(err.message, 3, 'denied');\n return;\n }\n throw err;\n }\n process.off('SIGINT', onSigint);\n\n const aborted = controller.signal.aborted;\n const saved = opts.save !== false;\n if (saved) await saveToFile(dir, result.nextState);\n\n if (reporter === 'json') {\n process.stdout.write(\n JSON.stringify(\n buildJsonReport(dir, ref.id, ref.plan, actor, result, saved, aborted, prepared.summary),\n null,\n 2,\n ) + '\\n',\n );\n } else if (reporter === 'junit') {\n process.stdout.write(buildJunitReport(ref.plan, result));\n } else {\n process.stdout.write(formatSummary(result, saved, aborted));\n }\n\n // An aborted run is never a pass, even if the steps that ran all passed.\n process.exitCode = result.passed && !aborted ? 0 : 1;\n });\n}\n\nfunction isReporter(value: string): value is Reporter {\n return (REPORTERS as readonly string[]).includes(value);\n}\n\n/**\n * Best-effort identity of whoever launched the run. Precedence: an explicit\n * `--as` override, then the workspace's GitHub session login, then the OS\n * username. Recorded for display and handed to {@link checkRunPermission}.\n */\nexport function resolveActor(local: WorkspaceLocal, override?: string): RunActor {\n const explicit = override?.trim();\n if (explicit) return { kind: 'unknown', name: explicit };\n\n const login = local.sessions.github.workspace?.accountLogin;\n if (login) return { kind: 'github', name: login };\n\n try {\n const username = os.userInfo().username;\n if (username) return { kind: 'os', name: username };\n } catch {\n // os.userInfo() throws when the uid has no passwd entry (some containers).\n }\n return ANONYMOUS_ACTOR;\n}\n\n/**\n * Authorization gate for `apicircle run`. Today every actor may run every\n * plan — this is intentionally permissive. When per-user run restrictions\n * land, enforce them here: inspect `ctx.actor` + `ctx.plan` and throw a\n * `PlanRunDeniedError` to block the run before any HTTP request fires. It is\n * wired into `runPlan` via the `authorize` option, so a denial is caught and\n * reported with exit code 3.\n */\nfunction checkRunPermission(_ctx: PlanRunAuthorizationContext): void {\n // FUTURE: per-user run authorization. Throw PlanRunDeniedError to deny.\n}\n\n// ---------------------------------------------------------------------------\n// reporting\n// ---------------------------------------------------------------------------\n\nfunction formatHeader(\n plan: ExecutionPlan,\n actor: RunActor,\n withAssertions: boolean,\n opts: RunOptions,\n): string {\n const enabled = plan.steps.filter((s) => s.enabled !== false).length;\n const flags = [\n withAssertions ? 'assertions on' : 'assertions off',\n opts.bail ? 'bail' : null,\n opts.env ? `env=${opts.env}` : null,\n ].filter((f): f is string => f !== null);\n return (\n `${kleur.bold('Plan')} ${plan.name} ${kleur.dim(\n `(${enabled}/${plan.steps.length} steps · ${flags.join(' · ')})`,\n )}\\n` + `${kleur.dim('Run by')} ${actor.name} ${kleur.dim(`(${actor.kind})`)}\\n\\n`\n );\n}\n\nfunction formatAttachmentPreparation(summary: AttachmentPreparationSummary): string {\n const status = `${summary.downloaded} downloaded, ${summary.alreadyPresent} already local`;\n const lines = [\n `${kleur.bold('Attachments')} ${summary.total} required ${kleur.dim(\n `(${status} - ${summary.cacheDir})`,\n )}`,\n ];\n for (const entry of summary.entries) {\n const source =\n entry.source === 'linked-workspace'\n ? `linked:${entry.linkedWorkspaceId ?? 'unknown'}`\n : 'workspace';\n const requiredBy = entry.requiredBy.map((item) => item.requestName).join(', ');\n lines.push(\n ` ${kleur.dim('file')} ${entry.filename} ${kleur.dim(\n `${source} - ${requiredBy} - ${entry.localPath}`,\n )}`,\n );\n }\n return `${lines.join('\\n')}\\n\\n`;\n}\n\nexport function formatStepLine(step: PlanStepResult): string {\n const n = `${step.stepIndex + 1}.`.padEnd(3);\n const method = (step.requestMethod || '—').padEnd(7);\n\n if (step.skipped) {\n return ` ${kleur.dim('–')} ${kleur.dim(n)} ${kleur.dim(method)} ${kleur.dim(\n `${step.requestName} skipped`,\n )}\\n`;\n }\n\n const mark = step.passed ? kleur.green('✓') : kleur.red('✗');\n const status = step.result?.status != null ? String(step.result.status) : '—';\n const duration = step.result ? `${step.result.durationMs}ms` : '';\n const name = step.requestName.padEnd(28);\n\n let line = ` ${mark} ${n} ${method} ${name} ${status.padEnd(4)} ${kleur.dim(duration)}`;\n\n if (step.assertionResults.length > 0) {\n const passed = step.assertionResults.filter((a) => a.passed).length;\n line += ` ${kleur.dim(`${passed}/${step.assertionResults.length} assertions`)}`;\n }\n line += '\\n';\n\n if (step.error) {\n line += ` ${kleur.red(step.error)}\\n`;\n }\n for (const a of step.assertionResults) {\n if (!a.passed) line += ` ${kleur.red('✗')} ${a.detail ?? `${a.kind} ${a.op}`}\\n`;\n }\n if (step.missingVariables.length > 0) {\n line += ` ${kleur.yellow('⚠')} unresolved: ${step.missingVariables\n .map((v) => `{{${v}}}`)\n .join(', ')}\\n`;\n }\n return line;\n}\n\nfunction tally(result: RunPlanResult): { passed: number; failed: number; skipped: number } {\n let passed = 0;\n let failed = 0;\n let skipped = 0;\n for (const s of result.steps) {\n if (s.skipped) skipped++;\n else if (s.passed) passed++;\n else failed++;\n }\n return { passed, failed, skipped };\n}\n\nfunction formatSummary(result: RunPlanResult, saved: boolean, aborted: boolean): string {\n if (result.steps.length === 0) {\n return `\\n${kleur.yellow('Plan has no steps.')}\\n`;\n }\n const { passed, failed, skipped } = tally(result);\n const parts = [\n kleur.green(`${passed} passed`),\n failed > 0 ? kleur.red(`${failed} failed`) : kleur.dim(`${failed} failed`),\n kleur.dim(`${skipped} skipped`),\n ];\n const verdict = result.passed && !aborted ? kleur.green('PASS') : kleur.red('FAIL');\n let out = `\\n${verdict} ${parts.join(kleur.dim(' · '))} ${kleur.dim(\n `· ${result.planRun.durationMs}ms`,\n )}\\n`;\n if (aborted) out += `${kleur.yellow('Run aborted before every step finished.')}\\n`;\n out += saved\n ? kleur.dim('Plan run saved to workspace history.\\n')\n : kleur.dim('Plan run not saved (--no-save).\\n');\n return out;\n}\n\nfunction buildJsonReport(\n workspace: string,\n planId: string,\n plan: ExecutionPlan,\n actor: RunActor,\n result: RunPlanResult,\n saved: boolean,\n aborted: boolean,\n attachments: AttachmentPreparationSummary,\n): unknown {\n return {\n workspace,\n plan: { id: planId, name: plan.name },\n actor,\n withAssertions: result.planRun.withAssertions,\n passed: result.passed && !aborted,\n aborted,\n durationMs: result.planRun.durationMs,\n saved,\n attachments,\n counts: tally(result),\n steps: result.steps.map((s) => ({\n step: s.stepIndex + 1,\n request: s.requestName,\n method: s.requestMethod,\n skipped: s.skipped,\n status: s.result?.status ?? null,\n ok: s.result?.ok ?? false,\n durationMs: s.result?.durationMs ?? 0,\n passed: s.passed,\n error: s.error ?? null,\n missingVariables: s.missingVariables,\n assertions: s.assertionResults.map((a) => ({\n kind: a.kind,\n op: a.op,\n target: a.target,\n expected: a.expected,\n passed: a.passed,\n detail: a.detail,\n })),\n })),\n };\n}\n\nfunction xmlEscape(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/** JUnit XML — consumable by CI dashboards as a plan-run review gate. */\nexport function buildJunitReport(plan: ExecutionPlan, result: RunPlanResult): string {\n const { failed, skipped } = tally(result);\n const total = result.steps.length;\n const suite = xmlEscape(plan.name);\n const suiteTime = (result.planRun.durationMs / 1000).toFixed(3);\n\n const cases = result.steps.map((s) => {\n const name = xmlEscape(`${s.stepIndex + 1}. ${s.requestName}`);\n const time = ((s.result?.durationMs ?? 0) / 1000).toFixed(3);\n const open = ` <testcase name=\"${name}\" classname=\"${suite}\" time=\"${time}\"`;\n if (s.skipped) return `${open}>\\n <skipped/>\\n </testcase>`;\n if (s.passed) return `${open}/>`;\n\n const reasons: string[] = [];\n if (s.error) reasons.push(s.error);\n for (const a of s.assertionResults) {\n if (!a.passed) reasons.push(a.detail ?? `assertion ${a.kind} ${a.op} failed`);\n }\n if (s.result && !s.result.ok && s.result.status != null) {\n reasons.push(`HTTP ${s.result.status}`);\n }\n const detail = xmlEscape(reasons.join('\\n') || 'step failed');\n const summary = detail.split('\\n')[0];\n return `${open}>\\n <failure message=\"${summary}\">${detail}</failure>\\n </testcase>`;\n });\n\n return (\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n' +\n `<testsuites name=\"${suite}\" tests=\"${total}\" failures=\"${failed}\" skipped=\"${skipped}\" time=\"${suiteTime}\">\\n` +\n ` <testsuite name=\"${suite}\" tests=\"${total}\" failures=\"${failed}\" skipped=\"${skipped}\" time=\"${suiteTime}\">\\n` +\n `${cases.join('\\n')}\\n` +\n ' </testsuite>\\n' +\n '</testsuites>\\n'\n );\n}\n\n/** Write a CLI error to stderr and set the exit code. `kind` colours the prefix. */\nfunction fail(message: string, code = 2, kind = 'error'): void {\n process.stderr.write(`${kleur.red(kind)}: ${message}\\n`);\n process.exitCode = code;\n}\n","import type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n createWorkspaceOnDisk,\n defaultWorkspacesRoot,\n listWorkspacesOnDisk,\n saveRegistryToDisk,\n} from '../util/resolveWorkspace';\nimport { findWorkspaceEntry, setActiveWorkspace } from '@apicircle/core/workspace/registry';\n\n// =============================================================================\n// `apicircle workspaces <list | create | use | path>` — manage the\n// multi-workspace registry from the terminal. Every other command\n// (`import`, `mcp`, `run`) resolves `--workspace-name` or `--workspace-path` against this\n// registry, so this is the CLI surface for seeing, creating, and switching\n// between the workspaces the desktop app + AI clients share.\n// =============================================================================\n\ninterface WorkspacesOptions {\n json?: boolean;\n}\n\nexport function registerWorkspacesCommand(program: Command): void {\n const ws = program\n .command('workspaces')\n .description('List, create, or switch the active workspace');\n\n ws.command('list')\n .description('List every workspace registered on this machine')\n .option('--json', 'Emit JSON instead of a formatted table')\n .action(async (opts: WorkspacesOptions) => {\n const { registry, root } = await listWorkspacesOnDisk();\n if (opts.json) {\n process.stdout.write(JSON.stringify({ root, registry }, null, 2) + '\\n');\n return;\n }\n if (registry.workspaces.length === 0) {\n process.stdout.write(\n `${kleur.dim('No workspaces registered yet at')} ${root}\\n` +\n `${kleur.dim('Run')} ${kleur.cyan('apicircle workspaces create <name>')} ${kleur.dim(\n 'or open the desktop app to seed one.',\n )}\\n`,\n );\n return;\n }\n process.stdout.write(`${kleur.dim('registry')}: ${root}\\n\\n`);\n // Sort by lastOpenedAt desc so the most recent shows first.\n const rows = [...registry.workspaces].sort((a, b) =>\n b.lastOpenedAt.localeCompare(a.lastOpenedAt),\n );\n const nameWidth = Math.max(4, ...rows.map((r) => r.name.length));\n const idWidth = Math.max(2, ...rows.map((r) => r.id.length));\n process.stdout.write(\n kleur.bold(\n ` ${''.padEnd(1)} ${'NAME'.padEnd(nameWidth)} ${'ID'.padEnd(idWidth)} LAST OPENED\\n`,\n ),\n );\n for (const w of rows) {\n const mark = w.id === registry.activeWorkspaceId ? kleur.green('●') : ' ';\n process.stdout.write(\n ` ${mark} ${w.name.padEnd(nameWidth)} ${kleur.dim(\n w.id.padEnd(idWidth),\n )} ${kleur.dim(w.lastOpenedAt)}\\n`,\n );\n }\n process.stdout.write(`\\n${kleur.dim('● = active')}\\n`);\n });\n\n ws.command('create')\n .description('Create a new workspace and add it to the registry')\n .argument('<name>', 'Human-readable label for the workspace')\n .option('--sample', 'Seed the workspace with one sample request', false)\n .action(async (name: string, opts: { sample?: boolean }) => {\n try {\n const { entry, dir, registry } = await createWorkspaceOnDisk({\n name,\n sampleRequest: opts.sample ?? false,\n });\n process.stdout.write(\n `${kleur.green('created')} workspace ${kleur.cyan(entry.name)} ${kleur.dim(`(${entry.id})`)}\\n` +\n ` at ${dir}\\n`,\n );\n if (registry.activeWorkspaceId === entry.id) {\n process.stdout.write(`${kleur.dim('marked as active')}\\n`);\n }\n } catch (err) {\n process.stderr.write(\n `${kleur.red('error')}: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n process.exit(2);\n }\n });\n\n ws.command('use')\n .description('Set the active workspace by id or name')\n .argument('<selector>', 'Workspace id or name')\n .action(async (selector: string) => {\n const { registry, root } = await listWorkspacesOnDisk();\n const entry = findWorkspaceEntry(registry, selector);\n if (!entry) {\n process.stderr.write(\n `${kleur.red('error')}: no workspace named \"${selector}\" in the registry at ${root}.\\n` +\n `${kleur.dim('Run')} ${kleur.cyan('apicircle workspaces list')} ${kleur.dim('to see what is available.')}\\n`,\n );\n process.exit(2);\n return;\n }\n const next = await setActiveWorkspace(root, entry.id);\n void next; // saveRegistry inside setActiveWorkspace already persisted it\n process.stdout.write(\n `${kleur.green('active')} workspace is now ${kleur.cyan(entry.name)} ${kleur.dim(`(${entry.id})`)}\\n`,\n );\n });\n\n ws.command('path')\n .description('Print the on-disk path for a workspace (or the workspaces root)')\n .argument('[selector]', 'Optional workspace id or name; prints the root when omitted')\n .action(async (selector?: string) => {\n if (!selector) {\n process.stdout.write(defaultWorkspacesRoot() + '\\n');\n return;\n }\n const { registry, root } = await listWorkspacesOnDisk();\n const entry = findWorkspaceEntry(registry, selector);\n if (!entry) {\n process.stderr.write(\n `${kleur.red('error')}: no workspace named \"${selector}\" in the registry at ${root}.\\n`,\n );\n process.exit(2);\n return;\n }\n // workspaceDirFor would re-import; the simplest computation is just root + id.\n // We use `saveRegistryToDisk` only to assert the import wiring is alive.\n void saveRegistryToDisk;\n const { workspaceDirFor } = await import('@apicircle/core/workspace/registry');\n process.stdout.write(workspaceDirFor(root, entry.id) + '\\n');\n });\n}\n","import { Command } from 'commander';\nimport { registerMockCommand } from './commands/mock';\nimport { registerMcpCommand } from './commands/mcp';\nimport { registerImportCommand } from './commands/import';\nimport { registerExportCommand } from './commands/export';\nimport { registerRunCommand } from './commands/run';\nimport { registerWorkspacesCommand } from './commands/workspaces';\nimport { CLI_PACKAGE_VERSION } from './packageVersion';\n\n// =============================================================================\n// `apicircle` — root CLI binary. Sub-commands live under ./commands.\n//\n// Designed for two audiences:\n// • Power users who want a no-Electron way to run mocks, drive the MCP\n// stdio server, or execute saved plans against a workspace folder.\n// • CI / automation that imports specs into a workspace.json checked into\n// git, or runs an execution plan as a review gate.\n// =============================================================================\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name('apicircle')\n .description('Command-line companion to API Circle Studio.')\n .version(CLI_PACKAGE_VERSION);\n\n registerMockCommand(program);\n registerMcpCommand(program);\n registerImportCommand(program);\n registerExportCommand(program);\n registerRunCommand(program);\n registerWorkspacesCommand(program);\n\n return program;\n}\n\nexport async function runCli(argv: readonly string[] = process.argv): Promise<void> {\n await buildProgram().parseAsync(argv);\n}\n\n// Run when this file is executed as a script. tsup wraps the CJS output\n// with a node shebang so this branch is what handles `apicircle <args>`.\n// We deliberately do *not* check require.main — works in both CJS and ESM.\n// `.ts` is also accepted so the E2E suite can run the source under tsx\n// without going through the dist bundle.\nconst entry = process.argv[1] ?? '';\nif (entry.endsWith('apicircle') || entry.endsWith('index.cjs') || entry.endsWith('index.ts')) {\n void runCli();\n}\n","import { CLI_PACKAGE_VERSION } from '../packageVersion';\nimport { formatRootHelp, hasRootHelpFlag, hasRootVersionFlag } from './args';\n\nexport async function runBin(argv: readonly string[] = process.argv): Promise<void> {\n const args = argv.slice(2);\n if (hasRootVersionFlag(args)) {\n process.stdout.write(`${CLI_PACKAGE_VERSION}\\n`);\n return;\n }\n if (hasRootHelpFlag(args)) {\n process.stdout.write(formatRootHelp());\n return;\n }\n\n const { runCli } = await import('../index');\n await runCli(argv);\n}\n\nconst entry = process.argv[1] ?? '';\nif (entry.endsWith('apicircle') || entry.endsWith('cli.cjs') || entry.endsWith('cli.ts')) {\n void runBin();\n}\n","export function hasRootVersionFlag(args: readonly string[]): boolean {\n return args.length === 1 && ['--version', '-v', '-V'].includes(args[0] ?? '');\n}\n\nexport function hasRootHelpFlag(args: readonly string[]): boolean {\n return args.length === 1 && ['--help', '-h', 'help'].includes(args[0] ?? '');\n}\n\nexport function formatRootHelp(): string {\n return `Usage: apicircle [options] [command]\n\nCommand-line companion to API Circle Studio.\n\nOptions:\n -v, -V, --version Print the version number.\n -h, --help Show help.\n\nCommands:\n mock [options] <workspace> Start a local mock server.\n mcp [options] [workspace] Start the MCP stdio server.\n import <source> <workspace> Import OpenAPI, Postman, Insomnia, or curl.\n run [options] <plan-id> Run an execution plan.\n workspaces Manage local workspace registries.\n\nRun \"apicircle <command> --help\" for command-specific help.\n`;\n}\n"],"mappings":"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","names":["fs","kleur","fs","path","import_node_fs","import_shared","entry","fs","path","import_node_fs","import_file_backed","import_shared","kleur","import_kleur","kleur","resolve","fs","import_node_fs","path","import_kleur","import_file_backed","import_mock_server_core","import_shared","kleur","fs","import_node_fs","path","import_kleur","import_core","fs","path","import_node_fs","fs","import_node_fs","path","import_core","kleur","entry","os","import_kleur","import_core","import_file_backed","kleur","entry","workspaceDirFor","import_kleur","import_registry","runCli","entry"]}
1
+ {"version":3,"sources":["../../package.json","../../src/packageVersion.ts","../../src/commands/mock.ts","../../src/util/loadWorkspace.ts","../../src/util/resolveWorkspace.ts","../../src/commands/mcp.ts","../../src/commands/import.ts","../../src/commands/export.ts","../../src/util/secrets.ts","../../src/util/executionAttachments.ts","../../src/commands/run.ts","../../src/commands/workspaces.ts","../../src/index.ts","../../src/bin/cli.ts","../../src/bin/args.ts"],"sourcesContent":["{\n \"name\": \"@apicircle/cli\",\n \"version\": \"1.0.8\",\n \"private\": false,\n \"type\": \"module\",\n \"description\": \"Command-line interface for API Circle Studio. Run mock servers, drive the MCP server, and import OpenAPI / Postman / Insomnia collections from any terminal.\",\n \"keywords\": [\n \"apicircle\",\n \"api-circle\",\n \"cli\",\n \"command-line\",\n \"api\",\n \"api-client\",\n \"http\",\n \"http-client\",\n \"mock-server\",\n \"mcp\",\n \"mcp-server\",\n \"openapi\",\n \"swagger\",\n \"postman\",\n \"insomnia\",\n \"import\",\n \"workspace\",\n \"headless\"\n ],\n \"license\": \"SEE LICENSE IN LICENSE\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/apicircle/studio.git\",\n \"directory\": \"packages/cli\"\n },\n \"homepage\": \"https://github.com/apicircle/studio#readme\",\n \"bugs\": \"https://github.com/apicircle/studio/issues\",\n \"engines\": {\n \"node\": \">=20\"\n },\n \"main\": \"./src/index.ts\",\n \"types\": \"./src/index.ts\",\n \"bin\": {\n \"apicircle\": \"./dist/bin/cli.cjs\"\n },\n \"exports\": {\n \".\": \"./src/index.ts\"\n },\n \"files\": [\n \"dist\"\n ],\n \"publishConfig\": {\n \"main\": \"./dist/index.cjs\",\n \"module\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.cts\",\n \"exports\": {\n \".\": {\n \"import\": {\n \"types\": \"./dist/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"require\": {\n \"types\": \"./dist/index.d.cts\",\n \"default\": \"./dist/index.cjs\"\n }\n }\n }\n },\n \"scripts\": {\n \"build\": \"tsup\",\n \"check\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"clean\": \"rm -rf dist node_modules\"\n },\n \"dependencies\": {\n \"@apicircle/core\": \"workspace:*\",\n \"@apicircle/mcp-server\": \"workspace:*\",\n \"@apicircle/mock-server-core\": \"workspace:*\",\n \"@apicircle/shared\": \"workspace:*\",\n \"commander\": \"^12.0.0\",\n \"kleur\": \"^4.1.5\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^20.0.0\",\n \"tsup\": \"^8.3.0\",\n \"typescript\": \"^5.4.0\",\n \"vitest\": \"^2.0.0\"\n }\n}\n","import packageJson from '../package.json';\n\nexport function readPackageVersion(): string {\n const version = (packageJson as { version?: unknown }).version;\n if (typeof version !== 'string' || version.length === 0) {\n throw new Error('Unable to read @apicircle/cli package version');\n }\n return version;\n}\n\nexport const CLI_PACKAGE_VERSION = readPackageVersion();\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n parseSourceToEndpoints,\n startMockServer,\n type MockServerHandle,\n} from '@apicircle/mock-server-core';\nimport { generateId, type MockServer } from '@apicircle/shared';\n\n// =============================================================================\n// `apicircle mock <spec>` — boot a mock server from an OpenAPI / Postman /\n// Insomnia file. The path's extension chooses the parser; user can override\n// with `--type {openapi,postman,insomnia}`.\n// =============================================================================\n\ninterface MockOptions {\n port?: string;\n host?: string;\n type?: 'openapi' | 'postman' | 'insomnia' | 'auto';\n format?: 'json' | 'yaml' | 'auto';\n cors?: boolean;\n}\n\nexport function registerMockCommand(program: Command): void {\n program\n .command('mock')\n .description('Run a mock server from an OpenAPI / Postman / Insomnia file')\n .argument('<spec>', 'Path to the spec file')\n .option('-p, --port <number>', 'TCP port to bind (defaults to a free port)')\n .option('-h, --host <host>', 'Hostname to bind', '127.0.0.1')\n .option('-t, --type <type>', 'Source type: openapi | postman | insomnia | auto', 'auto')\n .option('-f, --format <format>', 'OpenAPI format: json | yaml | auto', 'auto')\n .option('--cors', 'Enable permissive CORS', true)\n .action(async (spec: string, opts: MockOptions) => {\n const absolute = path.resolve(spec);\n const raw = await fs.readFile(absolute, 'utf-8');\n const type = inferType(absolute, opts.type ?? 'auto');\n const format = type === 'openapi' ? inferFormat(absolute, opts.format ?? 'auto') : 'json';\n\n const source = makeSource(type, format, raw);\n const parsed = await parseSourceToEndpoints(source);\n const mock: MockServer = {\n id: generateId(),\n name: path.basename(absolute),\n source,\n endpoints: parsed.endpoints,\n defaultPort: opts.port ? Number(opts.port) : null,\n cors: { enabled: opts.cors !== false, origins: ['*'] },\n createdAt: new Date().toISOString(),\n updatedAt: new Date().toISOString(),\n };\n\n const handle = await startMockServer(mock, {\n port: opts.port ? Number(opts.port) : undefined,\n host: opts.host,\n });\n process.stdout.write(\n `${kleur.green('Mock server')} listening on ${kleur.cyan(`http://${opts.host}:${handle.port}`)} ` +\n `with ${parsed.endpoints.length} endpoints (type=${type}). Press Ctrl-C to stop.\\n`,\n );\n if (parsed.warnings.length) {\n for (const w of parsed.warnings) {\n process.stderr.write(`${kleur.yellow('warn')}: ${w}\\n`);\n }\n }\n installShutdown(handle);\n });\n}\n\nexport function inferType(\n filePath: string,\n hint: NonNullable<MockOptions['type']>,\n): 'openapi' | 'postman' | 'insomnia' {\n if (hint && hint !== 'auto') return hint;\n const lower = filePath.toLowerCase();\n if (lower.includes('postman')) return 'postman';\n if (lower.includes('insomnia')) return 'insomnia';\n return 'openapi';\n}\n\nexport function inferFormat(\n filePath: string,\n hint: NonNullable<MockOptions['format']>,\n): 'json' | 'yaml' {\n if (hint && hint !== 'auto') return hint;\n const lower = filePath.toLowerCase();\n return lower.endsWith('.yaml') || lower.endsWith('.yml') ? 'yaml' : 'json';\n}\n\nexport function makeSource(\n type: 'openapi' | 'postman' | 'insomnia',\n format: 'json' | 'yaml',\n raw: string,\n): MockServer['source'] {\n switch (type) {\n case 'openapi':\n return { kind: 'openapi', spec: raw, format };\n case 'postman':\n return { kind: 'postman', collection: raw };\n case 'insomnia':\n return { kind: 'insomnia', export: raw };\n }\n}\n\nfunction installShutdown(handle: MockServerHandle): void {\n let closing = false;\n const shutdown = async () => {\n if (closing) return;\n closing = true;\n await handle.close();\n process.exit(0);\n };\n process.on('SIGINT', () => void shutdown());\n process.on('SIGTERM', () => void shutdown());\n}\n","import * as path from 'node:path';\nimport { promises as fs } from 'node:fs';\nimport { loadFromFile, saveToFile } from '@apicircle/core/workspace/file-backed';\nimport type { WorkspaceState } from '@apicircle/core';\nimport { FONT_SIZE_PERCENT_DEFAULT, generateId } from '@apicircle/shared';\n\n// =============================================================================\n// loadWorkspace — small wrapper around `@apicircle/core`'s file-backed\n// helpers that auto-creates an empty workspace on first run so users don't\n// have to seed a workspace.synced.json by hand before invoking commands.\n// =============================================================================\n\nexport async function ensureWorkspace(dir: string): Promise<WorkspaceState> {\n const resolved = path.resolve(dir);\n await fs.mkdir(resolved, { recursive: true });\n const existing = await loadFromFile(resolved, { allowMissing: true });\n if (existing) return existing;\n\n const now = new Date().toISOString();\n const workspaceId = generateId();\n const fresh: WorkspaceState = {\n synced: {\n schemaVersion: 1,\n workspaceId,\n collections: {\n tree: { id: generateId(), type: 'root', children: [] },\n requests: {},\n folders: {},\n },\n environments: { items: {}, activeName: null, priorityOrder: [] },\n linkedWorkspaces: {},\n linkedOverrides: { requests: {}, environmentVars: {} },\n releases: { self: null, perLink: {} },\n globalAssets: { schemas: {}, graphql: {}, files: {} },\n mockServers: {},\n meta: { createdAt: now, updatedAt: now, appVersion: '1.0.0' },\n },\n local: {\n schemaVersion: 1,\n workspaceId,\n executionPlans: {},\n history: { requestRuns: [], planRuns: [] },\n secretIndex: { entries: {} },\n sessions: { github: { workspace: null, links: {} } },\n connectedRepo: null,\n workingBranch: null,\n seededWorkspaceSha: null,\n retiredBranch: null,\n sync: { lastPulledSnapshot: null, lastPulledSha: null, lastPulledAt: null, dirtyKeys: [] },\n linkedCollections: {},\n attachmentCache: {},\n globalContext: {},\n mockRuntime: { active: {} },\n ui: {\n activeRequestId: null,\n sidebarExpandedSections: [],\n themeId: 'one-dark-pro',\n fontId: 'system-sans',\n fontSizePercent: FONT_SIZE_PERCENT_DEFAULT,\n },\n settings: { validateOnSend: true, monacoConsumesWheel: false },\n snapshots: { entries: [], maxBytes: 50 * 1024 * 1024 },\n },\n };\n await saveToFile(resolved, fresh);\n return fresh;\n}\n","import * as os from 'node:os';\nimport * as path from 'node:path';\nimport { promises as fs } from 'node:fs';\nimport {\n findWorkspaceEntry,\n loadRegistry,\n registerWorkspace,\n saveRegistry,\n workspaceDirFor,\n type WorkspaceRegistry,\n type WorkspaceRegistryEntry,\n} from '@apicircle/core/workspace/registry';\nimport { saveToFile } from '@apicircle/core/workspace/file-backed';\nimport { generateId, type Folder, type Request as ApiRequest } from '@apicircle/shared';\nimport type { WorkspaceState } from '@apicircle/core';\n\n// =============================================================================\n// CLI workspace selector — two explicit flags, no ambiguity.\n//\n// Every command that touches workspace state accepts two mutually-exclusive\n// flags:\n//\n// --workspace-name <name-or-id>\n// A logical handle — case-insensitive name match against the desktop\n// registry, falling back to id match. The common case for humans:\n// `--workspace-name Petstore`. Scripts that need to survive renames\n// can pass the long-form id here too.\n//\n// --workspace-path <dir>\n// A filesystem directory containing `workspace.synced.json`. The\n// back-compat path for CI / one-off flows that aren't registered\n// with the desktop app (e.g. a freshly git-cloned workspace repo).\n//\n// Passing both is an error. When NEITHER is passed:\n//\n// • A registry exists at userData/workspaces/ → use the active workspace.\n// • No registry exists → fall back to cwd (the\n// legacy single-workspace\n// flow CI scripts use).\n//\n// The CLI runs outside Electron, so we reproduce Electron's per-OS `userData`\n// convention here. `APICIRCLE_WORKSPACES_ROOT` overrides it for CI / tests.\n// =============================================================================\n\nconst APP_NAME = '@apicircle';\nconst APP_SUBDIR = 'desktop';\nconst WORKSPACES_DIRNAME = 'workspaces';\nconst LEGACY_WORKSPACE_DIRNAME = 'workspace';\n\nexport interface ResolvedWorkspace {\n /** Absolute directory containing workspace.synced.json + workspace.local.json. */\n dir: string;\n /** Workspace id when resolved via registry; null when resolved by raw path. */\n id: string | null;\n /** Display name when resolved via registry; null otherwise. */\n name: string | null;\n /** Whether the resolver looked at the registry to find this dir. */\n fromRegistry: boolean;\n /** The registry root that was consulted (or null when resolving raw paths). */\n registryRoot: string | null;\n}\n\nexport interface ResolveOptions {\n /** Raw value from `--workspace-name <name-or-id>`. */\n name?: string;\n /** Raw value from `--workspace-path <dir>`. */\n path?: string;\n /** Override for the desktop's `userData/workspaces/` (CI / tests). */\n workspacesRoot?: string;\n /** Override for the desktop's legacy `userData/workspace/`. */\n legacyDir?: string;\n /** When true (the default), missing target dirs raise. Set false for create paths. */\n expectExists?: boolean;\n}\n\n/**\n * Compute the on-disk `workspaces/` root the CLI consults for id / name\n * selectors. Honors `APICIRCLE_WORKSPACES_ROOT` first, then derives from\n * the OS-specific user-data convention used by Electron.\n */\nexport function defaultWorkspacesRoot(): string {\n const override = process.env.APICIRCLE_WORKSPACES_ROOT;\n if (override && override.length > 0) return path.resolve(override);\n return path.join(electronUserDataDir(), WORKSPACES_DIRNAME);\n}\n\nexport function defaultLegacyDir(): string {\n return path.join(electronUserDataDir(), LEGACY_WORKSPACE_DIRNAME);\n}\n\nfunction electronUserDataDir(): string {\n // Match Electron's `app.getPath('userData')` semantics. The desktop\n // package's name is `@apicircle/desktop` — Electron flattens the scope\n // into `@apicircle/desktop` on disk.\n const home = os.homedir();\n switch (process.platform) {\n case 'win32': {\n const appdata = process.env.APPDATA ?? path.join(home, 'AppData', 'Roaming');\n return path.join(appdata, APP_NAME, APP_SUBDIR);\n }\n case 'darwin':\n return path.join(home, 'Library', 'Application Support', APP_NAME, APP_SUBDIR);\n default:\n return path.join(\n process.env.XDG_CONFIG_HOME ?? path.join(home, '.config'),\n APP_NAME,\n APP_SUBDIR,\n );\n }\n}\n\n/**\n * Resolve `--workspace-name` / `--workspace-path` into a concrete on-disk\n * directory. Throws a `WorkspaceResolutionError` with a readable message\n * when no match is found, so callers can surface the failure to the user\n * without an opaque stack trace.\n *\n * Precedence rules:\n *\n * 1. Passing both flags is an error — they're mutually exclusive.\n * 2. `path` (when given) is treated as a literal filesystem directory.\n * The registry isn't consulted; the dir must exist (unless\n * `expectExists: false`).\n * 3. `name` (when given) is matched against the registry: exact id\n * first, then case-insensitive name. Errors with a \"did you run\n * `workspaces list`?\" hint when nothing matches.\n * 4. Neither given → active workspace from the registry, or cwd when\n * no registry exists.\n */\nexport async function resolveWorkspace(opts: ResolveOptions = {}): Promise<ResolvedWorkspace> {\n const root = opts.workspacesRoot ?? defaultWorkspacesRoot();\n const nameSelector = opts.name?.trim();\n const pathSelector = opts.path?.trim();\n const expectExists = opts.expectExists ?? true;\n\n if (nameSelector && pathSelector) {\n throw new WorkspaceResolutionError(\n '--workspace-name and --workspace-path are mutually exclusive. Pass one or neither.',\n 'both-flags',\n );\n }\n\n // Explicit path selector: skip the registry entirely.\n if (pathSelector) {\n const expanded = expandTilde(pathSelector);\n const dir = path.resolve(expanded);\n if (expectExists && !(await dirExists(dir))) {\n throw new WorkspaceResolutionError(`Workspace directory not found: ${dir}`, 'path-missing');\n }\n return { dir, id: null, name: null, fromRegistry: false, registryRoot: null };\n }\n\n const registry = await loadRegistry(root);\n\n if (nameSelector) {\n if (!registry) {\n throw new WorkspaceResolutionError(\n `No workspaces are registered at ${root}. Open the desktop app once to seed the registry, ` +\n `or pass --workspace-path <dir> to point at a workspace directory directly.`,\n 'no-registry',\n );\n }\n const entry = findWorkspaceEntry(registry, nameSelector);\n if (!entry) {\n throw new WorkspaceResolutionError(\n `No workspace named \"${nameSelector}\" in the registry at ${root}. ` +\n `Run \\`apicircle workspaces list\\` to see what's available.`,\n 'not-found',\n );\n }\n return {\n dir: workspaceDirFor(root, entry.id),\n id: entry.id,\n name: entry.name,\n fromRegistry: true,\n registryRoot: root,\n };\n }\n\n // No selector — pick active workspace, or fall back to cwd if no registry.\n if (registry && registry.activeWorkspaceId) {\n const active = registry.workspaces.find((w) => w.id === registry.activeWorkspaceId);\n if (active) {\n return {\n dir: workspaceDirFor(root, active.id),\n id: active.id,\n name: active.name,\n fromRegistry: true,\n registryRoot: root,\n };\n }\n }\n // Cwd fallback — preserves the pre-registry CLI flow for users who\n // organise their own workspace directories outside the desktop app.\n return {\n dir: path.resolve(process.cwd()),\n id: null,\n name: null,\n fromRegistry: false,\n registryRoot: null,\n };\n}\n\n/**\n * Create a new workspace on disk + add it to the registry. Returns the\n * fresh state + its registry entry. Idempotent against the id — if the\n * id is already in the registry, the existing entry is returned and the\n * on-disk files are NOT overwritten.\n */\nexport async function createWorkspaceOnDisk(args: {\n name: string;\n workspacesRoot?: string;\n sampleRequest?: boolean;\n}): Promise<{\n registry: WorkspaceRegistry;\n entry: WorkspaceRegistryEntry;\n state: WorkspaceState;\n dir: string;\n}> {\n const root = args.workspacesRoot ?? defaultWorkspacesRoot();\n const trimmed = args.name.trim();\n if (!trimmed) throw new Error('Workspace name is required');\n const existing = await loadRegistry(root);\n if (existing && existing.workspaces.some((w) => w.name.toLowerCase() === trimmed.toLowerCase())) {\n throw new Error(`A workspace named \"${trimmed}\" already exists`);\n }\n const workspaceId = generateId();\n const now = new Date().toISOString();\n const state = buildEmptyState(workspaceId, now, args.sampleRequest ?? false);\n const dir = workspaceDirFor(root, workspaceId);\n await saveToFile(dir, state);\n const entry: WorkspaceRegistryEntry = {\n id: workspaceId,\n name: trimmed,\n createdAt: now,\n lastOpenedAt: now,\n };\n const registry = await registerWorkspace(root, entry);\n return { registry, entry, state, dir };\n}\n\n/**\n * List every workspace registered on this machine. CLI consumers can call\n * this directly; it returns the empty list (not null) when no registry\n * exists yet, so callers can avoid null-checking.\n */\nexport async function listWorkspacesOnDisk(\n args: {\n workspacesRoot?: string;\n } = {},\n): Promise<{ registry: WorkspaceRegistry; root: string }> {\n const root = args.workspacesRoot ?? defaultWorkspacesRoot();\n const registry = (await loadRegistry(root)) ?? {\n schemaVersion: 1 as const,\n activeWorkspaceId: null,\n workspaces: [],\n };\n return { registry, root };\n}\n\n/**\n * Save the registry. Exposed so CLI commands that mutate the registry\n * (e.g. `workspaces switch`) can persist their changes without each one\n * re-importing from `@apicircle/core/workspace/registry`.\n */\nexport async function saveRegistryToDisk(\n registry: WorkspaceRegistry,\n workspacesRoot?: string,\n): Promise<void> {\n await saveRegistry(workspacesRoot ?? defaultWorkspacesRoot(), registry);\n}\n\nexport type WorkspaceResolutionCode = 'path-missing' | 'no-registry' | 'not-found' | 'both-flags';\n\nexport class WorkspaceResolutionError extends Error {\n readonly code: WorkspaceResolutionCode;\n constructor(message: string, code: WorkspaceResolutionCode) {\n super(message);\n this.name = 'WorkspaceResolutionError';\n this.code = code;\n }\n}\n\n// ---------------------------------------------------------------------------\n// internals\n// ---------------------------------------------------------------------------\n\nfunction expandTilde(value: string): string {\n if (value === '~') return os.homedir();\n if (value.startsWith('~/') || value.startsWith('~\\\\')) {\n return path.join(os.homedir(), value.slice(2));\n }\n return value;\n}\n\nasync function dirExists(p: string): Promise<boolean> {\n try {\n const st = await fs.stat(p);\n return st.isDirectory();\n } catch {\n return false;\n }\n}\n\nfunction buildEmptyState(workspaceId: string, now: string, withSample: boolean): WorkspaceState {\n const sample: ApiRequest | null = withSample\n ? {\n id: generateId(),\n name: 'Sample: GET /anything',\n folderId: null,\n method: 'GET',\n url: 'https://httpbin.org/anything',\n headers: [{ key: 'Accept', value: 'application/json', enabled: true }],\n query: [],\n body: { type: 'none', content: '' },\n auth: { type: 'inherit' },\n contextVars: [],\n extractions: [],\n assertions: [],\n createdAt: now,\n updatedAt: now,\n }\n : null;\n const folders: Record<string, Folder> = {};\n const requests: Record<string, ApiRequest> = sample ? { [sample.id]: sample } : {};\n return {\n synced: {\n schemaVersion: 1,\n workspaceId,\n collections: {\n tree: {\n id: generateId(),\n type: 'root',\n children: sample ? [{ kind: 'request', id: sample.id }] : [],\n },\n requests,\n folders,\n },\n environments: { items: {}, activeName: null, priorityOrder: [] },\n linkedWorkspaces: {},\n linkedOverrides: { requests: {}, environmentVars: {} },\n releases: { self: null, perLink: {} },\n globalAssets: { schemas: {}, graphql: {}, files: {} },\n mockServers: {},\n meta: { createdAt: now, updatedAt: now, appVersion: '1.0.0' },\n },\n local: {\n schemaVersion: 1,\n workspaceId,\n executionPlans: {},\n history: { requestRuns: [], planRuns: [] },\n secretIndex: { entries: {} },\n sessions: { github: { workspace: null, links: {} } },\n connectedRepo: null,\n workingBranch: null,\n seededWorkspaceSha: null,\n retiredBranch: null,\n sync: { lastPulledSnapshot: null, lastPulledSha: null, lastPulledAt: null, dirtyKeys: [] },\n linkedCollections: {},\n attachmentCache: {},\n globalContext: {},\n mockRuntime: { active: {} },\n ui: {\n activeRequestId: sample?.id ?? null,\n sidebarExpandedSections: [],\n themeId: 'one-dark-pro',\n fontId: 'system-sans',\n fontSizePercent: 100,\n },\n settings: { validateOnSend: true, monacoConsumesWheel: false },\n snapshots: { entries: [], maxBytes: 50 * 1024 * 1024 },\n },\n };\n}\n","import type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n createMcpServer,\n FileBackedWorkspaceProvider,\n InProcessMockController,\n} from '@apicircle/mcp-server';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle mcp` — boot the MCP stdio server against a workspace directory.\n// Mirrors `@apicircle/mcp-server`'s `bin/mcp-server.ts` but with friendlier\n// CLI ergonomics (default workspace = cwd, friendly error messages, etc).\n// =============================================================================\n\ninterface McpOptions {\n workspaceName?: string;\n workspacePath?: string;\n}\n\nexport function registerMcpCommand(program: Command): void {\n program\n .command('mcp')\n .description('Run the API Circle MCP server (stdio transport)')\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .action(async (opts: McpOptions) => {\n let dir: string;\n let label: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n dir = resolved.dir;\n label = resolved.fromRegistry ? `${resolved.name ?? resolved.id} (${dir})` : dir;\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n process.stderr.write(`${kleur.red('error')}: ${err.message}\\n`);\n process.exit(2);\n }\n throw err;\n }\n // Touch the workspace so subsequent reads don't fail. Errors here\n // surface to stderr and exit non-zero — the AI client wouldn't be\n // able to use a half-initialised workspace anyway.\n try {\n await ensureWorkspace(dir);\n } catch (err) {\n process.stderr.write(\n `${kleur.red('failed to initialise workspace')} at ${dir}: ${\n err instanceof Error ? err.message : String(err)\n }\\n`,\n );\n process.exit(1);\n }\n\n const workspace = new FileBackedWorkspaceProvider(dir);\n const mock = new InProcessMockController();\n const host = createMcpServer({ workspace, mock });\n process.stderr.write(`${kleur.green('apicircle-mcp')} ready · workspace=${label}\\n`);\n await host.connect();\n });\n}\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport { applyMutation, parseApicircleFolderExport } from '@apicircle/core';\nimport { saveToFile } from '@apicircle/core/workspace/file-backed';\nimport {\n parseInsomniaToEndpoints,\n parseOpenApiToEndpoints,\n parsePostmanToEndpoints,\n} from '@apicircle/mock-server-core';\nimport { generateId, type Request as ApiRequest } from '@apicircle/shared';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle import <type> <spec>` — read an external spec, persist one\n// request per operation into `<workspace>/workspace.synced.json`.\n// =============================================================================\n\ntype ImportType = 'curl' | 'openapi' | 'postman' | 'insomnia' | 'apicircle';\n\ninterface ImportOptions {\n workspaceName?: string;\n workspacePath?: string;\n format?: 'json' | 'yaml';\n}\n\nexport function registerImportCommand(program: Command): void {\n program\n .command('import')\n .description('Import a spec into a workspace folder')\n .argument(\n '<type>',\n 'Source type: openapi | postman | insomnia | curl | apicircle (the apicircle.folder/v1 envelope produced by `apicircle export folder`)',\n )\n .argument('<input>', 'Path to a spec file, or `-` to read from stdin')\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .option('-f, --format <format>', 'OpenAPI format: json | yaml', 'json')\n .action(async (type: ImportType, input: string, opts: ImportOptions) => {\n let dir: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n dir = resolved.dir;\n if (resolved.fromRegistry) {\n process.stderr.write(\n `${kleur.dim('workspace')}: ${kleur.cyan(resolved.name ?? resolved.id ?? '')} ${kleur.dim(`(${dir})`)}\\n`,\n );\n }\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n process.stderr.write(`${kleur.red('error')}: ${err.message}\\n`);\n process.exit(2);\n }\n throw err;\n }\n const raw = await readInput(input);\n const state = await ensureWorkspace(dir);\n let nextSynced = state.synced;\n let nextLocal = state.local;\n const created: string[] = [];\n\n const append = (req: ApiRequest) => {\n const out = applyMutation(\n { synced: nextSynced, local: nextLocal },\n { kind: 'request.create', request: req },\n );\n nextSynced = out.next.synced;\n nextLocal = out.next.local;\n created.push(req.id);\n };\n\n if (type === 'curl') {\n const { parseCurl } = await import('@apicircle/core');\n const parsed = parseCurl(raw);\n append(\n blankRequest({\n name: `cURL ${parsed.method} ${parsed.url}`.slice(0, 80),\n method: parsed.method,\n url: parsed.url,\n headers: parsed.headers,\n query: parsed.query,\n body: parsed.body,\n auth: parsed.auth,\n }),\n );\n } else if (type === 'openapi') {\n const parsed = await parseOpenApiToEndpoints(raw, opts.format ?? 'json');\n for (const ep of parsed.endpoints) {\n append(\n blankRequest({\n name: ep.example ?? `${ep.method} ${ep.pathPattern}`,\n method: ep.method,\n url: ep.pathPattern,\n }),\n );\n }\n } else if (type === 'postman') {\n const parsed = parsePostmanToEndpoints(raw);\n for (const ep of parsed.endpoints) {\n append(\n blankRequest({\n name: ep.example ?? `${ep.method} ${ep.pathPattern}`,\n method: ep.method,\n url: ep.pathPattern,\n }),\n );\n }\n } else if (type === 'insomnia') {\n const parsed = parseInsomniaToEndpoints(raw);\n for (const ep of parsed.endpoints) {\n append(\n blankRequest({\n name: ep.example ?? `${ep.method} ${ep.pathPattern}`,\n method: ep.method,\n url: ep.pathPattern,\n }),\n );\n }\n } else if (type === 'apicircle') {\n // API Circle exchange envelope — graft the folder + subtree +\n // dependencies via the same applyMutation patch the UI / MCP use.\n let parsedEnvelope;\n try {\n parsedEnvelope = parseApicircleFolderExport(raw);\n } catch (err) {\n process.stderr.write(\n `${kleur.red('error')}: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n process.exit(2);\n }\n const out = applyMutation(\n { synced: nextSynced, local: nextLocal },\n { kind: 'folder.import_apicircle', parsed: parsedEnvelope, parentFolderId: null },\n );\n nextSynced = out.next.synced;\n nextLocal = out.next.local;\n // `created` only counts requests in the other import branches —\n // mirror that here so the trailing line stays accurate. Folders\n // get reported separately below.\n for (const r of parsedEnvelope.requests) created.push(r.id);\n for (const w of parsedEnvelope.warnings) {\n process.stderr.write(`${kleur.yellow('warning')}: ${w}\\n`);\n }\n await saveToFile(dir, { synced: nextSynced, local: nextLocal });\n process.stdout.write(\n `${kleur.green('imported')} folder \"${parsedEnvelope.rootFolder.name}\" ` +\n `(${parsedEnvelope.subfolders.length + 1} folders, ${parsedEnvelope.requests.length} requests) into ${dir}\\n`,\n );\n if (parsedEnvelope.dependencies.files.length > 0) {\n process.stderr.write(\n `${kleur.yellow('note')}: ${parsedEnvelope.dependencies.files.length} file asset${parsedEnvelope.dependencies.files.length === 1 ? '' : 's'} ` +\n `landed without bytes — re-attach them inside Global Assets → Global Files.\\n`,\n );\n }\n return;\n } else {\n // The four-branch chain above is exhaustive at the type level, so\n // `type` narrows to `never` here. Cast to string for the error\n // message — at runtime this only fires if a caller bypasses the\n // commander enum and passes garbage like `apicircle import xml ...`.\n process.stderr.write(`${kleur.red('error')}: unknown type '${String(type)}'\\n`);\n process.exit(2);\n }\n\n await saveToFile(dir, { synced: nextSynced, local: nextLocal });\n process.stdout.write(\n `${kleur.green('imported')} ${created.length} request${created.length === 1 ? '' : 's'} into ${dir}\\n`,\n );\n });\n}\n\nasync function readInput(p: string): Promise<string> {\n if (p === '-') {\n return new Promise<string>((resolve, reject) => {\n let data = '';\n process.stdin.setEncoding('utf-8');\n // setEncoding('utf-8') causes `chunk` to arrive as a string at runtime,\n // but Node's types still surface it as `string | Buffer`. Coerce to\n // satisfy `restrict-plus-operands` without changing behaviour.\n process.stdin.on('data', (chunk: string | Buffer) => {\n data += typeof chunk === 'string' ? chunk : chunk.toString('utf-8');\n });\n process.stdin.on('end', () => resolve(data));\n process.stdin.on('error', reject);\n });\n }\n return fs.readFile(path.resolve(p), 'utf-8');\n}\n\nfunction blankRequest(\n partial: Partial<ApiRequest> & {\n name: string;\n method: ApiRequest['method'];\n url: string;\n },\n): ApiRequest {\n const now = new Date().toISOString();\n return {\n id: generateId(),\n folderId: null,\n headers: [],\n query: [],\n body: { type: 'none', content: '' },\n auth: { type: 'none' },\n contextVars: [],\n extractions: [],\n assertions: [],\n createdAt: now,\n updatedAt: now,\n ...partial,\n };\n}\n","import { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n collectFolderExport,\n redactFolderExportCredentials,\n serializeFolderExport,\n suggestFolderExportFilename,\n} from '@apicircle/core';\nimport type { Folder } from '@apicircle/shared';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle export folder <name-or-id> [--out file]` — write a single folder's\n// `apicircle.folder/v1` JSON envelope. Suitable for sharing one collection\n// with another teammate or workspace without round-tripping through Git.\n//\n// Auth credentials are REDACTED by default (matches the in-app modal's\n// safe default). Pass `--include-credential <id> [--include-credential ...]`\n// to opt specific fields IN; ids follow the report-side format\n// `<scope>:<ownerId>.<authType>.<field>` — surface them with\n// `apicircle export folder --list-credentials`.\n// =============================================================================\n\ninterface ExportFolderOptions {\n workspaceName?: string;\n workspacePath?: string;\n out?: string;\n includeCredential?: string[];\n listCredentials?: boolean;\n}\n\nexport function registerExportCommand(program: Command): void {\n const exportCmd = program\n .command('export')\n .description('Export workspace entities to portable JSON.');\n\n exportCmd\n .command('folder')\n .description('Export a folder (and its subtree) as an apicircle.folder/v1 JSON envelope.')\n .argument(\n '<folder>',\n 'Folder id, or display name (case-insensitive). Unique within the workspace.',\n )\n .option('-o, --out <path>', 'Write the JSON to this file. Defaults to stdout.')\n .option(\n '--include-credential <id>',\n 'Keep the credential field with this id (repeatable). Use --list-credentials to see ids.',\n (value: string, prev: string[] = []) => [...prev, value],\n [] as string[],\n )\n .option(\n '--list-credentials',\n 'Print the detected credentials + their ids and exit without writing anything.',\n )\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .action(async (folder: string, opts: ExportFolderOptions) => {\n let dir: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n });\n dir = resolved.dir;\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n process.stderr.write(`${kleur.red('error')}: ${err.message}\\n`);\n process.exit(2);\n }\n throw err;\n }\n const state = await ensureWorkspace(dir);\n const folderId = resolveFolderId(state.synced.collections.folders, folder);\n if (!folderId) {\n process.stderr.write(`${kleur.red('error')}: no folder matches \"${folder}\" in ${dir}\\n`);\n process.exit(2);\n }\n const collected = collectFolderExport({ synced: state.synced, folderId });\n if (!collected) {\n // Should not happen — resolveFolderId already proved it exists.\n process.stderr.write(`${kleur.red('error')}: folder \"${folder}\" no longer exists\\n`);\n process.exit(2);\n }\n if (opts.listCredentials) {\n if (collected.report.credentials.length === 0) {\n process.stdout.write('No credential-bearing auth fields detected.\\n');\n return;\n }\n for (const cred of collected.report.credentials) {\n process.stdout.write(`${cred.id}\\t${cred.label}\\t${cred.ownerName}\\n`);\n }\n return;\n }\n const includeIds = new Set<string>(opts.includeCredential ?? []);\n const envelope = redactFolderExportCredentials(collected.envelope, includeIds);\n const json = serializeFolderExport(envelope);\n if (opts.out) {\n const outPath = path.resolve(opts.out);\n await fs.writeFile(outPath, json, 'utf-8');\n process.stderr.write(\n `${kleur.green('exported')} folder \"${collected.report.folderName}\" → ${outPath}\\n`,\n );\n } else {\n process.stdout.write(json);\n process.stdout.write('\\n');\n process.stderr.write(\n `${kleur.green('exported')} folder \"${collected.report.folderName}\" ` +\n `(${collected.report.totalFolderCount} folders, ${collected.report.requestCount} requests, ` +\n `${collected.report.credentials.length - includeIds.size} credentials redacted)\\n`,\n );\n }\n // Surface a suggested filename in the trailing message even when\n // streaming to stdout so consumers piping into a tool have a\n // sensible name to suggest.\n if (!opts.out) {\n process.stderr.write(\n `${kleur.dim('hint')}: save with .apicircle.json, e.g. ${suggestFolderExportFilename(envelope)}\\n`,\n );\n }\n });\n}\n\nfunction resolveFolderId(folders: Record<string, Folder>, query: string): string | null {\n // Direct id match first.\n if (folders[query]) return query;\n // Case-insensitive unique name match — same trimming the editor uses.\n const norm = query.trim().toLowerCase();\n const matches = Object.values(folders).filter((f) => f.name.trim().toLowerCase() === norm);\n if (matches.length === 1) return matches[0].id;\n return null;\n}\n","import * as path from 'node:path';\nimport { promises as fs } from 'node:fs';\nimport type { WorkspaceState } from '@apicircle/core';\n\n// =============================================================================\n// CLI secret provisioning\n//\n// Secret values aren't synced to Git. Workspaces synced from a teammate carry\n// only `secretKeyId` references and a synced labels map (`secretKeys`). The\n// CLI must source the actual values from the runtime environment.\n//\n// Resolution order (later sources override earlier ones):\n// 1. `--secrets <file>.json` — `{ \"<id>\": \"<value>\" }`\n// 2. `APICIRCLE_SECRET_<id>=value` — env vars (prefix configurable)\n//\n// Resolved values feed `buildScope` as the `secrets` layer so `{{NAME}}`\n// references in environment variables (with `secretKeyId`) get expanded\n// at send time. Missing required ids surface as a single-block error before\n// any HTTP request goes out.\n// =============================================================================\n\nexport interface SecretRequirement {\n /** secretKeyId referenced by an env-variable in the workspace. */\n id: string;\n /** Best-known label (from `synced.secretKeys[id].label`) for display. */\n label: string;\n /** Where in the workspace the id is referenced (env name + var key). */\n references: Array<{ envName: string; varKey: string }>;\n}\n\nconst DEFAULT_PREFIX = 'APICIRCLE_SECRET_';\n\nexport interface BuildSecretsOptions {\n secretsFile?: string;\n envPrefix?: string;\n env?: NodeJS.ProcessEnv;\n}\n\nexport interface BuildSecretsResult {\n /** id → plaintext value, ready for buildScope. */\n byId: Record<string, string>;\n}\n\nexport async function buildSecretsFromCli(\n options: BuildSecretsOptions = {},\n): Promise<BuildSecretsResult> {\n const env = options.env ?? process.env;\n const prefix = options.envPrefix ?? DEFAULT_PREFIX;\n const byId: Record<string, string> = {};\n\n if (options.secretsFile) {\n const resolved = path.resolve(options.secretsFile);\n const raw = await fs.readFile(resolved, 'utf8');\n const parsed: unknown = JSON.parse(raw);\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n throw new Error(\n `--secrets ${options.secretsFile}: expected an object mapping secretKeyId → value`,\n );\n }\n for (const [id, value] of Object.entries(parsed as Record<string, unknown>)) {\n if (typeof value !== 'string') {\n throw new Error(`--secrets ${options.secretsFile}: value for \"${id}\" must be a string`);\n }\n byId[id] = value;\n }\n }\n\n for (const [name, value] of Object.entries(env)) {\n if (!name.startsWith(prefix) || typeof value !== 'string') continue;\n const id = name.slice(prefix.length);\n if (id) byId[id] = value;\n }\n\n return { byId };\n}\n\n/**\n * Walk a workspace and collect every `secretKeyId` referenced by an env\n * variable. Used to validate that the CLI received values for every\n * required id before executing a request.\n */\nexport function collectSecretRequirements(workspace: WorkspaceState): SecretRequirement[] {\n const labels = workspace.synced.secretKeys ?? {};\n const refs = new Map<string, SecretRequirement>();\n for (const [envName, env] of Object.entries(workspace.synced.environments.items)) {\n for (const v of env.variables) {\n if (!v.encrypted || !v.secretKeyId) continue;\n const id = v.secretKeyId;\n const requirement = refs.get(id) ?? {\n id,\n label: labels[id]?.label ?? `(unlabelled ${id.slice(0, 6)}…)`,\n references: [],\n };\n requirement.references.push({ envName, varKey: v.key });\n refs.set(id, requirement);\n }\n }\n return [...refs.values()];\n}\n\n/**\n * Format a missing-secrets error for the CLI. Returns a multi-line string\n * suitable for stderr; callers exit with code 2.\n */\nexport function formatMissingSecretsError(missing: SecretRequirement[]): string {\n const lines = ['Missing secret values for the following keys:'];\n for (const req of missing) {\n const refs = req.references.map((r) => `env \"${r.envName}\" var \"${r.varKey}\"`).join('; ');\n lines.push(` - id \"${req.id}\" (label \"${req.label}\") — referenced by ${refs}`);\n }\n lines.push('');\n lines.push(\n 'Provide values via APICIRCLE_SECRET_<id>=<value> environment variables or --secrets <file>.json.',\n );\n return lines.join('\\n');\n}\n\n/**\n * Convenience: assert every required secret has a value. Throws a CLI-formatted\n * error when anything is missing, otherwise returns the resolved id→value map.\n */\nexport async function resolveSecretsForWorkspace(\n workspace: WorkspaceState,\n options: BuildSecretsOptions = {},\n): Promise<Record<string, string>> {\n const { byId } = await buildSecretsFromCli(options);\n const missing = collectSecretRequirements(workspace).filter((r) => !(r.id in byId));\n if (missing.length > 0) {\n const err = new Error(formatMissingSecretsError(missing));\n (err as Error & { code?: string }).code = 'APICIRCLE_MISSING_SECRETS';\n throw err;\n }\n return byId;\n}\n","import { createHash } from 'node:crypto';\nimport { promises as fs } from 'node:fs';\nimport * as path from 'node:path';\nimport {\n collectAttachmentSlots,\n type AttachmentResolver,\n type WorkspaceState,\n} from '@apicircle/core';\nimport type {\n ExecutionPlan,\n LocalAttachmentCacheEntry,\n RequestBody,\n WorkspaceSynced,\n} from '@apicircle/shared';\n\nexport interface AttachmentPreparationSummary {\n total: number;\n downloaded: number;\n alreadyPresent: number;\n failed: number;\n cacheDir: string;\n entries: Array<{\n slotId: string;\n filename: string;\n localPath: string;\n source: 'workspace' | 'linked-workspace';\n linkedWorkspaceId?: string;\n requiredBy: Array<{ requestId: string; requestName: string }>;\n }>;\n}\n\nexport interface PreparedExecutionAttachments {\n state: WorkspaceState;\n resolveAttachment: AttachmentResolver;\n summary: AttachmentPreparationSummary;\n}\n\ninterface AttachmentRequirement {\n slotId: string;\n sha256?: string;\n filename?: string;\n mimeType?: string;\n size?: number;\n source: 'workspace' | 'linked-workspace';\n linkedWorkspaceId?: string;\n repoFullName?: string;\n branch?: string;\n publicRepo?: boolean;\n requiredBy: Array<{ requestId: string; requestName: string }>;\n}\n\nconst ATTACHMENTS_DIR = path.join('.apicircle', 'attachments');\n\nexport async function prepareExecutionAttachments(\n workspaceDir: string,\n state: WorkspaceState,\n plan?: ExecutionPlan,\n): Promise<PreparedExecutionAttachments> {\n const cacheDir = path.resolve(workspaceDir, ATTACHMENTS_DIR);\n const requirements = collectExecutionAttachmentRequirements(state, plan);\n await fs.mkdir(cacheDir, { recursive: true });\n\n let downloaded = 0;\n let alreadyPresent = 0;\n let failed = 0;\n const cache: Record<string, LocalAttachmentCacheEntry> = {\n ...(state.local.attachmentCache ?? {}),\n };\n const entries: AttachmentPreparationSummary['entries'] = [];\n\n for (const requirement of requirements) {\n const localPath = path.join(cacheDir, encodeURIComponent(requirement.slotId));\n const present = await hasExpectedFile(localPath, requirement.sha256);\n if (present) {\n alreadyPresent++;\n } else {\n try {\n const bytes = await downloadAttachment(requirement);\n if (!bytes) {\n throw new Error(\n `Attachment ${attachmentLabel(requirement)} was not found in ${sourceLabel(requirement)}.`,\n );\n }\n if (requirement.sha256 && sha256Hex(bytes) !== requirement.sha256) {\n throw new Error(\n `Attachment ${attachmentLabel(requirement)} failed checksum verification.`,\n );\n }\n await fs.writeFile(localPath, bytes, { mode: 0o600 });\n downloaded++;\n } catch (err) {\n failed++;\n throw new Error(\n `Attachment ${attachmentLabel(requirement)} is required by ${requiredByLabel(\n requirement,\n )} but could not be downloaded from ${sourceLabel(requirement)}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n }\n\n cache[requirement.slotId] = {\n slotId: requirement.slotId,\n filename: requirement.filename ?? requirement.slotId,\n mimeType: requirement.mimeType ?? 'application/octet-stream',\n size: requirement.size ?? (await fileSize(localPath)),\n sha256: requirement.sha256,\n localPath,\n storage: 'filesystem',\n source: requirement.source,\n ...(requirement.linkedWorkspaceId\n ? { linkedWorkspaceId: requirement.linkedWorkspaceId }\n : {}),\n requiredBy: requirement.requiredBy,\n downloadedAt: new Date().toISOString(),\n };\n entries.push({\n slotId: requirement.slotId,\n filename: requirement.filename ?? requirement.slotId,\n localPath,\n source: requirement.source,\n ...(requirement.linkedWorkspaceId\n ? { linkedWorkspaceId: requirement.linkedWorkspaceId }\n : {}),\n requiredBy: requirement.requiredBy,\n });\n }\n\n const nextState: WorkspaceState = {\n ...state,\n local: {\n ...state.local,\n attachmentCache: cache,\n },\n };\n\n return {\n state: nextState,\n resolveAttachment: createFileAttachmentResolver(nextState),\n summary: {\n total: requirements.length,\n downloaded,\n alreadyPresent,\n failed,\n cacheDir,\n entries,\n },\n };\n}\n\nfunction createFileAttachmentResolver(state: WorkspaceState): AttachmentResolver {\n return async (slotId) => {\n const meta = state.local.attachmentCache?.[slotId];\n if (!meta) return null;\n const bytes = await fs.readFile(meta.localPath);\n const view = new Uint8Array(bytes);\n const body = view.buffer.slice(view.byteOffset, view.byteOffset + view.byteLength);\n return {\n blob: new Blob([body], { type: meta.mimeType }),\n filename: meta.filename,\n };\n };\n}\n\nfunction collectExecutionAttachmentRequirements(\n state: WorkspaceState,\n plan?: ExecutionPlan,\n): AttachmentRequirement[] {\n const seen = new Map<string, AttachmentRequirement>();\n const localRequestFilter = requestFilterForPlan(plan, null);\n const localCollections = localRequestFilter\n ? {\n ...state.synced.collections,\n requests: Object.fromEntries(\n Object.entries(state.synced.collections.requests).filter(([id]) =>\n localRequestFilter.has(id),\n ),\n ),\n }\n : state.synced.collections;\n const workspaceSlots = collectAttachmentSlots({ ...state.synced, collections: localCollections });\n for (const slot of workspaceSlots) {\n const requiredBy = collectRequiredBy(localCollections.requests, slot.slotId);\n if (requiredBy.length === 0) continue;\n addRequirement(seen, {\n ...slot,\n source: 'workspace',\n repoFullName: state.local.connectedRepo?.fullName ?? undefined,\n branch: state.local.workingBranch?.name ?? undefined,\n publicRepo: state.local.connectedRepo ? !state.local.connectedRepo.isPrivate : false,\n requiredBy,\n });\n }\n\n for (const [linkedWorkspaceId, snapshot] of Object.entries(state.local.linkedCollections)) {\n const link = state.synced.linkedWorkspaces[linkedWorkspaceId];\n if (!link) continue;\n const linkedRequestFilter = requestFilterForPlan(plan, linkedWorkspaceId);\n if (plan && linkedRequestFilter && linkedRequestFilter.size === 0) continue;\n const linkedCollections = linkedRequestFilter\n ? {\n ...snapshot.collections,\n requests: Object.fromEntries(\n Object.entries(snapshot.collections.requests).filter(([id]) =>\n linkedRequestFilter.has(id),\n ),\n ),\n }\n : snapshot.collections;\n const linkedSynced: WorkspaceSynced = {\n ...state.synced,\n collections: linkedCollections,\n environments: snapshot.environments,\n globalAssets: snapshot.globalAssets ?? state.synced.globalAssets,\n };\n for (const slot of collectAttachmentSlots(linkedSynced)) {\n const requiredBy = collectRequiredBy(linkedCollections.requests, slot.slotId);\n if (requiredBy.length === 0) continue;\n addRequirement(seen, {\n ...slot,\n source: 'linked-workspace',\n linkedWorkspaceId,\n repoFullName: link.source.repoFullName,\n branch: link.source.branch,\n publicRepo: link.kind === 'public',\n requiredBy,\n });\n }\n }\n\n return [...seen.values()];\n}\n\nfunction requestFilterForPlan(\n plan: ExecutionPlan | undefined,\n linkedWorkspaceId: string | null,\n): Set<string> | null {\n if (!plan) return null;\n const ids = new Set<string>();\n for (const step of plan.steps) {\n if (step.enabled === false) continue;\n if ((step.linkedWorkspaceId ?? null) === linkedWorkspaceId) ids.add(step.requestId);\n }\n return ids;\n}\n\nfunction addRequirement(\n seen: Map<string, AttachmentRequirement>,\n requirement: AttachmentRequirement,\n): void {\n const existing = seen.get(requirement.slotId);\n if (!existing) {\n seen.set(requirement.slotId, requirement);\n return;\n }\n for (const usage of requirement.requiredBy) {\n if (!existing.requiredBy.some((item) => item.requestId === usage.requestId)) {\n existing.requiredBy.push(usage);\n }\n }\n}\n\nfunction collectRequiredBy(\n requests: WorkspaceSynced['collections']['requests'],\n slotId: string,\n): Array<{ requestId: string; requestName: string }> {\n const requiredBy: Array<{ requestId: string; requestName: string }> = [];\n for (const request of Object.values(requests)) {\n if (bodyReferencesSlot(request.body, slotId)) {\n requiredBy.push({ requestId: request.id, requestName: request.name });\n }\n }\n return requiredBy;\n}\n\nfunction bodyReferencesSlot(body: RequestBody, slotId: string): boolean {\n if (body.type === 'binary') return body.attachment?.slotId === slotId;\n if (body.type !== 'form-data') return false;\n return (body.formRows ?? []).some((row) => row.kind === 'file' && row.slotId === slotId);\n}\n\nasync function hasExpectedFile(localPath: string, sha256?: string): Promise<boolean> {\n try {\n const bytes = await fs.readFile(localPath);\n if (!sha256) return true;\n return sha256Hex(bytes) === sha256;\n } catch {\n return false;\n }\n}\n\nasync function fileSize(localPath: string): Promise<number> {\n try {\n return (await fs.stat(localPath)).size;\n } catch {\n return 0;\n }\n}\n\nasync function downloadAttachment(requirement: AttachmentRequirement): Promise<Uint8Array | null> {\n if (!requirement.repoFullName || !requirement.branch) return null;\n const [owner, repo] = requirement.repoFullName.split('/', 2);\n if (!owner || !repo) return null;\n const token = resolveGitHubToken(requirement);\n if (!token && !requirement.publicRepo) {\n throw new Error(\n 'private linked attachments need a GitHub token (set APICIRCLE_GITHUB_TOKEN or GITHUB_TOKEN)',\n );\n }\n\n const apiPath = ['.apicircle', 'attachments', requirement.slotId]\n .map(encodeURIComponent)\n .join('/');\n const url = `https://api.github.com/repos/${encodeURIComponent(owner)}/${encodeURIComponent(\n repo,\n )}/contents/${apiPath}?ref=${encodeURIComponent(requirement.branch)}`;\n const headers: Record<string, string> = {\n Accept: 'application/vnd.github+json',\n 'User-Agent': 'apicircle-cli',\n 'X-GitHub-Api-Version': '2022-11-28',\n };\n if (token) headers.Authorization = `Bearer ${token}`;\n\n const res = await fetch(url, { headers, cache: 'no-store' });\n if (res.status === 404) return null;\n if (!res.ok) {\n throw new Error(`GitHub returned ${res.status}: ${await res.text()}`);\n }\n const json = (await res.json()) as { type?: string; content?: string; encoding?: string };\n if (json.type !== 'file' || typeof json.content !== 'string') {\n throw new Error('GitHub response was not a file');\n }\n if (json.encoding !== 'base64') {\n throw new Error(`GitHub response used unsupported encoding ${json.encoding ?? '(missing)'}`);\n }\n return new Uint8Array(Buffer.from(json.content.replace(/\\n/g, ''), 'base64'));\n}\n\nfunction resolveGitHubToken(requirement: AttachmentRequirement): string {\n if (requirement.source === 'linked-workspace') {\n return (\n process.env.APICIRCLE_E2E_BOT_PAT_LINK_DEDICATED ??\n process.env.APICIRCLE_GITHUB_TOKEN ??\n process.env.GITHUB_TOKEN ??\n process.env.APICIRCLE_E2E_GITHUB_PAT ??\n process.env.APICIRCLE_E2E_BOT_PAT ??\n ''\n );\n }\n return (\n process.env.APICIRCLE_GITHUB_TOKEN ??\n process.env.GITHUB_TOKEN ??\n process.env.APICIRCLE_E2E_GITHUB_PAT ??\n process.env.APICIRCLE_E2E_BOT_PAT ??\n ''\n );\n}\n\nfunction sha256Hex(bytes: Uint8Array): string {\n return createHash('sha256').update(bytes).digest('hex');\n}\n\nfunction attachmentLabel(requirement: AttachmentRequirement): string {\n return `${requirement.filename ?? requirement.slotId} (${requirement.slotId})`;\n}\n\nfunction sourceLabel(requirement: AttachmentRequirement): string {\n const repo = requirement.repoFullName ?? 'local workspace';\n const branch = requirement.branch ? `@${requirement.branch}` : '';\n return `${repo}${branch}`;\n}\n\nfunction requiredByLabel(requirement: AttachmentRequirement): string {\n return requirement.requiredBy.map((item) => item.requestName).join(', ') || 'a request';\n}\n","import * as os from 'node:os';\nimport type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n ANONYMOUS_ACTOR,\n PlanRunDeniedError,\n resolvePlanRef,\n runPlan,\n type PlanRunAuthorizationContext,\n type PlanStepResult,\n type RunActor,\n type RunPlanResult,\n} from '@apicircle/core';\nimport { loadFromFile, saveToFile } from '@apicircle/core/workspace/file-backed';\nimport type { ExecutionPlan, WorkspaceLocal } from '@apicircle/shared';\nimport { buildSecretsFromCli } from '../util/secrets';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\nimport {\n prepareExecutionAttachments,\n type AttachmentPreparationSummary,\n type PreparedExecutionAttachments,\n} from '../util/executionAttachments';\n\n// =============================================================================\n// `apicircle run <plan>` — execute a saved execution plan headlessly and print\n// a pass/fail report. Sits alongside `apicircle mock` and `apicircle mcp` as\n// the third runtime entry point. Drives the runtime-agnostic engine in\n// `@apicircle/core` (`runPlan`), so the CLI owns only argument parsing,\n// workspace IO, runner-identity resolution, and report formatting.\n//\n// Exit codes:\n// 0 every executed step passed\n// 1 the plan ran but a step failed (or the run was aborted)\n// 2 usage error — no workspace, unknown plan, bad option\n// 3 the run was denied by the authorization gate\n// =============================================================================\n\nconst REPORTERS = ['text', 'json', 'junit'] as const;\ntype Reporter = (typeof REPORTERS)[number];\n\ninterface RunOptions {\n workspaceName?: string;\n workspacePath?: string;\n /** Commander sets this `false` when `--no-assertions` is passed. */\n assertions?: boolean;\n secrets?: string;\n /** Commander sets this `false` when `--no-save` is passed. */\n save?: boolean;\n reporter?: string;\n bail?: boolean;\n env?: string;\n as?: string;\n}\n\nexport function registerRunCommand(program: Command): void {\n program\n .command('run')\n .description('Run a saved execution plan from a workspace and report the result')\n .argument('<plan>', 'Plan name or id to run')\n .option(\n '--workspace-name <name-or-id>',\n 'Registry workspace name (case-insensitive) or id. Defaults to the active workspace.',\n )\n .option(\n '-w, --workspace-path <dir>',\n 'Filesystem directory containing workspace.synced.json (skips the registry).',\n )\n .option('--no-assertions', 'Run requests without evaluating their assertions')\n .option('-s, --secrets <file>', 'JSON file mapping secretKeyId → plaintext value')\n .option('--no-save', 'Do not write the plan run to workspace history')\n .option('--reporter <format>', 'Report format: text | json | junit', 'text')\n .option('--bail', 'Stop the run at the first failed step')\n .option('-e, --env <name>', 'Layer a local environment on top of the run')\n .option('--as <actor>', 'Override the recorded runner identity')\n .action(async (planRef: string, opts: RunOptions) => {\n let dir: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n dir = resolved.dir;\n if (resolved.fromRegistry) {\n process.stderr.write(\n `${kleur.dim('workspace')}: ${kleur.cyan(resolved.name ?? resolved.id ?? '')} ${kleur.dim(`(${dir})`)}\\n`,\n );\n }\n } catch (err) {\n if (err instanceof WorkspaceResolutionError) {\n fail(err.message);\n return;\n }\n throw err;\n }\n\n const reporter = opts.reporter ?? 'text';\n if (!isReporter(reporter)) {\n fail(`unknown --reporter \"${reporter}\" (expected: ${REPORTERS.join(', ')})`);\n return;\n }\n\n const state = await loadFromFile(dir, { allowMissing: true });\n if (!state) {\n fail(`no workspace found at ${dir} (expected workspace.synced.json)`);\n return;\n }\n\n const ref = resolvePlanRef(state.synced, planRef);\n if (!ref.ok) {\n fail(ref.error);\n if (ref.available.length > 0) {\n process.stderr.write(`Available plans: ${ref.available.join(', ')}\\n`);\n }\n return;\n }\n\n if (opts.env && !state.synced.environments.items[opts.env]) {\n const names = Object.keys(state.synced.environments.items);\n fail(`no environment named \"${opts.env}\" in this workspace`);\n if (names.length > 0) {\n process.stderr.write(`Available environments: ${names.join(', ')}\\n`);\n }\n return;\n }\n\n let secretsById: Record<string, string>;\n try {\n secretsById = (await buildSecretsFromCli({ secretsFile: opts.secrets })).byId;\n } catch (err) {\n fail(err instanceof Error ? err.message : String(err));\n return;\n }\n\n const actor = resolveActor(state.local, opts.as);\n const withAssertions = opts.assertions !== false;\n const text = reporter === 'text';\n\n // Ctrl+C aborts gracefully between steps (and the in-flight request)\n // rather than killing the process — the partial run is still reported.\n const controller = new AbortController();\n const onSigint = (): void => controller.abort(new Error('aborted by SIGINT'));\n process.on('SIGINT', onSigint);\n\n if (text) process.stdout.write(formatHeader(ref.plan, actor, withAssertions, opts));\n\n let prepared: PreparedExecutionAttachments;\n try {\n prepared = await prepareExecutionAttachments(dir, state, ref.plan);\n } catch (err) {\n process.off('SIGINT', onSigint);\n fail(err instanceof Error ? err.message : String(err), 1, 'attachment');\n return;\n }\n if (text && prepared.summary.total > 0) {\n process.stdout.write(formatAttachmentPreparation(prepared.summary));\n }\n\n let result: RunPlanResult;\n try {\n result = await runPlan(prepared.state, ref.id, {\n withAssertions,\n bail: opts.bail === true,\n env: opts.env,\n secretsById,\n actor,\n signal: controller.signal,\n resolveAttachment: prepared.resolveAttachment,\n authorize: checkRunPermission,\n onStep: text ? (step) => process.stdout.write(formatStepLine(step)) : undefined,\n });\n } catch (err) {\n process.off('SIGINT', onSigint);\n if (err instanceof PlanRunDeniedError) {\n fail(err.message, 3, 'denied');\n return;\n }\n throw err;\n }\n process.off('SIGINT', onSigint);\n\n const aborted = controller.signal.aborted;\n const saved = opts.save !== false;\n if (saved) await saveToFile(dir, result.nextState);\n\n if (reporter === 'json') {\n process.stdout.write(\n JSON.stringify(\n buildJsonReport(dir, ref.id, ref.plan, actor, result, saved, aborted, prepared.summary),\n null,\n 2,\n ) + '\\n',\n );\n } else if (reporter === 'junit') {\n process.stdout.write(buildJunitReport(ref.plan, result));\n } else {\n process.stdout.write(formatSummary(result, saved, aborted));\n }\n\n // An aborted run is never a pass, even if the steps that ran all passed.\n process.exitCode = result.passed && !aborted ? 0 : 1;\n });\n}\n\nfunction isReporter(value: string): value is Reporter {\n return (REPORTERS as readonly string[]).includes(value);\n}\n\n/**\n * Best-effort identity of whoever launched the run. Precedence: an explicit\n * `--as` override, then the workspace's GitHub session login, then the OS\n * username. Recorded for display and handed to {@link checkRunPermission}.\n */\nexport function resolveActor(local: WorkspaceLocal, override?: string): RunActor {\n const explicit = override?.trim();\n if (explicit) return { kind: 'unknown', name: explicit };\n\n const login = local.sessions.github.workspace?.accountLogin;\n if (login) return { kind: 'github', name: login };\n\n try {\n const username = os.userInfo().username;\n if (username) return { kind: 'os', name: username };\n } catch {\n // os.userInfo() throws when the uid has no passwd entry (some containers).\n }\n return ANONYMOUS_ACTOR;\n}\n\n/**\n * Authorization gate for `apicircle run`. Today every actor may run every\n * plan — this is intentionally permissive. When per-user run restrictions\n * land, enforce them here: inspect `ctx.actor` + `ctx.plan` and throw a\n * `PlanRunDeniedError` to block the run before any HTTP request fires. It is\n * wired into `runPlan` via the `authorize` option, so a denial is caught and\n * reported with exit code 3.\n */\nfunction checkRunPermission(_ctx: PlanRunAuthorizationContext): void {\n // FUTURE: per-user run authorization. Throw PlanRunDeniedError to deny.\n}\n\n// ---------------------------------------------------------------------------\n// reporting\n// ---------------------------------------------------------------------------\n\nfunction formatHeader(\n plan: ExecutionPlan,\n actor: RunActor,\n withAssertions: boolean,\n opts: RunOptions,\n): string {\n const enabled = plan.steps.filter((s) => s.enabled !== false).length;\n const flags = [\n withAssertions ? 'assertions on' : 'assertions off',\n opts.bail ? 'bail' : null,\n opts.env ? `env=${opts.env}` : null,\n ].filter((f): f is string => f !== null);\n return (\n `${kleur.bold('Plan')} ${plan.name} ${kleur.dim(\n `(${enabled}/${plan.steps.length} steps · ${flags.join(' · ')})`,\n )}\\n` + `${kleur.dim('Run by')} ${actor.name} ${kleur.dim(`(${actor.kind})`)}\\n\\n`\n );\n}\n\nfunction formatAttachmentPreparation(summary: AttachmentPreparationSummary): string {\n const status = `${summary.downloaded} downloaded, ${summary.alreadyPresent} already local`;\n const lines = [\n `${kleur.bold('Attachments')} ${summary.total} required ${kleur.dim(\n `(${status} - ${summary.cacheDir})`,\n )}`,\n ];\n for (const entry of summary.entries) {\n const source =\n entry.source === 'linked-workspace'\n ? `linked:${entry.linkedWorkspaceId ?? 'unknown'}`\n : 'workspace';\n const requiredBy = entry.requiredBy.map((item) => item.requestName).join(', ');\n lines.push(\n ` ${kleur.dim('file')} ${entry.filename} ${kleur.dim(\n `${source} - ${requiredBy} - ${entry.localPath}`,\n )}`,\n );\n }\n return `${lines.join('\\n')}\\n\\n`;\n}\n\nexport function formatStepLine(step: PlanStepResult): string {\n const n = `${step.stepIndex + 1}.`.padEnd(3);\n const method = (step.requestMethod || '—').padEnd(7);\n\n if (step.skipped) {\n return ` ${kleur.dim('–')} ${kleur.dim(n)} ${kleur.dim(method)} ${kleur.dim(\n `${step.requestName} skipped`,\n )}\\n`;\n }\n\n const mark = step.passed ? kleur.green('✓') : kleur.red('✗');\n const status = step.result?.status != null ? String(step.result.status) : '—';\n const duration = step.result ? `${step.result.durationMs}ms` : '';\n const name = step.requestName.padEnd(28);\n\n let line = ` ${mark} ${n} ${method} ${name} ${status.padEnd(4)} ${kleur.dim(duration)}`;\n\n if (step.assertionResults.length > 0) {\n const passed = step.assertionResults.filter((a) => a.passed).length;\n line += ` ${kleur.dim(`${passed}/${step.assertionResults.length} assertions`)}`;\n }\n line += '\\n';\n\n if (step.error) {\n line += ` ${kleur.red(step.error)}\\n`;\n }\n for (const a of step.assertionResults) {\n if (!a.passed) line += ` ${kleur.red('✗')} ${a.detail ?? `${a.kind} ${a.op}`}\\n`;\n }\n if (step.missingVariables.length > 0) {\n line += ` ${kleur.yellow('⚠')} unresolved: ${step.missingVariables\n .map((v) => `{{${v}}}`)\n .join(', ')}\\n`;\n }\n return line;\n}\n\nfunction tally(result: RunPlanResult): { passed: number; failed: number; skipped: number } {\n let passed = 0;\n let failed = 0;\n let skipped = 0;\n for (const s of result.steps) {\n if (s.skipped) skipped++;\n else if (s.passed) passed++;\n else failed++;\n }\n return { passed, failed, skipped };\n}\n\nfunction formatSummary(result: RunPlanResult, saved: boolean, aborted: boolean): string {\n if (result.steps.length === 0) {\n return `\\n${kleur.yellow('Plan has no steps.')}\\n`;\n }\n const { passed, failed, skipped } = tally(result);\n const parts = [\n kleur.green(`${passed} passed`),\n failed > 0 ? kleur.red(`${failed} failed`) : kleur.dim(`${failed} failed`),\n kleur.dim(`${skipped} skipped`),\n ];\n const verdict = result.passed && !aborted ? kleur.green('PASS') : kleur.red('FAIL');\n let out = `\\n${verdict} ${parts.join(kleur.dim(' · '))} ${kleur.dim(\n `· ${result.planRun.durationMs}ms`,\n )}\\n`;\n if (aborted) out += `${kleur.yellow('Run aborted before every step finished.')}\\n`;\n out += saved\n ? kleur.dim('Plan run saved to workspace history.\\n')\n : kleur.dim('Plan run not saved (--no-save).\\n');\n return out;\n}\n\nfunction buildJsonReport(\n workspace: string,\n planId: string,\n plan: ExecutionPlan,\n actor: RunActor,\n result: RunPlanResult,\n saved: boolean,\n aborted: boolean,\n attachments: AttachmentPreparationSummary,\n): unknown {\n return {\n workspace,\n plan: { id: planId, name: plan.name },\n actor,\n withAssertions: result.planRun.withAssertions,\n passed: result.passed && !aborted,\n aborted,\n durationMs: result.planRun.durationMs,\n saved,\n attachments,\n counts: tally(result),\n steps: result.steps.map((s) => ({\n step: s.stepIndex + 1,\n request: s.requestName,\n method: s.requestMethod,\n skipped: s.skipped,\n status: s.result?.status ?? null,\n ok: s.result?.ok ?? false,\n durationMs: s.result?.durationMs ?? 0,\n passed: s.passed,\n error: s.error ?? null,\n missingVariables: s.missingVariables,\n assertions: s.assertionResults.map((a) => ({\n kind: a.kind,\n op: a.op,\n target: a.target,\n expected: a.expected,\n passed: a.passed,\n detail: a.detail,\n })),\n })),\n };\n}\n\nfunction xmlEscape(value: string): string {\n return value\n .replace(/&/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;')\n .replace(/\"/g, '&quot;');\n}\n\n/** JUnit XML — consumable by CI dashboards as a plan-run review gate. */\nexport function buildJunitReport(plan: ExecutionPlan, result: RunPlanResult): string {\n const { failed, skipped } = tally(result);\n const total = result.steps.length;\n const suite = xmlEscape(plan.name);\n const suiteTime = (result.planRun.durationMs / 1000).toFixed(3);\n\n const cases = result.steps.map((s) => {\n const name = xmlEscape(`${s.stepIndex + 1}. ${s.requestName}`);\n const time = ((s.result?.durationMs ?? 0) / 1000).toFixed(3);\n const open = ` <testcase name=\"${name}\" classname=\"${suite}\" time=\"${time}\"`;\n if (s.skipped) return `${open}>\\n <skipped/>\\n </testcase>`;\n if (s.passed) return `${open}/>`;\n\n const reasons: string[] = [];\n if (s.error) reasons.push(s.error);\n for (const a of s.assertionResults) {\n if (!a.passed) reasons.push(a.detail ?? `assertion ${a.kind} ${a.op} failed`);\n }\n if (s.result && !s.result.ok && s.result.status != null) {\n reasons.push(`HTTP ${s.result.status}`);\n }\n const detail = xmlEscape(reasons.join('\\n') || 'step failed');\n const summary = detail.split('\\n')[0];\n return `${open}>\\n <failure message=\"${summary}\">${detail}</failure>\\n </testcase>`;\n });\n\n return (\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>\\n' +\n `<testsuites name=\"${suite}\" tests=\"${total}\" failures=\"${failed}\" skipped=\"${skipped}\" time=\"${suiteTime}\">\\n` +\n ` <testsuite name=\"${suite}\" tests=\"${total}\" failures=\"${failed}\" skipped=\"${skipped}\" time=\"${suiteTime}\">\\n` +\n `${cases.join('\\n')}\\n` +\n ' </testsuite>\\n' +\n '</testsuites>\\n'\n );\n}\n\n/** Write a CLI error to stderr and set the exit code. `kind` colours the prefix. */\nfunction fail(message: string, code = 2, kind = 'error'): void {\n process.stderr.write(`${kleur.red(kind)}: ${message}\\n`);\n process.exitCode = code;\n}\n","import type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n createWorkspaceOnDisk,\n defaultWorkspacesRoot,\n listWorkspacesOnDisk,\n saveRegistryToDisk,\n} from '../util/resolveWorkspace';\nimport { findWorkspaceEntry, setActiveWorkspace } from '@apicircle/core/workspace/registry';\n\n// =============================================================================\n// `apicircle workspaces <list | create | use | path>` — manage the\n// multi-workspace registry from the terminal. Every other command\n// (`import`, `mcp`, `run`) resolves `--workspace-name` or `--workspace-path` against this\n// registry, so this is the CLI surface for seeing, creating, and switching\n// between the workspaces the desktop app + AI clients share.\n// =============================================================================\n\ninterface WorkspacesOptions {\n json?: boolean;\n}\n\nexport function registerWorkspacesCommand(program: Command): void {\n const ws = program\n .command('workspaces')\n .description('List, create, or switch the active workspace');\n\n ws.command('list')\n .description('List every workspace registered on this machine')\n .option('--json', 'Emit JSON instead of a formatted table')\n .action(async (opts: WorkspacesOptions) => {\n const { registry, root } = await listWorkspacesOnDisk();\n if (opts.json) {\n process.stdout.write(JSON.stringify({ root, registry }, null, 2) + '\\n');\n return;\n }\n if (registry.workspaces.length === 0) {\n process.stdout.write(\n `${kleur.dim('No workspaces registered yet at')} ${root}\\n` +\n `${kleur.dim('Run')} ${kleur.cyan('apicircle workspaces create <name>')} ${kleur.dim(\n 'or open the desktop app to seed one.',\n )}\\n`,\n );\n return;\n }\n process.stdout.write(`${kleur.dim('registry')}: ${root}\\n\\n`);\n // Sort by lastOpenedAt desc so the most recent shows first.\n const rows = [...registry.workspaces].sort((a, b) =>\n b.lastOpenedAt.localeCompare(a.lastOpenedAt),\n );\n const nameWidth = Math.max(4, ...rows.map((r) => r.name.length));\n const idWidth = Math.max(2, ...rows.map((r) => r.id.length));\n process.stdout.write(\n kleur.bold(\n ` ${''.padEnd(1)} ${'NAME'.padEnd(nameWidth)} ${'ID'.padEnd(idWidth)} LAST OPENED\\n`,\n ),\n );\n for (const w of rows) {\n const mark = w.id === registry.activeWorkspaceId ? kleur.green('●') : ' ';\n process.stdout.write(\n ` ${mark} ${w.name.padEnd(nameWidth)} ${kleur.dim(\n w.id.padEnd(idWidth),\n )} ${kleur.dim(w.lastOpenedAt)}\\n`,\n );\n }\n process.stdout.write(`\\n${kleur.dim('● = active')}\\n`);\n });\n\n ws.command('create')\n .description('Create a new workspace and add it to the registry')\n .argument('<name>', 'Human-readable label for the workspace')\n .option('--sample', 'Seed the workspace with one sample request', false)\n .action(async (name: string, opts: { sample?: boolean }) => {\n try {\n const { entry, dir, registry } = await createWorkspaceOnDisk({\n name,\n sampleRequest: opts.sample ?? false,\n });\n process.stdout.write(\n `${kleur.green('created')} workspace ${kleur.cyan(entry.name)} ${kleur.dim(`(${entry.id})`)}\\n` +\n ` at ${dir}\\n`,\n );\n if (registry.activeWorkspaceId === entry.id) {\n process.stdout.write(`${kleur.dim('marked as active')}\\n`);\n }\n } catch (err) {\n process.stderr.write(\n `${kleur.red('error')}: ${err instanceof Error ? err.message : String(err)}\\n`,\n );\n process.exit(2);\n }\n });\n\n ws.command('use')\n .description('Set the active workspace by id or name')\n .argument('<selector>', 'Workspace id or name')\n .action(async (selector: string) => {\n const { registry, root } = await listWorkspacesOnDisk();\n const entry = findWorkspaceEntry(registry, selector);\n if (!entry) {\n process.stderr.write(\n `${kleur.red('error')}: no workspace named \"${selector}\" in the registry at ${root}.\\n` +\n `${kleur.dim('Run')} ${kleur.cyan('apicircle workspaces list')} ${kleur.dim('to see what is available.')}\\n`,\n );\n process.exit(2);\n return;\n }\n const next = await setActiveWorkspace(root, entry.id);\n void next; // saveRegistry inside setActiveWorkspace already persisted it\n process.stdout.write(\n `${kleur.green('active')} workspace is now ${kleur.cyan(entry.name)} ${kleur.dim(`(${entry.id})`)}\\n`,\n );\n });\n\n ws.command('path')\n .description('Print the on-disk path for a workspace (or the workspaces root)')\n .argument('[selector]', 'Optional workspace id or name; prints the root when omitted')\n .action(async (selector?: string) => {\n if (!selector) {\n process.stdout.write(defaultWorkspacesRoot() + '\\n');\n return;\n }\n const { registry, root } = await listWorkspacesOnDisk();\n const entry = findWorkspaceEntry(registry, selector);\n if (!entry) {\n process.stderr.write(\n `${kleur.red('error')}: no workspace named \"${selector}\" in the registry at ${root}.\\n`,\n );\n process.exit(2);\n return;\n }\n // workspaceDirFor would re-import; the simplest computation is just root + id.\n // We use `saveRegistryToDisk` only to assert the import wiring is alive.\n void saveRegistryToDisk;\n const { workspaceDirFor } = await import('@apicircle/core/workspace/registry');\n process.stdout.write(workspaceDirFor(root, entry.id) + '\\n');\n });\n}\n","import { Command } from 'commander';\nimport { registerMockCommand } from './commands/mock';\nimport { registerMcpCommand } from './commands/mcp';\nimport { registerImportCommand } from './commands/import';\nimport { registerExportCommand } from './commands/export';\nimport { registerRunCommand } from './commands/run';\nimport { registerWorkspacesCommand } from './commands/workspaces';\nimport { CLI_PACKAGE_VERSION } from './packageVersion';\n\n// =============================================================================\n// `apicircle` — root CLI binary. Sub-commands live under ./commands.\n//\n// Designed for two audiences:\n// • Power users who want a no-Electron way to run mocks, drive the MCP\n// stdio server, or execute saved plans against a workspace folder.\n// • CI / automation that imports specs into a workspace.json checked into\n// git, or runs an execution plan as a review gate.\n// =============================================================================\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name('apicircle')\n .description('Command-line companion to API Circle Studio.')\n .version(CLI_PACKAGE_VERSION);\n\n registerMockCommand(program);\n registerMcpCommand(program);\n registerImportCommand(program);\n registerExportCommand(program);\n registerRunCommand(program);\n registerWorkspacesCommand(program);\n\n return program;\n}\n\nexport async function runCli(argv: readonly string[] = process.argv): Promise<void> {\n await buildProgram().parseAsync(argv);\n}\n\n// Run when this file is executed as a script. tsup wraps the CJS output\n// with a node shebang so this branch is what handles `apicircle <args>`.\n// We deliberately do *not* check require.main — works in both CJS and ESM.\n// `.ts` is also accepted so the E2E suite can run the source under tsx\n// without going through the dist bundle.\nconst entry = process.argv[1] ?? '';\nif (entry.endsWith('apicircle') || entry.endsWith('index.cjs') || entry.endsWith('index.ts')) {\n void runCli();\n}\n","import { CLI_PACKAGE_VERSION } from '../packageVersion';\nimport { formatRootHelp, hasRootHelpFlag, hasRootVersionFlag } from './args';\n\nexport async function runBin(argv: readonly string[] = process.argv): Promise<void> {\n const args = argv.slice(2);\n if (hasRootVersionFlag(args)) {\n process.stdout.write(`${CLI_PACKAGE_VERSION}\\n`);\n return;\n }\n if (hasRootHelpFlag(args)) {\n process.stdout.write(formatRootHelp());\n return;\n }\n\n const { runCli } = await import('../index');\n await runCli(argv);\n}\n\nconst entry = process.argv[1] ?? '';\nif (entry.endsWith('apicircle') || entry.endsWith('cli.cjs') || entry.endsWith('cli.ts')) {\n void runBin();\n}\n","export function hasRootVersionFlag(args: readonly string[]): boolean {\n return args.length === 1 && ['--version', '-v', '-V'].includes(args[0] ?? '');\n}\n\nexport function hasRootHelpFlag(args: readonly string[]): boolean {\n return args.length === 1 && ['--help', '-h', 'help'].includes(args[0] ?? '');\n}\n\nexport function formatRootHelp(): string {\n return `Usage: apicircle [options] [command]\n\nCommand-line companion to API Circle Studio.\n\nOptions:\n -v, -V, --version Print the version number.\n -h, --help Show help.\n\nCommands:\n mock [options] <workspace> Start a local mock server.\n mcp [options] [workspace] Start the MCP stdio server.\n import <source> <workspace> Import OpenAPI, Postman, Insomnia, or curl.\n run [options] <plan-id> Run an execution plan.\n workspaces Manage local workspace registries.\n\nRun \"apicircle <command> --help\" for command-specific help.\n`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA,MACE,MAAQ;AAAA,MACR,SAAW;AAAA,MACX,SAAW;AAAA,MACX,MAAQ;AAAA,MACR,aAAe;AAAA,MACf,UAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,SAAW;AAAA,MACX,YAAc;AAAA,QACZ,MAAQ;AAAA,QACR,KAAO;AAAA,QACP,WAAa;AAAA,MACf;AAAA,MACA,UAAY;AAAA,MACZ,MAAQ;AAAA,MACR,SAAW;AAAA,QACT,MAAQ;AAAA,MACV;AAAA,MACA,MAAQ;AAAA,MACR,OAAS;AAAA,MACT,KAAO;AAAA,QACL,WAAa;AAAA,MACf;AAAA,MACA,SAAW;AAAA,QACT,KAAK;AAAA,MACP;AAAA,MACA,OAAS;AAAA,QACP;AAAA,MACF;AAAA,MACA,eAAiB;AAAA,QACf,MAAQ;AAAA,QACR,QAAU;AAAA,QACV,OAAS;AAAA,QACT,SAAW;AAAA,UACT,KAAK;AAAA,YACH,QAAU;AAAA,cACR,OAAS;AAAA,cACT,SAAW;AAAA,YACb;AAAA,YACA,SAAW;AAAA,cACT,OAAS;AAAA,cACT,SAAW;AAAA,YACb;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,SAAW;AAAA,QACT,OAAS;AAAA,QACT,OAAS;AAAA,QACT,MAAQ;AAAA,QACR,OAAS;AAAA,MACX;AAAA,MACA,cAAgB;AAAA,QACd,mBAAmB;AAAA,QACnB,yBAAyB;AAAA,QACzB,+BAA+B;AAAA,QAC/B,qBAAqB;AAAA,QACrB,WAAa;AAAA,QACb,OAAS;AAAA,MACX;AAAA,MACA,iBAAmB;AAAA,QACjB,eAAe;AAAA,QACf,MAAQ;AAAA,QACR,YAAc;AAAA,QACd,QAAU;AAAA,MACZ;AAAA,IACF;AAAA;AAAA;;;ACnFO,SAAS,qBAA6B;AAC3C,QAAM,UAAW,gBAAsC;AACvD,MAAI,OAAO,YAAY,YAAY,QAAQ,WAAW,GAAG;AACvD,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACjE;AACA,SAAO;AACT;AARA,IAUa;AAVb;AAAA;AAAA;AAAA;AAUO,IAAM,sBAAsB,mBAAmB;AAAA;AAAA;;;ACe/C,SAAS,oBAAoB,SAAwB;AAC1D,UACG,QAAQ,MAAM,EACd,YAAY,6DAA6D,EACzE,SAAS,UAAU,uBAAuB,EAC1C,OAAO,uBAAuB,4CAA4C,EAC1E,OAAO,qBAAqB,oBAAoB,WAAW,EAC3D,OAAO,qBAAqB,oDAAoD,MAAM,EACtF,OAAO,yBAAyB,sCAAsC,MAAM,EAC5E,OAAO,UAAU,0BAA0B,IAAI,EAC/C,OAAO,OAAO,MAAc,SAAsB;AACjD,UAAM,WAAgB,aAAQ,IAAI;AAClC,UAAM,MAAM,MAAM,eAAAA,SAAG,SAAS,UAAU,OAAO;AAC/C,UAAM,OAAO,UAAU,UAAU,KAAK,QAAQ,MAAM;AACpD,UAAM,SAAS,SAAS,YAAY,YAAY,UAAU,KAAK,UAAU,MAAM,IAAI;AAEnF,UAAM,SAAS,WAAW,MAAM,QAAQ,GAAG;AAC3C,UAAM,SAAS,UAAM,gDAAuB,MAAM;AAClD,UAAM,OAAmB;AAAA,MACvB,QAAI,0BAAW;AAAA,MACf,MAAW,cAAS,QAAQ;AAAA,MAC5B;AAAA,MACA,WAAW,OAAO;AAAA,MAClB,aAAa,KAAK,OAAO,OAAO,KAAK,IAAI,IAAI;AAAA,MAC7C,MAAM,EAAE,SAAS,KAAK,SAAS,OAAO,SAAS,CAAC,GAAG,EAAE;AAAA,MACrD,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,MAClC,YAAW,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC;AAEA,UAAM,SAAS,UAAM,yCAAgB,MAAM;AAAA,MACzC,MAAM,KAAK,OAAO,OAAO,KAAK,IAAI,IAAI;AAAA,MACtC,MAAM,KAAK;AAAA,IACb,CAAC;AACD,YAAQ,OAAO;AAAA,MACb,GAAG,aAAAC,QAAM,MAAM,aAAa,CAAC,iBAAiB,aAAAA,QAAM,KAAK,UAAU,KAAK,IAAI,IAAI,OAAO,IAAI,EAAE,CAAC,SACpF,OAAO,UAAU,MAAM,oBAAoB,IAAI;AAAA;AAAA,IAC3D;AACA,QAAI,OAAO,SAAS,QAAQ;AAC1B,iBAAW,KAAK,OAAO,UAAU;AAC/B,gBAAQ,OAAO,MAAM,GAAG,aAAAA,QAAM,OAAO,MAAM,CAAC,KAAK,CAAC;AAAA,CAAI;AAAA,MACxD;AAAA,IACF;AACA,oBAAgB,MAAM;AAAA,EACxB,CAAC;AACL;AAEO,SAAS,UACd,UACA,MACoC;AACpC,MAAI,QAAQ,SAAS,OAAQ,QAAO;AACpC,QAAM,QAAQ,SAAS,YAAY;AACnC,MAAI,MAAM,SAAS,SAAS,EAAG,QAAO;AACtC,MAAI,MAAM,SAAS,UAAU,EAAG,QAAO;AACvC,SAAO;AACT;AAEO,SAAS,YACd,UACA,MACiB;AACjB,MAAI,QAAQ,SAAS,OAAQ,QAAO;AACpC,QAAM,QAAQ,SAAS,YAAY;AACnC,SAAO,MAAM,SAAS,OAAO,KAAK,MAAM,SAAS,MAAM,IAAI,SAAS;AACtE;AAEO,SAAS,WACd,MACA,QACA,KACsB;AACtB,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,MAAM,WAAW,MAAM,KAAK,OAAO;AAAA,IAC9C,KAAK;AACH,aAAO,EAAE,MAAM,WAAW,YAAY,IAAI;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,MAAM,YAAY,QAAQ,IAAI;AAAA,EAC3C;AACF;AAEA,SAAS,gBAAgB,QAAgC;AACvD,MAAI,UAAU;AACd,QAAM,WAAW,YAAY;AAC3B,QAAI,QAAS;AACb,cAAU;AACV,UAAM,OAAO,MAAM;AACnB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,UAAQ,GAAG,UAAU,MAAM,KAAK,SAAS,CAAC;AAC1C,UAAQ,GAAG,WAAW,MAAM,KAAK,SAAS,CAAC;AAC7C;AApHA,oBACA,MAEA,cACA,yBAKA;AATA;AAAA;AAAA;AAAA,qBAA+B;AAC/B,WAAsB;AAEtB,mBAAkB;AAClB,8BAIO;AACP,oBAA4C;AAAA;AAAA;;;ACG5C,eAAsB,gBAAgB,KAAsC;AAC1E,QAAM,WAAgB,cAAQ,GAAG;AACjC,QAAM,gBAAAC,SAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAM,WAAW,UAAM,iCAAa,UAAU,EAAE,cAAc,KAAK,CAAC;AACpE,MAAI,SAAU,QAAO;AAErB,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,QAAM,kBAAc,2BAAW;AAC/B,QAAM,QAAwB;AAAA,IAC5B,QAAQ;AAAA,MACN,eAAe;AAAA,MACf;AAAA,MACA,aAAa;AAAA,QACX,MAAM,EAAE,QAAI,2BAAW,GAAG,MAAM,QAAQ,UAAU,CAAC,EAAE;AAAA,QACrD,UAAU,CAAC;AAAA,QACX,SAAS,CAAC;AAAA,MACZ;AAAA,MACA,cAAc,EAAE,OAAO,CAAC,GAAG,YAAY,MAAM,eAAe,CAAC,EAAE;AAAA,MAC/D,kBAAkB,CAAC;AAAA,MACnB,iBAAiB,EAAE,UAAU,CAAC,GAAG,iBAAiB,CAAC,EAAE;AAAA,MACrD,UAAU,EAAE,MAAM,MAAM,SAAS,CAAC,EAAE;AAAA,MACpC,cAAc,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,MACpD,aAAa,CAAC;AAAA,MACd,MAAM,EAAE,WAAW,KAAK,WAAW,KAAK,YAAY,QAAQ;AAAA,IAC9D;AAAA,IACA,OAAO;AAAA,MACL,eAAe;AAAA,MACf;AAAA,MACA,gBAAgB,CAAC;AAAA,MACjB,SAAS,EAAE,aAAa,CAAC,GAAG,UAAU,CAAC,EAAE;AAAA,MACzC,aAAa,EAAE,SAAS,CAAC,EAAE;AAAA,MAC3B,UAAU,EAAE,QAAQ,EAAE,WAAW,MAAM,OAAO,CAAC,EAAE,EAAE;AAAA,MACnD,eAAe;AAAA,MACf,eAAe;AAAA,MACf,oBAAoB;AAAA,MACpB,eAAe;AAAA,MACf,MAAM,EAAE,oBAAoB,MAAM,eAAe,MAAM,cAAc,MAAM,WAAW,CAAC,EAAE;AAAA,MACzF,mBAAmB,CAAC;AAAA,MACpB,iBAAiB,CAAC;AAAA,MAClB,eAAe,CAAC;AAAA,MAChB,aAAa,EAAE,QAAQ,CAAC,EAAE;AAAA,MAC1B,IAAI;AAAA,QACF,iBAAiB;AAAA,QACjB,yBAAyB,CAAC;AAAA,QAC1B,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,iBAAiB;AAAA,MACnB;AAAA,MACA,UAAU,EAAE,gBAAgB,MAAM,qBAAqB,MAAM;AAAA,MAC7D,WAAW,EAAE,SAAS,CAAC,GAAG,UAAU,KAAK,OAAO,KAAK;AAAA,IACvD;AAAA,EACF;AACA,YAAM,+BAAW,UAAU,KAAK;AAChC,SAAO;AACT;AAlEA,IAAAC,OACAC,iBACA,oBAEAC;AAJA;AAAA;AAAA;AAAA,IAAAF,QAAsB;AACtB,IAAAC,kBAA+B;AAC/B,yBAAyC;AAEzC,IAAAC,iBAAsD;AAAA;AAAA;;;AC4E/C,SAAS,wBAAgC;AAC9C,QAAM,WAAW,QAAQ,IAAI;AAC7B,MAAI,YAAY,SAAS,SAAS,EAAG,QAAY,cAAQ,QAAQ;AACjE,SAAY,WAAK,oBAAoB,GAAG,kBAAkB;AAC5D;AAMA,SAAS,sBAA8B;AAIrC,QAAM,OAAU,WAAQ;AACxB,UAAQ,QAAQ,UAAU;AAAA,IACxB,KAAK,SAAS;AACZ,YAAM,UAAU,QAAQ,IAAI,WAAgB,WAAK,MAAM,WAAW,SAAS;AAC3E,aAAY,WAAK,SAAS,UAAU,UAAU;AAAA,IAChD;AAAA,IACA,KAAK;AACH,aAAY,WAAK,MAAM,WAAW,uBAAuB,UAAU,UAAU;AAAA,IAC/E;AACE,aAAY;AAAA,QACV,QAAQ,IAAI,mBAAwB,WAAK,MAAM,SAAS;AAAA,QACxD;AAAA,QACA;AAAA,MACF;AAAA,EACJ;AACF;AAoBA,eAAsB,iBAAiB,OAAuB,CAAC,GAA+B;AAC5F,QAAM,OAAO,KAAK,kBAAkB,sBAAsB;AAC1D,QAAM,eAAe,KAAK,MAAM,KAAK;AACrC,QAAM,eAAe,KAAK,MAAM,KAAK;AACrC,QAAM,eAAe,KAAK,gBAAgB;AAE1C,MAAI,gBAAgB,cAAc;AAChC,UAAM,IAAI;AAAA,MACR;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,cAAc;AAChB,UAAM,WAAW,YAAY,YAAY;AACzC,UAAM,MAAW,cAAQ,QAAQ;AACjC,QAAI,gBAAgB,CAAE,MAAM,UAAU,GAAG,GAAI;AAC3C,YAAM,IAAI,yBAAyB,kCAAkC,GAAG,IAAI,cAAc;AAAA,IAC5F;AACA,WAAO,EAAE,KAAK,IAAI,MAAM,MAAM,MAAM,cAAc,OAAO,cAAc,KAAK;AAAA,EAC9E;AAEA,QAAM,WAAW,UAAM,8BAAa,IAAI;AAExC,MAAI,cAAc;AAChB,QAAI,CAAC,UAAU;AACb,YAAM,IAAI;AAAA,QACR,mCAAmC,IAAI;AAAA,QAEvC;AAAA,MACF;AAAA,IACF;AACA,UAAMC,aAAQ,oCAAmB,UAAU,YAAY;AACvD,QAAI,CAACA,QAAO;AACV,YAAM,IAAI;AAAA,QACR,uBAAuB,YAAY,wBAAwB,IAAI;AAAA,QAE/D;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAK,iCAAgB,MAAMA,OAAM,EAAE;AAAA,MACnC,IAAIA,OAAM;AAAA,MACV,MAAMA,OAAM;AAAA,MACZ,cAAc;AAAA,MACd,cAAc;AAAA,IAChB;AAAA,EACF;AAGA,MAAI,YAAY,SAAS,mBAAmB;AAC1C,UAAM,SAAS,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,OAAO,SAAS,iBAAiB;AAClF,QAAI,QAAQ;AACV,aAAO;AAAA,QACL,SAAK,iCAAgB,MAAM,OAAO,EAAE;AAAA,QACpC,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,KAAU,cAAQ,QAAQ,IAAI,CAAC;AAAA,IAC/B,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,cAAc;AAAA,IACd,cAAc;AAAA,EAChB;AACF;AAQA,eAAsB,sBAAsB,MASzC;AACD,QAAM,OAAO,KAAK,kBAAkB,sBAAsB;AAC1D,QAAM,UAAU,KAAK,KAAK,KAAK;AAC/B,MAAI,CAAC,QAAS,OAAM,IAAI,MAAM,4BAA4B;AAC1D,QAAM,WAAW,UAAM,8BAAa,IAAI;AACxC,MAAI,YAAY,SAAS,WAAW,KAAK,CAAC,MAAM,EAAE,KAAK,YAAY,MAAM,QAAQ,YAAY,CAAC,GAAG;AAC/F,UAAM,IAAI,MAAM,sBAAsB,OAAO,kBAAkB;AAAA,EACjE;AACA,QAAM,kBAAc,2BAAW;AAC/B,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,QAAM,QAAQ,gBAAgB,aAAa,KAAK,KAAK,iBAAiB,KAAK;AAC3E,QAAM,UAAM,iCAAgB,MAAM,WAAW;AAC7C,YAAM,gCAAW,KAAK,KAAK;AAC3B,QAAMA,SAAgC;AAAA,IACpC,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,WAAW;AAAA,IACX,cAAc;AAAA,EAChB;AACA,QAAM,WAAW,UAAM,mCAAkB,MAAMA,MAAK;AACpD,SAAO,EAAE,UAAU,OAAAA,QAAO,OAAO,IAAI;AACvC;AAOA,eAAsB,qBACpB,OAEI,CAAC,GACmD;AACxD,QAAM,OAAO,KAAK,kBAAkB,sBAAsB;AAC1D,QAAM,WAAY,UAAM,8BAAa,IAAI,KAAM;AAAA,IAC7C,eAAe;AAAA,IACf,mBAAmB;AAAA,IACnB,YAAY,CAAC;AAAA,EACf;AACA,SAAO,EAAE,UAAU,KAAK;AAC1B;AAOA,eAAsB,mBACpB,UACA,gBACe;AACf,YAAM,8BAAa,kBAAkB,sBAAsB,GAAG,QAAQ;AACxE;AAiBA,SAAS,YAAY,OAAuB;AAC1C,MAAI,UAAU,IAAK,QAAU,WAAQ;AACrC,MAAI,MAAM,WAAW,IAAI,KAAK,MAAM,WAAW,KAAK,GAAG;AACrD,WAAY,WAAQ,WAAQ,GAAG,MAAM,MAAM,CAAC,CAAC;AAAA,EAC/C;AACA,SAAO;AACT;AAEA,eAAe,UAAU,GAA6B;AACpD,MAAI;AACF,UAAM,KAAK,MAAM,gBAAAC,SAAG,KAAK,CAAC;AAC1B,WAAO,GAAG,YAAY;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,aAAqB,KAAa,YAAqC;AAC9F,QAAM,SAA4B,aAC9B;AAAA,IACE,QAAI,2BAAW;AAAA,IACf,MAAM;AAAA,IACN,UAAU;AAAA,IACV,QAAQ;AAAA,IACR,KAAK;AAAA,IACL,SAAS,CAAC,EAAE,KAAK,UAAU,OAAO,oBAAoB,SAAS,KAAK,CAAC;AAAA,IACrE,OAAO,CAAC;AAAA,IACR,MAAM,EAAE,MAAM,QAAQ,SAAS,GAAG;AAAA,IAClC,MAAM,EAAE,MAAM,UAAU;AAAA,IACxB,aAAa,CAAC;AAAA,IACd,aAAa,CAAC;AAAA,IACd,YAAY,CAAC;AAAA,IACb,WAAW;AAAA,IACX,WAAW;AAAA,EACb,IACA;AACJ,QAAM,UAAkC,CAAC;AACzC,QAAM,WAAuC,SAAS,EAAE,CAAC,OAAO,EAAE,GAAG,OAAO,IAAI,CAAC;AACjF,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,eAAe;AAAA,MACf;AAAA,MACA,aAAa;AAAA,QACX,MAAM;AAAA,UACJ,QAAI,2BAAW;AAAA,UACf,MAAM;AAAA,UACN,UAAU,SAAS,CAAC,EAAE,MAAM,WAAW,IAAI,OAAO,GAAG,CAAC,IAAI,CAAC;AAAA,QAC7D;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,cAAc,EAAE,OAAO,CAAC,GAAG,YAAY,MAAM,eAAe,CAAC,EAAE;AAAA,MAC/D,kBAAkB,CAAC;AAAA,MACnB,iBAAiB,EAAE,UAAU,CAAC,GAAG,iBAAiB,CAAC,EAAE;AAAA,MACrD,UAAU,EAAE,MAAM,MAAM,SAAS,CAAC,EAAE;AAAA,MACpC,cAAc,EAAE,SAAS,CAAC,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,MACpD,aAAa,CAAC;AAAA,MACd,MAAM,EAAE,WAAW,KAAK,WAAW,KAAK,YAAY,QAAQ;AAAA,IAC9D;AAAA,IACA,OAAO;AAAA,MACL,eAAe;AAAA,MACf;AAAA,MACA,gBAAgB,CAAC;AAAA,MACjB,SAAS,EAAE,aAAa,CAAC,GAAG,UAAU,CAAC,EAAE;AAAA,MACzC,aAAa,EAAE,SAAS,CAAC,EAAE;AAAA,MAC3B,UAAU,EAAE,QAAQ,EAAE,WAAW,MAAM,OAAO,CAAC,EAAE,EAAE;AAAA,MACnD,eAAe;AAAA,MACf,eAAe;AAAA,MACf,oBAAoB;AAAA,MACpB,eAAe;AAAA,MACf,MAAM,EAAE,oBAAoB,MAAM,eAAe,MAAM,cAAc,MAAM,WAAW,CAAC,EAAE;AAAA,MACzF,mBAAmB,CAAC;AAAA,MACpB,iBAAiB,CAAC;AAAA,MAClB,eAAe,CAAC;AAAA,MAChB,aAAa,EAAE,QAAQ,CAAC,EAAE;AAAA,MAC1B,IAAI;AAAA,QACF,iBAAiB,QAAQ,MAAM;AAAA,QAC/B,yBAAyB,CAAC;AAAA,QAC1B,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,iBAAiB;AAAA,MACnB;AAAA,MACA,UAAU,EAAE,gBAAgB,MAAM,qBAAqB,MAAM;AAAA,MAC7D,WAAW,EAAE,SAAS,CAAC,GAAG,UAAU,KAAK,OAAO,KAAK;AAAA,IACvD;AAAA,EACF;AACF;AArXA,QACAC,OACAC,iBACA,iBASAC,qBACAC,gBA+BM,UACA,YACA,oBAoOO;AAlRb;AAAA;AAAA;AAAA,SAAoB;AACpB,IAAAH,QAAsB;AACtB,IAAAC,kBAA+B;AAC/B,sBAQO;AACP,IAAAC,sBAA2B;AAC3B,IAAAC,iBAAoE;AA+BpE,IAAM,WAAW;AACjB,IAAM,aAAa;AACnB,IAAM,qBAAqB;AAoOpB,IAAM,2BAAN,cAAuC,MAAM;AAAA,MACzC;AAAA,MACT,YAAY,SAAiB,MAA+B;AAC1D,cAAM,OAAO;AACb,aAAK,OAAO;AACZ,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;ACpQO,SAAS,mBAAmB,SAAwB;AACzD,UACG,QAAQ,KAAK,EACb,YAAY,iDAAiD,EAC7D;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,OAAO,SAAqB;AAClC,QAAI;AACJ,QAAI;AACJ,QAAI;AACF,YAAM,WAAW,MAAM,iBAAiB;AAAA,QACtC,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,YAAM,SAAS;AACf,cAAQ,SAAS,eAAe,GAAG,SAAS,QAAQ,SAAS,EAAE,KAAK,GAAG,MAAM;AAAA,IAC/E,SAAS,KAAK;AACZ,UAAI,eAAe,0BAA0B;AAC3C,gBAAQ,OAAO,MAAM,GAAG,cAAAC,QAAM,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO;AAAA,CAAI;AAC9D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM;AAAA,IACR;AAIA,QAAI;AACF,YAAM,gBAAgB,GAAG;AAAA,IAC3B,SAAS,KAAK;AACZ,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAA,QAAM,IAAI,gCAAgC,CAAC,OAAO,GAAG,KACtD,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,YAAY,IAAI,8CAA4B,GAAG;AACrD,UAAM,OAAO,IAAI,0CAAwB;AACzC,UAAM,WAAO,mCAAgB,EAAE,WAAW,KAAK,CAAC;AAChD,YAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,MAAM,eAAe,CAAC,yBAAsB,KAAK;AAAA,CAAI;AACnF,UAAM,KAAK,QAAQ;AAAA,EACrB,CAAC;AACL;AAvEA,IACAC,eACA;AAFA;AAAA;AAAA;AACA,IAAAA,gBAAkB;AAClB,wBAIO;AACP;AACA;AAAA;AAAA;;;ACoBO,SAAS,sBAAsB,SAAwB;AAC5D,UACG,QAAQ,QAAQ,EAChB,YAAY,uCAAuC,EACnD;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,SAAS,WAAW,gDAAgD,EACpE;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,yBAAyB,+BAA+B,MAAM,EACrE,OAAO,OAAO,MAAkB,OAAe,SAAwB;AACtE,QAAI;AACJ,QAAI;AACF,YAAM,WAAW,MAAM,iBAAiB;AAAA,QACtC,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,YAAM,SAAS;AACf,UAAI,SAAS,cAAc;AACzB,gBAAQ,OAAO;AAAA,UACb,GAAG,cAAAC,QAAM,IAAI,WAAW,CAAC,KAAK,cAAAA,QAAM,KAAK,SAAS,QAAQ,SAAS,MAAM,EAAE,CAAC,IAAI,cAAAA,QAAM,IAAI,IAAI,GAAG,GAAG,CAAC;AAAA;AAAA,QACvG;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,0BAA0B;AAC3C,gBAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO;AAAA,CAAI;AAC9D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM;AAAA,IACR;AACA,UAAM,MAAM,MAAM,UAAU,KAAK;AACjC,UAAM,QAAQ,MAAM,gBAAgB,GAAG;AACvC,QAAI,aAAa,MAAM;AACvB,QAAI,YAAY,MAAM;AACtB,UAAM,UAAoB,CAAC;AAE3B,UAAM,SAAS,CAAC,QAAoB;AAClC,YAAM,UAAM;AAAA,QACV,EAAE,QAAQ,YAAY,OAAO,UAAU;AAAA,QACvC,EAAE,MAAM,kBAAkB,SAAS,IAAI;AAAA,MACzC;AACA,mBAAa,IAAI,KAAK;AACtB,kBAAY,IAAI,KAAK;AACrB,cAAQ,KAAK,IAAI,EAAE;AAAA,IACrB;AAEA,QAAI,SAAS,QAAQ;AACnB,YAAM,EAAE,UAAU,IAAI,MAAM,OAAO,iBAAiB;AACpD,YAAM,SAAS,UAAU,GAAG;AAC5B;AAAA,QACE,aAAa;AAAA,UACX,MAAM,QAAQ,OAAO,MAAM,IAAI,OAAO,GAAG,GAAG,MAAM,GAAG,EAAE;AAAA,UACvD,QAAQ,OAAO;AAAA,UACf,KAAK,OAAO;AAAA,UACZ,SAAS,OAAO;AAAA,UAChB,OAAO,OAAO;AAAA,UACd,MAAM,OAAO;AAAA,UACb,MAAM,OAAO;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF,WAAW,SAAS,WAAW;AAC7B,YAAM,SAAS,UAAM,kDAAwB,KAAK,KAAK,UAAU,MAAM;AACvE,iBAAW,MAAM,OAAO,WAAW;AACjC;AAAA,UACE,aAAa;AAAA,YACX,MAAM,GAAG,WAAW,GAAG,GAAG,MAAM,IAAI,GAAG,WAAW;AAAA,YAClD,QAAQ,GAAG;AAAA,YACX,KAAK,GAAG;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,WAAW,SAAS,WAAW;AAC7B,YAAM,aAAS,kDAAwB,GAAG;AAC1C,iBAAW,MAAM,OAAO,WAAW;AACjC;AAAA,UACE,aAAa;AAAA,YACX,MAAM,GAAG,WAAW,GAAG,GAAG,MAAM,IAAI,GAAG,WAAW;AAAA,YAClD,QAAQ,GAAG;AAAA,YACX,KAAK,GAAG;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,WAAW,SAAS,YAAY;AAC9B,YAAM,aAAS,mDAAyB,GAAG;AAC3C,iBAAW,MAAM,OAAO,WAAW;AACjC;AAAA,UACE,aAAa;AAAA,YACX,MAAM,GAAG,WAAW,GAAG,GAAG,MAAM,IAAI,GAAG,WAAW;AAAA,YAClD,QAAQ,GAAG;AAAA,YACX,KAAK,GAAG;AAAA,UACV,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF,WAAW,SAAS,aAAa;AAG/B,UAAI;AACJ,UAAI;AACF,6BAAiB,wCAA2B,GAAG;AAAA,MACjD,SAAS,KAAK;AACZ,gBAAQ,OAAO;AAAA,UACb,GAAG,cAAAA,QAAM,IAAI,OAAO,CAAC,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA;AAAA,QAC5E;AACA,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM,UAAM;AAAA,QACV,EAAE,QAAQ,YAAY,OAAO,UAAU;AAAA,QACvC,EAAE,MAAM,2BAA2B,QAAQ,gBAAgB,gBAAgB,KAAK;AAAA,MAClF;AACA,mBAAa,IAAI,KAAK;AACtB,kBAAY,IAAI,KAAK;AAIrB,iBAAW,KAAK,eAAe,SAAU,SAAQ,KAAK,EAAE,EAAE;AAC1D,iBAAW,KAAK,eAAe,UAAU;AACvC,gBAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,OAAO,SAAS,CAAC,KAAK,CAAC;AAAA,CAAI;AAAA,MAC3D;AACA,gBAAM,gCAAW,KAAK,EAAE,QAAQ,YAAY,OAAO,UAAU,CAAC;AAC9D,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAA,QAAM,MAAM,UAAU,CAAC,YAAY,eAAe,WAAW,IAAI,MAC9D,eAAe,WAAW,SAAS,CAAC,aAAa,eAAe,SAAS,MAAM,mBAAmB,GAAG;AAAA;AAAA,MAC7G;AACA,UAAI,eAAe,aAAa,MAAM,SAAS,GAAG;AAChD,gBAAQ,OAAO;AAAA,UACb,GAAG,cAAAA,QAAM,OAAO,MAAM,CAAC,KAAK,eAAe,aAAa,MAAM,MAAM,cAAc,eAAe,aAAa,MAAM,WAAW,IAAI,KAAK,GAAG;AAAA;AAAA,QAE7I;AAAA,MACF;AACA;AAAA,IACF,OAAO;AAKL,cAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,IAAI,OAAO,CAAC,mBAAmB,OAAO,IAAI,CAAC;AAAA,CAAK;AAC9E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,cAAM,gCAAW,KAAK,EAAE,QAAQ,YAAY,OAAO,UAAU,CAAC;AAC9D,YAAQ,OAAO;AAAA,MACb,GAAG,cAAAA,QAAM,MAAM,UAAU,CAAC,IAAI,QAAQ,MAAM,WAAW,QAAQ,WAAW,IAAI,KAAK,GAAG,SAAS,GAAG;AAAA;AAAA,IACpG;AAAA,EACF,CAAC;AACL;AAEA,eAAe,UAAU,GAA4B;AACnD,MAAI,MAAM,KAAK;AACb,WAAO,IAAI,QAAgB,CAACC,UAAS,WAAW;AAC9C,UAAI,OAAO;AACX,cAAQ,MAAM,YAAY,OAAO;AAIjC,cAAQ,MAAM,GAAG,QAAQ,CAAC,UAA2B;AACnD,gBAAQ,OAAO,UAAU,WAAW,QAAQ,MAAM,SAAS,OAAO;AAAA,MACpE,CAAC;AACD,cAAQ,MAAM,GAAG,OAAO,MAAMA,SAAQ,IAAI,CAAC;AAC3C,cAAQ,MAAM,GAAG,SAAS,MAAM;AAAA,IAClC,CAAC;AAAA,EACH;AACA,SAAO,gBAAAC,SAAG,SAAc,cAAQ,CAAC,GAAG,OAAO;AAC7C;AAEA,SAAS,aACP,SAKY;AACZ,QAAM,OAAM,oBAAI,KAAK,GAAE,YAAY;AACnC,SAAO;AAAA,IACL,QAAI,2BAAW;AAAA,IACf,UAAU;AAAA,IACV,SAAS,CAAC;AAAA,IACV,OAAO,CAAC;AAAA,IACR,MAAM,EAAE,MAAM,QAAQ,SAAS,GAAG;AAAA,IAClC,MAAM,EAAE,MAAM,OAAO;AAAA,IACrB,aAAa,CAAC;AAAA,IACd,aAAa,CAAC;AAAA,IACd,YAAY,CAAC;AAAA,IACb,WAAW;AAAA,IACX,WAAW;AAAA,IACX,GAAG;AAAA,EACL;AACF;AA/NA,IAAAC,iBACAC,OAEAC,eACA,aACAC,qBACAC,0BAKAC;AAXA;AAAA;AAAA;AAAA,IAAAL,kBAA+B;AAC/B,IAAAC,QAAsB;AAEtB,IAAAC,gBAAkB;AAClB,kBAA0D;AAC1D,IAAAC,sBAA2B;AAC3B,IAAAC,2BAIO;AACP,IAAAC,iBAAuD;AACvD;AACA;AAAA;AAAA;;;ACqBO,SAAS,sBAAsB,SAAwB;AAC5D,QAAM,YAAY,QACf,QAAQ,QAAQ,EAChB,YAAY,6CAA6C;AAE5D,YACG,QAAQ,QAAQ,EAChB,YAAY,4EAA4E,EACxF;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,oBAAoB,kDAAkD,EAC7E;AAAA,IACC;AAAA,IACA;AAAA,IACA,CAAC,OAAe,OAAiB,CAAC,MAAM,CAAC,GAAG,MAAM,KAAK;AAAA,IACvD,CAAC;AAAA,EACH,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,OAAO,QAAgB,SAA8B;AAC3D,QAAI;AACJ,QAAI;AACF,YAAM,WAAW,MAAM,iBAAiB;AAAA,QACtC,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,MACb,CAAC;AACD,YAAM,SAAS;AAAA,IACjB,SAAS,KAAK;AACZ,UAAI,eAAe,0BAA0B;AAC3C,gBAAQ,OAAO,MAAM,GAAG,cAAAC,QAAM,IAAI,OAAO,CAAC,KAAK,IAAI,OAAO;AAAA,CAAI;AAC9D,gBAAQ,KAAK,CAAC;AAAA,MAChB;AACA,YAAM;AAAA,IACR;AACA,UAAM,QAAQ,MAAM,gBAAgB,GAAG;AACvC,UAAM,WAAW,gBAAgB,MAAM,OAAO,YAAY,SAAS,MAAM;AACzE,QAAI,CAAC,UAAU;AACb,cAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,IAAI,OAAO,CAAC,wBAAwB,MAAM,QAAQ,GAAG;AAAA,CAAI;AACvF,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,UAAM,gBAAY,kCAAoB,EAAE,QAAQ,MAAM,QAAQ,SAAS,CAAC;AACxE,QAAI,CAAC,WAAW;AAEd,cAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,IAAI,OAAO,CAAC,aAAa,MAAM;AAAA,CAAsB;AACnF,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,QAAI,KAAK,iBAAiB;AACxB,UAAI,UAAU,OAAO,YAAY,WAAW,GAAG;AAC7C,gBAAQ,OAAO,MAAM,+CAA+C;AACpE;AAAA,MACF;AACA,iBAAW,QAAQ,UAAU,OAAO,aAAa;AAC/C,gBAAQ,OAAO,MAAM,GAAG,KAAK,EAAE,IAAK,KAAK,KAAK,IAAK,KAAK,SAAS;AAAA,CAAI;AAAA,MACvE;AACA;AAAA,IACF;AACA,UAAM,aAAa,IAAI,IAAY,KAAK,qBAAqB,CAAC,CAAC;AAC/D,UAAM,eAAW,4CAA8B,UAAU,UAAU,UAAU;AAC7E,UAAM,WAAO,oCAAsB,QAAQ;AAC3C,QAAI,KAAK,KAAK;AACZ,YAAM,UAAe,cAAQ,KAAK,GAAG;AACrC,YAAM,gBAAAC,SAAG,UAAU,SAAS,MAAM,OAAO;AACzC,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAD,QAAM,MAAM,UAAU,CAAC,YAAY,UAAU,OAAO,UAAU,YAAO,OAAO;AAAA;AAAA,MACjF;AAAA,IACF,OAAO;AACL,cAAQ,OAAO,MAAM,IAAI;AACzB,cAAQ,OAAO,MAAM,IAAI;AACzB,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAA,QAAM,MAAM,UAAU,CAAC,YAAY,UAAU,OAAO,UAAU,MAC3D,UAAU,OAAO,gBAAgB,aAAa,UAAU,OAAO,YAAY,cAC5E,UAAU,OAAO,YAAY,SAAS,WAAW,IAAI;AAAA;AAAA,MAC5D;AAAA,IACF;AAIA,QAAI,CAAC,KAAK,KAAK;AACb,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAA,QAAM,IAAI,MAAM,CAAC,yCAAqC,0CAA4B,QAAQ,CAAC;AAAA;AAAA,MAChG;AAAA,IACF;AAAA,EACF,CAAC;AACL;AAEA,SAAS,gBAAgB,SAAiC,OAA8B;AAEtF,MAAI,QAAQ,KAAK,EAAG,QAAO;AAE3B,QAAM,OAAO,MAAM,KAAK,EAAE,YAAY;AACtC,QAAM,UAAU,OAAO,OAAO,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,KAAK,EAAE,YAAY,MAAM,IAAI;AACzF,MAAI,QAAQ,WAAW,EAAG,QAAO,QAAQ,CAAC,EAAE;AAC5C,SAAO;AACT;AA3IA,IAAAE,iBACAC,OAEAC,eACAC;AAJA;AAAA;AAAA;AAAA,IAAAH,kBAA+B;AAC/B,IAAAC,QAAsB;AAEtB,IAAAC,gBAAkB;AAClB,IAAAC,eAKO;AAEP;AACA;AAAA;AAAA;;;AC+BA,eAAsB,oBACpB,UAA+B,CAAC,GACH;AAC7B,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,QAAM,SAAS,QAAQ,aAAa;AACpC,QAAM,OAA+B,CAAC;AAEtC,MAAI,QAAQ,aAAa;AACvB,UAAM,WAAgB,cAAQ,QAAQ,WAAW;AACjD,UAAM,MAAM,MAAM,gBAAAC,SAAG,SAAS,UAAU,MAAM;AAC9C,UAAM,SAAkB,KAAK,MAAM,GAAG;AACtC,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,GAAG;AAClE,YAAM,IAAI;AAAA,QACR,aAAa,QAAQ,WAAW;AAAA,MAClC;AAAA,IACF;AACA,eAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,MAAiC,GAAG;AAC3E,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,IAAI,MAAM,aAAa,QAAQ,WAAW,gBAAgB,EAAE,oBAAoB;AAAA,MACxF;AACA,WAAK,EAAE,IAAI;AAAA,IACb;AAAA,EACF;AAEA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC/C,QAAI,CAAC,KAAK,WAAW,MAAM,KAAK,OAAO,UAAU,SAAU;AAC3D,UAAM,KAAK,KAAK,MAAM,OAAO,MAAM;AACnC,QAAI,GAAI,MAAK,EAAE,IAAI;AAAA,EACrB;AAEA,SAAO,EAAE,KAAK;AAChB;AA1EA,IAAAC,OACAC,iBA6BM;AA9BN;AAAA;AAAA;AAAA,IAAAD,QAAsB;AACtB,IAAAC,kBAA+B;AA6B/B,IAAM,iBAAiB;AAAA;AAAA;;;ACuBvB,eAAsB,4BACpB,cACA,OACA,MACuC;AACvC,QAAM,WAAgB,cAAQ,cAAc,eAAe;AAC3D,QAAM,eAAe,uCAAuC,OAAO,IAAI;AACvE,QAAM,gBAAAC,SAAG,MAAM,UAAU,EAAE,WAAW,KAAK,CAAC;AAE5C,MAAI,aAAa;AACjB,MAAI,iBAAiB;AACrB,MAAI,SAAS;AACb,QAAM,QAAmD;AAAA,IACvD,GAAI,MAAM,MAAM,mBAAmB,CAAC;AAAA,EACtC;AACA,QAAM,UAAmD,CAAC;AAE1D,aAAW,eAAe,cAAc;AACtC,UAAM,YAAiB,WAAK,UAAU,mBAAmB,YAAY,MAAM,CAAC;AAC5E,UAAM,UAAU,MAAM,gBAAgB,WAAW,YAAY,MAAM;AACnE,QAAI,SAAS;AACX;AAAA,IACF,OAAO;AACL,UAAI;AACF,cAAM,QAAQ,MAAM,mBAAmB,WAAW;AAClD,YAAI,CAAC,OAAO;AACV,gBAAM,IAAI;AAAA,YACR,cAAc,gBAAgB,WAAW,CAAC,qBAAqB,YAAY,WAAW,CAAC;AAAA,UACzF;AAAA,QACF;AACA,YAAI,YAAY,UAAU,UAAU,KAAK,MAAM,YAAY,QAAQ;AACjE,gBAAM,IAAI;AAAA,YACR,cAAc,gBAAgB,WAAW,CAAC;AAAA,UAC5C;AAAA,QACF;AACA,cAAM,gBAAAA,SAAG,UAAU,WAAW,OAAO,EAAE,MAAM,IAAM,CAAC;AACpD;AAAA,MACF,SAAS,KAAK;AACZ;AACA,cAAM,IAAI;AAAA,UACR,cAAc,gBAAgB,WAAW,CAAC,mBAAmB;AAAA,YAC3D;AAAA,UACF,CAAC,qCAAqC,YAAY,WAAW,CAAC,KAC5D,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CACjD;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,UAAM,YAAY,MAAM,IAAI;AAAA,MAC1B,QAAQ,YAAY;AAAA,MACpB,UAAU,YAAY,YAAY,YAAY;AAAA,MAC9C,UAAU,YAAY,YAAY;AAAA,MAClC,MAAM,YAAY,QAAS,MAAM,SAAS,SAAS;AAAA,MACnD,QAAQ,YAAY;AAAA,MACpB;AAAA,MACA,SAAS;AAAA,MACT,QAAQ,YAAY;AAAA,MACpB,GAAI,YAAY,oBACZ,EAAE,mBAAmB,YAAY,kBAAkB,IACnD,CAAC;AAAA,MACL,YAAY,YAAY;AAAA,MACxB,eAAc,oBAAI,KAAK,GAAE,YAAY;AAAA,IACvC;AACA,YAAQ,KAAK;AAAA,MACX,QAAQ,YAAY;AAAA,MACpB,UAAU,YAAY,YAAY,YAAY;AAAA,MAC9C;AAAA,MACA,QAAQ,YAAY;AAAA,MACpB,GAAI,YAAY,oBACZ,EAAE,mBAAmB,YAAY,kBAAkB,IACnD,CAAC;AAAA,MACL,YAAY,YAAY;AAAA,IAC1B,CAAC;AAAA,EACH;AAEA,QAAM,YAA4B;AAAA,IAChC,GAAG;AAAA,IACH,OAAO;AAAA,MACL,GAAG,MAAM;AAAA,MACT,iBAAiB;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP,mBAAmB,6BAA6B,SAAS;AAAA,IACzD,SAAS;AAAA,MACP,OAAO,aAAa;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AAEA,SAAS,6BAA6B,OAA2C;AAC/E,SAAO,OAAO,WAAW;AACvB,UAAM,OAAO,MAAM,MAAM,kBAAkB,MAAM;AACjD,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,QAAQ,MAAM,gBAAAA,SAAG,SAAS,KAAK,SAAS;AAC9C,UAAM,OAAO,IAAI,WAAW,KAAK;AACjC,UAAM,OAAO,KAAK,OAAO,MAAM,KAAK,YAAY,KAAK,aAAa,KAAK,UAAU;AACjF,WAAO;AAAA,MACL,MAAM,IAAI,KAAK,CAAC,IAAI,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;AAAA,MAC9C,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AACF;AAEA,SAAS,uCACP,OACA,MACyB;AACzB,QAAM,OAAO,oBAAI,IAAmC;AACpD,QAAM,qBAAqB,qBAAqB,MAAM,IAAI;AAC1D,QAAM,mBAAmB,qBACrB;AAAA,IACE,GAAG,MAAM,OAAO;AAAA,IAChB,UAAU,OAAO;AAAA,MACf,OAAO,QAAQ,MAAM,OAAO,YAAY,QAAQ,EAAE;AAAA,QAAO,CAAC,CAAC,EAAE,MAC3D,mBAAmB,IAAI,EAAE;AAAA,MAC3B;AAAA,IACF;AAAA,EACF,IACA,MAAM,OAAO;AACjB,QAAM,qBAAiB,qCAAuB,EAAE,GAAG,MAAM,QAAQ,aAAa,iBAAiB,CAAC;AAChG,aAAW,QAAQ,gBAAgB;AACjC,UAAM,aAAa,kBAAkB,iBAAiB,UAAU,KAAK,MAAM;AAC3E,QAAI,WAAW,WAAW,EAAG;AAC7B,mBAAe,MAAM;AAAA,MACnB,GAAG;AAAA,MACH,QAAQ;AAAA,MACR,cAAc,MAAM,MAAM,eAAe,YAAY;AAAA,MACrD,QAAQ,MAAM,MAAM,eAAe,QAAQ;AAAA,MAC3C,YAAY,MAAM,MAAM,gBAAgB,CAAC,MAAM,MAAM,cAAc,YAAY;AAAA,MAC/E;AAAA,IACF,CAAC;AAAA,EACH;AAEA,aAAW,CAAC,mBAAmB,QAAQ,KAAK,OAAO,QAAQ,MAAM,MAAM,iBAAiB,GAAG;AACzF,UAAM,OAAO,MAAM,OAAO,iBAAiB,iBAAiB;AAC5D,QAAI,CAAC,KAAM;AACX,UAAM,sBAAsB,qBAAqB,MAAM,iBAAiB;AACxE,QAAI,QAAQ,uBAAuB,oBAAoB,SAAS,EAAG;AACnE,UAAM,oBAAoB,sBACtB;AAAA,MACE,GAAG,SAAS;AAAA,MACZ,UAAU,OAAO;AAAA,QACf,OAAO,QAAQ,SAAS,YAAY,QAAQ,EAAE;AAAA,UAAO,CAAC,CAAC,EAAE,MACvD,oBAAoB,IAAI,EAAE;AAAA,QAC5B;AAAA,MACF;AAAA,IACF,IACA,SAAS;AACb,UAAM,eAAgC;AAAA,MACpC,GAAG,MAAM;AAAA,MACT,aAAa;AAAA,MACb,cAAc,SAAS;AAAA,MACvB,cAAc,SAAS,gBAAgB,MAAM,OAAO;AAAA,IACtD;AACA,eAAW,YAAQ,qCAAuB,YAAY,GAAG;AACvD,YAAM,aAAa,kBAAkB,kBAAkB,UAAU,KAAK,MAAM;AAC5E,UAAI,WAAW,WAAW,EAAG;AAC7B,qBAAe,MAAM;AAAA,QACnB,GAAG;AAAA,QACH,QAAQ;AAAA,QACR;AAAA,QACA,cAAc,KAAK,OAAO;AAAA,QAC1B,QAAQ,KAAK,OAAO;AAAA,QACpB,YAAY,KAAK,SAAS;AAAA,QAC1B;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,KAAK,OAAO,CAAC;AAC1B;AAEA,SAAS,qBACP,MACA,mBACoB;AACpB,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,MAAM,oBAAI,IAAY;AAC5B,aAAW,QAAQ,KAAK,OAAO;AAC7B,QAAI,KAAK,YAAY,MAAO;AAC5B,SAAK,KAAK,qBAAqB,UAAU,kBAAmB,KAAI,IAAI,KAAK,SAAS;AAAA,EACpF;AACA,SAAO;AACT;AAEA,SAAS,eACP,MACA,aACM;AACN,QAAM,WAAW,KAAK,IAAI,YAAY,MAAM;AAC5C,MAAI,CAAC,UAAU;AACb,SAAK,IAAI,YAAY,QAAQ,WAAW;AACxC;AAAA,EACF;AACA,aAAW,SAAS,YAAY,YAAY;AAC1C,QAAI,CAAC,SAAS,WAAW,KAAK,CAAC,SAAS,KAAK,cAAc,MAAM,SAAS,GAAG;AAC3E,eAAS,WAAW,KAAK,KAAK;AAAA,IAChC;AAAA,EACF;AACF;AAEA,SAAS,kBACP,UACA,QACmD;AACnD,QAAM,aAAgE,CAAC;AACvE,aAAW,WAAW,OAAO,OAAO,QAAQ,GAAG;AAC7C,QAAI,mBAAmB,QAAQ,MAAM,MAAM,GAAG;AAC5C,iBAAW,KAAK,EAAE,WAAW,QAAQ,IAAI,aAAa,QAAQ,KAAK,CAAC;AAAA,IACtE;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,mBAAmB,MAAmB,QAAyB;AACtE,MAAI,KAAK,SAAS,SAAU,QAAO,KAAK,YAAY,WAAW;AAC/D,MAAI,KAAK,SAAS,YAAa,QAAO;AACtC,UAAQ,KAAK,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,IAAI,SAAS,UAAU,IAAI,WAAW,MAAM;AACzF;AAEA,eAAe,gBAAgB,WAAmB,QAAmC;AACnF,MAAI;AACF,UAAM,QAAQ,MAAM,gBAAAA,SAAG,SAAS,SAAS;AACzC,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,UAAU,KAAK,MAAM;AAAA,EAC9B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,SAAS,WAAoC;AAC1D,MAAI;AACF,YAAQ,MAAM,gBAAAA,SAAG,KAAK,SAAS,GAAG;AAAA,EACpC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,mBAAmB,aAAgE;AAChG,MAAI,CAAC,YAAY,gBAAgB,CAAC,YAAY,OAAQ,QAAO;AAC7D,QAAM,CAAC,OAAO,IAAI,IAAI,YAAY,aAAa,MAAM,KAAK,CAAC;AAC3D,MAAI,CAAC,SAAS,CAAC,KAAM,QAAO;AAC5B,QAAM,QAAQ,mBAAmB,WAAW;AAC5C,MAAI,CAAC,SAAS,CAAC,YAAY,YAAY;AACrC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAU,CAAC,cAAc,eAAe,YAAY,MAAM,EAC7D,IAAI,kBAAkB,EACtB,KAAK,GAAG;AACX,QAAM,MAAM,gCAAgC,mBAAmB,KAAK,CAAC,IAAI;AAAA,IACvE;AAAA,EACF,CAAC,aAAa,OAAO,QAAQ,mBAAmB,YAAY,MAAM,CAAC;AACnE,QAAM,UAAkC;AAAA,IACtC,QAAQ;AAAA,IACR,cAAc;AAAA,IACd,wBAAwB;AAAA,EAC1B;AACA,MAAI,MAAO,SAAQ,gBAAgB,UAAU,KAAK;AAElD,QAAM,MAAM,MAAM,MAAM,KAAK,EAAE,SAAS,OAAO,WAAW,CAAC;AAC3D,MAAI,IAAI,WAAW,IAAK,QAAO;AAC/B,MAAI,CAAC,IAAI,IAAI;AACX,UAAM,IAAI,MAAM,mBAAmB,IAAI,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,EAAE;AAAA,EACtE;AACA,QAAM,OAAQ,MAAM,IAAI,KAAK;AAC7B,MAAI,KAAK,SAAS,UAAU,OAAO,KAAK,YAAY,UAAU;AAC5D,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AACA,MAAI,KAAK,aAAa,UAAU;AAC9B,UAAM,IAAI,MAAM,6CAA6C,KAAK,YAAY,WAAW,EAAE;AAAA,EAC7F;AACA,SAAO,IAAI,WAAW,OAAO,KAAK,KAAK,QAAQ,QAAQ,OAAO,EAAE,GAAG,QAAQ,CAAC;AAC9E;AAEA,SAAS,mBAAmB,aAA4C;AACtE,MAAI,YAAY,WAAW,oBAAoB;AAC7C,WACE,QAAQ,IAAI,wCACZ,QAAQ,IAAI,0BACZ,QAAQ,IAAI,gBACZ,QAAQ,IAAI,4BACZ,QAAQ,IAAI,yBACZ;AAAA,EAEJ;AACA,SACE,QAAQ,IAAI,0BACZ,QAAQ,IAAI,gBACZ,QAAQ,IAAI,4BACZ,QAAQ,IAAI,yBACZ;AAEJ;AAEA,SAAS,UAAU,OAA2B;AAC5C,aAAO,+BAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AACxD;AAEA,SAAS,gBAAgB,aAA4C;AACnE,SAAO,GAAG,YAAY,YAAY,YAAY,MAAM,KAAK,YAAY,MAAM;AAC7E;AAEA,SAAS,YAAY,aAA4C;AAC/D,QAAM,OAAO,YAAY,gBAAgB;AACzC,QAAM,SAAS,YAAY,SAAS,IAAI,YAAY,MAAM,KAAK;AAC/D,SAAO,GAAG,IAAI,GAAG,MAAM;AACzB;AAEA,SAAS,gBAAgB,aAA4C;AACnE,SAAO,YAAY,WAAW,IAAI,CAAC,SAAS,KAAK,WAAW,EAAE,KAAK,IAAI,KAAK;AAC9E;AAvXA,wBACAC,iBACAC,OACAC,cAgDM;AAnDN;AAAA;AAAA;AAAA,yBAA2B;AAC3B,IAAAF,kBAA+B;AAC/B,IAAAC,QAAsB;AACtB,IAAAC,eAIO;AA4CP,IAAM,kBAAuB,WAAK,cAAc,aAAa;AAAA;AAAA;;;ACGtD,SAAS,mBAAmB,SAAwB;AACzD,UACG,QAAQ,KAAK,EACb,YAAY,mEAAmE,EAC/E,SAAS,UAAU,wBAAwB,EAC3C;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC;AAAA,IACC;AAAA,IACA;AAAA,EACF,EACC,OAAO,mBAAmB,kDAAkD,EAC5E,OAAO,wBAAwB,sDAAiD,EAChF,OAAO,aAAa,gDAAgD,EACpE,OAAO,uBAAuB,sCAAsC,MAAM,EAC1E,OAAO,UAAU,uCAAuC,EACxD,OAAO,oBAAoB,6CAA6C,EACxE,OAAO,gBAAgB,uCAAuC,EAC9D,OAAO,OAAO,SAAiB,SAAqB;AACnD,QAAI;AACJ,QAAI;AACF,YAAM,WAAW,MAAM,iBAAiB;AAAA,QACtC,MAAM,KAAK;AAAA,QACX,MAAM,KAAK;AAAA,QACX,cAAc;AAAA,MAChB,CAAC;AACD,YAAM,SAAS;AACf,UAAI,SAAS,cAAc;AACzB,gBAAQ,OAAO;AAAA,UACb,GAAG,cAAAC,QAAM,IAAI,WAAW,CAAC,KAAK,cAAAA,QAAM,KAAK,SAAS,QAAQ,SAAS,MAAM,EAAE,CAAC,IAAI,cAAAA,QAAM,IAAI,IAAI,GAAG,GAAG,CAAC;AAAA;AAAA,QACvG;AAAA,MACF;AAAA,IACF,SAAS,KAAK;AACZ,UAAI,eAAe,0BAA0B;AAC3C,aAAK,IAAI,OAAO;AAChB;AAAA,MACF;AACA,YAAM;AAAA,IACR;AAEA,UAAM,WAAW,KAAK,YAAY;AAClC,QAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,WAAK,uBAAuB,QAAQ,gBAAgB,UAAU,KAAK,IAAI,CAAC,GAAG;AAC3E;AAAA,IACF;AAEA,UAAM,QAAQ,UAAM,kCAAa,KAAK,EAAE,cAAc,KAAK,CAAC;AAC5D,QAAI,CAAC,OAAO;AACV,WAAK,yBAAyB,GAAG,mCAAmC;AACpE;AAAA,IACF;AAEA,UAAM,UAAM,6BAAe,MAAM,QAAQ,OAAO;AAChD,QAAI,CAAC,IAAI,IAAI;AACX,WAAK,IAAI,KAAK;AACd,UAAI,IAAI,UAAU,SAAS,GAAG;AAC5B,gBAAQ,OAAO,MAAM,oBAAoB,IAAI,UAAU,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,MACvE;AACA;AAAA,IACF;AAEA,QAAI,KAAK,OAAO,CAAC,MAAM,OAAO,aAAa,MAAM,KAAK,GAAG,GAAG;AAC1D,YAAM,QAAQ,OAAO,KAAK,MAAM,OAAO,aAAa,KAAK;AACzD,WAAK,yBAAyB,KAAK,GAAG,qBAAqB;AAC3D,UAAI,MAAM,SAAS,GAAG;AACpB,gBAAQ,OAAO,MAAM,2BAA2B,MAAM,KAAK,IAAI,CAAC;AAAA,CAAI;AAAA,MACtE;AACA;AAAA,IACF;AAEA,QAAI;AACJ,QAAI;AACF,qBAAe,MAAM,oBAAoB,EAAE,aAAa,KAAK,QAAQ,CAAC,GAAG;AAAA,IAC3E,SAAS,KAAK;AACZ,WAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AACrD;AAAA,IACF;AAEA,UAAM,QAAQ,aAAa,MAAM,OAAO,KAAK,EAAE;AAC/C,UAAM,iBAAiB,KAAK,eAAe;AAC3C,UAAM,OAAO,aAAa;AAI1B,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,WAAW,MAAY,WAAW,MAAM,IAAI,MAAM,mBAAmB,CAAC;AAC5E,YAAQ,GAAG,UAAU,QAAQ;AAE7B,QAAI,KAAM,SAAQ,OAAO,MAAM,aAAa,IAAI,MAAM,OAAO,gBAAgB,IAAI,CAAC;AAElF,QAAI;AACJ,QAAI;AACF,iBAAW,MAAM,4BAA4B,KAAK,OAAO,IAAI,IAAI;AAAA,IACnE,SAAS,KAAK;AACZ,cAAQ,IAAI,UAAU,QAAQ;AAC9B,WAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAAG,GAAG,YAAY;AACtE;AAAA,IACF;AACA,QAAI,QAAQ,SAAS,QAAQ,QAAQ,GAAG;AACtC,cAAQ,OAAO,MAAM,4BAA4B,SAAS,OAAO,CAAC;AAAA,IACpE;AAEA,QAAI;AACJ,QAAI;AACF,eAAS,UAAM,sBAAQ,SAAS,OAAO,IAAI,IAAI;AAAA,QAC7C;AAAA,QACA,MAAM,KAAK,SAAS;AAAA,QACpB,KAAK,KAAK;AAAA,QACV;AAAA,QACA;AAAA,QACA,QAAQ,WAAW;AAAA,QACnB,mBAAmB,SAAS;AAAA,QAC5B,WAAW;AAAA,QACX,QAAQ,OAAO,CAAC,SAAS,QAAQ,OAAO,MAAM,eAAe,IAAI,CAAC,IAAI;AAAA,MACxE,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,cAAQ,IAAI,UAAU,QAAQ;AAC9B,UAAI,eAAe,iCAAoB;AACrC,aAAK,IAAI,SAAS,GAAG,QAAQ;AAC7B;AAAA,MACF;AACA,YAAM;AAAA,IACR;AACA,YAAQ,IAAI,UAAU,QAAQ;AAE9B,UAAM,UAAU,WAAW,OAAO;AAClC,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,MAAO,WAAM,gCAAW,KAAK,OAAO,SAAS;AAEjD,QAAI,aAAa,QAAQ;AACvB,cAAQ,OAAO;AAAA,QACb,KAAK;AAAA,UACH,gBAAgB,KAAK,IAAI,IAAI,IAAI,MAAM,OAAO,QAAQ,OAAO,SAAS,SAAS,OAAO;AAAA,UACtF;AAAA,UACA;AAAA,QACF,IAAI;AAAA,MACN;AAAA,IACF,WAAW,aAAa,SAAS;AAC/B,cAAQ,OAAO,MAAM,iBAAiB,IAAI,MAAM,MAAM,CAAC;AAAA,IACzD,OAAO;AACL,cAAQ,OAAO,MAAM,cAAc,QAAQ,OAAO,OAAO,CAAC;AAAA,IAC5D;AAGA,YAAQ,WAAW,OAAO,UAAU,CAAC,UAAU,IAAI;AAAA,EACrD,CAAC;AACL;AAEA,SAAS,WAAW,OAAkC;AACpD,SAAQ,UAAgC,SAAS,KAAK;AACxD;AAOO,SAAS,aAAa,OAAuB,UAA6B;AAC/E,QAAM,WAAW,UAAU,KAAK;AAChC,MAAI,SAAU,QAAO,EAAE,MAAM,WAAW,MAAM,SAAS;AAEvD,QAAM,QAAQ,MAAM,SAAS,OAAO,WAAW;AAC/C,MAAI,MAAO,QAAO,EAAE,MAAM,UAAU,MAAM,MAAM;AAEhD,MAAI;AACF,UAAM,WAAc,aAAS,EAAE;AAC/B,QAAI,SAAU,QAAO,EAAE,MAAM,MAAM,MAAM,SAAS;AAAA,EACpD,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAUA,SAAS,mBAAmB,MAAyC;AAErE;AAMA,SAAS,aACP,MACA,OACA,gBACA,MACQ;AACR,QAAM,UAAU,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,YAAY,KAAK,EAAE;AAC9D,QAAM,QAAQ;AAAA,IACZ,iBAAiB,kBAAkB;AAAA,IACnC,KAAK,OAAO,SAAS;AAAA,IACrB,KAAK,MAAM,OAAO,KAAK,GAAG,KAAK;AAAA,EACjC,EAAE,OAAO,CAAC,MAAmB,MAAM,IAAI;AACvC,SACE,GAAG,cAAAA,QAAM,KAAK,MAAM,CAAC,IAAI,KAAK,IAAI,KAAK,cAAAA,QAAM;AAAA,IAC3C,IAAI,OAAO,IAAI,KAAK,MAAM,MAAM,eAAY,MAAM,KAAK,QAAK,CAAC;AAAA,EAC/D,CAAC;AAAA,EAAU,cAAAA,QAAM,IAAI,QAAQ,CAAC,IAAI,MAAM,IAAI,IAAI,cAAAA,QAAM,IAAI,IAAI,MAAM,IAAI,GAAG,CAAC;AAAA;AAAA;AAEhF;AAEA,SAAS,4BAA4B,SAA+C;AAClF,QAAM,SAAS,GAAG,QAAQ,UAAU,gBAAgB,QAAQ,cAAc;AAC1E,QAAM,QAAQ;AAAA,IACZ,GAAG,cAAAA,QAAM,KAAK,aAAa,CAAC,IAAI,QAAQ,KAAK,aAAa,cAAAA,QAAM;AAAA,MAC9D,IAAI,MAAM,MAAM,QAAQ,QAAQ;AAAA,IAClC,CAAC;AAAA,EACH;AACA,aAAWC,UAAS,QAAQ,SAAS;AACnC,UAAM,SACJA,OAAM,WAAW,qBACb,UAAUA,OAAM,qBAAqB,SAAS,KAC9C;AACN,UAAM,aAAaA,OAAM,WAAW,IAAI,CAAC,SAAS,KAAK,WAAW,EAAE,KAAK,IAAI;AAC7E,UAAM;AAAA,MACJ,KAAK,cAAAD,QAAM,IAAI,MAAM,CAAC,IAAIC,OAAM,QAAQ,IAAI,cAAAD,QAAM;AAAA,QAChD,GAAG,MAAM,MAAM,UAAU,MAAMC,OAAM,SAAS;AAAA,MAChD,CAAC;AAAA,IACH;AAAA,EACF;AACA,SAAO,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA;AAC5B;AAEO,SAAS,eAAe,MAA8B;AAC3D,QAAM,IAAI,GAAG,KAAK,YAAY,CAAC,IAAI,OAAO,CAAC;AAC3C,QAAM,UAAU,KAAK,iBAAiB,UAAK,OAAO,CAAC;AAEnD,MAAI,KAAK,SAAS;AAChB,WAAO,KAAK,cAAAD,QAAM,IAAI,QAAG,CAAC,IAAI,cAAAA,QAAM,IAAI,CAAC,CAAC,IAAI,cAAAA,QAAM,IAAI,MAAM,CAAC,IAAI,cAAAA,QAAM;AAAA,MACvE,GAAG,KAAK,WAAW;AAAA,IACrB,CAAC;AAAA;AAAA,EACH;AAEA,QAAM,OAAO,KAAK,SAAS,cAAAA,QAAM,MAAM,QAAG,IAAI,cAAAA,QAAM,IAAI,QAAG;AAC3D,QAAM,SAAS,KAAK,QAAQ,UAAU,OAAO,OAAO,KAAK,OAAO,MAAM,IAAI;AAC1E,QAAM,WAAW,KAAK,SAAS,GAAG,KAAK,OAAO,UAAU,OAAO;AAC/D,QAAM,OAAO,KAAK,YAAY,OAAO,EAAE;AAEvC,MAAI,OAAO,KAAK,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,IAAI,IAAI,OAAO,OAAO,CAAC,CAAC,IAAI,cAAAA,QAAM,IAAI,QAAQ,CAAC;AAEtF,MAAI,KAAK,iBAAiB,SAAS,GAAG;AACpC,UAAM,SAAS,KAAK,iBAAiB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE;AAC7D,YAAQ,KAAK,cAAAA,QAAM,IAAI,GAAG,MAAM,IAAI,KAAK,iBAAiB,MAAM,aAAa,CAAC;AAAA,EAChF;AACA,UAAQ;AAER,MAAI,KAAK,OAAO;AACd,YAAQ,SAAS,cAAAA,QAAM,IAAI,KAAK,KAAK,CAAC;AAAA;AAAA,EACxC;AACA,aAAW,KAAK,KAAK,kBAAkB;AACrC,QAAI,CAAC,EAAE,OAAQ,SAAQ,SAAS,cAAAA,QAAM,IAAI,QAAG,CAAC,IAAI,EAAE,UAAU,GAAG,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE;AAAA;AAAA,EACnF;AACA,MAAI,KAAK,iBAAiB,SAAS,GAAG;AACpC,YAAQ,SAAS,cAAAA,QAAM,OAAO,QAAG,CAAC,gBAAgB,KAAK,iBACpD,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,EACrB,KAAK,IAAI,CAAC;AAAA;AAAA,EACf;AACA,SAAO;AACT;AAEA,SAAS,MAAM,QAA4E;AACzF,MAAI,SAAS;AACb,MAAI,SAAS;AACb,MAAI,UAAU;AACd,aAAW,KAAK,OAAO,OAAO;AAC5B,QAAI,EAAE,QAAS;AAAA,aACN,EAAE,OAAQ;AAAA,QACd;AAAA,EACP;AACA,SAAO,EAAE,QAAQ,QAAQ,QAAQ;AACnC;AAEA,SAAS,cAAc,QAAuB,OAAgB,SAA0B;AACtF,MAAI,OAAO,MAAM,WAAW,GAAG;AAC7B,WAAO;AAAA,EAAK,cAAAA,QAAM,OAAO,oBAAoB,CAAC;AAAA;AAAA,EAChD;AACA,QAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,MAAM,MAAM;AAChD,QAAM,QAAQ;AAAA,IACZ,cAAAA,QAAM,MAAM,GAAG,MAAM,SAAS;AAAA,IAC9B,SAAS,IAAI,cAAAA,QAAM,IAAI,GAAG,MAAM,SAAS,IAAI,cAAAA,QAAM,IAAI,GAAG,MAAM,SAAS;AAAA,IACzE,cAAAA,QAAM,IAAI,GAAG,OAAO,UAAU;AAAA,EAChC;AACA,QAAM,UAAU,OAAO,UAAU,CAAC,UAAU,cAAAA,QAAM,MAAM,MAAM,IAAI,cAAAA,QAAM,IAAI,MAAM;AAClF,MAAI,MAAM;AAAA,EAAK,OAAO,KAAK,MAAM,KAAK,cAAAA,QAAM,IAAI,QAAK,CAAC,CAAC,KAAK,cAAAA,QAAM;AAAA,IAChE,QAAK,OAAO,QAAQ,UAAU;AAAA,EAChC,CAAC;AAAA;AACD,MAAI,QAAS,QAAO,GAAG,cAAAA,QAAM,OAAO,yCAAyC,CAAC;AAAA;AAC9E,SAAO,QACH,cAAAA,QAAM,IAAI,wCAAwC,IAClD,cAAAA,QAAM,IAAI,mCAAmC;AACjD,SAAO;AACT;AAEA,SAAS,gBACP,WACA,QACA,MACA,OACA,QACA,OACA,SACA,aACS;AACT,SAAO;AAAA,IACL;AAAA,IACA,MAAM,EAAE,IAAI,QAAQ,MAAM,KAAK,KAAK;AAAA,IACpC;AAAA,IACA,gBAAgB,OAAO,QAAQ;AAAA,IAC/B,QAAQ,OAAO,UAAU,CAAC;AAAA,IAC1B;AAAA,IACA,YAAY,OAAO,QAAQ;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,QAAQ,MAAM,MAAM;AAAA,IACpB,OAAO,OAAO,MAAM,IAAI,CAAC,OAAO;AAAA,MAC9B,MAAM,EAAE,YAAY;AAAA,MACpB,SAAS,EAAE;AAAA,MACX,QAAQ,EAAE;AAAA,MACV,SAAS,EAAE;AAAA,MACX,QAAQ,EAAE,QAAQ,UAAU;AAAA,MAC5B,IAAI,EAAE,QAAQ,MAAM;AAAA,MACpB,YAAY,EAAE,QAAQ,cAAc;AAAA,MACpC,QAAQ,EAAE;AAAA,MACV,OAAO,EAAE,SAAS;AAAA,MAClB,kBAAkB,EAAE;AAAA,MACpB,YAAY,EAAE,iBAAiB,IAAI,CAAC,OAAO;AAAA,QACzC,MAAM,EAAE;AAAA,QACR,IAAI,EAAE;AAAA,QACN,QAAQ,EAAE;AAAA,QACV,UAAU,EAAE;AAAA,QACZ,QAAQ,EAAE;AAAA,QACV,QAAQ,EAAE;AAAA,MACZ,EAAE;AAAA,IACJ,EAAE;AAAA,EACJ;AACF;AAEA,SAAS,UAAU,OAAuB;AACxC,SAAO,MACJ,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,MAAM,EACpB,QAAQ,MAAM,QAAQ;AAC3B;AAGO,SAAS,iBAAiB,MAAqB,QAA+B;AACnF,QAAM,EAAE,QAAQ,QAAQ,IAAI,MAAM,MAAM;AACxC,QAAM,QAAQ,OAAO,MAAM;AAC3B,QAAM,QAAQ,UAAU,KAAK,IAAI;AACjC,QAAM,aAAa,OAAO,QAAQ,aAAa,KAAM,QAAQ,CAAC;AAE9D,QAAM,QAAQ,OAAO,MAAM,IAAI,CAAC,MAAM;AACpC,UAAM,OAAO,UAAU,GAAG,EAAE,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE;AAC7D,UAAM,SAAS,EAAE,QAAQ,cAAc,KAAK,KAAM,QAAQ,CAAC;AAC3D,UAAM,OAAO,uBAAuB,IAAI,gBAAgB,KAAK,WAAW,IAAI;AAC5E,QAAI,EAAE,QAAS,QAAO,GAAG,IAAI;AAAA;AAAA;AAC7B,QAAI,EAAE,OAAQ,QAAO,GAAG,IAAI;AAE5B,UAAM,UAAoB,CAAC;AAC3B,QAAI,EAAE,MAAO,SAAQ,KAAK,EAAE,KAAK;AACjC,eAAW,KAAK,EAAE,kBAAkB;AAClC,UAAI,CAAC,EAAE,OAAQ,SAAQ,KAAK,EAAE,UAAU,aAAa,EAAE,IAAI,IAAI,EAAE,EAAE,SAAS;AAAA,IAC9E;AACA,QAAI,EAAE,UAAU,CAAC,EAAE,OAAO,MAAM,EAAE,OAAO,UAAU,MAAM;AACvD,cAAQ,KAAK,QAAQ,EAAE,OAAO,MAAM,EAAE;AAAA,IACxC;AACA,UAAM,SAAS,UAAU,QAAQ,KAAK,IAAI,KAAK,aAAa;AAC5D,UAAM,UAAU,OAAO,MAAM,IAAI,EAAE,CAAC;AACpC,WAAO,GAAG,IAAI;AAAA,0BAA8B,OAAO,KAAK,MAAM;AAAA;AAAA,EAChE,CAAC;AAED,SACE;AAAA,oBACqB,KAAK,YAAY,KAAK,eAAe,MAAM,cAAc,OAAO,WAAW,SAAS;AAAA,qBACnF,KAAK,YAAY,KAAK,eAAe,MAAM,cAAc,OAAO,WAAW,SAAS;AAAA,EACvG,MAAM,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAIvB;AAGA,SAAS,KAAK,SAAiB,OAAO,GAAG,OAAO,SAAe;AAC7D,UAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,IAAI,IAAI,CAAC,KAAK,OAAO;AAAA,CAAI;AACvD,UAAQ,WAAW;AACrB;AAjcA,IAAAE,KAEAC,eACAC,cAUAC,qBAwBM;AArCN;AAAA;AAAA;AAAA,IAAAH,MAAoB;AAEpB,IAAAC,gBAAkB;AAClB,IAAAC,eASO;AACP,IAAAC,sBAAyC;AAEzC;AACA;AACA;AAoBA,IAAM,YAAY,CAAC,QAAQ,QAAQ,OAAO;AAAA;AAAA;;;ACfnC,SAAS,0BAA0B,SAAwB;AAChE,QAAM,KAAK,QACR,QAAQ,YAAY,EACpB,YAAY,8CAA8C;AAE7D,KAAG,QAAQ,MAAM,EACd,YAAY,iDAAiD,EAC7D,OAAO,UAAU,wCAAwC,EACzD,OAAO,OAAO,SAA4B;AACzC,UAAM,EAAE,UAAU,KAAK,IAAI,MAAM,qBAAqB;AACtD,QAAI,KAAK,MAAM;AACb,cAAQ,OAAO,MAAM,KAAK,UAAU,EAAE,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,IAAI;AACvE;AAAA,IACF;AACA,QAAI,SAAS,WAAW,WAAW,GAAG;AACpC,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAC,QAAM,IAAI,iCAAiC,CAAC,IAAI,IAAI;AAAA,EAClD,cAAAA,QAAM,IAAI,KAAK,CAAC,IAAI,cAAAA,QAAM,KAAK,oCAAoC,CAAC,IAAI,cAAAA,QAAM;AAAA,UAC/E;AAAA,QACF,CAAC;AAAA;AAAA,MACL;AACA;AAAA,IACF;AACA,YAAQ,OAAO,MAAM,GAAG,cAAAA,QAAM,IAAI,UAAU,CAAC,KAAK,IAAI;AAAA;AAAA,CAAM;AAE5D,UAAM,OAAO,CAAC,GAAG,SAAS,UAAU,EAAE;AAAA,MAAK,CAAC,GAAG,MAC7C,EAAE,aAAa,cAAc,EAAE,YAAY;AAAA,IAC7C;AACA,UAAM,YAAY,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AAC/D,UAAM,UAAU,KAAK,IAAI,GAAG,GAAG,KAAK,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC;AAC3D,YAAQ,OAAO;AAAA,MACb,cAAAA,QAAM;AAAA,QACJ,KAAK,GAAG,OAAO,CAAC,CAAC,IAAI,OAAO,OAAO,SAAS,CAAC,KAAK,KAAK,OAAO,OAAO,CAAC;AAAA;AAAA,MACxE;AAAA,IACF;AACA,eAAW,KAAK,MAAM;AACpB,YAAM,OAAO,EAAE,OAAO,SAAS,oBAAoB,cAAAA,QAAM,MAAM,QAAG,IAAI;AACtE,cAAQ,OAAO;AAAA,QACb,KAAK,IAAI,IAAI,EAAE,KAAK,OAAO,SAAS,CAAC,KAAK,cAAAA,QAAM;AAAA,UAC9C,EAAE,GAAG,OAAO,OAAO;AAAA,QACrB,CAAC,KAAK,cAAAA,QAAM,IAAI,EAAE,YAAY,CAAC;AAAA;AAAA,MACjC;AAAA,IACF;AACA,YAAQ,OAAO,MAAM;AAAA,EAAK,cAAAA,QAAM,IAAI,iBAAY,CAAC;AAAA,CAAI;AAAA,EACvD,CAAC;AAEH,KAAG,QAAQ,QAAQ,EAChB,YAAY,mDAAmD,EAC/D,SAAS,UAAU,wCAAwC,EAC3D,OAAO,YAAY,8CAA8C,KAAK,EACtE,OAAO,OAAO,MAAc,SAA+B;AAC1D,QAAI;AACF,YAAM,EAAE,OAAAC,QAAO,KAAK,SAAS,IAAI,MAAM,sBAAsB;AAAA,QAC3D;AAAA,QACA,eAAe,KAAK,UAAU;AAAA,MAChC,CAAC;AACD,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAD,QAAM,MAAM,SAAS,CAAC,cAAc,cAAAA,QAAM,KAAKC,OAAM,IAAI,CAAC,IAAI,cAAAD,QAAM,IAAI,IAAIC,OAAM,EAAE,GAAG,CAAC;AAAA,OACjF,GAAG;AAAA;AAAA,MACf;AACA,UAAI,SAAS,sBAAsBA,OAAM,IAAI;AAC3C,gBAAQ,OAAO,MAAM,GAAG,cAAAD,QAAM,IAAI,kBAAkB,CAAC;AAAA,CAAI;AAAA,MAC3D;AAAA,IACF,SAAS,KAAK;AACZ,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAA,QAAM,IAAI,OAAO,CAAC,KAAK,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,CAAC;AAAA;AAAA,MAC5E;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAAA,EACF,CAAC;AAEH,KAAG,QAAQ,KAAK,EACb,YAAY,wCAAwC,EACpD,SAAS,cAAc,sBAAsB,EAC7C,OAAO,OAAO,aAAqB;AAClC,UAAM,EAAE,UAAU,KAAK,IAAI,MAAM,qBAAqB;AACtD,UAAMC,aAAQ,qCAAmB,UAAU,QAAQ;AACnD,QAAI,CAACA,QAAO;AACV,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAD,QAAM,IAAI,OAAO,CAAC,yBAAyB,QAAQ,wBAAwB,IAAI;AAAA,EAC7E,cAAAA,QAAM,IAAI,KAAK,CAAC,IAAI,cAAAA,QAAM,KAAK,2BAA2B,CAAC,IAAI,cAAAA,QAAM,IAAI,2BAA2B,CAAC;AAAA;AAAA,MAC5G;AACA,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AACA,UAAM,OAAO,UAAM,qCAAmB,MAAMC,OAAM,EAAE;AACpD,SAAK;AACL,YAAQ,OAAO;AAAA,MACb,GAAG,cAAAD,QAAM,MAAM,QAAQ,CAAC,qBAAqB,cAAAA,QAAM,KAAKC,OAAM,IAAI,CAAC,IAAI,cAAAD,QAAM,IAAI,IAAIC,OAAM,EAAE,GAAG,CAAC;AAAA;AAAA,IACnG;AAAA,EACF,CAAC;AAEH,KAAG,QAAQ,MAAM,EACd,YAAY,iEAAiE,EAC7E,SAAS,cAAc,6DAA6D,EACpF,OAAO,OAAO,aAAsB;AACnC,QAAI,CAAC,UAAU;AACb,cAAQ,OAAO,MAAM,sBAAsB,IAAI,IAAI;AACnD;AAAA,IACF;AACA,UAAM,EAAE,UAAU,KAAK,IAAI,MAAM,qBAAqB;AACtD,UAAMA,aAAQ,qCAAmB,UAAU,QAAQ;AACnD,QAAI,CAACA,QAAO;AACV,cAAQ,OAAO;AAAA,QACb,GAAG,cAAAD,QAAM,IAAI,OAAO,CAAC,yBAAyB,QAAQ,wBAAwB,IAAI;AAAA;AAAA,MACpF;AACA,cAAQ,KAAK,CAAC;AACd;AAAA,IACF;AAGA,SAAK;AACL,UAAM,EAAE,iBAAAE,iBAAgB,IAAI,MAAM,OAAO,oCAAoC;AAC7E,YAAQ,OAAO,MAAMA,iBAAgB,MAAMD,OAAM,EAAE,IAAI,IAAI;AAAA,EAC7D,CAAC;AACL;AAzIA,IACAE,eAOAC;AARA;AAAA;AAAA;AACA,IAAAD,gBAAkB;AAClB;AAMA,IAAAC,mBAAuD;AAAA;AAAA;;;ACRvD;AAAA;AAAA;AAAA;AAAA;AAmBO,SAAS,eAAwB;AACtC,QAAM,UAAU,IAAI,yBAAQ;AAC5B,UACG,KAAK,WAAW,EAChB,YAAY,8CAA8C,EAC1D,QAAQ,mBAAmB;AAE9B,sBAAoB,OAAO;AAC3B,qBAAmB,OAAO;AAC1B,wBAAsB,OAAO;AAC7B,wBAAsB,OAAO;AAC7B,qBAAmB,OAAO;AAC1B,4BAA0B,OAAO;AAEjC,SAAO;AACT;AAEA,eAAsB,OAAO,OAA0B,QAAQ,MAAqB;AAClF,QAAM,aAAa,EAAE,WAAW,IAAI;AACtC;AAtCA,sBA6CM;AA7CN;AAAA;AAAA;AAAA,uBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AAsCA,IAAM,QAAQ,QAAQ,KAAK,CAAC,KAAK;AACjC,QAAI,MAAM,SAAS,WAAW,KAAK,MAAM,SAAS,WAAW,KAAK,MAAM,SAAS,UAAU,GAAG;AAC5F,WAAK,OAAO;AAAA,IACd;AAAA;AAAA;;;AChDA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAO,SAAS,mBAAmB,MAAkC;AACnE,SAAO,KAAK,WAAW,KAAK,CAAC,aAAa,MAAM,IAAI,EAAE,SAAS,KAAK,CAAC,KAAK,EAAE;AAC9E;AAEO,SAAS,gBAAgB,MAAkC;AAChE,SAAO,KAAK,WAAW,KAAK,CAAC,UAAU,MAAM,MAAM,EAAE,SAAS,KAAK,CAAC,KAAK,EAAE;AAC7E;AAEO,SAAS,iBAAyB;AACvC,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiBT;;;ADvBA,eAAsB,OAAO,OAA0B,QAAQ,MAAqB;AAClF,QAAM,OAAO,KAAK,MAAM,CAAC;AACzB,MAAI,mBAAmB,IAAI,GAAG;AAC5B,YAAQ,OAAO,MAAM,GAAG,mBAAmB;AAAA,CAAI;AAC/C;AAAA,EACF;AACA,MAAI,gBAAgB,IAAI,GAAG;AACzB,YAAQ,OAAO,MAAM,eAAe,CAAC;AACrC;AAAA,EACF;AAEA,QAAM,EAAE,QAAAC,QAAO,IAAI,MAAM;AACzB,QAAMA,QAAO,IAAI;AACnB;AAEA,IAAMC,SAAQ,QAAQ,KAAK,CAAC,KAAK;AACjC,IAAIA,OAAM,SAAS,WAAW,KAAKA,OAAM,SAAS,SAAS,KAAKA,OAAM,SAAS,QAAQ,GAAG;AACxF,OAAK,OAAO;AACd;","names":["fs","kleur","fs","path","import_node_fs","import_shared","entry","fs","path","import_node_fs","import_file_backed","import_shared","kleur","import_kleur","kleur","resolve","fs","import_node_fs","path","import_kleur","import_file_backed","import_mock_server_core","import_shared","kleur","fs","import_node_fs","path","import_kleur","import_core","fs","path","import_node_fs","fs","import_node_fs","path","import_core","kleur","entry","os","import_kleur","import_core","import_file_backed","kleur","entry","workspaceDirFor","import_kleur","import_registry","runCli","entry"]}