@apicircle/cli 1.0.9 → 1.1.2

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":["../src/index.ts","../src/commands/mock.ts","../src/commands/mcp.ts","../src/util/loadWorkspace.ts","../src/util/resolveWorkspace.ts","../src/commands/import.ts","../src/commands/export.ts","../src/commands/run.ts","../src/util/secrets.ts","../src/util/executionAttachments.ts","../src/commands/workspaces.ts","../package.json","../src/packageVersion.ts"],"sourcesContent":["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 { 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 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 * 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 { 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 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 * 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 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","{\n \"name\": \"@apicircle/cli\",\n \"version\": \"1.0.9\",\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"],"mappings":"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","names":["fs","kleur","import_kleur","path","import_node_fs","import_shared","fs","path","import_node_fs","import_file_backed","import_shared","entry","fs","kleur","import_node_fs","path","import_kleur","import_file_backed","import_mock_server_core","import_shared","kleur","resolve","fs","import_node_fs","path","import_kleur","import_core","kleur","fs","os","import_kleur","import_core","import_file_backed","path","import_node_fs","fs","import_node_fs","path","import_core","fs","kleur","entry","import_kleur","import_registry","kleur","entry","workspaceDirFor"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/mock.ts","../src/commands/mocks.ts","../src/util/loadWorkspace.ts","../src/util/resolveWorkspace.ts","../src/commands/mcp.ts","../src/commands/import.ts","../src/commands/export.ts","../src/commands/run.ts","../src/util/secrets.ts","../src/util/executionAttachments.ts","../src/commands/workspaces.ts","../src/commands/linked.ts","../../git/src/github/errors.ts","../../git/src/github/api.ts","../src/commands/release.ts","../src/commands/folder.ts","../package.json","../src/packageVersion.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { registerMockCommand } from './commands/mock';\nimport { registerMocksCommand } from './commands/mocks';\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 { registerLinkedCommand } from './commands/linked';\nimport { registerReleaseCommand } from './commands/release';\nimport { registerFolderCommand } from './commands/folder';\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 registerMocksCommand(program);\n registerMcpCommand(program);\n registerImportCommand(program);\n registerExportCommand(program);\n registerRunCommand(program);\n registerWorkspacesCommand(program);\n registerLinkedCommand(program);\n registerReleaseCommand(program);\n registerFolderCommand(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 { 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 type { Command } from 'commander';\nimport kleur from 'kleur';\nimport { saveToFile } from '@apicircle/core/workspace/file-backed';\nimport type { MockServer, WorkspaceSynced } from '@apicircle/shared';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle mocks <subcommand>` — manage mock-server definitions in the\n// active workspace from the terminal. Headless surface for the same\n// `defaultPort` field the Web/Desktop UI, VS Code, and the\n// `mock.set_default_port` MCP tool all drive.\n//\n// Current subcommands:\n// • `list` — alias for `mock list` that focuses on workspace-stored\n// definitions (CRUD), not a running runtime.\n// • `set-port <id-or-name> [port]` — pin a default port (or clear it).\n//\n// `apicircle mock <spec>` (singular) keeps its existing semantics:\n// stream a mock server from a spec file on the fly. The plural `mocks`\n// group operates on persisted workspace definitions.\n// =============================================================================\n\ninterface MocksCommonOptions {\n workspaceName?: string;\n workspacePath?: string;\n}\n\nexport function registerMocksCommand(program: Command): void {\n const mocks = program\n .command('mocks')\n .description('Manage mock-server definitions in the active workspace');\n\n mocks\n .command('list')\n .description('List every mock server in the workspace + its default port')\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.json (skips the registry).',\n )\n .option('--json', 'Emit JSON instead of a formatted table')\n .action(async (opts: MocksCommonOptions & { json?: boolean }) => {\n const dir = await resolveDir(opts);\n const state = await ensureWorkspace(dir);\n const mockList = Object.values(state.synced.mockServers);\n if (opts.json) {\n process.stdout.write(\n JSON.stringify(\n mockList.map((m) => ({\n id: m.id,\n name: m.name,\n defaultPort: m.defaultPort,\n endpoints: m.endpoints.length,\n })),\n null,\n 2,\n ) + '\\n',\n );\n return;\n }\n if (mockList.length === 0) {\n process.stdout.write(`${kleur.dim('No mock servers in this workspace.')}\\n`);\n return;\n }\n const nameWidth = Math.max(4, ...mockList.map((m) => m.name.length));\n const idWidth = Math.max(2, ...mockList.map((m) => m.id.length));\n process.stdout.write(\n kleur.bold(\n ` ${'NAME'.padEnd(nameWidth)} ${'ID'.padEnd(idWidth)} ${'PORT'.padStart(6)} ENDPOINTS\\n`,\n ),\n );\n for (const m of mockList) {\n const portLabel = m.defaultPort === null ? kleur.dim('auto') : String(m.defaultPort);\n process.stdout.write(\n ` ${m.name.padEnd(nameWidth)} ${kleur.dim(m.id.padEnd(idWidth))} ${portLabel.padStart(6)} ${m.endpoints.length}\\n`,\n );\n }\n });\n\n mocks\n .command('set-port')\n .description('Set (or clear) the default port for a mock server in the active workspace')\n .argument('<selector>', 'Mock server id or case-insensitive name')\n .argument(\n '[port]',\n 'Port 1024-65535, or omit / \"auto\" / \"null\" to clear back to free-port mode',\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.json (skips the registry).',\n )\n .action(async (selector: string, portArg: string | undefined, opts: MocksCommonOptions) => {\n const dir = await resolveDir(opts);\n const state = await ensureWorkspace(dir);\n const target = findMock(state.synced, selector);\n if (!target) {\n process.stderr.write(\n `${kleur.red('error')}: no mock named \"${selector}\" in this workspace. ` +\n `Run ${kleur.cyan('apicircle mocks list')} to see what's available.\\n`,\n );\n process.exit(2);\n return;\n }\n const nextPort = parsePortArg(portArg);\n if (nextPort === 'invalid') {\n process.stderr.write(\n `${kleur.red('error')}: port must be an integer in 1024-65535, or \"auto\" / \"null\" / omitted to clear.\\n`,\n );\n process.exit(2);\n return;\n }\n if (target.defaultPort === nextPort) {\n process.stdout.write(\n `${kleur.dim('unchanged')}: \"${target.name}\" already has defaultPort ${\n nextPort === null ? 'auto' : String(nextPort)\n }.\\n`,\n );\n return;\n }\n const now = new Date().toISOString();\n const updated: MockServer = { ...target, defaultPort: nextPort, updatedAt: now };\n const nextSynced: WorkspaceSynced = {\n ...state.synced,\n mockServers: { ...state.synced.mockServers, [target.id]: updated },\n meta: { ...state.synced.meta, updatedAt: now },\n };\n await saveToFile(dir, { synced: nextSynced, local: state.local });\n process.stdout.write(\n `${kleur.green('updated')} \"${target.name}\" defaultPort = ${\n nextPort === null ? kleur.dim('auto (free port)') : kleur.cyan(String(nextPort))\n }\\n`,\n );\n });\n}\n\nasync function resolveDir(opts: MocksCommonOptions): Promise<string> {\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n return 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}\n\nfunction findMock(synced: WorkspaceSynced, selector: string): MockServer | undefined {\n const all = Object.values(synced.mockServers);\n const byId = all.find((m) => m.id === selector);\n if (byId) return byId;\n const lower = selector.toLowerCase();\n return all.find((m) => m.name.toLowerCase() === lower);\n}\n\n// Returns:\n// • null → caller wants to clear the port (auto / null / blank / omitted)\n// • number → a valid 1024-65535 port\n// • 'invalid' sentinel → caller passed something we can't accept\nexport function parsePortArg(raw: string | undefined): number | null | 'invalid' {\n if (raw === undefined) return null;\n const trimmed = raw.trim();\n if (trimmed === '' || trimmed.toLowerCase() === 'auto' || trimmed.toLowerCase() === 'null') {\n return null;\n }\n const n = Number(trimmed);\n if (!Number.isInteger(n)) return 'invalid';\n if (n < 1024 || n > 65535) return 'invalid';\n return n;\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.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 defaultApicircleRoot,\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 registry,\n// 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.json`. For CI / one-off\n// flows that aren't registered (e.g. a freshly git-cloned workspace).\n//\n// Passing both is an error. When NEITHER is passed:\n//\n// • A registry exists at ~/.apicircle/ → use the active workspace.\n// • No registry exists → fall back to cwd.\n//\n// `APICIRCLE_WORKSPACES_ROOT` overrides the root for CI / tests.\n// =============================================================================\n\nexport interface ResolvedWorkspace {\n /** Absolute directory containing workspace.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 `~/.apicircle/` (CI / tests). */\n workspacesRoot?: string;\n /** When true (the default), missing target dirs raise. Set false for create paths. */\n expectExists?: boolean;\n}\n\n/**\n * The root directory the CLI consults for registry-based workspace resolution.\n * Honors `APICIRCLE_WORKSPACES_ROOT` first, then falls back to `~/.apicircle/`.\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 defaultApicircleRoot();\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.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.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.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.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 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.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.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 * 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 sourceWorkspaceId: string;\n linkedWorkspaceId?: string;\n repoFullName?: string;\n branch?: string;\n publicRepo?: boolean;\n requiredBy: Array<{ requestId: string; requestName: string }>;\n}\n\nconst ATTACHMENTS_DIR = '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 resolvedLocal = path.resolve(localPath);\n if (!resolvedLocal.startsWith(path.resolve(cacheDir) + path.sep)) {\n throw new Error(`Attachment path escapes cache directory: ${requirement.slotId}`);\n }\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 sourceWorkspaceId: state.synced.workspaceId,\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 sourceWorkspaceId: link.sourceWorkspaceId,\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 = [\n '.apicircle',\n `workspace-${requirement.sourceWorkspaceId}`,\n 'attachments',\n requirement.slotId,\n ]\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 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 type { Command } from 'commander';\nimport kleur from 'kleur';\nimport {\n fetchRemoteWorkspaceJson,\n applyMutation,\n buildLinkedSnapshot,\n ledgerFromProbe,\n parseLinkedWorkspaceJson,\n} from '@apicircle/core';\nimport { saveToFile } from '@apicircle/core/workspace/file-backed';\nimport { generateId, type LinkedWorkspace } from '@apicircle/shared';\nimport { GitHubClient } from '@apicircle/git';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle linked` — sub-commands for managing linked workspaces from the CLI.\n//\n// apicircle linked link <repo> [--branch] [--pinned-version] [--kind]\n// apicircle linked refresh <id>\n// apicircle linked list\n// apicircle linked unlink <id>\n//\n// Tokens come from `--token <tok>` or the `GITHUB_TOKEN` env var. Public-kind\n// links can fetch anonymously; private-kind requires a token.\n// =============================================================================\n\ninterface SharedOptions {\n workspaceName?: string;\n workspacePath?: string;\n token?: string;\n}\n\nfunction resolveToken(opts: SharedOptions): string {\n return (opts.token ?? process.env.GITHUB_TOKEN ?? '').trim();\n}\n\nasync function resolveDir(opts: SharedOptions): Promise<string> {\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: false,\n });\n if (resolved.fromRegistry) {\n process.stderr.write(\n `${kleur.dim('workspace')}: ${kleur.cyan(resolved.name ?? resolved.id ?? '')} ${kleur.dim(`(${resolved.dir})`)}\\n`,\n );\n }\n return 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}\n\nexport function registerLinkedCommand(program: Command): void {\n const linked = program\n .command('linked')\n .description('Manage linked workspaces (the workspaces this one consumes).');\n\n linked\n .command('list')\n .description('List linked workspaces in the active workspace.')\n .option('--workspace-name <name-or-id>', 'Workspace name or id.')\n .option('-w, --workspace-path <dir>', 'Workspace folder path.')\n .action(async (opts: SharedOptions) => {\n const dir = await resolveDir(opts);\n const state = await ensureWorkspace(dir);\n const links = Object.values(state.synced.linkedWorkspaces);\n if (links.length === 0) {\n process.stdout.write(`${kleur.dim('No linked workspaces.')}\\n`);\n return;\n }\n for (const l of links) {\n const pin = l.pinnedVersion ? `v${l.pinnedVersion}` : 'unpinned';\n const ledger = state.synced.releases.perLink[l.id];\n const cur = ledger?.currentVersion ? ` · cached current v${ledger.currentVersion}` : '';\n process.stdout.write(\n `${kleur.cyan(l.id)} ${kleur.bold(l.name)} ${kleur.dim(`${l.kind} · ${l.source.repoFullName}@${l.source.branch} · ${pin}${cur}`)}\\n`,\n );\n }\n });\n\n linked\n .command('link <repo>')\n .description('Link a source workspace repo (owner/name).')\n .option('-b, --branch <branch>', 'Source branch.', 'main')\n .option('--pinned-version <version>', 'Pin a specific version (defaults to source current).')\n .option('--kind <kind>', 'private | public', 'private')\n .option('--workspace-name <name-or-id>', 'Workspace name or id.')\n .option('-w, --workspace-path <dir>', 'Workspace folder path.')\n .option('--token <token>', 'GitHub token (or set GITHUB_TOKEN).')\n .action(\n async (\n repo: string,\n opts: SharedOptions & {\n branch: string;\n pinnedVersion?: string;\n kind: 'private' | 'public';\n },\n ) => {\n if (!repo.includes('/')) {\n process.stderr.write(`${kleur.red('error')}: repo must be owner/name\\n`);\n process.exit(2);\n }\n if (opts.kind !== 'public' && opts.kind !== 'private') {\n process.stderr.write(`${kleur.red('error')}: --kind must be private or public\\n`);\n process.exit(2);\n }\n const token = resolveToken(opts);\n if (opts.kind === 'private' && !token) {\n process.stderr.write(\n `${kleur.red('error')}: a token is required for private repos (--token or GITHUB_TOKEN)\\n`,\n );\n process.exit(2);\n }\n const dir = await resolveDir(opts);\n const state = await ensureWorkspace(dir);\n const dup = Object.values(state.synced.linkedWorkspaces).find(\n (l) => l.source.repoFullName === repo && l.source.branch === opts.branch,\n );\n if (dup) {\n process.stderr.write(\n `${kleur.red('error')}: already linked to ${repo}@${opts.branch} (${dup.id})\\n`,\n );\n process.exit(2);\n }\n\n const [owner, name] = repo.split('/', 2);\n const client = new GitHubClient();\n const result = await fetchRemoteWorkspaceJson(async (p) => {\n const f = await client.getContents(token, owner, name, p, opts.branch);\n return f?.content ?? null;\n });\n if ('error' in result) {\n process.stderr.write(`${kleur.red('error')}: ${repo}@${opts.branch}: ${result.error}\\n`);\n process.exit(2);\n }\n const probe = parseLinkedWorkspaceJson(result.content);\n const ledger = ledgerFromProbe(probe);\n const link: LinkedWorkspace = {\n id: generateId(),\n kind: opts.kind,\n name: repo,\n sourceWorkspaceId: result.workspaceId,\n source: {\n provider: 'github',\n repoFullName: repo,\n branch: opts.branch,\n sessionMode: 'workspace',\n },\n scope: ['collections', 'environments'],\n pinnedVersion: opts.pinnedVersion ?? ledger.currentVersion,\n updatePolicy: 'manual',\n linkedAt: new Date().toISOString(),\n requiredSecretKeyIds: probe.secretKeys ? Object.keys(probe.secretKeys) : [],\n };\n const snapshot = buildLinkedSnapshot(probe, link) ?? undefined;\n const out = applyMutation(state, {\n kind: 'linkedWorkspace.upsert',\n link,\n ledger,\n ...(snapshot ? { snapshot } : {}),\n });\n await saveToFile(dir, out.next);\n process.stdout.write(\n `${kleur.green('linked')} ${kleur.bold(repo)} ${kleur.dim(`(id ${link.id}, ${link.pinnedVersion ? `v${link.pinnedVersion}` : 'unpinned'})`)}\\n`,\n );\n },\n );\n\n linked\n .command('refresh <id>')\n .description(\"Re-pull a linked workspace's cached release ledger.\")\n .option('--workspace-name <name-or-id>', 'Workspace name or id.')\n .option('-w, --workspace-path <dir>', 'Workspace folder path.')\n .option('--token <token>', 'GitHub token (or set GITHUB_TOKEN).')\n .action(async (id: string, opts: SharedOptions) => {\n const dir = await resolveDir(opts);\n const state = await ensureWorkspace(dir);\n const link = state.synced.linkedWorkspaces[id];\n if (!link) {\n process.stderr.write(`${kleur.red('error')}: linked workspace ${id} not found\\n`);\n process.exit(2);\n }\n const token = resolveToken(opts);\n if (link.kind === 'private' && !token) {\n process.stderr.write(\n `${kleur.red('error')}: a token is required for private links (--token or GITHUB_TOKEN)\\n`,\n );\n process.exit(2);\n }\n const [owner, name] = link.source.repoFullName.split('/', 2);\n const client = new GitHubClient();\n const result = await fetchRemoteWorkspaceJson(async (p) => {\n const f = await client.getContents(token, owner, name, p, link.source.branch);\n return f?.content ?? null;\n });\n if ('error' in result) {\n process.stderr.write(\n `${kleur.red('error')}: ${link.source.repoFullName}@${link.source.branch}: ${result.error}\\n`,\n );\n process.exit(2);\n }\n const probe = parseLinkedWorkspaceJson(result.content);\n const ledger = ledgerFromProbe(probe);\n const needsSnapshot = !state.local.linkedCollections[id];\n const snapshot = needsSnapshot ? (buildLinkedSnapshot(probe, link) ?? undefined) : undefined;\n const out = applyMutation(state, {\n kind: 'linkedWorkspace.upsert',\n link,\n ledger,\n ...(snapshot ? { snapshot } : {}),\n });\n await saveToFile(dir, out.next);\n process.stdout.write(\n `${kleur.green('refreshed')} ${kleur.bold(link.name)} ${kleur.dim(`(${ledger.versions.length} version(s), current ${ledger.currentVersion ?? 'none'})`)}\\n`,\n );\n });\n\n linked\n .command('unlink <id>')\n .description('Unlink a workspace (drops cached ledger + overrides + snapshot).')\n .option('--workspace-name <name-or-id>', 'Workspace name or id.')\n .option('-w, --workspace-path <dir>', 'Workspace folder path.')\n .action(async (id: string, opts: SharedOptions) => {\n const dir = await resolveDir(opts);\n const state = await ensureWorkspace(dir);\n if (!state.synced.linkedWorkspaces[id]) {\n process.stderr.write(`${kleur.red('error')}: linked workspace ${id} not found\\n`);\n process.exit(2);\n }\n const out = applyMutation(state, { kind: 'linkedWorkspace.remove', id });\n await saveToFile(dir, out.next);\n process.stdout.write(`${kleur.green('unlinked')} ${kleur.dim(id)}\\n`);\n });\n}\n","// Typed errors for the GitHub REST client. Catching these in the UI lets us\n// drive the right recovery path: scope-missing → \"Update token now?\" modal,\n// rate-limited → \"wait N seconds\" copy, network → \"check your connection,\"\n// unknown 5xx → generic.\n\nexport class GitHubError extends Error {\n constructor(\n message: string,\n readonly status: number,\n readonly body?: unknown,\n ) {\n super(message);\n this.name = 'GitHubError';\n }\n}\n\nexport class MissingScopeError extends GitHubError {\n /** Scope strings the API said are missing, e.g. ['pull_request']. */\n readonly missingScopes: string[];\n /** Scope strings the token currently grants, parsed from x-oauth-scopes. */\n readonly grantedScopes: string[];\n\n constructor(message: string, status: number, missingScopes: string[], grantedScopes: string[]) {\n super(message, status);\n this.name = 'MissingScopeError';\n this.missingScopes = missingScopes;\n this.grantedScopes = grantedScopes;\n }\n}\n\nexport class RateLimitedError extends GitHubError {\n /** Unix timestamp (ms) when the rate-limit window resets. */\n readonly resetAtMs: number;\n constructor(message: string, status: number, resetAtMs: number) {\n super(message, status);\n this.name = 'RateLimitedError';\n this.resetAtMs = resetAtMs;\n }\n}\n\nexport class UnauthorizedError extends GitHubError {\n constructor(message: string, status: number) {\n super(message, status);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * The fetch was aborted by our own timeout (default 15 s). Surfaced with\n * status 0 because there was no HTTP response. Distinct from a generic\n * `GitHubError(0)` so the UI can render retry-able copy and warn the user\n * that a write may have partially landed on the server.\n */\nexport class TimeoutError extends GitHubError {\n /** Timeout that fired, in ms. Useful for the UI message. */\n readonly timeoutMs: number;\n constructor(message: string, timeoutMs: number) {\n super(message, 0);\n this.name = 'TimeoutError';\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Remote ref moved since we last synced — e.g. someone force-pushed the\n * branch. Thrown by `pushWorkspace` *before* uploading blobs, so the user\n * is steered to refresh first rather than discovering the divergence\n * inside a failed `updateRef`.\n */\nexport class BranchDivergedError extends GitHubError {\n readonly expectedSha: string;\n readonly actualSha: string;\n constructor(message: string, expectedSha: string, actualSha: string) {\n super(message, 0);\n this.name = 'BranchDivergedError';\n this.expectedSha = expectedSha;\n this.actualSha = actualSha;\n }\n}\n","// Tiny GitHub REST client. We avoid pulling in @octokit/* because we only\n// need a handful of endpoints and the typed errors are more important than\n// the breadth of coverage.\n//\n// Token-handling rule: the caller passes the PAT per call. The client never\n// logs it, never stores it, never includes it in error messages. The host\n// (ui-components) is responsible for token storage (Secret Vault).\n\nimport {\n GitHubError,\n MissingScopeError,\n RateLimitedError,\n TimeoutError,\n UnauthorizedError,\n} from './errors';\n\nconst API_BASE = 'https://api.github.com';\nconst LOGIN_BASE = 'https://github.com';\n\nexport interface GitHubViewer {\n login: string;\n id: number;\n name: string | null;\n avatarUrl: string | null;\n}\n\nexport interface ScopeInfo {\n granted: string[];\n acceptedRequired?: string[];\n}\n\nexport interface GitHubRepo {\n /** owner/name, the canonical workspace identifier on GitHub. */\n fullName: string;\n owner: string;\n name: string;\n defaultBranch: string;\n visibility: 'public' | 'private' | 'internal';\n isPrivate: boolean;\n pushable: boolean;\n}\n\nexport interface GitHubBranch {\n name: string;\n commitSha: string;\n}\n\nexport interface GitHubClientOptions {\n /** Override the API base URL (e.g. GitHub Enterprise). */\n baseUrl?: string;\n /**\n * Override the base for `github.com/login/*` OAuth endpoints. Defaults to\n * `https://github.com`. The browser path sets this to a same-origin\n * proxy (e.g. `/_gh-oauth`) because GitHub doesn't send CORS headers on\n * the device-flow endpoints.\n */\n loginBaseUrl?: string;\n /** Inject a custom fetch — used by tests to mock without msw. */\n fetchImpl?: typeof fetch;\n /** Hard timeout per call. Defaults to 15s. */\n timeoutMs?: number;\n}\n\nexport interface GitRef {\n ref: string; // e.g. \"refs/heads/apicircle/payments-a3f9c2\"\n sha: string;\n}\n\nexport interface GitCommitSummary {\n sha: string;\n treeSha: string;\n message: string;\n}\n\nexport interface TreeEntryInput {\n path: string;\n mode?: '100644' | '100755' | '040000' | '160000' | '120000';\n type?: 'blob' | 'tree' | 'commit';\n /** Inline content — used for text files we don't need to base64. */\n content?: string;\n /** Pre-uploaded blob sha — used for binary attachments. */\n sha?: string | null;\n}\n\nexport interface CreatedTree {\n sha: string;\n}\n\nexport interface CreatedCommit {\n sha: string;\n treeSha: string;\n}\n\nexport interface CreatedBlob {\n sha: string;\n size: number;\n}\n\nexport interface PullRequestSummary {\n number: number;\n /** GitHub UI URL (e.g. https://github.com/me/api/pull/12) — what we link to. */\n htmlUrl: string;\n state: 'open' | 'closed';\n title: string;\n}\n\nexport interface MarketplaceRepo {\n fullName: string;\n owner: string;\n name: string;\n description: string;\n topics: string[];\n stargazers: number;\n defaultBranch: string;\n}\n\nexport interface FileContents {\n /** Raw file bytes decoded from GitHub's base64 transport. */\n content: string;\n /** Git blob SHA — used for fast equality checks across pulls. */\n sha: string;\n /** Path returned by GitHub (matches what we requested). */\n path: string;\n size: number;\n}\n\nexport interface BinaryFileContents {\n /** Raw file bytes — used for binary attachments where UTF-8 decoding would corrupt the data. */\n bytes: Uint8Array;\n sha: string;\n path: string;\n size: number;\n}\n\nconst DEFAULT_TIMEOUT_MS = 15_000;\n\ninterface CallOptions {\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n body?: unknown;\n signal?: AbortSignal;\n /** Scopes the caller wants verified — surfaced into MissingScopeError. */\n requiredScopes?: string[];\n}\n\nexport class GitHubClient {\n private readonly baseUrl: string;\n private readonly loginBaseUrl: string;\n private readonly fetchImpl: typeof fetch;\n private readonly timeoutMs: number;\n\n constructor(opts: GitHubClientOptions = {}) {\n this.baseUrl = opts.baseUrl ?? API_BASE;\n this.loginBaseUrl = (opts.loginBaseUrl ?? LOGIN_BASE).replace(/\\/$/, '');\n this.fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);\n this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n }\n\n /**\n * Fetch the authenticated user. Doubles as a \"verify token\" probe — used\n * by the Secret Vault Sessions tab to refresh the granted-scopes list.\n */\n async getViewer(\n token: string,\n opts: CallOptions = {},\n ): Promise<{\n viewer: GitHubViewer;\n scopes: ScopeInfo;\n }> {\n const { json, response } = await this.call<RawUser>(token, '/user', opts);\n return {\n viewer: {\n login: json.login,\n id: json.id,\n name: json.name ?? null,\n avatarUrl: json.avatar_url ?? null,\n },\n scopes: parseScopes(response.headers),\n };\n }\n\n /**\n * List repositories the authenticated user can access. Used by the repo\n * picker. Capped at 100 sorted by recent push; users with thousands of\n * repos can paginate later.\n */\n async listAccessibleRepos(token: string, opts: CallOptions = {}): Promise<GitHubRepo[]> {\n const { json } = await this.call<RawRepo[]>(\n token,\n '/user/repos?per_page=100&sort=pushed&affiliation=owner,collaborator,organization_member',\n opts,\n );\n return json.map(normalizeRepo);\n }\n\n /**\n * Fetch a specific repo. Validates the user-supplied owner/name pair\n * exists + is accessible, and exposes the default branch.\n */\n async getRepo(\n token: string,\n owner: string,\n name: string,\n opts: CallOptions = {},\n ): Promise<GitHubRepo> {\n const { json } = await this.call<RawRepo>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`,\n opts,\n );\n return normalizeRepo(json);\n }\n\n /**\n * Read the head SHA of a branch. Used to seed a new working branch from\n * main before any edits land.\n */\n async getBranchHead(\n token: string,\n owner: string,\n name: string,\n branch: string,\n opts: CallOptions = {},\n ): Promise<GitHubBranch> {\n const { json } = await this.call<RawBranch>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/branches/${encodeURIComponent(branch)}`,\n opts,\n );\n return { name: json.name, commitSha: json.commit.sha };\n }\n\n /**\n * List branches on a repo. Used by the Link Workspace repo-browser to\n * populate the branch dropdown after the user picks a repo. Capped at\n * 100 (GitHub's max page size); repos with more branches paginate.\n */\n async listBranches(\n token: string,\n owner: string,\n name: string,\n opts: CallOptions = {},\n ): Promise<GitHubBranch[]> {\n const { json } = await this.call<RawBranch[]>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/branches?per_page=100`,\n opts,\n );\n return json.map((b) => ({ name: b.name, commitSha: b.commit.sha }));\n }\n\n /**\n * Create a new branch ref pointing at `sha`. The auto-branch flow calls\n * this with the head SHA from `getBranchHead(main)`.\n *\n * GitHub returns 422 with \"Reference already exists\" when the branch\n * already exists; that surfaces as a GitHubError(422) so the UI can\n * prompt for a different name.\n */\n async createBranch(\n token: string,\n owner: string,\n name: string,\n branchName: string,\n sha: string,\n opts: CallOptions = {},\n ): Promise<GitHubBranch> {\n const { json } = await this.call<RawRefResponse>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/refs`,\n {\n ...opts,\n method: 'POST',\n body: { ref: `refs/heads/${branchName}`, sha },\n requiredScopes: ['repo'],\n },\n );\n return { name: branchName, commitSha: json.object.sha };\n }\n\n /**\n * Read a branch ref's current commit SHA. Used at the start of push-to-\n * save to find the parent commit before building the new tree.\n */\n async getRef(\n token: string,\n owner: string,\n name: string,\n branch: string,\n opts: CallOptions = {},\n ): Promise<GitRef> {\n const { json } = await this.call<RawRefResponse>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/refs/heads/${encodeURIComponent(branch)}`,\n opts,\n );\n return { ref: json.ref, sha: json.object.sha };\n }\n\n /**\n * Read a commit's tree SHA. Used so the new tree can be built `base_tree`\n * — every path we don't override is inherited from the parent.\n */\n async getCommit(\n token: string,\n owner: string,\n name: string,\n sha: string,\n opts: CallOptions = {},\n ): Promise<GitCommitSummary> {\n const { json } = await this.call<RawCommit>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/commits/${encodeURIComponent(sha)}`,\n opts,\n );\n return {\n sha: json.sha,\n treeSha: json.tree.sha,\n message: json.message,\n };\n }\n\n /**\n * Upload a blob to the repo and return its SHA. Used by push-to-save\n * (P4.3b) for binary attachments — text files go straight into a tree\n * entry's `content`, but binary bytes have to go through a blob first.\n *\n * `content` is base64 when `encoding === 'base64'`. GitHub stores blobs\n * deduplicated by their git-sha1 (not our sha256), so re-uploading the\n * same bytes is cheap on their side; we save a roundtrip locally by\n * tracking lastPushedBlobSha per slot in a future revision.\n */\n async createBlob(\n token: string,\n owner: string,\n name: string,\n args: { content: string; encoding: 'utf-8' | 'base64' },\n opts: CallOptions = {},\n ): Promise<CreatedBlob> {\n const { json } = await this.call<{ sha: string; size?: number }>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/blobs`,\n {\n ...opts,\n method: 'POST',\n body: { content: args.content, encoding: args.encoding },\n requiredScopes: ['repo'],\n },\n );\n return { sha: json.sha, size: json.size ?? 0 };\n }\n\n /**\n * Build a new tree from `entries`, layered over `baseTreeSha`. Entries\n * with `content` are inlined (text path); entries with a pre-uploaded\n * `sha` reference an existing blob (binary path — used by attachments).\n */\n async createTree(\n token: string,\n owner: string,\n name: string,\n args: { baseTreeSha: string; entries: TreeEntryInput[] },\n opts: CallOptions = {},\n ): Promise<CreatedTree> {\n const tree = args.entries.map((e) => ({\n path: e.path,\n mode: e.mode ?? '100644',\n type: e.type ?? 'blob',\n ...(e.content !== undefined ? { content: e.content } : {}),\n ...(e.sha !== undefined ? { sha: e.sha } : {}),\n }));\n const { json } = await this.call<{ sha: string }>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/trees`,\n {\n ...opts,\n method: 'POST',\n body: { base_tree: args.baseTreeSha, tree },\n requiredScopes: ['repo'],\n },\n );\n return { sha: json.sha };\n }\n\n /**\n * Create a new commit object pointing at the given tree, with the given\n * parents. Returns the new commit's SHA + the tree it points at.\n */\n async createCommit(\n token: string,\n owner: string,\n name: string,\n args: { message: string; treeSha: string; parents: string[] },\n opts: CallOptions = {},\n ): Promise<CreatedCommit> {\n const { json } = await this.call<RawCommit>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/commits`,\n {\n ...opts,\n method: 'POST',\n body: {\n message: args.message,\n tree: args.treeSha,\n parents: args.parents,\n },\n requiredScopes: ['repo'],\n },\n );\n return { sha: json.sha, treeSha: json.tree.sha };\n }\n\n /**\n * Fast-forward a branch ref to a new commit SHA. Pass `force: true` to\n * skip the FF check (we don't — push-to-save is always FF over the ref\n * we just read with getRef()).\n */\n async updateRef(\n token: string,\n owner: string,\n name: string,\n args: { branch: string; sha: string; force?: boolean },\n opts: CallOptions = {},\n ): Promise<GitRef> {\n const { json } = await this.call<RawRefResponse>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/refs/heads/${encodeURIComponent(args.branch)}`,\n {\n ...opts,\n method: 'PATCH',\n body: { sha: args.sha, force: args.force ?? false },\n requiredScopes: ['repo'],\n },\n );\n return { ref: json.ref, sha: json.object.sha };\n }\n\n /**\n * Search GitHub for public API Circle workspaces. Appends\n * `topic:apicircle` to the user-supplied query so only repos carrying\n * the `apicircle` topic — the topic the Releases & Topics dialog\n * locks onto every workspace repo — surface in results. GitHub\n * matches the bare query against repository name, description, and\n * topics, so category words like `payments` narrow the marketplace by\n * topic. An empty query lists every public API Circle workspace. Top\n * 30 results. Token is optional — anonymous browsing is supported\n * (lower GitHub rate limits apply); pass a PAT when one is available\n * to lift them. `sort` controls ordering: omit for GitHub's\n * best-match relevance, or pass `'stars'` / `'updated'`.\n */\n async searchMarketplaceRepos(\n token: string | null,\n query: string,\n opts: CallOptions & { sort?: 'stars' | 'updated' } = {},\n ): Promise<MarketplaceRepo[]> {\n const { sort, ...callOpts } = opts;\n const fullQuery = `${query.trim()} topic:apicircle`.trim();\n const sortParam = sort ? `&sort=${sort}&order=desc` : '';\n const path = `/search/repositories?q=${encodeURIComponent(fullQuery)}&per_page=30${sortParam}`;\n const { json } = await this.call<{ items?: RawSearchRepo[] }>(token, path, callOpts);\n const items = json.items ?? [];\n return items.map(normalizeMarketplaceRepo);\n }\n\n /**\n * Start GitHub's OAuth Device Flow. Returns a user-facing code the\n * user types into github.com/login/device + a device_code the app\n * polls with. Pure browser-safe: no client_secret involved (device\n * flow is the only OAuth path GitHub supports for public clients).\n *\n * Requires the OAuth App to have \"Enable Device Flow\" turned on in\n * its GitHub settings — surface 400 with `not_supported` to the user\n * if the App owner hasn't done that yet.\n */\n async startDeviceFlow(\n clientId: string,\n scope: string,\n opts: CallOptions = {},\n ): Promise<{\n deviceCode: string;\n userCode: string;\n verificationUri: string;\n expiresIn: number;\n interval: number;\n }> {\n const url = `${this.loginBaseUrl}/login/device/code`;\n const response = await this.fetchImpl(url, {\n method: 'POST',\n headers: { Accept: 'application/json', 'Content-Type': 'application/json' },\n body: JSON.stringify({ client_id: clientId, scope }),\n signal: opts.signal,\n });\n if (!response.ok) {\n throw new GitHubError(\n `Device-flow start failed: HTTP ${response.status}`,\n response.status,\n {},\n );\n }\n const json = (await response.json()) as {\n device_code: string;\n user_code: string;\n verification_uri: string;\n expires_in: number;\n interval: number;\n error?: string;\n error_description?: string;\n };\n if (json.error) {\n throw new GitHubError(json.error_description ?? json.error, 400, json);\n }\n return {\n deviceCode: json.device_code,\n userCode: json.user_code,\n verificationUri: json.verification_uri,\n expiresIn: json.expires_in,\n interval: json.interval,\n };\n }\n\n /**\n * Poll for the access token after the user has authorized the device\n * code. GitHub returns `authorization_pending` until the user\n * completes the flow, `slow_down` if we polled too fast, then a real\n * token. Caller wraps this in a polling loop bounded by `expiresIn`.\n */\n async pollDeviceToken(\n clientId: string,\n deviceCode: string,\n opts: CallOptions = {},\n ): Promise<\n | { kind: 'pending'; slowDown: boolean }\n | { kind: 'denied'; reason: string }\n | { kind: 'expired' }\n | { kind: 'granted'; accessToken: string; tokenType: string; scope: string }\n > {\n const url = `${this.loginBaseUrl}/login/oauth/access_token`;\n const response = await this.fetchImpl(url, {\n method: 'POST',\n headers: { Accept: 'application/json', 'Content-Type': 'application/json' },\n body: JSON.stringify({\n client_id: clientId,\n device_code: deviceCode,\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n }),\n signal: opts.signal,\n });\n const json = (await response.json()) as {\n access_token?: string;\n token_type?: string;\n scope?: string;\n error?: string;\n error_description?: string;\n };\n if (json.access_token) {\n return {\n kind: 'granted',\n accessToken: json.access_token,\n tokenType: json.token_type ?? 'bearer',\n scope: json.scope ?? '',\n };\n }\n if (json.error === 'authorization_pending') return { kind: 'pending', slowDown: false };\n if (json.error === 'slow_down') return { kind: 'pending', slowDown: true };\n if (json.error === 'expired_token') return { kind: 'expired' };\n if (json.error === 'access_denied')\n return { kind: 'denied', reason: json.error_description ?? 'User denied authorization' };\n // Any other error: throw so the UI surfaces it.\n throw new GitHubError(\n json.error_description ?? json.error ?? 'Device-token poll failed',\n response.status,\n json,\n );\n }\n\n /**\n * Create a lightweight Git tag (a ref under `refs/tags/<name>`) on the\n * given commit SHA. Used by the publish-release flow when the user\n * opts in to \"Create Git tag v<x.y.z>\". Returns the resolved ref.\n *\n * GitHub returns 422 with \"Reference already exists\" when the tag is\n * a duplicate; that surfaces as a GitHubError(422) so the UI can warn\n * the user without ever overwriting an existing tag.\n */\n async createTag(\n token: string,\n owner: string,\n name: string,\n args: { tagName: string; sha: string },\n opts: CallOptions = {},\n ): Promise<GitRef> {\n const { json } = await this.call<RawRefResponse>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/refs`,\n {\n ...opts,\n method: 'POST',\n body: { ref: `refs/tags/${args.tagName}`, sha: args.sha },\n requiredScopes: ['repo'],\n },\n );\n return { ref: json.ref, sha: json.object.sha };\n }\n\n /**\n * Compare two commits. Returns the relationship classification GitHub\n * gives us: `ahead` (head is descendant of base), `behind` (base is\n * descendant of head), `identical`, or `diverged` (the two histories\n * share a base but neither contains the other — typical of a force-push\n * that rewrote history under us).\n *\n * Used by the refresh path so we never silently 3-way-merge across a\n * history rewrite — divergence steers the user through an explicit\n * \"history rewritten\" modal instead of corrupting local state.\n */\n async compareCommits(\n token: string,\n owner: string,\n name: string,\n base: string,\n head: string,\n opts: CallOptions = {},\n ): Promise<{\n status: 'ahead' | 'behind' | 'identical' | 'diverged';\n aheadBy: number;\n behindBy: number;\n }> {\n const { json } = await this.call<{\n status: 'ahead' | 'behind' | 'identical' | 'diverged';\n ahead_by: number;\n behind_by: number;\n }>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/compare/${encodeURIComponent(\n base,\n )}...${encodeURIComponent(head)}`,\n { ...opts, requiredScopes: ['repo'] },\n );\n return {\n status: json.status,\n aheadBy: json.ahead_by,\n behindBy: json.behind_by,\n };\n }\n\n /**\n * Is `ancestor` reachable from `descendant`? Thin wrapper around\n * `compareCommits` — \"ahead\" or \"identical\" means yes; \"behind\" or\n * \"diverged\" means the histories don't fit, so the answer is no.\n */\n async isAncestor(\n token: string,\n owner: string,\n name: string,\n ancestor: string,\n descendant: string,\n opts: CallOptions = {},\n ): Promise<boolean> {\n if (ancestor === descendant) return true;\n const cmp = await this.compareCommits(token, owner, name, ancestor, descendant, opts);\n return cmp.status === 'ahead' || cmp.status === 'identical';\n }\n\n /**\n * Create a GitHub Release pointing at an existing tag. Used by the\n * publish-release flow when the user opts in to \"Create GitHub\n * Release\". Returns the release's HTML URL so the UI can show a\n * \"Released — view on GitHub\" link.\n *\n * Pass `prerelease: true` for semver pre-release identifiers (e.g.\n * `1.0.0-rc.1`); GitHub's Releases UI flags those distinctly.\n */\n async createRelease(\n token: string,\n owner: string,\n name: string,\n args: {\n tagName: string;\n releaseName?: string;\n body?: string;\n draft?: boolean;\n prerelease?: boolean;\n },\n opts: CallOptions = {},\n ): Promise<{ id: number; htmlUrl: string; tagName: string }> {\n const { json } = await this.call<{\n id: number;\n html_url: string;\n tag_name: string;\n }>(token, `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/releases`, {\n ...opts,\n method: 'POST',\n body: {\n tag_name: args.tagName,\n name: args.releaseName ?? args.tagName,\n body: args.body ?? '',\n draft: args.draft ?? false,\n prerelease: args.prerelease ?? false,\n },\n requiredScopes: ['repo'],\n });\n return { id: json.id, htmlUrl: json.html_url, tagName: json.tag_name };\n }\n\n /**\n * Read a tag ref's current commit SHA. Used by the Release & topics\n * modal to detect whether a tag with the chosen name already exists\n * (so the UI can surface an \"Override existing tag\" toggle instead of\n * silently 422'ing through createTag).\n *\n * Returns `null` when the tag doesn't exist (404). Other failures\n * surface as typed errors.\n */\n async getTagSha(\n token: string,\n owner: string,\n name: string,\n tagName: string,\n opts: CallOptions = {},\n ): Promise<string | null> {\n try {\n const { json } = await this.call<RawRefResponse>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/refs/tags/${encodeURIComponent(tagName)}`,\n opts,\n );\n return json.object.sha;\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return null;\n throw err;\n }\n }\n\n /**\n * Delete a ref. Used to support the \"Override existing tag\" path on\n * the Release & topics modal — we delete the existing tag ref, then\n * createTag against the new SHA. (GitHub doesn't have a single\n * \"force-update tag\" endpoint via the simple refs API.)\n *\n * `ref` is the bare suffix, e.g. `tags/v1.0.0` or `heads/feature-x`.\n */\n async deleteRef(\n token: string,\n owner: string,\n name: string,\n ref: string,\n opts: CallOptions = {},\n ): Promise<void> {\n await this.call<unknown>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/git/refs/${ref\n .split('/')\n .map(encodeURIComponent)\n .join('/')}`,\n {\n ...opts,\n method: 'DELETE',\n requiredScopes: ['repo'],\n },\n );\n }\n\n /**\n * Read the repo's current topic list. Topics drive marketplace\n * discoverability — public API Circle workspaces include `apicircle`\n * plus user-chosen category topics.\n *\n * Note: GitHub's topics API uses a custom Accept header, but we treat\n * that as transport detail; the `application/vnd.github.mercy-preview+json`\n * preview is now stable so the default Accept works.\n */\n async listRepoTopics(\n token: string,\n owner: string,\n name: string,\n opts: CallOptions = {},\n ): Promise<string[]> {\n const { json } = await this.call<{ names: string[] }>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/topics`,\n opts,\n );\n return Array.isArray(json.names) ? json.names : [];\n }\n\n /**\n * Replace the repo's full topic list. GitHub's `PUT /topics` endpoint\n * is a full replace (not a merge), so the caller must pass the\n * complete desired list. Caps at 20 topics; each must match\n * `^[a-z0-9][a-z0-9-]*$` and be ≤ 50 chars (GitHub enforces this with\n * a 422). Returns the persisted list.\n */\n async setRepoTopics(\n token: string,\n owner: string,\n name: string,\n topics: string[],\n opts: CallOptions = {},\n ): Promise<string[]> {\n const { json } = await this.call<{ names: string[] }>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/topics`,\n {\n ...opts,\n method: 'PUT',\n body: { names: topics },\n requiredScopes: ['repo'],\n },\n );\n return Array.isArray(json.names) ? json.names : [];\n }\n\n /**\n * Fetch a single file's contents from a branch / commit. Returns\n * `null` when GitHub answers 404 (file simply doesn't exist on that\n * ref — the common case for the very first pull). Other failures\n * surface as the usual typed errors.\n *\n * Used by the refresh flow to read remote `workspace.json` so the\n * 3-way diff can compare it against the local doc.\n */\n async getContents(\n token: string,\n owner: string,\n name: string,\n path: string,\n ref: string,\n opts: CallOptions = {},\n ): Promise<FileContents | null> {\n const query = `?ref=${encodeURIComponent(ref)}`;\n try {\n const { json } = await this.call<RawFileContents>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/contents/${path\n .split('/')\n .map(encodeURIComponent)\n .join('/')}${query}`,\n opts,\n );\n // GitHub may return an array for directories — we only care about files.\n if (Array.isArray(json) || json.type !== 'file') {\n throw new GitHubError(`Path ${path} is not a file`, 422, json);\n }\n // GitHub wraps base64 in lines of 60 chars + \\n; strip them before decoding.\n const cleaned = json.content.replace(/\\n/g, '');\n const decoded = decodeBase64Utf8(cleaned);\n return { content: decoded, sha: json.sha, path: json.path, size: json.size };\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return null;\n throw err;\n }\n }\n\n /**\n * Create or update a file via the Contents API. The killer feature here\n * vs. the git-data flow (createBlob → createTree → createCommit →\n * updateRef) is that this works on **truly empty repos**: GitHub's git\n * database isn't initialized until the first commit lands, so all the\n * `/git/*` endpoints reject with 409 \"Git Repository is empty\" — but\n * `PUT /contents/{path}` atomically initializes the database with a\n * single-file commit on the supplied branch (defaulting to the repo's\n * default branch).\n *\n * Used by the seed-initial-commit flow to bootstrap a freshly-created\n * empty repo with a scaffold `workspace.json`.\n *\n * `contentBase64` must already be base64-encoded — caller chooses the\n * encoder (TextEncoder for UTF-8 strings, raw bytes for binaries).\n */\n async putContents(\n token: string,\n owner: string,\n name: string,\n path: string,\n args: { message: string; contentBase64: string; branch?: string; sha?: string },\n opts: CallOptions = {},\n ): Promise<{ commitSha: string; contentSha: string }> {\n const body: Record<string, unknown> = {\n message: args.message,\n content: args.contentBase64,\n };\n if (args.branch) body.branch = args.branch;\n if (args.sha) body.sha = args.sha;\n const { json } = await this.call<{\n commit: { sha: string };\n content: { sha: string };\n }>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/contents/${path\n .split('/')\n .map(encodeURIComponent)\n .join('/')}`,\n {\n ...opts,\n method: 'PUT',\n body,\n requiredScopes: ['repo'],\n },\n );\n return { commitSha: json.commit.sha, contentSha: json.content.sha };\n }\n\n /**\n * Same as `getContents` but returns the raw bytes instead of UTF-8\n * decoding the file. Used by the refresh flow to pull\n * `.apicircle/workspace-<id>/attachments/<slotId>` blobs into local IDB without\n * mangling binary data through TextDecoder.\n */\n async getBinaryContents(\n token: string,\n owner: string,\n name: string,\n path: string,\n ref: string,\n opts: CallOptions = {},\n ): Promise<BinaryFileContents | null> {\n const query = `?ref=${encodeURIComponent(ref)}`;\n try {\n const { json } = await this.call<RawFileContents>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/contents/${path\n .split('/')\n .map(encodeURIComponent)\n .join('/')}${query}`,\n opts,\n );\n if (Array.isArray(json) || json.type !== 'file') {\n throw new GitHubError(`Path ${path} is not a file`, 422, json);\n }\n const cleaned = json.content.replace(/\\n/g, '');\n const bytes = decodeBase64Bytes(cleaned);\n return { bytes, sha: json.sha, path: json.path, size: json.size };\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return null;\n throw err;\n }\n }\n\n /**\n * Open a pull request from `head` (the working branch) into `base` (the\n * repo's default branch). PR creation needs the `pull_request` scope on\n * top of `repo`; missing-scope errors flow through MissingScopeError so\n * the UI can prompt the user to update the token without losing branch\n * state (Plan §3.7).\n *\n * GitHub returns 422 when:\n * - head/base are equal (nothing to merge)\n * - a PR already exists between this head and base\n * - the head branch doesn't exist\n * All three surface as a plain GitHubError(422); the UI message is\n * picked up from response.body.message.\n */\n /**\n * Fetch a single pull request by number. Used by the refresh flow to\n * detect whether a previously-opened PR has been merged on GitHub —\n * `merged: true` is what triggers the working-branch retirement path.\n *\n * Returns `null` on 404 (PR was deleted or never existed at this number);\n * other failures surface as the usual typed errors.\n */\n async getPullRequest(\n token: string,\n owner: string,\n name: string,\n number: number,\n opts: CallOptions = {},\n ): Promise<{\n number: number;\n htmlUrl: string;\n state: 'open' | 'closed';\n merged: boolean;\n } | null> {\n try {\n const { json } = await this.call<RawPullRequest & { merged?: boolean }>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/pulls/${number}`,\n opts,\n );\n return {\n number: json.number,\n htmlUrl: json.html_url,\n state: json.state,\n merged: json.merged === true,\n };\n } catch (err) {\n if (err instanceof GitHubError && err.status === 404) return null;\n throw err;\n }\n }\n\n /**\n * List pull requests on a repo. The capability-probe path uses this with\n * `perPage: 1` to determine whether the token can read PRs (and, by\n * extension on classic PATs, whether it can also create them).\n *\n * Caller declares `requiredScopes` to surface a `MissingScopeError` on\n * 403, so the capability probe can recognise the missing-scope case\n * cleanly vs. transient 5xx/network failures.\n */\n async listPullRequests(\n token: string,\n owner: string,\n name: string,\n args: { perPage?: number; state?: 'open' | 'closed' | 'all' } = {},\n opts: CallOptions = {},\n ): Promise<PullRequestSummary[]> {\n const params = new URLSearchParams();\n params.set('per_page', String(args.perPage ?? 30));\n if (args.state) params.set('state', args.state);\n const { json } = await this.call<RawPullRequest[]>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/pulls?${params.toString()}`,\n {\n ...opts,\n requiredScopes: ['repo', 'pull_request'],\n },\n );\n return json.map((pr) => ({\n number: pr.number,\n htmlUrl: pr.html_url,\n state: pr.state,\n title: pr.title,\n }));\n }\n\n async createPullRequest(\n token: string,\n owner: string,\n name: string,\n args: { title: string; body: string; head: string; base: string; draft?: boolean },\n opts: CallOptions = {},\n ): Promise<PullRequestSummary> {\n const { json } = await this.call<RawPullRequest>(\n token,\n `/repos/${encodeURIComponent(owner)}/${encodeURIComponent(name)}/pulls`,\n {\n ...opts,\n method: 'POST',\n body: {\n title: args.title,\n body: args.body,\n head: args.head,\n base: args.base,\n draft: args.draft ?? false,\n },\n requiredScopes: ['repo', 'pull_request'],\n },\n );\n return {\n number: json.number,\n htmlUrl: json.html_url,\n state: json.state,\n title: json.title,\n };\n }\n\n // --- low-level call ----------------------------------------------------\n\n private async call<T>(\n token: string | null,\n path: string,\n opts: CallOptions = {},\n ): Promise<{ json: T; response: Response }> {\n const url = path.startsWith('http') ? path : `${this.baseUrl}${path}`;\n const controller = new AbortController();\n const onExternalAbort = () => controller.abort(opts.signal!.reason);\n if (opts.signal) {\n if (opts.signal.aborted) controller.abort(opts.signal.reason);\n else opts.signal.addEventListener('abort', onExternalAbort, { once: true });\n }\n const timeoutHandle = setTimeout(\n () => controller.abort(new Error(`GitHub request timed out after ${this.timeoutMs}ms`)),\n this.timeoutMs,\n );\n\n let response: Response;\n let timedOut = false;\n try {\n response = await this.fetchImpl(url, {\n method: opts.method ?? 'GET',\n headers: {\n Accept: 'application/vnd.github+json',\n 'X-GitHub-Api-Version': '2022-11-28',\n ...(token ? { Authorization: `Bearer ${token}` } : {}),\n ...(opts.body !== undefined ? { 'Content-Type': 'application/json' } : {}),\n },\n cache: 'no-store',\n body: opts.body !== undefined ? JSON.stringify(opts.body) : undefined,\n signal: controller.signal,\n });\n } catch (err) {\n // Distinguish *our* timeout from a network error or a caller-aborted\n // request. AbortError + a non-aborted external signal === our timeout.\n const isAbort = err instanceof DOMException && err.name === 'AbortError';\n const callerAborted = opts.signal?.aborted ?? false;\n if (isAbort && !callerAborted) {\n timedOut = true;\n throw new TimeoutError(\n `GitHub request timed out after ${this.timeoutMs}ms. The write may have partially landed — refresh before retrying.`,\n this.timeoutMs,\n );\n }\n throw err;\n } finally {\n clearTimeout(timeoutHandle);\n if (opts.signal) opts.signal.removeEventListener('abort', onExternalAbort);\n // Silence unused-let warning under strict ts; `timedOut` is a marker\n // for callers reading the catch block to follow the flow.\n void timedOut;\n }\n\n if (response.ok) {\n // 204 No Content (and 205 Reset Content) carry an empty body —\n // calling .json() on those throws \"Unexpected end of JSON input\".\n // The caller types the response as `T` so an empty object is the\n // safe sentinel; DELETE-style endpoints either ignore the value\n // or care only about `response.status`.\n if (response.status === 204 || response.status === 205) {\n return { json: {} as T, response };\n }\n const json = (await response.json()) as T;\n return { json, response };\n }\n\n const errBody = await safeReadJson(response);\n throw classifyError(response, errBody, opts.requiredScopes ?? []);\n }\n}\n\n// --- helpers ---------------------------------------------------------------\n\ninterface RawUser {\n login: string;\n id: number;\n name?: string | null;\n avatar_url?: string;\n}\n\ninterface RawRepo {\n full_name: string;\n name: string;\n owner: { login: string };\n default_branch: string;\n visibility?: 'public' | 'private' | 'internal';\n private?: boolean;\n permissions?: { push?: boolean; admin?: boolean };\n}\n\ninterface RawBranch {\n name: string;\n commit: { sha: string };\n}\n\ninterface RawRefResponse {\n ref: string;\n object: { sha: string };\n}\n\ninterface RawCommit {\n sha: string;\n message: string;\n tree: { sha: string };\n parents?: { sha: string }[];\n}\n\ninterface RawPullRequest {\n number: number;\n html_url: string;\n state: 'open' | 'closed';\n title: string;\n}\n\ninterface RawSearchRepo {\n full_name: string;\n name: string;\n owner: { login: string };\n description?: string | null;\n topics?: string[];\n stargazers_count?: number;\n default_branch?: string;\n}\n\nfunction normalizeMarketplaceRepo(raw: RawSearchRepo): MarketplaceRepo {\n return {\n fullName: raw.full_name,\n owner: raw.owner.login,\n name: raw.name,\n description: raw.description ?? '',\n topics: raw.topics ?? [],\n stargazers: raw.stargazers_count ?? 0,\n defaultBranch: raw.default_branch ?? 'main',\n };\n}\n\ninterface RawFileContents {\n type: string;\n content: string;\n sha: string;\n path: string;\n size: number;\n encoding: string;\n}\n\n/**\n * Decode GitHub's base64 file content as UTF-8. Pure — doesn't depend on\n * `Buffer` (we run in browsers + jsdom).\n */\nfunction decodeBase64Utf8(b64: string): string {\n return new TextDecoder('utf-8').decode(decodeBase64Bytes(b64));\n}\n\n/**\n * Decode GitHub's base64 file content into raw bytes. Used for binary\n * attachments where UTF-8 decoding would corrupt the data.\n */\nfunction decodeBase64Bytes(b64: string): Uint8Array {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);\n return bytes;\n}\n\nfunction normalizeRepo(raw: RawRepo): GitHubRepo {\n const visibility: GitHubRepo['visibility'] =\n raw.visibility ?? (raw.private === true ? 'private' : 'public');\n const isPrivate = raw.private ?? visibility !== 'public';\n // `permissions` is only included when the caller is authenticated; absence\n // means we can't push (e.g. listing a public repo through an app token).\n const pushable = raw.permissions?.push === true || raw.permissions?.admin === true;\n return {\n fullName: raw.full_name,\n owner: raw.owner.login,\n name: raw.name,\n defaultBranch: raw.default_branch,\n visibility,\n isPrivate,\n pushable,\n };\n}\n\nfunction parseScopes(headers: Headers): ScopeInfo {\n const raw = headers.get('x-oauth-scopes') ?? '';\n const granted = raw\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n const acceptedHeader = headers.get('x-accepted-oauth-scopes') ?? '';\n const acceptedRequired = acceptedHeader\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n return acceptedRequired.length > 0 ? { granted, acceptedRequired } : { granted };\n}\n\nfunction classifyError(\n response: Response,\n body: unknown,\n callerRequiredScopes: string[],\n): GitHubError {\n const message = extractMessage(body) ?? response.statusText;\n const status = response.status;\n\n if (status === 401) {\n return new UnauthorizedError(message || 'Unauthorized — token rejected', status);\n }\n\n if (status === 403) {\n // Rate-limited?\n const remaining = response.headers.get('x-ratelimit-remaining');\n const reset = response.headers.get('x-ratelimit-reset');\n if (remaining === '0' && reset) {\n const resetAtMs = Number(reset) * 1000;\n const deltaMs = Math.max(0, resetAtMs - Date.now());\n const totalSeconds = Math.ceil(deltaMs / 1000);\n const human =\n totalSeconds < 60\n ? `${totalSeconds}s`\n : totalSeconds < 3600\n ? `${Math.ceil(totalSeconds / 60)} min`\n : `${Math.ceil(totalSeconds / 3600)} h`;\n return new RateLimitedError(\n `GitHub rate limit reached. Resets in ${human} (at ${new Date(resetAtMs).toISOString()}).`,\n status,\n resetAtMs,\n );\n }\n // Scope-missing?\n const accepted = (response.headers.get('x-accepted-oauth-scopes') ?? '')\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n const granted = (response.headers.get('x-oauth-scopes') ?? '')\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n const missing =\n accepted.length > 0\n ? accepted.filter((s) => !granted.includes(s))\n : callerRequiredScopes.filter((s) => !granted.includes(s));\n if (missing.length > 0) {\n return new MissingScopeError(\n `GitHub denied this action: missing scopes ${missing.join(', ')}.`,\n status,\n missing,\n granted,\n );\n }\n }\n\n return new GitHubError(message || 'GitHub API call failed', status, body);\n}\n\nfunction extractMessage(body: unknown): string | null {\n if (typeof body === 'object' && body !== null && 'message' in body) {\n const m = body.message;\n if (typeof m === 'string') return m;\n }\n return null;\n}\n\nasync function safeReadJson(response: Response): Promise<unknown> {\n try {\n return (await response.json()) as unknown;\n } catch {\n return null;\n }\n}\n","import type { Command } from 'commander';\nimport kleur from 'kleur';\nimport { GitHubClient } from '@apicircle/git';\n\n// =============================================================================\n// `apicircle release tag <repo> <version>` — create a `v<version>` git tag on\n// the repo's default branch HEAD, optionally a GitHub Release. Tokens come from\n// `--token` or `GITHUB_TOKEN`.\n//\n// `apicircle release topics <repo>` — list / set the repo's topics (the\n// `apicircle` topic is always kept; it drives marketplace discovery).\n// =============================================================================\n\ninterface TagOptions {\n release?: boolean;\n notes?: string;\n override?: boolean;\n token?: string;\n}\n\ninterface TopicsOptions {\n set?: string;\n token?: string;\n}\n\nconst TOPIC_RE = /^[a-z0-9][a-z0-9-]*$/;\n\nfunction resolveToken(opts: { token?: string }): string {\n return (opts.token ?? process.env.GITHUB_TOKEN ?? '').trim();\n}\n\nfunction parseRepo(repo: string): { owner: string; name: string } | null {\n if (!repo.includes('/')) return null;\n const [owner, name] = repo.split('/', 2);\n return { owner, name };\n}\n\nexport function registerReleaseCommand(program: Command): void {\n const release = program\n .command('release')\n .description(\"Tag releases and edit topics on the workspace's GitHub repo.\");\n\n release\n .command('tag <repo> <version>')\n .description('Create a v<version> tag on the default branch HEAD.')\n .option('-r, --release', 'Also create a GitHub Release for the tag.')\n .option('-n, --notes <notes>', 'Release notes (used when --release is set).', '')\n .option('--override', 'Replace an existing tag of the same name.')\n .option('--token <token>', 'GitHub token (or set GITHUB_TOKEN).')\n .action(async (repo: string, version: string, opts: TagOptions) => {\n const parsed = parseRepo(repo);\n if (!parsed) {\n process.stderr.write(`${kleur.red('error')}: repo must be owner/name\\n`);\n process.exit(2);\n }\n const token = resolveToken(opts);\n if (!token) {\n process.stderr.write(\n `${kleur.red('error')}: a token is required (--token or GITHUB_TOKEN)\\n`,\n );\n process.exit(2);\n }\n const tagName = `v${version.replace(/^v/, '')}`;\n const client = new GitHubClient();\n try {\n const meta = await client.getRepo(token, parsed.owner, parsed.name);\n const ref = await client.getRef(token, parsed.owner, parsed.name, meta.defaultBranch);\n const existing = await client.getTagSha(token, parsed.owner, parsed.name, tagName);\n if (existing !== null) {\n if (!opts.override) {\n process.stderr.write(\n `${kleur.red('error')}: tag ${tagName} already exists at ${existing.slice(0, 7)} — pass --override to replace\\n`,\n );\n process.exit(2);\n }\n await client.deleteRef(token, parsed.owner, parsed.name, `tags/${tagName}`);\n }\n await client.createTag(token, parsed.owner, parsed.name, { tagName, sha: ref.sha });\n process.stdout.write(\n `${kleur.green('tagged')} ${kleur.bold(tagName)} ${kleur.dim(`on ${meta.defaultBranch} (${ref.sha.slice(0, 7)})`)}\\n`,\n );\n if (opts.release) {\n const r = await client.createRelease(token, parsed.owner, parsed.name, {\n tagName,\n releaseName: tagName,\n body: opts.notes ?? '',\n });\n process.stdout.write(`${kleur.green('release')} ${kleur.dim(r.htmlUrl)}\\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 release\n .command('topics <repo>')\n .description(\"List or set the repo's topics ('apicircle' is always kept).\")\n .option('--set <topics>', 'Comma-separated topics to set (replaces existing).')\n .option('--token <token>', 'GitHub token (or set GITHUB_TOKEN).')\n .action(async (repo: string, opts: TopicsOptions) => {\n const parsed = parseRepo(repo);\n if (!parsed) {\n process.stderr.write(`${kleur.red('error')}: repo must be owner/name\\n`);\n process.exit(2);\n }\n const token = resolveToken(opts);\n if (!token) {\n process.stderr.write(\n `${kleur.red('error')}: a token is required (--token or GITHUB_TOKEN)\\n`,\n );\n process.exit(2);\n }\n const client = new GitHubClient();\n try {\n if (opts.set === undefined) {\n const list = await client.listRepoTopics(token, parsed.owner, parsed.name);\n if (list.length === 0) {\n process.stdout.write(`${kleur.dim('(no topics)')}\\n`);\n } else {\n for (const t of list) process.stdout.write(`${t}\\n`);\n }\n return;\n }\n const normalized = Array.from(\n new Set([\n 'apicircle',\n ...opts.set\n .split(',')\n .map((t) => t.trim().toLowerCase())\n .filter(Boolean),\n ]),\n );\n for (const t of normalized) {\n if (!TOPIC_RE.test(t)) {\n process.stderr.write(`${kleur.red('error')}: invalid topic \"${t}\"\\n`);\n process.exit(2);\n }\n if (t.length > 50) {\n process.stderr.write(`${kleur.red('error')}: topic \"${t}\" exceeds 50 characters\\n`);\n process.exit(2);\n }\n }\n if (normalized.length > 20) {\n process.stderr.write(`${kleur.red('error')}: GitHub allows at most 20 topics\\n`);\n process.exit(2);\n }\n const saved = await client.setRepoTopics(token, parsed.owner, parsed.name, normalized);\n process.stdout.write(`${kleur.green('topics set')} ${kleur.dim(`(${saved.length})`)}\\n`);\n for (const t of saved) process.stdout.write(` ${t}\\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","import type { Command } from 'commander';\nimport kleur from 'kleur';\nimport type { Folder, RequestAuth } from '@apicircle/shared';\nimport { generateId } from '@apicircle/shared';\nimport { FileBackedWorkspaceProvider } from '@apicircle/mcp-server';\nimport { ensureWorkspace } from '../util/loadWorkspace';\nimport { resolveWorkspace, WorkspaceResolutionError } from '../util/resolveWorkspace';\n\n// =============================================================================\n// `apicircle folder <list | create | rename | set-auth | clear-auth | move |\n// delete>` — manage the workspace's folder tree from the terminal. Every\n// subcommand routes through applyMutation (via FileBackedWorkspaceProvider),\n// so semantics match the MCP / VS Code / UI surfaces exactly.\n//\n// Folder-level auth uses the same LLM-friendly subset MCP exposes\n// (`bearer`, `basic`, `api-key`, `custom-header`, `none`, `inherit`). For\n// OAuth2 / AWS / Hawk / NTLM / JWT folder-auth, edit the folder via the\n// VS Code YAML editor or the web/desktop UI — those grants require runtime\n// state the CLI doesn't have.\n// =============================================================================\n\ninterface BaseOptions {\n workspaceName?: string;\n workspacePath?: string;\n}\n\ninterface CreateOptions extends BaseOptions {\n name?: string;\n parent?: string | null;\n type?: string;\n token?: string;\n username?: string;\n password?: string;\n key?: string;\n value?: string;\n addTo?: string;\n}\n\ninterface RenameOptions extends BaseOptions {\n name: string;\n}\n\ninterface SetAuthOptions extends BaseOptions {\n type: string;\n token?: string;\n username?: string;\n password?: string;\n key?: string;\n value?: string;\n addTo?: string;\n}\n\ninterface MoveOptions extends BaseOptions {\n parent?: string | null;\n}\n\ninterface ListOptions extends BaseOptions {\n json?: boolean;\n}\n\nconst COMMON_OPTS = (cmd: Command): Command =>\n cmd\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 the .apicircle/ workspace (skips the registry).',\n );\n\nasync function openWorkspace(\n opts: BaseOptions,\n): Promise<{ provider: FileBackedWorkspaceProvider; dir: string }> {\n let dir: string;\n try {\n const resolved = await resolveWorkspace({\n name: opts.workspaceName,\n path: opts.workspacePath,\n expectExists: true,\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 await ensureWorkspace(dir);\n return { provider: new FileBackedWorkspaceProvider(dir), dir };\n}\n\nexport function registerFolderCommand(program: Command): void {\n const folder = program\n .command('folder')\n .description('List, create, rename, move, set auth, or delete folders.');\n\n COMMON_OPTS(\n folder\n .command('list')\n .description('Print the folder tree (with auth markers).')\n .option('--json', 'Emit JSON instead of a formatted tree'),\n ).action(async (opts: ListOptions) => {\n const { provider } = await openWorkspace(opts);\n const state = await provider.read();\n const folders = state.synced.collections.folders;\n if (opts.json) {\n process.stdout.write(JSON.stringify(Object.values(folders), null, 2) + '\\n');\n return;\n }\n if (Object.keys(folders).length === 0) {\n process.stdout.write(`${kleur.dim('No folders in this workspace.')}\\n`);\n return;\n }\n const roots = Object.values(folders).filter((f) => f.parentId === null);\n roots.sort((a, b) => a.name.localeCompare(b.name));\n for (const root of roots) printTree(root, folders, 0);\n });\n\n COMMON_OPTS(\n folder\n .command('create')\n .description(\n 'Create a new folder. Optionally seed folder-level auth in the same call (saves a follow-up `folder set-auth` round-trip). Prints the new id.',\n )\n .requiredOption('--name <name>', 'Folder name (must be unique among siblings)')\n .option('--parent <id>', 'Parent folder id (omit for top level)')\n .option(\n '--type <type>',\n 'Initial auth type: bearer | basic | api-key | custom-header | none | inherit',\n )\n .option('--token <token>', 'Token (bearer)')\n .option('--username <user>', 'Username (basic)')\n .option('--password <pass>', 'Password (basic)')\n .option('--key <key>', 'Key (api-key / custom-header)')\n .option('--value <value>', 'Value (api-key / custom-header)')\n .option('--add-to <where>', 'Where to inject api-key: header | query | cookie', 'header'),\n ).action(async (opts: CreateOptions) => {\n const initialAuth = opts.type ? buildAuthFromCli({ ...opts, type: opts.type }) : undefined;\n const { provider } = await openWorkspace(opts);\n const f: Folder = {\n id: generateId(),\n name: opts.name!.trim(),\n parentId: opts.parent ?? null,\n ...(initialAuth ? { auth: initialAuth } : {}),\n };\n const result = await provider.apply({ kind: 'folder.create', folder: f });\n if ((result.changedIds.length ?? 0) === 0) {\n process.stderr.write(`${kleur.red('error')}: folder.create no-op (duplicate id?)\\n`);\n process.exit(1);\n }\n const authNote = initialAuth ? ` auth=${initialAuth.type}` : '';\n process.stdout.write(`${kleur.green('created')} ${f.id} ${f.name}${authNote}\\n`);\n });\n\n COMMON_OPTS(\n folder\n .command('rename')\n .description('Rename a folder. Fails if a sibling already has the new name.')\n .argument('<id>', 'Folder id')\n .requiredOption('--name <name>', 'New name'),\n ).action(async (id: string, opts: RenameOptions) => {\n const { provider } = await openWorkspace(opts);\n const result = await provider.apply({\n kind: 'folder.update',\n id,\n patch: { name: opts.name.trim() },\n });\n if (result.changedIds.length === 0) {\n process.stderr.write(\n `${kleur.red('error')}: rename rejected — folder not found, or a sibling already has the name \"${opts.name}\".\\n`,\n );\n process.exit(1);\n }\n process.stdout.write(`${kleur.green('renamed')} ${id} ${opts.name}\\n`);\n });\n\n COMMON_OPTS(\n folder\n .command('set-auth')\n .description('Set folder-level auth. Descendants with `auth.type: inherit` will pick it up.')\n .argument('<id>', 'Folder id')\n .requiredOption(\n '--type <type>',\n 'Auth type: bearer | basic | api-key | custom-header | none | inherit',\n )\n .option('--token <token>', 'Token (bearer)')\n .option('--username <user>', 'Username (basic)')\n .option('--password <pass>', 'Password (basic)')\n .option('--key <key>', 'Key (api-key / custom-header)')\n .option('--value <value>', 'Value (api-key / custom-header)')\n .option('--add-to <where>', 'Where to inject api-key: header | query | cookie', 'header'),\n ).action(async (id: string, opts: SetAuthOptions) => {\n const auth = buildAuthFromCli(opts);\n const { provider } = await openWorkspace(opts);\n const result = await provider.apply({\n kind: 'folder.update',\n id,\n patch: { auth },\n });\n if (result.changedIds.length === 0) {\n process.stderr.write(`${kleur.red('error')}: folder ${id} not found.\\n`);\n process.exit(1);\n }\n process.stdout.write(`${kleur.green('updated')} ${id} auth.type=${auth.type}\\n`);\n });\n\n COMMON_OPTS(\n folder\n .command('clear-auth')\n .description('Clear folder-level auth. Descendants `inherit` walks further up.')\n .argument('<id>', 'Folder id'),\n ).action(async (id: string, opts: BaseOptions) => {\n const { provider } = await openWorkspace(opts);\n const result = await provider.apply({\n kind: 'folder.update',\n id,\n patch: { auth: undefined },\n });\n if (result.changedIds.length === 0) {\n process.stderr.write(`${kleur.red('error')}: folder ${id} not found.\\n`);\n process.exit(1);\n }\n process.stdout.write(`${kleur.green('cleared auth')} ${id}\\n`);\n });\n\n COMMON_OPTS(\n folder\n .command('move')\n .description('Reparent a folder. Cycles + self-parenting are rejected.')\n .argument('<id>', 'Folder id')\n .option('--parent <id>', 'New parent id (omit for top level)'),\n ).action(async (id: string, opts: MoveOptions) => {\n const { provider } = await openWorkspace(opts);\n const result = await provider.apply({\n kind: 'folder.move',\n id,\n newParentId: opts.parent ?? null,\n });\n if (result.changedIds.length === 0) {\n process.stderr.write(\n `${kleur.red('error')}: move rejected — folder not found, same parent, self-parent, or cycle.\\n`,\n );\n process.exit(1);\n }\n process.stdout.write(`${kleur.green('moved')} ${id} parent=${opts.parent ?? '(root)'}\\n`);\n });\n\n COMMON_OPTS(\n folder\n .command('delete')\n .description('Delete a folder. Direct children reparent to its parent.')\n .argument('<id>', 'Folder id'),\n ).action(async (id: string, opts: BaseOptions) => {\n const { provider } = await openWorkspace(opts);\n const result = await provider.apply({ kind: 'folder.delete', id });\n if (result.changedIds.length === 0) {\n process.stderr.write(`${kleur.red('error')}: folder ${id} not found.\\n`);\n process.exit(1);\n }\n process.stdout.write(`${kleur.green('deleted')} ${id}\\n`);\n });\n}\n\nfunction buildAuthFromCli(opts: SetAuthOptions): RequestAuth {\n switch (opts.type) {\n case 'none':\n return { type: 'none' };\n case 'inherit':\n return { type: 'inherit' };\n case 'bearer':\n return { type: 'bearer', token: opts.token ?? '' };\n case 'basic':\n return { type: 'basic', username: opts.username ?? '', password: opts.password ?? '' };\n case 'api-key':\n return {\n type: 'api-key',\n key: opts.key ?? '',\n value: opts.value ?? '',\n addTo: opts.addTo === 'query' || opts.addTo === 'cookie' ? opts.addTo : 'header',\n };\n case 'custom-header':\n return { type: 'custom-header', key: opts.key ?? '', value: opts.value ?? '' };\n default:\n process.stderr.write(\n `${kleur.red('error')}: --type \"${opts.type}\" not supported by the CLI. Use bearer | basic | api-key | custom-header | none | inherit. For OAuth2 / AWS / Hawk / NTLM / JWT, edit the folder YAML in VS Code or the web/desktop app.\\n`,\n );\n process.exit(2);\n }\n}\n\nfunction printTree(folder: Folder, all: Record<string, Folder>, depth: number): void {\n const indent = ' '.repeat(depth);\n const authTag =\n folder.auth && folder.auth.type !== 'none' && folder.auth.type !== 'inherit'\n ? ` ${kleur.cyan(`[auth: ${folder.auth.type}]`)}`\n : '';\n process.stdout.write(`${indent}${kleur.bold(folder.name)} ${kleur.dim(folder.id)}${authTag}\\n`);\n const children = Object.values(all)\n .filter((f) => f.parentId === folder.id)\n .sort((a, b) => a.name.localeCompare(b.name));\n for (const c of children) printTree(c, all, depth + 1);\n}\n","{\n \"name\": \"@apicircle/cli\",\n \"version\": \"1.1.2\",\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 \"@apicircle/git\": \"workspace:*\",\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"],"mappings":"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","names":["fs","kleur","import_kleur","import_file_backed","path","import_node_fs","import_shared","fs","path","import_node_fs","import_file_backed","import_shared","entry","fs","kleur","import_kleur","kleur","import_node_fs","path","import_kleur","import_file_backed","import_mock_server_core","import_shared","kleur","resolve","fs","import_node_fs","path","import_kleur","import_core","kleur","fs","os","import_kleur","import_core","import_file_backed","path","import_node_fs","fs","import_node_fs","path","import_core","fs","kleur","entry","import_kleur","import_registry","kleur","entry","workspaceDirFor","import_kleur","import_core","import_file_backed","import_shared","path","resolveDir","kleur","import_kleur","resolveToken","kleur","import_kleur","import_shared","import_mcp_server","kleur"]}