@macroscope/cli 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/handler.ts","../src/core/blueprints.ts","../src/core/project.ts","../../contracts/src/version.ts","../../contracts/src/fs.ts","../../contracts/src/manifest.ts","../../contracts/src/payload.ts","../../contracts/src/search.ts","../../contracts/src/api.ts","../../contracts/src/error.ts","../src/core/manifest.ts","../src/core/scanner.ts","../src/ui/api/terminal-resolver.ts","../src/ui/api/terminal-ws.ts","../src/cli.ts","../src/core/version.ts","../src/ui/ui-server.ts","../src/ui/api/blocks-handler.ts","../src/ui/api/blueprints-handler.ts","../src/ui/api/code-handler.ts","../src/ui/api/markdown-handler.ts","../src/ui/api/service-manager.ts","../src/ui/api/service-readiness.ts","../src/ui/api/services-handler.ts"],"sourcesContent":["/**\n * The locked substrate contract. The v1 control layer extends this interface;\n * it never bypasses it.\n *\n * A `Handler` is what a blueprint exports. It declares a `kind` and zero or more\n * optional async operations. Each operation returns data — never side effects —\n * and never throws \"not implemented\"; missing methods simply mean the operation\n * isn't supported for that kind.\n *\n * No top-level side effects on import. Importing a handler must not spawn\n * processes, open ports, or read files. Side effects belong inside methods.\n *\n * Trust model: blueprints are USER-AUTHORED CODE in the user's own project.\n * The loader imports them via jiti and runs them at full process privilege.\n * This is the same trust model as a `package.json` postinstall script, an\n * ESLint plugin, a Storybook addon, or a vite.config.ts — code in your repo\n * runs as you. There is no sandbox. If you do not trust a blueprint, do not\n * put it in your project.\n */\nexport interface Handler {\n /** Required. Must match the blueprint folder name. */\n kind: string;\n /** Named views shown as tabs in the block-detail page. v1 ships iframe + terminal types. */\n views?: Record<string, ViewSpec>;\n /** Produce something the UI/CLI/MCP can display for this block. */\n render?: (block: Block) => Promise<RenderResult>;\n /** Run whatever counts as a test for this kind. */\n test?: (block: Block) => Promise<TestResult>;\n /** Produce build artifacts for this kind. */\n build?: (block: Block) => Promise<BuildResult>;\n /** Create a new block of this kind in `targetDir` with the given name. */\n scaffold?: (targetDir: string, name: string) => Promise<void>;\n /** Generate a free-form textual description of a block, used by semantic search. */\n describe?: (block: Block) => Promise<string>;\n}\n\n/**\n * A block is an instance of a kind: a folder somewhere in the user's project\n * with a `macroscope.yaml`. Handlers receive these as input.\n *\n * For M0 (this PR) we don't actually load blocks yet — this type exists so the\n * Handler interface can be locked.\n */\nexport interface Block {\n /** Stable identifier. POSIX relative path from project root by default; overridable via the manifest `id` field. */\n id: string;\n /** Absolute path to the block's folder. */\n path: string;\n /** Parsed and validated manifest. */\n manifest: BlockManifest;\n}\n\n/**\n * The manifest is the data side of a block (the `macroscope.yaml`). The shape\n * here is the substrate's view of it; individual blueprints may require\n * additional fields under their own `kind`.\n */\nexport interface BlockManifest {\n /** Must reference a registered blueprint's `kind`. */\n kind: string;\n /** Optional override for the auto-derived block id. */\n id?: string;\n name?: string;\n description?: string;\n tags?: string[];\n source?: string;\n preview?: string;\n docs?: string;\n tests?: string | string[];\n /** Unknown fields pass through to handlers per the v0 spec — never errors. */\n [field: string]: unknown;\n}\n\n/**\n * A view is one tab in the block-detail page. Three view types exist:\n * - iframe: embed any URL the blueprint resolves.\n * - terminal: spawn the resolved command server-side and stream its\n * stdin/stdout/stderr to a browser xterm.js terminal.\n * - hybrid: combine a static artifact (iframe URL) with an on-demand\n * command (terminal). UI shows the URL by default and a Run button\n * that switches to the terminal and spawns the command.\n */\nexport type ViewSpec = IframeViewSpec | TerminalViewSpec | HybridViewSpec;\n\nexport interface IframeViewSpec {\n type: 'iframe';\n url: string | ((block: Block) => string | Promise<string>);\n /** Optional backing service. macroscope spawns this on demand the first time the\n * view is opened in the UI, polls readyWhen.url, and only loads the iframe\n * once the service responds. */\n service?: ServiceSpec;\n}\n\nexport interface ServiceSpec {\n /** Human-readable label shown in the \"starting…\" state. Defaults to command[0]. */\n name?: string;\n /** argv-style command. Function form is resolved server-side per block. */\n command: string[] | ((block: Block) => string[] | Promise<string[]>);\n /** Working directory. Defaults to project root. */\n cwd?: string | ((block: Block) => string | Promise<string>);\n /** Service is ready when this URL responds with any non-5xx status. */\n readyWhen: { url: string };\n /** Max ms to wait for readiness before declaring failure. Default: 30_000. */\n startupTimeoutMs?: number;\n}\n\nexport interface TerminalViewSpec {\n type: 'terminal';\n /** argv-style: ['vitest', 'run', '<file>']. Function form is resolved server-side per block. */\n command: string[] | ((block: Block) => string[] | Promise<string[]>);\n}\n\n/**\n * A hybrid view shows a static artifact (e.g. test source code) by default and\n * lets the user switch to a terminal that runs an on-demand command (e.g.\n * `vitest run`) via a Run button. Useful for \"read code → press button → see\n * what happens → toggle back\" workflows.\n */\nexport interface HybridViewSpec {\n type: 'hybrid';\n /** Static artifact URL. Same semantics as IframeViewSpec.url. */\n url: string | ((block: Block) => string | Promise<string>);\n /** On-demand command. Same semantics as TerminalViewSpec.command. */\n command: string[] | ((block: Block) => string[] | Promise<string[]>);\n /** Label for the Run button. Default: \"Run\". */\n runLabel?: string;\n /** Label for the code-side toggle. Default: \"Code\". */\n codeLabel?: string;\n /** Label for the terminal-side toggle. Default: \"Terminal\". */\n terminalLabel?: string;\n}\n\nexport type RenderResult =\n | { type: 'iframe'; entry: string }\n | { type: 'html'; html: string }\n | { type: 'markdown'; source: string }\n | { type: 'image'; src: string }\n | { type: 'error'; message: string }\n | { type: 'none'; reason: string };\n\nexport type TestResult =\n | { type: 'pass'; output?: string }\n | { type: 'fail'; output: string }\n | { type: 'error'; message: string }\n | { type: 'none'; reason: string };\n\nexport type BuildResult =\n | { type: 'ok'; artifacts?: string[] }\n | { type: 'error'; message: string }\n | { type: 'none'; reason: string };\n\n/**\n * Convenience type guard for runtime validation. Used by the blueprint loader\n * to verify that a default export looks like a Handler before accepting it.\n */\nexport function isHandler(value: unknown): value is Handler {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n if (typeof v.kind !== 'string' || v.kind.length === 0) return false;\n for (const method of ['render', 'test', 'build', 'scaffold', 'describe'] as const) {\n if (v[method] !== undefined && typeof v[method] !== 'function') return false;\n }\n if (v.views !== undefined) {\n if (typeof v.views !== 'object' || v.views === null) return false;\n for (const [, spec] of Object.entries(v.views as Record<string, unknown>)) {\n if (!isViewSpec(spec)) return false;\n }\n }\n return true;\n}\n\nfunction isViewSpec(value: unknown): value is ViewSpec {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n switch (v.type) {\n case 'iframe':\n if (typeof v.url !== 'string' && typeof v.url !== 'function') return false;\n if (v.service !== undefined && !isServiceSpec(v.service)) return false;\n return true;\n case 'terminal':\n return (\n typeof v.command === 'function' ||\n (Array.isArray(v.command) && v.command.every((c) => typeof c === 'string'))\n );\n case 'hybrid': {\n const urlOk = typeof v.url === 'string' || typeof v.url === 'function';\n const commandOk =\n typeof v.command === 'function' ||\n (Array.isArray(v.command) && v.command.every((c) => typeof c === 'string'));\n if (!urlOk || !commandOk) return false;\n for (const key of ['runLabel', 'codeLabel', 'terminalLabel'] as const) {\n if (v[key] !== undefined && typeof v[key] !== 'string') return false;\n }\n return true;\n }\n default:\n return false;\n }\n}\n\nfunction isServiceSpec(value: unknown): value is ServiceSpec {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n const commandOk =\n typeof v.command === 'function' ||\n (Array.isArray(v.command) && v.command.every((c) => typeof c === 'string'));\n if (!commandOk) return false;\n if (typeof v.readyWhen !== 'object' || v.readyWhen === null) return false;\n const ready = v.readyWhen as Record<string, unknown>;\n if (typeof ready.url !== 'string') return false;\n if (v.name !== undefined && typeof v.name !== 'string') return false;\n if (v.cwd !== undefined && typeof v.cwd !== 'string' && typeof v.cwd !== 'function') {\n return false;\n }\n if (v.startupTimeoutMs !== undefined && typeof v.startupTimeoutMs !== 'number') return false;\n return true;\n}\n","import { type Dirent, existsSync } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { createJiti } from 'jiti';\nimport { type Handler, isHandler } from './handler.js';\nimport type { Project } from './project.js';\n\n/** Filenames tried, in order. First match wins. */\nconst HANDLER_FILENAMES = ['handler.ts', 'handler.mjs', 'handler.js'] as const;\n\n/** Optional operation methods on Handler. Order = preferred display order. */\nconst OPERATION_NAMES = ['render', 'test', 'build', 'scaffold', 'describe'] as const;\nexport type HandlerCapability = (typeof OPERATION_NAMES)[number];\n\nexport interface LoadedBlueprint {\n /** Kind name. Equal to the folder basename AND handler.kind (enforced at load time). */\n kind: string;\n /** Absolute path to the blueprint folder. */\n folder: string;\n /** Absolute path to the loaded handler file. */\n file: string;\n /** The validated Handler default export. */\n handler: Handler;\n /** Which optional operations this handler supports. */\n capabilities: HandlerCapability[];\n}\n\nexport type BlueprintLoadCause =\n | 'no-handler-file'\n | 'import-failed'\n | 'no-default-export'\n | 'invalid-handler-shape'\n | 'kind-mismatch';\n\nexport interface BlueprintLoadError {\n /** Absolute path to the blueprint folder. */\n folder: string;\n /** The folder basename — used to identify the failed blueprint even if its declared kind is wrong. */\n kind: string;\n /** Tagged cause for programmatic handling. */\n cause: BlueprintLoadCause;\n /** Human-readable message naming the file and what is wrong. */\n message: string;\n}\n\nexport interface BlueprintLoadResult {\n blueprints: LoadedBlueprint[];\n errors: BlueprintLoadError[];\n}\n\n/**\n * Discover and load every blueprint under `<project.root>/.macroscope/blueprints/`.\n *\n * Each subfolder is one blueprint. We look for `handler.ts | .mjs | .js` inside\n * it, import the default export via jiti (so users can write plain TypeScript\n * with no build step), and validate the shape against the Handler interface.\n *\n * Per-blueprint failures are collected in `errors` instead of thrown. A single\n * broken handler does not blind the rest of the catalog.\n */\nexport async function loadBlueprints(project: Project): Promise<BlueprintLoadResult> {\n const blueprintsDir = join(project.root, '.macroscope', 'blueprints');\n if (!existsSync(blueprintsDir)) {\n return { blueprints: [], errors: [] };\n }\n\n let entries: Dirent<string>[];\n try {\n entries = await readdir(blueprintsDir, { withFileTypes: true, encoding: 'utf8' });\n } catch {\n return { blueprints: [], errors: [] };\n }\n\n const blueprints: LoadedBlueprint[] = [];\n const errors: BlueprintLoadError[] = [];\n const jiti = createJiti(import.meta.url);\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const folder = join(blueprintsDir, entry.name);\n // Normalize to NFC. macOS HFS+/APFS may return NFD-decomposed names from\n // readdir; user handler code typically declares `kind` in NFC. Comparing\n // raw bytes would silently fail for blueprints with non-ASCII names.\n const kind = entry.name.normalize('NFC');\n const result = await loadOne(folder, kind, jiti);\n if (result.ok) {\n blueprints.push(result.blueprint);\n } else {\n errors.push(result.error);\n }\n }\n\n blueprints.sort((a, b) => (a.kind < b.kind ? -1 : 1));\n errors.sort((a, b) => (a.kind < b.kind ? -1 : 1));\n return { blueprints, errors };\n}\n\ntype LoadOutcome =\n | { ok: true; blueprint: LoadedBlueprint }\n | { ok: false; error: BlueprintLoadError };\n\nasync function loadOne(\n folder: string,\n kind: string,\n jiti: ReturnType<typeof createJiti>,\n): Promise<LoadOutcome> {\n let file: string | null = null;\n for (const filename of HANDLER_FILENAMES) {\n const candidate = join(folder, filename);\n if (existsSync(candidate)) {\n file = candidate;\n break;\n }\n }\n\n if (!file) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'no-handler-file',\n message: `Blueprint folder ${folder} has no handler file. Expected one of: ${HANDLER_FILENAMES.join(', ')}.`,\n },\n };\n }\n\n let mod: unknown;\n try {\n mod = await jiti.import(file);\n } catch (err) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'import-failed',\n message: `Failed to import ${file}: ${(err as Error).message}`,\n },\n };\n }\n\n const def = extractDefault(mod);\n if (def === undefined) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'no-default-export',\n message: `Blueprint at ${file} has no default export. Use \\`export default { kind: '${kind}', ... } satisfies Handler\\`.`,\n },\n };\n }\n\n if (!isHandler(def)) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'invalid-handler-shape',\n message: `Default export of ${file} is not a valid Handler. It must be an object with a non-empty string \\`kind\\` field and optional async methods (render, test, build, scaffold, describe).`,\n },\n };\n }\n\n if (def.kind !== kind) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'kind-mismatch',\n message: `Blueprint at ${file} declares \\`kind: '${def.kind}'\\` but lives in folder \\`${kind}/\\`. The kind field must match the folder name.`,\n },\n };\n }\n\n const handlerRecord = def as unknown as Record<string, unknown>;\n const capabilities = OPERATION_NAMES.filter((op) => typeof handlerRecord[op] === 'function');\n\n return {\n ok: true,\n blueprint: { kind: def.kind, folder, file, handler: def, capabilities },\n };\n}\n\nfunction extractDefault(mod: unknown): unknown {\n if (mod === null || mod === undefined) return undefined;\n if (typeof mod !== 'object') return mod;\n // jiti wraps the namespace in a Proxy that returns the namespace itself when\n // `.default` is accessed but no default export exists. Use hasOwnProperty so\n // we don't mistake a Proxy fallback for a real default.\n if (!Object.prototype.hasOwnProperty.call(mod, 'default')) return undefined;\n return (mod as Record<string, unknown>).default;\n}\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport { z } from 'zod';\n\nexport const projectConfigSchema = z.object({\n scanRoots: z.array(z.string()).default(['.']),\n ignore: z.array(z.string()).default(['node_modules', '.git', 'dist', '.macroscope']),\n});\n\nexport type ProjectConfig = z.infer<typeof projectConfigSchema>;\n\nexport interface Project {\n /** Absolute path to the project root (the directory containing .macroscope/). */\n root: string;\n /** Parsed .macroscope/config.yaml, with defaults filled in. */\n config: ProjectConfig;\n}\n\nexport class ProjectNotFoundError extends Error {\n constructor(startedFrom: string) {\n super(\n `No macroscope project found. Walked up from ${startedFrom} looking for a .macroscope/ directory but reached the filesystem root. Run \\`npm create macroscope\\` to scaffold one, or cd into an existing project.`,\n );\n this.name = 'ProjectNotFoundError';\n }\n}\n\n/**\n * Find the project root by walking up from `cwd` looking for a `.macroscope/`\n * directory. The macroscope root is the directory that *contains* `.macroscope`.\n * If config.yaml is present inside, it is parsed; otherwise defaults are used.\n */\nexport async function findProject(cwd: string = process.cwd()): Promise<Project> {\n const startedFrom = resolve(cwd);\n let current = startedFrom;\n while (true) {\n if (existsSync(join(current, '.macroscope'))) {\n return { root: current, config: await loadConfig(current) };\n }\n const parent = dirname(current);\n if (parent === current) {\n throw new ProjectNotFoundError(startedFrom);\n }\n current = parent;\n }\n}\n\nasync function loadConfig(root: string): Promise<ProjectConfig> {\n const configPath = join(root, '.macroscope', 'config.yaml');\n if (!existsSync(configPath)) {\n return projectConfigSchema.parse({});\n }\n const raw = await readFile(configPath, 'utf8');\n let parsed: unknown;\n try {\n parsed = parseYaml(raw) ?? {};\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to parse ${configPath}: ${msg}`);\n }\n const result = projectConfigSchema.safeParse(parsed);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid project config at ${configPath}:\\n${issues}`);\n }\n return result.data;\n}\n","/**\n * Wire-format version for cloud-side documents (MeilisearchDoc). Bumped when\n * the doc shape changes in a way that requires reindexing. The catch-up scan\n * watches for a mismatch with the server-reported version and triggers a full\n * re-push (see `catchup.ts`).\n */\nexport const SCHEMA_VERSION = 1 as const;\nexport type SchemaVersion = typeof SCHEMA_VERSION;\n","/**\n * Filesystem paths macroscope reads and writes. Two roots:\n *\n * user — under `~/.macroscope/`; survives across projects.\n * project — under `<project>/.macroscope/`; specific to a worktree.\n *\n * Paths are POSIX-style and relative to their root. Callers resolve them\n * against the relevant base directory (`os.homedir()` or the project root).\n */\nexport const FILESYSTEM_LAYOUT = {\n user: {\n /** `~/.macroscope/` */\n rootDir: '.macroscope',\n /** `~/.macroscope/credentials` — OAuth token store, mode 0600. */\n credentialsFile: '.macroscope/credentials',\n /** `~/.macroscope/machine-id` — stable per-install identifier. */\n machineIdFile: '.macroscope/machine-id',\n },\n project: {\n /** `<project>/.macroscope/` */\n rootDir: '.macroscope',\n /** `<project>/.macroscope/blueprints/` — one folder per kind. */\n blueprintsDir: '.macroscope/blueprints',\n /** `<project>/.macroscope/cache/` */\n cacheDir: '.macroscope/cache',\n /** `<project>/.macroscope/cache/hashes.json` — content-hash cache used by catch-up scan. */\n hashesFile: '.macroscope/cache/hashes.json',\n /** `<project>/.macroscope/cache/queue.json` — watcher push queue, survives restart. */\n queueFile: '.macroscope/cache/queue.json',\n },\n} as const;\n\nexport type FilesystemLayout = typeof FILESYSTEM_LAYOUT;\n","import { z } from 'zod';\n\n/**\n * The on-disk `macroscope.yaml` manifest. Substrate-level fields are listed\n * explicitly; blueprints may attach additional kind-specific fields, which\n * pass through unchanged (`.passthrough()`).\n */\nexport const BlockManifestSchema = z\n .object({\n /** Must reference a registered blueprint's `kind`. */\n kind: z.string().min(1),\n /** Optional override for the auto-derived block id (POSIX relative path). */\n id: z.string().optional(),\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n source: z.string().optional(),\n preview: z.string().optional(),\n docs: z.string().optional(),\n tests: z.union([z.string(), z.array(z.string())]).optional(),\n })\n .passthrough();\n\nexport type BlockManifest = z.infer<typeof BlockManifestSchema>;\n","import { z } from 'zod';\n\n/**\n * One exported symbol from a block's source files. Extracted by the TS\n * compiler API. `signature` is the rendered TypeScript signature string\n * (e.g. `function foo(x: string): number`); the exact rendering is the\n * extractor's responsibility (see T5).\n */\nexport const SymbolSignatureSchema = z.object({\n name: z.string().min(1),\n kind: z.string().min(1),\n signature: z.string(),\n});\nexport type SymbolSignature = z.infer<typeof SymbolSignatureSchema>;\n\n/**\n * What the watcher pushes to the cloud per block. The cloud combines this\n * with cloud-side fields (repo, worktreeId, path, lastActiveAt, contentHash)\n * to form the `MeilisearchDoc` that lands in the user's index.\n */\nexport const UploadPayloadSchema = z.object({\n /** Stable block id (POSIX relative path or manifest `id` override). */\n blockId: z.string().min(1),\n kind: z.string().min(1),\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n /** Exported symbols extracted from the block's source files. */\n symbols: z.array(SymbolSignatureSchema),\n /** First ~500 chars of the README, if any. */\n readmeExcerpt: z.string().optional(),\n});\nexport type UploadPayload = z.infer<typeof UploadPayloadSchema>;\n\n/**\n * The doc shape stored in Meilisearch. Identity is the tuple\n * (repo, worktreeId, blockId): two worktrees of the same repo produce\n * distinct docs and filter independently.\n */\nexport const MeilisearchDocSchema = UploadPayloadSchema.extend({\n /** SHA-256 over the canonical JSON of the UploadPayload (see T6). */\n contentHash: z.string().min(1),\n /** Git remote URL (normalised) or local repo name when no remote exists. */\n repo: z.string().min(1),\n /** hash(machineUuid + absolutePath) — see ARCHITECTURE.md. */\n worktreeId: z.string().min(1),\n /** POSIX path from the worktree root to the block folder. */\n path: z.string().min(1),\n /** Unix epoch milliseconds. Refreshed on every push and by `/scope/touch`. */\n lastActiveAt: z.number().int().nonnegative(),\n});\nexport type MeilisearchDoc = z.infer<typeof MeilisearchDocSchema>;\n","import { z } from 'zod';\n\n/**\n * One cloud-side search result. Returned by `GET /search`. Carries enough\n * to render a result row without a second fetch.\n */\nexport const BlockHitSchema = z.object({\n blockId: z.string().min(1),\n kind: z.string().min(1),\n name: z.string().optional(),\n description: z.string().optional(),\n repo: z.string().min(1),\n worktreeId: z.string().min(1),\n path: z.string().min(1),\n /** Relevance score from Meilisearch hybrid ranking. Larger = more relevant. */\n score: z.number(),\n});\nexport type BlockHit = z.infer<typeof BlockHitSchema>;\n\n/**\n * One local-side code search result. Produced by `git grep` (T10). Lives in\n * contracts so the UI's merged-results view can speak one type.\n */\nexport const CodeMatchSchema = z.object({\n /** POSIX path from the worktree root. */\n file: z.string().min(1),\n /** 1-based line number. */\n line: z.number().int().positive(),\n /** 1-based column number, when available. */\n column: z.number().int().positive().optional(),\n /** A single line of source text containing the match. */\n preview: z.string(),\n});\nexport type CodeMatch = z.infer<typeof CodeMatchSchema>;\n","import { z } from 'zod';\nimport { MeilisearchDocSchema } from './payload.js';\nimport { BlockHitSchema } from './search.js';\n\n/* ------------------------------ POST /index/batch ------------------------------ */\n\nexport const IndexBatchRequestSchema = z.object({\n /** Per-block docs to upsert. The cloud routes these to the user's Meilisearch index. */\n upserts: z.array(MeilisearchDocSchema),\n /** Block ids to delete. Empty array is valid (upsert-only batch). */\n deletes: z.array(z.string().min(1)),\n});\nexport type IndexBatchRequest = z.infer<typeof IndexBatchRequestSchema>;\n\nexport const IndexBatchResponseSchema = z.object({\n /** Unix epoch ms of server-side acknowledgement. */\n acceptedAt: z.number().int().nonnegative(),\n /** Number of upserts accepted (deletes excluded). */\n accepted: z.number().int().nonnegative(),\n});\nexport type IndexBatchResponse = z.infer<typeof IndexBatchResponseSchema>;\n\n/* --------------------------------- GET /search --------------------------------- */\n\nexport const SearchRequestSchema = z.object({\n q: z.string().min(1),\n /** Restrict to one worktree. Omit to search across all of the user's worktrees. */\n worktreeId: z.string().optional(),\n /** Restrict to one repo. */\n repo: z.string().optional(),\n /** Restrict to one block kind. */\n kind: z.string().optional(),\n /** Cap on returned hits. Server enforces an upper bound. */\n limit: z.number().int().positive().optional(),\n});\nexport type SearchRequest = z.infer<typeof SearchRequestSchema>;\n\nexport const SearchResponseSchema = z.object({\n hits: z.array(BlockHitSchema),\n /** Approximate total match count from Meilisearch (estimated, not exact). */\n totalEstimated: z.number().int().nonnegative(),\n});\nexport type SearchResponse = z.infer<typeof SearchResponseSchema>;\n\n/* --------------------------------- DELETE /index -------------------------------- */\n\nexport const DeleteIndexResponseSchema = z.object({\n deletedAt: z.number().int().nonnegative(),\n});\nexport type DeleteIndexResponse = z.infer<typeof DeleteIndexResponseSchema>;\n\n/* ------------------------------ POST /scope/touch ------------------------------ */\n\nexport const ScopeTouchRequestSchema = z.object({\n worktreeId: z.string().min(1),\n repo: z.string().min(1),\n});\nexport type ScopeTouchRequest = z.infer<typeof ScopeTouchRequestSchema>;\n\nexport const ScopeTouchResponseSchema = z.object({\n touchedAt: z.number().int().nonnegative(),\n});\nexport type ScopeTouchResponse = z.infer<typeof ScopeTouchResponseSchema>;\n\n/* --------------------------------- GET /health --------------------------------- */\n\nexport const HealthResponseSchema = z.object({\n status: z.literal('ok'),\n schemaVersion: z.number().int().positive(),\n});\nexport type HealthResponse = z.infer<typeof HealthResponseSchema>;\n\n/**\n * Endpoint manifest. One row per route, suitable for type-checking a server\n * router and a typed client against a single source of truth.\n *\n * Serialization convention: for `method: 'GET'` endpoints the request schema's\n * fields are sent as URL query parameters (never a body). For `POST`/`DELETE`\n * the request schema is the JSON body. `request: null` means the endpoint\n * takes no request payload at all.\n */\nexport const API_ENDPOINTS = {\n indexBatch: {\n method: 'POST',\n path: '/index/batch',\n request: IndexBatchRequestSchema,\n response: IndexBatchResponseSchema,\n },\n search: {\n method: 'GET',\n path: '/search',\n request: SearchRequestSchema,\n response: SearchResponseSchema,\n },\n deleteIndex: {\n method: 'DELETE',\n path: '/index',\n request: null,\n response: DeleteIndexResponseSchema,\n },\n scopeTouch: {\n method: 'POST',\n path: '/scope/touch',\n request: ScopeTouchRequestSchema,\n response: ScopeTouchResponseSchema,\n },\n health: {\n method: 'GET',\n path: '/health',\n request: null,\n response: HealthResponseSchema,\n },\n} as const;\n\nexport type ApiEndpoints = typeof API_ENDPOINTS;\n","import { z } from 'zod';\n\n/**\n * The uniform error shape returned by every API endpoint on failure. Per the\n * CLAUDE.md invariant: errors name the file path and the broken field where\n * applicable.\n */\nexport const ErrorEnvelopeSchema = z.object({\n error: z.object({\n /** Stable machine-readable code (e.g. `unauthorized`, `validation_failed`). */\n code: z.string().min(1),\n /** Human-readable message. */\n message: z.string().min(1),\n /** Source file path when the error originates from parsing a manifest or other on-disk artifact. Set by the CLI side (see `ScanError`) and by the cloud when validating uploaded manifests. */\n file: z.string().optional(),\n /** Path of the offending field when the error is validation-related. */\n field: z.string().optional(),\n /** Server-assigned request id for log correlation. */\n requestId: z.string().optional(),\n }),\n});\n\nexport type ErrorEnvelope = z.infer<typeof ErrorEnvelopeSchema>;\n","import { type BlockManifest, BlockManifestSchema } from '@macroscope/contracts';\n\nexport const manifestSchema = BlockManifestSchema;\nexport type Manifest = BlockManifest;\n","import { createHash } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { dirname, join, relative, sep } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type { ZodError } from 'zod';\nimport type { Block, BlockManifest } from './handler.js';\nimport { manifestSchema } from './manifest.js';\nimport type { Project } from './project.js';\n\nexport interface ScannedBlock extends Block {\n /** SHA-256 over the manifest text. Used later by the index for change detection. */\n contentHash: string;\n}\n\nexport interface ScanError {\n file: string;\n kind: 'parse' | 'validation' | 'io';\n message: string;\n field?: string;\n}\n\nexport interface ScanResult {\n blocks: ScannedBlock[];\n errors: ScanError[];\n}\n\nexport async function scan(project: Project): Promise<ScanResult> {\n const blocks: ScannedBlock[] = [];\n const errors: ScanError[] = [];\n const ignore = new Set(project.config.ignore);\n const seenIds = new Set<string>();\n\n for (const root of project.config.scanRoots) {\n const start = join(project.root, root);\n if (!existsSync(start)) continue;\n for await (const manifestPath of findManifests(start, ignore)) {\n const result = await parseBlock(manifestPath, project.root);\n if (result.kind === 'ok') {\n if (seenIds.has(result.block.id)) {\n errors.push({\n file: manifestPath,\n kind: 'validation',\n message: `Duplicate block id \"${result.block.id}\" at ${manifestPath}. Set an explicit \\`id:\\` field to disambiguate.`,\n field: 'id',\n });\n } else {\n seenIds.add(result.block.id);\n blocks.push(result.block);\n }\n } else {\n errors.push(result.error);\n }\n }\n }\n\n blocks.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));\n return { blocks, errors };\n}\n\nasync function* findManifests(dir: string, ignore: Set<string>): AsyncGenerator<string> {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.isFile() && entry.name === 'macroscope.yaml') {\n yield join(dir, entry.name);\n }\n }\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (ignore.has(entry.name)) continue;\n yield* findManifests(join(dir, entry.name), ignore);\n }\n}\n\ntype ParseOutcome = { kind: 'ok'; block: ScannedBlock } | { kind: 'err'; error: ScanError };\n\nasync function parseBlock(manifestPath: string, projectRoot: string): Promise<ParseOutcome> {\n let raw: string;\n try {\n raw = await readFile(manifestPath, 'utf8');\n } catch (err) {\n return {\n kind: 'err',\n error: {\n file: manifestPath,\n kind: 'io',\n message: `Failed to read manifest at ${manifestPath}: ${(err as Error).message}`,\n },\n };\n }\n\n let yamlValue: unknown;\n try {\n yamlValue = parseYaml(raw);\n } catch (err) {\n return {\n kind: 'err',\n error: {\n file: manifestPath,\n kind: 'parse',\n message: `Invalid YAML in ${manifestPath}: ${(err as Error).message}`,\n },\n };\n }\n\n const parsed = manifestSchema.safeParse(yamlValue);\n if (!parsed.success) {\n const first = firstZodIssue(parsed.error);\n return {\n kind: 'err',\n error: {\n file: manifestPath,\n kind: 'validation',\n message: `Manifest at ${manifestPath} is invalid: field \\`${first.fieldPath}\\` ${first.message}.`,\n field: first.fieldPath,\n },\n };\n }\n\n const manifest = parsed.data as BlockManifest;\n const blockDir = dirname(manifestPath);\n const defaultId = toPosix(relative(projectRoot, blockDir));\n const id = manifest.id ?? defaultId;\n const contentHash = createHash('sha256').update(raw).digest('hex');\n\n return {\n kind: 'ok',\n block: { id, path: blockDir, manifest, contentHash },\n };\n}\n\nfunction firstZodIssue(err: ZodError): { fieldPath: string; message: string } {\n const issue = err.issues[0];\n if (!issue) return { fieldPath: '(root)', message: 'unknown validation error' };\n const fieldPath = issue.path.length ? issue.path.join('.') : '(root)';\n return { fieldPath, message: issue.message.toLowerCase() };\n}\n\nfunction toPosix(p: string): string {\n return p.split(sep).join('/');\n}\n","import { loadBlueprints } from '../../core/blueprints.js';\nimport type { Block } from '../../core/handler.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\nimport { scan } from '../../core/scanner.js';\n\nexport interface ResolvedCommand {\n ok: true;\n command: string[];\n /** Working directory for the subprocess. Defaults to the project root. */\n cwd: string;\n}\n\nexport interface ResolveError {\n ok: false;\n error: string;\n}\n\nconst COMMAND_RESOLVE_TIMEOUT_MS = 5000;\n\nexport async function resolveTerminalCommand(\n cwd: string,\n blockId: string,\n viewKey: string,\n): Promise<ResolvedCommand | ResolveError> {\n let project: Awaited<ReturnType<typeof findProject>>;\n try {\n project = await findProject(cwd);\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n return { ok: false, error: err.message };\n }\n return { ok: false, error: (err as Error).message };\n }\n\n const [scanResult, blueprintResult] = await Promise.all([scan(project), loadBlueprints(project)]);\n const block = scanResult.blocks.find((b) => b.id === blockId);\n if (!block) {\n return { ok: false, error: `No block found with id \"${blockId}\".` };\n }\n const blueprint = blueprintResult.blueprints.find((bp) => bp.kind === block.manifest.kind);\n if (!blueprint) {\n return { ok: false, error: `No blueprint registered for kind \"${block.manifest.kind}\".` };\n }\n const spec = blueprint.handler.views?.[viewKey];\n if (!spec) {\n return { ok: false, error: `Blueprint \"${blueprint.kind}\" has no view named \"${viewKey}\".` };\n }\n // Terminal views and hybrid views both expose a `command` that the WebSocket\n // route can spawn. Hybrid views additionally have a `url` for the code side\n // (resolved by /api/blocks), but the terminal half lives here.\n if (spec.type !== 'terminal' && spec.type !== 'hybrid') {\n return {\n ok: false,\n error: `View \"${viewKey}\" on \"${blueprint.kind}\" has no terminal command.`,\n };\n }\n\n const blockInput: Block = { id: block.id, path: block.path, manifest: block.manifest };\n let command: string[];\n if (Array.isArray(spec.command)) {\n command = spec.command;\n } else {\n try {\n command = await withTimeout(spec.command(blockInput), COMMAND_RESOLVE_TIMEOUT_MS);\n } catch (err) {\n return { ok: false, error: `Command resolver failed: ${(err as Error).message}` };\n }\n if (!Array.isArray(command) || !command.every((c) => typeof c === 'string')) {\n return { ok: false, error: 'Command resolver did not return a string[].' };\n }\n }\n\n return { ok: true, command, cwd: project.root };\n}\n\nfunction withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {\n return Promise.race([\n p,\n new Promise<T>((_, reject) =>\n setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms),\n ),\n ]);\n}\n","import { type ChildProcess, spawn } from 'node:child_process';\nimport type { IncomingMessage, Server } from 'node:http';\nimport type { Socket } from 'node:net';\nimport { type WebSocket, WebSocketServer } from 'ws';\nimport { resolveTerminalCommand } from './terminal-resolver.js';\n\nlet spawnOverride: { command: string[]; cwd?: string } | null = null;\n\n/** Test seam: replace the resolved command with a synthetic one. Only for tests. */\nexport function setSpawnOverride(override: { command: string[]; cwd?: string } | null): void {\n spawnOverride = override;\n}\n\nexport function attachTerminalWs(httpServer: Server, defaultCwd: string): void {\n const wss = new WebSocketServer({ noServer: true });\n\n httpServer.on('upgrade', (req, socket, head) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.pathname !== '/api/terminal') {\n socket.destroy();\n return;\n }\n wss.handleUpgrade(req, socket as Socket, head, (ws) => {\n handleConnection(ws, req, defaultCwd);\n });\n });\n}\n\nasync function handleConnection(\n ws: WebSocket,\n req: IncomingMessage,\n defaultCwd: string,\n): Promise<void> {\n const url = new URL(req.url ?? '/', 'http://localhost');\n const blockId = url.searchParams.get('blockId') ?? '';\n const viewKey = url.searchParams.get('viewKey') ?? '';\n\n let command: string[];\n let cwd: string;\n if (spawnOverride) {\n command = spawnOverride.command;\n cwd = spawnOverride.cwd ?? defaultCwd;\n } else {\n const resolved = await resolveTerminalCommand(defaultCwd, blockId, viewKey);\n if (!resolved.ok) {\n send(ws, { type: 'error', message: resolved.error });\n ws.close();\n return;\n }\n command = resolved.command;\n cwd = resolved.cwd;\n }\n\n if (command.length === 0) {\n send(ws, { type: 'error', message: 'empty command' });\n ws.close();\n return;\n }\n\n send(ws, { type: 'open', command });\n\n const [bin, ...args] = command as [string, ...string[]];\n let child: ChildProcess;\n try {\n child = spawn(bin, args, { cwd, stdio: ['pipe', 'pipe', 'pipe'] });\n } catch (err) {\n send(ws, { type: 'error', message: `failed to spawn: ${(err as Error).message}` });\n ws.close();\n return;\n }\n\n child.stdout?.on('data', (chunk: Buffer) => send(ws, { type: 'out', data: chunk.toString() }));\n child.stderr?.on('data', (chunk: Buffer) => send(ws, { type: 'err', data: chunk.toString() }));\n child.on('exit', (code, signal) => {\n send(ws, { type: 'close', code, signal });\n ws.close();\n });\n child.on('error', (err) => {\n send(ws, { type: 'error', message: err.message });\n ws.close();\n });\n\n ws.on('message', (raw) => {\n let frame: { type: string; data?: string };\n try {\n frame = JSON.parse(raw.toString());\n } catch {\n return;\n }\n if (frame.type === 'in' && typeof frame.data === 'string') {\n child.stdin?.write(frame.data);\n } else if (frame.type === 'eof') {\n child.stdin?.end();\n }\n });\n\n ws.on('close', () => {\n if (!child.killed) child.kill();\n });\n}\n\nfunction send(ws: WebSocket, frame: object): void {\n try {\n ws.send(JSON.stringify(frame));\n } catch {\n // Connection closed mid-send. Ignore.\n }\n}\n","#!/usr/bin/env node\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport { Command } from 'commander';\nimport importLocal from 'import-local';\nimport { type BlueprintLoadResult, loadBlueprints } from './core/blueprints.js';\nimport { ProjectNotFoundError, findProject } from './core/project.js';\nimport { VERSION } from './core/version.js';\nimport { startUiServer } from './ui/ui-server.js';\n\nif (importLocal(import.meta.url)) {\n // Defer to a locally-installed macroscope if present.\n} else {\n main();\n}\n\nfunction main(): void {\n const program = new Command();\n\n program\n .name('macroscope')\n .description('Catalogue tooling for AI-collaborative software development')\n .version(VERSION, '-v, --version')\n .option('--json', 'output machine-readable JSON');\n\n program\n .command('hello')\n .description('Placeholder — proves the CLI wiring works')\n .action((_opts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n if (globalOpts.json) {\n process.stdout.write(`${JSON.stringify({ ok: true, message: 'hello from macroscope' })}\\n`);\n } else {\n process.stdout.write('hello from macroscope\\n');\n }\n });\n\n program\n .command('blueprints')\n .description('List the unit blueprints defined in this project (.macroscope/blueprints/)')\n .option('--cwd <path>', 'project search starts here (defaults to current dir)')\n .action(async (cmdOpts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n await runBlueprints({ cwd: cmdOpts.cwd, json: !!globalOpts.json });\n });\n\n program\n .command('ui')\n .description('Open the macroscope web UI in your browser')\n .option('--cwd <path>', 'project search starts here (defaults to current dir)')\n .option('--port <n>', 'port to listen on (default: auto-pick a free port)', (v) =>\n Number.parseInt(v, 10),\n )\n .option('--no-open', \"don't automatically open a browser\")\n .action(async (cmdOpts) => {\n await runUi({\n cwd: cmdOpts.cwd,\n port: cmdOpts.port,\n open: cmdOpts.open !== false,\n });\n });\n\n program.parse(process.argv);\n}\n\nasync function runBlueprints(opts: { cwd?: string; json: boolean }): Promise<void> {\n let project: Awaited<ReturnType<typeof findProject>>;\n try {\n project = await findProject(opts.cwd ?? process.cwd());\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n writeError(err.message, opts.json);\n process.exit(1);\n }\n writeError(`${(err as Error).message}`, opts.json);\n process.exit(1);\n }\n\n const result = await loadBlueprints(project);\n if (opts.json) {\n writeJson(result);\n } else {\n writeHuman(result);\n }\n if (result.errors.length > 0) {\n process.exitCode = 1;\n }\n}\n\nfunction writeHuman(result: BlueprintLoadResult): void {\n if (result.blueprints.length === 0 && result.errors.length === 0) {\n process.stdout.write(\n 'No blueprints found. Create one at .macroscope/blueprints/<kind>/handler.ts.\\n',\n );\n return;\n }\n\n if (result.blueprints.length > 0) {\n for (const bp of result.blueprints) {\n const caps = bp.capabilities.length > 0 ? bp.capabilities.join(', ') : '(no operations)';\n process.stdout.write(`${bp.kind.padEnd(24)} ${caps}\\n`);\n }\n }\n\n if (result.errors.length > 0) {\n process.stderr.write(`\\n${result.errors.length} blueprint error(s):\\n`);\n for (const e of result.errors) {\n process.stderr.write(` [${e.kind}] ${e.message}\\n`);\n }\n }\n}\n\nfunction writeJson(result: BlueprintLoadResult): void {\n const out = {\n blueprints: result.blueprints.map((b) => ({\n kind: b.kind,\n folder: b.folder,\n file: b.file,\n capabilities: b.capabilities,\n })),\n errors: result.errors,\n };\n process.stdout.write(`${JSON.stringify(out, null, 2)}\\n`);\n}\n\nasync function runUi(opts: { cwd?: string; port?: number; open: boolean }): Promise<void> {\n const cwd = opts.cwd ?? process.cwd();\n try {\n await findProject(cwd);\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n process.stderr.write(`${err.message}\\n`);\n process.exit(1);\n }\n throw err;\n }\n\n const here = dirname(fileURLToPath(import.meta.url));\n const staticDir = resolve(here, 'ui');\n\n let server: Awaited<ReturnType<typeof startUiServer>>;\n try {\n server = await startUiServer({ cwd, staticDir, port: opts.port, open: opts.open });\n } catch (err) {\n process.stderr.write(`macroscope ui: ${(err as Error).message}\\n`);\n process.exit(1);\n }\n\n process.stdout.write(`macroscope ui running at ${server.url}\\n`);\n process.stdout.write('Press Ctrl+C to stop.\\n');\n\n const shutdown = async (): Promise<void> => {\n await server.close();\n process.exit(0);\n };\n process.on('SIGINT', () => void shutdown());\n process.on('SIGTERM', () => void shutdown());\n}\n\nfunction writeError(message: string, json: boolean): void {\n if (json) {\n process.stdout.write(`${JSON.stringify({ ok: false, error: message })}\\n`);\n } else {\n process.stderr.write(`${message}\\n`);\n }\n}\n","export const VERSION = '0.0.0';\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { type IncomingMessage, type ServerResponse, createServer } from 'node:http';\nimport { extname, join, normalize, resolve } from 'node:path';\nimport { handleBlocksRequest } from './api/blocks-handler.js';\nimport { handleBlueprintsRequest } from './api/blueprints-handler.js';\nimport { handleCodeRequest } from './api/code-handler.js';\nimport { handleMarkdownRequest } from './api/markdown-handler.js';\nimport { ServiceManager } from './api/service-manager.js';\nimport { handleServiceEnsureRequest } from './api/services-handler.js';\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.htm': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.map': 'application/json; charset=utf-8',\n};\n\nexport interface StartUiServerOptions {\n /** Project root (or any descendant) — used by /api/blueprints to find .macroscope/. */\n cwd: string;\n /** Directory holding the pre-built UI bundle (index.html + assets). */\n staticDir: string;\n /** Port to listen on. 0 picks any free port. */\n port?: number;\n /** Whether to auto-open the system browser. Default true. */\n open?: boolean;\n}\n\nexport interface RunningUiServer {\n url: string;\n port: number;\n close: () => Promise<void>;\n}\n\n/**\n * Start the macroscope web UI server. Serves the pre-built bundle as static\n * files and answers /api/blueprints with the live loader output.\n *\n * No Vite at runtime — the bundle ships with the package.\n */\nexport async function startUiServer(opts: StartUiServerOptions): Promise<RunningUiServer> {\n const staticDir = resolve(opts.staticDir);\n if (!existsSync(staticDir)) {\n throw new Error(\n `Macroscope UI build is missing. Expected files at ${staticDir}. Run \\`pnpm build\\` first.`,\n );\n }\n const indexFile = join(staticDir, 'index.html');\n if (!existsSync(indexFile)) {\n throw new Error(`Macroscope UI build is incomplete: ${indexFile} not found.`);\n }\n\n const serviceManager = new ServiceManager();\n\n const server = createServer((req, res) => {\n void handleRequest(req, res, staticDir, opts.cwd, serviceManager).catch((err) => {\n respondError(res, 500, err instanceof Error ? err.message : String(err));\n });\n });\n\n const port = await new Promise<number>((resolveListen, reject) => {\n server.once('error', reject);\n server.listen(opts.port ?? 0, '127.0.0.1', () => {\n const addr = server.address();\n if (!addr || typeof addr === 'string') {\n reject(new Error('Server did not start with an address'));\n return;\n }\n resolveListen(addr.port);\n });\n });\n\n const { attachTerminalWs } = await import('./api/terminal-ws.js');\n attachTerminalWs(server, opts.cwd);\n\n const url = `http://localhost:${port}`;\n\n if (opts.open !== false) {\n try {\n const openModule = await import('open');\n const openFn = openModule.default ?? openModule;\n await (openFn as (target: string) => Promise<unknown>)(url);\n } catch {\n // Browser-launch failure is not fatal. The URL still works.\n }\n }\n\n const onSignal = () => serviceManager.shutdown();\n process.once('SIGINT', onSignal);\n process.once('SIGTERM', onSignal);\n\n return {\n url,\n port,\n close: () =>\n new Promise<void>((resolveClose, reject) => {\n serviceManager.shutdown();\n process.off('SIGINT', onSignal);\n process.off('SIGTERM', onSignal);\n server.close((err) => (err ? reject(err) : resolveClose()));\n }),\n };\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n staticDir: string,\n cwd: string,\n serviceManager: ServiceManager,\n): Promise<void> {\n const url = new URL(req.url ?? '/', 'http://localhost');\n\n if (url.pathname === '/api/blueprints') {\n const result = await handleBlueprintsRequest(cwd);\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n if (url.pathname === '/api/blocks') {\n const result = await handleBlocksRequest(cwd);\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n if (url.pathname === '/api/markdown') {\n const requestedPath = url.searchParams.get('path');\n if (!requestedPath) {\n res.statusCode = 400;\n res.setHeader('content-type', 'text/plain');\n res.end('Missing ?path');\n return;\n }\n const absolute = resolve(cwd, requestedPath);\n if (!absolute.startsWith(resolve(cwd))) {\n res.statusCode = 403;\n res.setHeader('content-type', 'text/plain');\n res.end('Forbidden');\n return;\n }\n const result = await handleMarkdownRequest(absolute);\n res.statusCode = result.status;\n res.setHeader('content-type', result.contentType);\n res.end(result.body);\n return;\n }\n\n if (url.pathname === '/api/code') {\n const requestedPath = url.searchParams.get('path');\n const lang = url.searchParams.get('lang') ?? undefined;\n if (!requestedPath) {\n res.statusCode = 400;\n res.setHeader('content-type', 'text/plain');\n res.end('Missing ?path');\n return;\n }\n const absolute = resolve(cwd, requestedPath);\n if (!absolute.startsWith(resolve(cwd))) {\n res.statusCode = 403;\n res.setHeader('content-type', 'text/plain');\n res.end('Forbidden');\n return;\n }\n const result = await handleCodeRequest(absolute, lang);\n res.statusCode = result.status;\n res.setHeader('content-type', result.contentType);\n res.end(result.body);\n return;\n }\n\n if (url.pathname === '/api/services/ensure' && req.method === 'POST') {\n const raw = await readBody(req);\n let parsed: { blockId?: string; viewKey?: string };\n try {\n parsed = JSON.parse(raw || '{}');\n } catch {\n res.statusCode = 400;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify({ error: 'invalid json' }));\n return;\n }\n const result = await handleServiceEnsureRequest(cwd, serviceManager, {\n blockId: parsed.blockId ?? '',\n viewKey: parsed.viewKey ?? '',\n });\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n // Resolve the requested static file, defending against path traversal.\n const requested = url.pathname === '/' ? '/index.html' : url.pathname;\n const absolutePath = normalize(join(staticDir, requested));\n if (!absolutePath.startsWith(staticDir)) {\n respondError(res, 403, 'Forbidden');\n return;\n }\n\n try {\n const content = await readFile(absolutePath);\n res.setHeader('content-type', MIME_TYPES[extname(absolutePath)] ?? 'application/octet-stream');\n res.end(content);\n return;\n } catch {\n // SPA fallback: any unknown route serves index.html so client-side routing works.\n try {\n const indexContent = await readFile(join(staticDir, 'index.html'));\n res.setHeader('content-type', 'text/html; charset=utf-8');\n res.end(indexContent);\n } catch {\n respondError(res, 404, 'Not found');\n }\n }\n}\n\nfunction respondError(res: ServerResponse, status: number, message: string): void {\n res.statusCode = status;\n res.setHeader('content-type', 'text/plain; charset=utf-8');\n res.end(message);\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolveBody, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (c: Buffer) => chunks.push(c));\n req.on('end', () => resolveBody(Buffer.concat(chunks).toString()));\n req.on('error', reject);\n });\n}\n","import { type LoadedBlueprint, loadBlueprints } from '../../core/blueprints.js';\nimport type { Block, Handler, ServiceSpec } from '../../core/handler.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\nimport { type ScannedBlock, scan } from '../../core/scanner.js';\n\nexport interface BlocksResponse {\n status: 200 | 404 | 500;\n body: unknown;\n}\n\nexport type ResolvedView =\n | { type: 'iframe'; key: string; label: string; url: string; service: ServiceMeta | null }\n | { type: 'terminal'; key: string; label: string }\n | {\n type: 'hybrid';\n key: string;\n label: string;\n url: string;\n runLabel: string;\n codeLabel: string;\n terminalLabel: string;\n };\n\nexport interface ServiceMeta {\n /** Display name for the loading UI. Defaults to command[0]. */\n name: string;\n}\n\n/** Per-resolver timeout. Plan-eng-review P1 fix. */\nexport const URL_RESOLVE_TIMEOUT_MS = 5000;\n\nexport async function handleBlocksRequest(cwd: string): Promise<BlocksResponse> {\n try {\n const project = await findProject(cwd);\n const [scanResult, blueprintResult] = await Promise.all([\n scan(project),\n loadBlueprints(project),\n ]);\n const byKind = new Map<string, LoadedBlueprint>();\n for (const bp of blueprintResult.blueprints) byKind.set(bp.kind, bp);\n\n const blocks = await Promise.all(\n scanResult.blocks.map(async (block) => ({\n id: block.id,\n path: block.path,\n manifest: block.manifest,\n contentHash: block.contentHash,\n views: await resolveViewsWithTimeout(\n block,\n byKind.get(block.manifest.kind)?.handler,\n URL_RESOLVE_TIMEOUT_MS,\n ),\n })),\n );\n\n return {\n status: 200,\n body: {\n blocks,\n errors: scanResult.errors,\n blueprintErrors: blueprintResult.errors,\n },\n };\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n return { status: 404, body: { error: err.message } };\n }\n return { status: 500, body: { error: (err as Error).message } };\n }\n}\n\nexport async function resolveViewsWithTimeout(\n block: ScannedBlock | Block,\n handler: Handler | undefined,\n timeoutMs = URL_RESOLVE_TIMEOUT_MS,\n): Promise<ResolvedView[]> {\n if (!handler?.views) return [];\n const blockInput: Block = { id: block.id, path: block.path, manifest: block.manifest };\n const resolved: ResolvedView[] = [];\n for (const [key, spec] of Object.entries(handler.views)) {\n if (spec.type === 'iframe') {\n const service: ServiceMeta | null = spec.service\n ? { name: spec.service.name ?? firstArg(spec.service.command) }\n : null;\n if (typeof spec.url === 'string') {\n resolved.push({ type: 'iframe', key, label: titleize(key), url: spec.url, service });\n continue;\n }\n try {\n const url = await withTimeout(spec.url(blockInput), timeoutMs);\n if (typeof url !== 'string') continue;\n resolved.push({ type: 'iframe', key, label: titleize(key), url, service });\n } catch {\n // Resolver threw OR timed out. Skip this view; block still loads.\n }\n } else if (spec.type === 'terminal') {\n // Terminal commands resolve lazily when the WebSocket opens. The /api/blocks\n // response only carries the view descriptor; the actual command runs server-side\n // when the user clicks the tab.\n resolved.push({ type: 'terminal', key, label: titleize(key) });\n } else if (spec.type === 'hybrid') {\n // Like iframe + terminal combined. The URL is resolved now; the command\n // resolves lazily via the same WebSocket flow as a terminal view.\n const runLabel = spec.runLabel ?? 'Run';\n const codeLabel = spec.codeLabel ?? 'Code';\n const terminalLabel = spec.terminalLabel ?? 'Terminal';\n if (typeof spec.url === 'string') {\n resolved.push({\n type: 'hybrid',\n key,\n label: titleize(key),\n url: spec.url,\n runLabel,\n codeLabel,\n terminalLabel,\n });\n continue;\n }\n try {\n const url = await withTimeout(spec.url(blockInput), timeoutMs);\n if (typeof url !== 'string') continue;\n resolved.push({\n type: 'hybrid',\n key,\n label: titleize(key),\n url,\n runLabel,\n codeLabel,\n terminalLabel,\n });\n } catch {\n // URL resolver failed; skip the view.\n }\n }\n }\n return resolved;\n}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return Promise.race([\n promise,\n new Promise<T>((_, reject) =>\n setTimeout(() => reject(new Error(`url resolver timed out after ${ms}ms`)), ms),\n ),\n ]);\n}\n\nfunction titleize(key: string): string {\n return key.charAt(0).toUpperCase() + key.slice(1).replace(/-/g, ' ');\n}\n\nfunction firstArg(command: ServiceSpec['command']): string {\n if (Array.isArray(command)) return command[0] ?? 'service';\n return 'service';\n}\n","import { loadBlueprints } from '../../core/blueprints.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\n\nexport interface BlueprintsResponse {\n status: 200 | 404 | 500;\n body: unknown;\n}\n\n/**\n * Pure request handler: resolve the project, load blueprints, return a\n * status + JSON-serializable body. Strips the live Handler function from\n * each blueprint before serializing.\n *\n * This is the boundary between the Node-side substrate (filesystem + jiti)\n * and the browser-side UI. Test it without booting Vite.\n */\nexport async function handleBlueprintsRequest(cwd: string): Promise<BlueprintsResponse> {\n try {\n const project = await findProject(cwd);\n const result = await loadBlueprints(project);\n return {\n status: 200,\n body: {\n blueprints: result.blueprints.map((b) => ({\n kind: b.kind,\n folder: b.folder,\n file: b.file,\n capabilities: b.capabilities,\n })),\n errors: result.errors,\n },\n };\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n return { status: 404, body: { error: err.message } };\n }\n const message = err instanceof Error ? err.message : String(err);\n return { status: 500, body: { error: message } };\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { codeToHtml } from 'shiki';\n\nexport interface CodeResponse {\n status: 200 | 404 | 500;\n contentType: string;\n body: string;\n}\n\nconst EXT_TO_LANG: Record<string, string> = {\n '.ts': 'typescript',\n '.tsx': 'tsx',\n '.js': 'javascript',\n '.jsx': 'jsx',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.json': 'json',\n '.css': 'css',\n '.html': 'html',\n '.md': 'markdown',\n '.yaml': 'yaml',\n '.yml': 'yaml',\n '.sh': 'shell',\n '.py': 'python',\n '.rs': 'rust',\n '.go': 'go',\n};\n\nexport async function handleCodeRequest(\n absolutePath: string,\n language?: string,\n): Promise<CodeResponse> {\n let raw: string;\n try {\n raw = await readFile(absolutePath, 'utf8');\n } catch {\n return errorResponse(404, `File not found: ${absolutePath}`);\n }\n\n const lang = language ?? EXT_TO_LANG[extname(absolutePath).toLowerCase()] ?? 'text';\n try {\n const inner = await codeToHtml(raw, { lang, theme: 'github-dark' });\n return {\n status: 200,\n contentType: 'text/html; charset=utf-8',\n body: wrap(inner),\n };\n } catch {\n // Unknown language → render as plain text.\n const fallback = `<pre>${escapeHtml(raw)}</pre>`;\n return {\n status: 200,\n contentType: 'text/html; charset=utf-8',\n body: wrap(fallback),\n };\n }\n}\n\nfunction wrap(inner: string): string {\n return `<!doctype html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <title>macroscope · code</title>\n <style>\n body { margin: 0; padding: 0; font-family: ui-monospace, SFMono-Regular, monospace; }\n pre { margin: 0; padding: 1rem; overflow-x: auto; line-height: 1.5; font-size: 13px; }\n </style>\n</head>\n<body>${inner}</body>\n</html>`;\n}\n\nfunction errorResponse(status: 404 | 500, message: string): CodeResponse {\n return {\n status,\n contentType: 'text/html; charset=utf-8',\n body: `<!doctype html><body><pre>${escapeHtml(message)}</pre></body>`,\n };\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' })[c] ?? c);\n}\n","import { readFile } from 'node:fs/promises';\nimport { marked } from 'marked';\n\nexport interface MarkdownResponse {\n status: 200 | 404 | 500;\n contentType: string;\n body: string;\n}\n\nexport async function handleMarkdownRequest(absolutePath: string): Promise<MarkdownResponse> {\n let raw: string;\n try {\n raw = await readFile(absolutePath, 'utf8');\n } catch {\n return errorResponse(404, `File not found: ${absolutePath}`);\n }\n\n try {\n const inner = await marked.parse(raw);\n return {\n status: 200,\n contentType: 'text/html; charset=utf-8',\n body: wrap(inner),\n };\n } catch (err) {\n return errorResponse(500, `Failed to render markdown: ${(err as Error).message}`);\n }\n}\n\nfunction wrap(inner: string): string {\n return `<!doctype html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <title>macroscope · markdown</title>\n <style>\n body { font-family: ui-sans-serif, system-ui, sans-serif; max-width: 760px; margin: 2rem auto; padding: 0 1rem; line-height: 1.6; color: #18181b; }\n h1, h2, h3 { margin-top: 1.6em; }\n code { background: #f4f4f5; padding: 0.1em 0.3em; border-radius: 3px; font-size: 0.9em; }\n pre { background: #18181b; color: #fafafa; padding: 1em; border-radius: 6px; overflow-x: auto; }\n pre code { background: transparent; padding: 0; color: inherit; }\n a { color: #2563eb; }\n </style>\n</head>\n<body>${inner}</body>\n</html>`;\n}\n\nfunction errorResponse(status: 404 | 500, message: string): MarkdownResponse {\n return {\n status,\n contentType: 'text/html; charset=utf-8',\n body: `<!doctype html><body><pre>${escapeHtml(message)}</pre></body>`,\n };\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' })[c] ?? c);\n}\n","import type { ChildProcess, SpawnOptions } from 'node:child_process';\nimport { spawn as nodeSpawn } from 'node:child_process';\nimport { pollReadiness as defaultPoll } from './service-readiness.js';\n\nexport type ServiceStatus = 'starting' | 'ready' | 'failed';\n\nexport interface ServiceState {\n status: ServiceStatus;\n logs: string;\n message?: string;\n adopted?: boolean;\n}\n\nexport interface EnsureInput {\n command: string[];\n cwd: string;\n readyUrl: string;\n probeFirst?: boolean;\n startupTimeoutMs?: number;\n}\n\nexport interface ServiceManagerDeps {\n spawn?: (cmd: string, args: string[], opts: SpawnOptions) => ChildProcess;\n pollReadiness?: typeof defaultPoll;\n}\n\nconst LOG_BUFFER_BYTES = 4096;\n\nexport class ServiceManager {\n private spawn: NonNullable<ServiceManagerDeps['spawn']>;\n private poll: NonNullable<ServiceManagerDeps['pollReadiness']>;\n private services = new Map<\n string,\n { state: ServiceState; child?: ChildProcess; abort: AbortController }\n >();\n\n constructor(deps: ServiceManagerDeps = {}) {\n this.spawn = deps.spawn ?? nodeSpawn;\n this.poll = deps.pollReadiness ?? defaultPoll;\n }\n\n keyFor(input: { command: string[]; cwd: string }): string {\n return JSON.stringify({ command: input.command, cwd: input.cwd });\n }\n\n get(key: string): ServiceState | undefined {\n return this.services.get(key)?.state;\n }\n\n async ensure(input: EnsureInput): Promise<ServiceState> {\n const key = this.keyFor(input);\n const existing = this.services.get(key);\n if (existing) return existing.state;\n\n if (input.probeFirst) {\n const probe = await this.poll(input.readyUrl, { timeoutMs: 500, intervalMs: 100 });\n if (probe.ready) {\n const state: ServiceState = { status: 'ready', logs: '', adopted: true };\n this.services.set(key, { state, abort: new AbortController() });\n return state;\n }\n }\n\n const [bin, ...args] = input.command;\n if (!bin) return { status: 'failed', logs: '', message: 'empty command' };\n\n const abort = new AbortController();\n const state: ServiceState = { status: 'starting', logs: '' };\n\n let child: ChildProcess;\n try {\n child = this.spawn(bin, args, { cwd: input.cwd, stdio: ['ignore', 'pipe', 'pipe'] });\n } catch (err) {\n return { status: 'failed', logs: '', message: `spawn failed: ${(err as Error).message}` };\n }\n\n this.services.set(key, { state, child, abort });\n\n const appendLog = (chunk: Buffer) => {\n state.logs = (state.logs + chunk.toString()).slice(-LOG_BUFFER_BYTES);\n };\n child.stdout?.on('data', appendLog);\n child.stderr?.on('data', appendLog);\n\n child.on('exit', (code) => {\n if (state.status === 'starting' || state.status === 'ready') {\n state.status = 'failed';\n state.message = `process exited with code ${code}`;\n abort.abort();\n }\n });\n child.on('error', (err) => {\n if (state.status === 'starting') {\n state.status = 'failed';\n state.message = err.message;\n abort.abort();\n }\n });\n\n void this.poll(input.readyUrl, {\n timeoutMs: input.startupTimeoutMs ?? 30_000,\n signal: abort.signal,\n }).then((result) => {\n if (state.status !== 'starting') return;\n if (result.ready) {\n state.status = 'ready';\n } else if (!result.aborted) {\n state.status = 'failed';\n state.message = `readiness check failed: ${result.lastError ?? 'timeout'}`;\n if (!child.killed) child.kill();\n }\n });\n\n return state;\n }\n\n shutdown(): void {\n for (const entry of this.services.values()) {\n entry.abort.abort();\n if (entry.child && !entry.child.killed) entry.child.kill();\n }\n this.services.clear();\n }\n}\n","export interface PollOptions {\n timeoutMs?: number;\n intervalMs?: number;\n signal?: AbortSignal;\n fetch?: typeof fetch;\n}\n\nexport interface PollResult {\n ready: boolean;\n aborted?: boolean;\n lastError?: string;\n}\n\nexport async function pollReadiness(url: string, opts: PollOptions = {}): Promise<PollResult> {\n const timeoutMs = opts.timeoutMs ?? 30_000;\n const intervalMs = opts.intervalMs ?? 250;\n const fetchImpl = opts.fetch ?? fetch;\n const deadline = Date.now() + timeoutMs;\n let lastError = '';\n\n while (Date.now() < deadline) {\n if (opts.signal?.aborted) return { ready: false, aborted: true };\n try {\n const fetchPromise = fetchImpl(url, { signal: opts.signal });\n let onAbort: (() => void) | null = null;\n const signal = opts.signal;\n const abortPromise = signal\n ? new Promise<never>((_, reject) => {\n onAbort = () => {\n reject(new AbortError());\n };\n signal.addEventListener('abort', onAbort, { once: true });\n })\n : new Promise<never>(() => {});\n try {\n const res = await Promise.race([fetchPromise, abortPromise]);\n if (res.status < 500) return { ready: true };\n lastError = `status ${res.status}`;\n } finally {\n if (onAbort && opts.signal) opts.signal.removeEventListener('abort', onAbort);\n }\n } catch (err) {\n if (opts.signal?.aborted || err instanceof AbortError) return { ready: false, aborted: true };\n lastError = err instanceof Error ? err.message : String(err);\n }\n const result = await sleep(intervalMs, opts.signal);\n if (result.aborted) return { ready: false, aborted: true };\n }\n return { ready: false, lastError };\n}\n\nclass AbortError extends Error {\n constructor() {\n super('aborted');\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<{ aborted: boolean }> {\n return new Promise((resolve) => {\n let onAbort: (() => void) | null = null;\n const t = setTimeout(() => {\n if (onAbort && signal) signal.removeEventListener('abort', onAbort);\n resolve({ aborted: false });\n }, ms);\n if (signal?.aborted) {\n clearTimeout(t);\n resolve({ aborted: true });\n return;\n }\n onAbort = () => {\n clearTimeout(t);\n if (signal && onAbort) signal.removeEventListener('abort', onAbort);\n resolve({ aborted: true });\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n","import { loadBlueprints } from '../../core/blueprints.js';\nimport type { Block, ServiceSpec } from '../../core/handler.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\nimport { scan } from '../../core/scanner.js';\nimport type { ServiceManager, ServiceState } from './service-manager.js';\n\nexport interface ServiceEnsureBody {\n blockId: string;\n viewKey: string;\n}\n\nexport interface ServiceEnsureResponse {\n status: 200 | 400 | 404 | 500;\n body: { status?: ServiceState['status']; message?: string; error?: string; logs?: string };\n}\n\nexport async function handleServiceEnsureRequest(\n cwd: string,\n manager: ServiceManager,\n input: ServiceEnsureBody,\n): Promise<ServiceEnsureResponse> {\n if (!input.blockId || !input.viewKey) {\n return { status: 400, body: { error: 'blockId and viewKey are required' } };\n }\n try {\n const project = await findProject(cwd);\n const [scanResult, blueprintResult] = await Promise.all([\n scan(project),\n loadBlueprints(project),\n ]);\n\n const block = scanResult.blocks.find((b) => b.id === input.blockId);\n if (!block) return { status: 404, body: { error: `unknown block: ${input.blockId}` } };\n\n const bp = blueprintResult.blueprints.find((b) => b.kind === block.manifest.kind);\n const viewSpec = bp?.handler.views?.[input.viewKey];\n if (!viewSpec || viewSpec.type !== 'iframe' || !viewSpec.service) {\n return { status: 404, body: { error: `view ${input.viewKey} has no service` } };\n }\n const svc: ServiceSpec = viewSpec.service;\n\n const blockInput: Block = { id: block.id, path: block.path, manifest: block.manifest };\n const command = typeof svc.command === 'function' ? await svc.command(blockInput) : svc.command;\n const cwdResolved =\n typeof svc.cwd === 'function' ? await svc.cwd(blockInput) : (svc.cwd ?? project.root);\n\n const state = await manager.ensure({\n command,\n cwd: cwdResolved,\n readyUrl: svc.readyWhen.url,\n probeFirst: true,\n startupTimeoutMs: svc.startupTimeoutMs,\n });\n\n return {\n status: 200,\n body: {\n status: state.status,\n message: state.message,\n logs: state.status === 'failed' ? state.logs : undefined,\n },\n };\n } catch (err) {\n if (err instanceof ProjectNotFoundError) return { status: 404, body: { error: err.message } };\n return { status: 500, body: { error: (err as Error).message } };\n }\n}\n"],"mappings":"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","names":["existsSync","join","z","existsSync","readFile","readdir","dirname","join","parseYaml","withTimeout","dirname","resolve","existsSync","readFile","extname","join","resolve","readFile","readFile","errorResponse","wrap","escapeHtml","resolve","state","resolve","existsSync","join","attachTerminalWs","readFile","extname","dirname","resolve"]}
1
+ {"version":3,"sources":["../../contracts/src/version.ts","../../contracts/src/fs.ts","../../contracts/src/manifest.ts","../../contracts/src/payload.ts","../../contracts/src/search.ts","../../contracts/src/api.ts","../../contracts/src/error.ts","../../contracts/src/auth.ts","../src/core/project.ts","../src/core/handler.ts","../src/core/blueprints.ts","../src/core/manifest.ts","../src/core/scanner.ts","../src/util/process-group.ts","../src/ui/api/terminal-resolver.ts","../src/ui/api/terminal-ws.ts","../src/cli.ts","../src/auth/errors.ts","../src/auth/callback-server.ts","../src/auth/credentials.ts","../src/auth/pkce.ts","../src/auth/state.ts","../src/auth/token-exchange.ts","../src/auth/user-info.ts","../src/auth/login.ts","../src/auth/providers/github.ts","../src/auth/providers/gitlab.ts","../src/auth/providers/index.ts","../src/auth/cli.ts","../src/util/lifecycle.ts","../src/commands/login.ts","../src/commands/logout.ts","../src/cloud/client.ts","../src/commands/search.ts","../src/local/code-search.ts","../src/commands/status.ts","../src/core/version.ts","../src/ui/ui-server.ts","../src/local/catchup.ts","../src/core/extractor.ts","../src/core/hasher.ts","../src/local/repo-id.ts","../src/local/watcher.ts","../src/local/worktree-id.ts","../src/ui/api/blocks-handler.ts","../src/ui/api/blueprints-handler.ts","../src/ui/api/code-handler.ts","../src/ui/api/code-search-handler.ts","../src/ui/api/context-handler.ts","../src/ui/api/markdown-handler.ts","../src/ui/api/progress-stream.ts","../src/ui/api/proxy.ts","../src/ui/api/service-manager.ts","../src/ui/api/service-readiness.ts","../src/ui/api/services-handler.ts"],"sourcesContent":["/**\n * Wire-format version for cloud-side documents (MeilisearchDoc). Bumped when\n * the doc shape changes in a way that requires reindexing. The catch-up scan\n * watches for a mismatch with the server-reported version and triggers a full\n * re-push (see `catchup.ts`).\n */\nexport const SCHEMA_VERSION = 1 as const;\nexport type SchemaVersion = typeof SCHEMA_VERSION;\n","/**\n * Filesystem paths macroscope reads and writes. Two roots:\n *\n * user — under `~/.macroscope/`; survives across projects.\n * project — under `<project>/.macroscope/`; specific to a worktree.\n *\n * Paths are POSIX-style and relative to their root. Callers resolve them\n * against the relevant base directory (`os.homedir()` or the project root).\n */\nexport const FILESYSTEM_LAYOUT = {\n user: {\n /** `~/.macroscope/` */\n rootDir: '.macroscope',\n /** `~/.macroscope/credentials` — OAuth token store, mode 0600. */\n credentialsFile: '.macroscope/credentials',\n /** `~/.macroscope/machine-id` — stable per-install identifier. */\n machineIdFile: '.macroscope/machine-id',\n },\n project: {\n /** `<project>/.macroscope/` */\n rootDir: '.macroscope',\n /** `<project>/.macroscope/blueprints/` — one folder per kind. */\n blueprintsDir: '.macroscope/blueprints',\n /** `<project>/.macroscope/cache/` */\n cacheDir: '.macroscope/cache',\n /** `<project>/.macroscope/cache/hashes.json` — content-hash cache used by catch-up scan. */\n hashesFile: '.macroscope/cache/hashes.json',\n /** `<project>/.macroscope/cache/queue.json` — watcher push queue, survives restart. */\n queueFile: '.macroscope/cache/queue.json',\n },\n} as const;\n\nexport type FilesystemLayout = typeof FILESYSTEM_LAYOUT;\n","import { z } from 'zod';\n\n/**\n * The on-disk `macroscope.yaml` manifest. Substrate-level fields are listed\n * explicitly; blueprints may attach additional kind-specific fields, which\n * pass through unchanged (`.passthrough()`).\n */\nexport const BlockManifestSchema = z\n .object({\n /** Must reference a registered blueprint's `kind`. */\n kind: z.string().min(1),\n /** Optional override for the auto-derived block id (POSIX relative path). */\n id: z.string().optional(),\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n source: z.string().optional(),\n preview: z.string().optional(),\n docs: z.string().optional(),\n tests: z.union([z.string(), z.array(z.string())]).optional(),\n })\n .passthrough();\n\nexport type BlockManifest = z.infer<typeof BlockManifestSchema>;\n","import { z } from 'zod';\n\n/**\n * One exported symbol from a block's source files. Extracted by the TS\n * compiler API. `signature` is the rendered TypeScript signature string\n * (e.g. `function foo(x: string): number`); the exact rendering is the\n * extractor's responsibility (see T5).\n */\nexport const SymbolSignatureSchema = z.object({\n name: z.string().min(1),\n kind: z.string().min(1),\n signature: z.string(),\n});\nexport type SymbolSignature = z.infer<typeof SymbolSignatureSchema>;\n\n/**\n * What the watcher pushes to the cloud per block. The cloud combines this\n * with cloud-side fields (repo, worktreeId, path, lastActiveAt, contentHash)\n * to form the `MeilisearchDoc` that lands in the user's index.\n */\nexport const UploadPayloadSchema = z.object({\n /** Stable block id (POSIX relative path or manifest `id` override). */\n blockId: z.string().min(1),\n kind: z.string().min(1),\n name: z.string().optional(),\n description: z.string().optional(),\n tags: z.array(z.string()).optional(),\n /** Exported symbols extracted from the block's source files. */\n symbols: z.array(SymbolSignatureSchema),\n /** First ~500 chars of the README, if any. */\n readmeExcerpt: z.string().optional(),\n});\nexport type UploadPayload = z.infer<typeof UploadPayloadSchema>;\n\n/**\n * The doc shape stored in Meilisearch. Identity is the tuple\n * (repo, worktreeId, blockId): two worktrees of the same repo produce\n * distinct docs and filter independently.\n */\nexport const MeilisearchDocSchema = UploadPayloadSchema.extend({\n /** SHA-256 over the canonical JSON of the UploadPayload (see T6). */\n contentHash: z.string().min(1),\n /** Git remote URL (normalised) or local repo name when no remote exists. */\n repo: z.string().min(1),\n /** hash(machineUuid + absolutePath) — see ARCHITECTURE.md. */\n worktreeId: z.string().min(1),\n /** POSIX path from the worktree root to the block folder. */\n path: z.string().min(1),\n /** Unix epoch milliseconds. Refreshed on every push and by `/scope/touch`. */\n lastActiveAt: z.number().int().nonnegative(),\n});\nexport type MeilisearchDoc = z.infer<typeof MeilisearchDocSchema>;\n","import { z } from 'zod';\n\n/**\n * One cloud-side search result. Returned by `GET /search`. Carries enough\n * to render a result row without a second fetch.\n */\nexport const BlockHitSchema = z.object({\n blockId: z.string().min(1),\n kind: z.string().min(1),\n name: z.string().optional(),\n description: z.string().optional(),\n repo: z.string().min(1),\n worktreeId: z.string().min(1),\n path: z.string().min(1),\n /** Relevance score from Meilisearch hybrid ranking. Larger = more relevant. */\n score: z.number(),\n});\nexport type BlockHit = z.infer<typeof BlockHitSchema>;\n\n/**\n * One local-side code search result. Produced by `git grep` (T10). Lives in\n * contracts so the UI's merged-results view can speak one type.\n */\nexport const CodeMatchSchema = z.object({\n /** POSIX path from the worktree root. */\n file: z.string().min(1),\n /** 1-based line number. */\n line: z.number().int().positive(),\n /** 1-based column number, when available. */\n column: z.number().int().positive().optional(),\n /** A single line of source text containing the match. */\n preview: z.string(),\n});\nexport type CodeMatch = z.infer<typeof CodeMatchSchema>;\n","import { z } from 'zod';\nimport { MeilisearchDocSchema } from './payload.js';\nimport { BlockHitSchema } from './search.js';\n\n/* ------------------------------ POST /index/batch ------------------------------ */\n\nexport const IndexBatchRequestSchema = z.object({\n /** Per-block docs to upsert. The cloud routes these to the user's Meilisearch index. */\n upserts: z.array(MeilisearchDocSchema),\n /** Block ids to delete. Empty array is valid (upsert-only batch). */\n deletes: z.array(z.string().min(1)),\n});\nexport type IndexBatchRequest = z.infer<typeof IndexBatchRequestSchema>;\n\nexport const IndexBatchResponseSchema = z.object({\n /** Unix epoch ms of server-side acknowledgement. */\n acceptedAt: z.number().int().nonnegative(),\n /** Number of upserts accepted (deletes excluded). */\n accepted: z.number().int().nonnegative(),\n});\nexport type IndexBatchResponse = z.infer<typeof IndexBatchResponseSchema>;\n\n/* --------------------------------- GET /search --------------------------------- */\n\nexport const SearchRequestSchema = z.object({\n q: z.string().min(1),\n /** Restrict to one worktree. Omit to search across all of the user's worktrees. */\n worktreeId: z.string().optional(),\n /** Restrict to one repo. */\n repo: z.string().optional(),\n /** Restrict to one block kind. */\n kind: z.string().optional(),\n /** Cap on returned hits. Server enforces an upper bound. */\n limit: z.number().int().positive().optional(),\n});\nexport type SearchRequest = z.infer<typeof SearchRequestSchema>;\n\nexport const SearchResponseSchema = z.object({\n hits: z.array(BlockHitSchema),\n /** Approximate total match count from Meilisearch (estimated, not exact). */\n totalEstimated: z.number().int().nonnegative(),\n});\nexport type SearchResponse = z.infer<typeof SearchResponseSchema>;\n\n/* --------------------------------- DELETE /index -------------------------------- */\n\nexport const DeleteIndexResponseSchema = z.object({\n deletedAt: z.number().int().nonnegative(),\n});\nexport type DeleteIndexResponse = z.infer<typeof DeleteIndexResponseSchema>;\n\n/* ------------------------------ POST /scope/touch ------------------------------ */\n\nexport const ScopeTouchRequestSchema = z.object({\n worktreeId: z.string().min(1),\n repo: z.string().min(1),\n});\nexport type ScopeTouchRequest = z.infer<typeof ScopeTouchRequestSchema>;\n\nexport const ScopeTouchResponseSchema = z.object({\n touchedAt: z.number().int().nonnegative(),\n});\nexport type ScopeTouchResponse = z.infer<typeof ScopeTouchResponseSchema>;\n\n/* --------------------------------- GET /health --------------------------------- */\n\nexport const HealthResponseSchema = z.object({\n status: z.literal('ok'),\n schemaVersion: z.number().int().positive(),\n});\nexport type HealthResponse = z.infer<typeof HealthResponseSchema>;\n\n/**\n * Endpoint manifest. One row per route, suitable for type-checking a server\n * router and a typed client against a single source of truth.\n *\n * Serialization convention: for `method: 'GET'` endpoints the request schema's\n * fields are sent as URL query parameters (never a body). For `POST`/`DELETE`\n * the request schema is the JSON body. `request: null` means the endpoint\n * takes no request payload at all.\n */\nexport const API_ENDPOINTS = {\n indexBatch: {\n method: 'POST',\n path: '/index/batch',\n request: IndexBatchRequestSchema,\n response: IndexBatchResponseSchema,\n },\n search: {\n method: 'GET',\n path: '/search',\n request: SearchRequestSchema,\n response: SearchResponseSchema,\n },\n deleteIndex: {\n method: 'DELETE',\n path: '/index',\n request: null,\n response: DeleteIndexResponseSchema,\n },\n scopeTouch: {\n method: 'POST',\n path: '/scope/touch',\n request: ScopeTouchRequestSchema,\n response: ScopeTouchResponseSchema,\n },\n health: {\n method: 'GET',\n path: '/health',\n request: null,\n response: HealthResponseSchema,\n },\n} as const;\n\nexport type ApiEndpoints = typeof API_ENDPOINTS;\n","import { z } from 'zod';\n\n/**\n * The uniform error shape returned by every API endpoint on failure. Per the\n * CLAUDE.md invariant: errors name the file path and the broken field where\n * applicable.\n */\nexport const ErrorEnvelopeSchema = z.object({\n error: z.object({\n /** Stable machine-readable code (e.g. `unauthorized`, `validation_failed`). */\n code: z.string().min(1),\n /** Human-readable message. */\n message: z.string().min(1),\n /** Source file path when the error originates from parsing a manifest or other on-disk artifact. Set by the CLI side (see `ScanError`) and by the cloud when validating uploaded manifests. */\n file: z.string().optional(),\n /** Path of the offending field when the error is validation-related. */\n field: z.string().optional(),\n /** Server-assigned request id for log correlation. */\n requestId: z.string().optional(),\n }),\n});\n\nexport type ErrorEnvelope = z.infer<typeof ErrorEnvelopeSchema>;\n","import { z } from 'zod';\n\n/**\n * Supported Git host identity providers. v1 ships GitHub and GitLab. Other\n * providers (Bitbucket, Gitea, self-hosted GitLab) are deferred to v1.1; see\n * TODOS.md.\n */\nexport const ProviderSchema = z.enum(['github', 'gitlab']);\nexport type Provider = z.infer<typeof ProviderSchema>;\n\n/**\n * On-disk shape of `~/.macroscope/credentials` (file mode 0600). Written by\n * `macroscope login` (T9) and read by the local proxy (T11) when forwarding\n * the bearer token to the cloud API. Refresh-token and expiry are optional —\n * not every provider issues a refresh token, and some access tokens have no\n * explicit expiry.\n */\nexport const OAuthCredentialsSchema = z.object({\n provider: ProviderSchema,\n accessToken: z.string().min(1),\n refreshToken: z.string().min(1).optional(),\n /** Unix epoch milliseconds at which `accessToken` expires. */\n expiresAt: z.number().int().nonnegative().optional(),\n /** Provider-side user id (e.g. GitHub `id`, GitLab `id`). Optional — useful\n * for UI display (\"logged in as alexspdlr on github\") and for the CLI to\n * short-circuit redundant `/user` lookups. */\n providerUserId: z.string().min(1).optional(),\n});\nexport type OAuthCredentials = z.infer<typeof OAuthCredentialsSchema>;\n\n/**\n * The authenticated-request context the OAuth validation middleware (T12)\n * attaches to every request after verifying the bearer token. Downstream\n * handlers read these fields to scope queries to the right user index.\n *\n * Identity derivation (per ARCHITECTURE.md):\n * userId = hash(provider + \":\" + providerUserId)\n * indexName = \"user_\" + userId\n *\n * Same human on different providers ⇒ different userId. Intentional — keeps\n * cross-provider identity confusion impossible at the storage layer.\n */\nexport const UserContextSchema = z.object({\n userId: z.string().min(1),\n indexName: z.string().min(1),\n provider: ProviderSchema,\n});\nexport type UserContext = z.infer<typeof UserContextSchema>;\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { dirname, join, resolve } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport { z } from 'zod';\n\nexport const projectConfigSchema = z.object({\n scanRoots: z.array(z.string()).default(['.']),\n ignore: z.array(z.string()).default(['node_modules', '.git', 'dist', '.macroscope']),\n});\n\nexport type ProjectConfig = z.infer<typeof projectConfigSchema>;\n\nexport interface Project {\n /** Absolute path to the project root (the directory containing .macroscope/). */\n root: string;\n /** Parsed .macroscope/config.yaml, with defaults filled in. */\n config: ProjectConfig;\n}\n\nexport class ProjectNotFoundError extends Error {\n constructor(startedFrom: string) {\n super(\n `No macroscope project found. Walked up from ${startedFrom} looking for a .macroscope/ directory but reached the filesystem root. Run \\`npm create macroscope\\` to scaffold one, or cd into an existing project.`,\n );\n this.name = 'ProjectNotFoundError';\n }\n}\n\n/**\n * Find the project root by walking up from `cwd` looking for a `.macroscope/`\n * directory. The macroscope root is the directory that *contains* `.macroscope`.\n * If config.yaml is present inside, it is parsed; otherwise defaults are used.\n */\nexport async function findProject(cwd: string = process.cwd()): Promise<Project> {\n const startedFrom = resolve(cwd);\n let current = startedFrom;\n while (true) {\n if (existsSync(join(current, '.macroscope'))) {\n return { root: current, config: await loadConfig(current) };\n }\n const parent = dirname(current);\n if (parent === current) {\n throw new ProjectNotFoundError(startedFrom);\n }\n current = parent;\n }\n}\n\nasync function loadConfig(root: string): Promise<ProjectConfig> {\n const configPath = join(root, '.macroscope', 'config.yaml');\n if (!existsSync(configPath)) {\n return projectConfigSchema.parse({});\n }\n const raw = await readFile(configPath, 'utf8');\n let parsed: unknown;\n try {\n parsed = parseYaml(raw) ?? {};\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n throw new Error(`Failed to parse ${configPath}: ${msg}`);\n }\n const result = projectConfigSchema.safeParse(parsed);\n if (!result.success) {\n const issues = result.error.issues\n .map((i) => ` - ${i.path.join('.') || '(root)'}: ${i.message}`)\n .join('\\n');\n throw new Error(`Invalid project config at ${configPath}:\\n${issues}`);\n }\n return result.data;\n}\n","/**\n * The locked substrate contract. The v1 control layer extends this interface;\n * it never bypasses it.\n *\n * A `Handler` is what a blueprint exports. It declares a `kind` and zero or more\n * optional async operations. Each operation returns data — never side effects —\n * and never throws \"not implemented\"; missing methods simply mean the operation\n * isn't supported for that kind.\n *\n * No top-level side effects on import. Importing a handler must not spawn\n * processes, open ports, or read files. Side effects belong inside methods.\n *\n * Trust model: blueprints are USER-AUTHORED CODE in the user's own project.\n * The loader imports them via jiti and runs them at full process privilege.\n * This is the same trust model as a `package.json` postinstall script, an\n * ESLint plugin, a Storybook addon, or a vite.config.ts — code in your repo\n * runs as you. There is no sandbox. If you do not trust a blueprint, do not\n * put it in your project.\n */\nexport interface Handler {\n /** Required. Must match the blueprint folder name. */\n kind: string;\n /** Named views shown as tabs in the block-detail page. v1 ships iframe + terminal types. */\n views?: Record<string, ViewSpec>;\n /** Produce something the UI/CLI/MCP can display for this block. */\n render?: (block: Block) => Promise<RenderResult>;\n /** Run whatever counts as a test for this kind. */\n test?: (block: Block) => Promise<TestResult>;\n /** Produce build artifacts for this kind. */\n build?: (block: Block) => Promise<BuildResult>;\n /** Create a new block of this kind in `targetDir` with the given name. */\n scaffold?: (targetDir: string, name: string) => Promise<void>;\n /** Generate a free-form textual description of a block, used by semantic search. */\n describe?: (block: Block) => Promise<string>;\n}\n\n/**\n * A block is an instance of a kind: a folder somewhere in the user's project\n * with a `macroscope.yaml`. Handlers receive these as input.\n *\n * For M0 (this PR) we don't actually load blocks yet — this type exists so the\n * Handler interface can be locked.\n */\nexport interface Block {\n /** Stable identifier. POSIX relative path from project root by default; overridable via the manifest `id` field. */\n id: string;\n /** Absolute path to the block's folder. */\n path: string;\n /** Parsed and validated manifest. */\n manifest: BlockManifest;\n}\n\n/**\n * The manifest is the data side of a block (the `macroscope.yaml`). The shape\n * here is the substrate's view of it; individual blueprints may require\n * additional fields under their own `kind`.\n */\nexport interface BlockManifest {\n /** Must reference a registered blueprint's `kind`. */\n kind: string;\n /** Optional override for the auto-derived block id. */\n id?: string;\n name?: string;\n description?: string;\n tags?: string[];\n source?: string;\n preview?: string;\n docs?: string;\n tests?: string | string[];\n /** Unknown fields pass through to handlers per the v0 spec — never errors. */\n [field: string]: unknown;\n}\n\n/**\n * A view is one tab in the block-detail page. Three view types exist:\n * - iframe: embed any URL the blueprint resolves.\n * - terminal: spawn the resolved command server-side and stream its\n * stdin/stdout/stderr to a browser xterm.js terminal.\n * - hybrid: combine a static artifact (iframe URL) with an on-demand\n * command (terminal). UI shows the URL by default and a Run button\n * that switches to the terminal and spawns the command.\n */\nexport type ViewSpec = IframeViewSpec | TerminalViewSpec | HybridViewSpec;\n\nexport interface IframeViewSpec {\n type: 'iframe';\n url: string | ((block: Block) => string | Promise<string>);\n /** Optional backing service. macroscope spawns this on demand the first time the\n * view is opened in the UI, polls readyWhen.url, and only loads the iframe\n * once the service responds. */\n service?: ServiceSpec;\n}\n\nexport interface ServiceSpec {\n /** Human-readable label shown in the \"starting…\" state. Defaults to command[0]. */\n name?: string;\n /** argv-style command. Function form is resolved server-side per block. */\n command: string[] | ((block: Block) => string[] | Promise<string[]>);\n /** Working directory. Defaults to project root. */\n cwd?: string | ((block: Block) => string | Promise<string>);\n /** Service is ready when this URL responds with any non-5xx status. */\n readyWhen: { url: string };\n /** Max ms to wait for readiness before declaring failure. Default: 30_000. */\n startupTimeoutMs?: number;\n}\n\nexport interface TerminalViewSpec {\n type: 'terminal';\n /** argv-style: ['vitest', 'run', '<file>']. Function form is resolved server-side per block. */\n command: string[] | ((block: Block) => string[] | Promise<string[]>);\n}\n\n/**\n * A hybrid view shows a static artifact (e.g. test source code) by default and\n * lets the user switch to a terminal that runs an on-demand command (e.g.\n * `vitest run`) via a Run button. Useful for \"read code → press button → see\n * what happens → toggle back\" workflows.\n */\nexport interface HybridViewSpec {\n type: 'hybrid';\n /** Static artifact URL. Same semantics as IframeViewSpec.url. */\n url: string | ((block: Block) => string | Promise<string>);\n /** On-demand command. Same semantics as TerminalViewSpec.command. */\n command: string[] | ((block: Block) => string[] | Promise<string[]>);\n /** Label for the Run button. Default: \"Run\". */\n runLabel?: string;\n /** Label for the code-side toggle. Default: \"Code\". */\n codeLabel?: string;\n /** Label for the terminal-side toggle. Default: \"Terminal\". */\n terminalLabel?: string;\n}\n\nexport type RenderResult =\n | { type: 'iframe'; entry: string }\n | { type: 'html'; html: string }\n | { type: 'markdown'; source: string }\n | { type: 'image'; src: string }\n | { type: 'error'; message: string }\n | { type: 'none'; reason: string };\n\nexport type TestResult =\n | { type: 'pass'; output?: string }\n | { type: 'fail'; output: string }\n | { type: 'error'; message: string }\n | { type: 'none'; reason: string };\n\nexport type BuildResult =\n | { type: 'ok'; artifacts?: string[] }\n | { type: 'error'; message: string }\n | { type: 'none'; reason: string };\n\n/**\n * Convenience type guard for runtime validation. Used by the blueprint loader\n * to verify that a default export looks like a Handler before accepting it.\n */\nexport function isHandler(value: unknown): value is Handler {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n if (typeof v.kind !== 'string' || v.kind.length === 0) return false;\n for (const method of ['render', 'test', 'build', 'scaffold', 'describe'] as const) {\n if (v[method] !== undefined && typeof v[method] !== 'function') return false;\n }\n if (v.views !== undefined) {\n if (typeof v.views !== 'object' || v.views === null) return false;\n for (const [, spec] of Object.entries(v.views as Record<string, unknown>)) {\n if (!isViewSpec(spec)) return false;\n }\n }\n return true;\n}\n\nfunction isViewSpec(value: unknown): value is ViewSpec {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n switch (v.type) {\n case 'iframe':\n if (typeof v.url !== 'string' && typeof v.url !== 'function') return false;\n if (v.service !== undefined && !isServiceSpec(v.service)) return false;\n return true;\n case 'terminal':\n return (\n typeof v.command === 'function' ||\n (Array.isArray(v.command) && v.command.every((c) => typeof c === 'string'))\n );\n case 'hybrid': {\n const urlOk = typeof v.url === 'string' || typeof v.url === 'function';\n const commandOk =\n typeof v.command === 'function' ||\n (Array.isArray(v.command) && v.command.every((c) => typeof c === 'string'));\n if (!urlOk || !commandOk) return false;\n for (const key of ['runLabel', 'codeLabel', 'terminalLabel'] as const) {\n if (v[key] !== undefined && typeof v[key] !== 'string') return false;\n }\n return true;\n }\n default:\n return false;\n }\n}\n\nfunction isServiceSpec(value: unknown): value is ServiceSpec {\n if (typeof value !== 'object' || value === null) return false;\n const v = value as Record<string, unknown>;\n const commandOk =\n typeof v.command === 'function' ||\n (Array.isArray(v.command) && v.command.every((c) => typeof c === 'string'));\n if (!commandOk) return false;\n if (typeof v.readyWhen !== 'object' || v.readyWhen === null) return false;\n const ready = v.readyWhen as Record<string, unknown>;\n if (typeof ready.url !== 'string') return false;\n if (v.name !== undefined && typeof v.name !== 'string') return false;\n if (v.cwd !== undefined && typeof v.cwd !== 'string' && typeof v.cwd !== 'function') {\n return false;\n }\n if (v.startupTimeoutMs !== undefined && typeof v.startupTimeoutMs !== 'number') return false;\n return true;\n}\n","import { type Dirent, existsSync } from 'node:fs';\nimport { readdir } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport { createJiti } from 'jiti';\nimport { type Handler, isHandler } from './handler.js';\nimport type { Project } from './project.js';\n\n/** Filenames tried, in order. First match wins. */\nconst HANDLER_FILENAMES = ['handler.ts', 'handler.mjs', 'handler.js'] as const;\n\n/** Optional operation methods on Handler. Order = preferred display order. */\nconst OPERATION_NAMES = ['render', 'test', 'build', 'scaffold', 'describe'] as const;\nexport type HandlerCapability = (typeof OPERATION_NAMES)[number];\n\nexport interface LoadedBlueprint {\n /** Kind name. Equal to the folder basename AND handler.kind (enforced at load time). */\n kind: string;\n /** Absolute path to the blueprint folder. */\n folder: string;\n /** Absolute path to the loaded handler file. */\n file: string;\n /** The validated Handler default export. */\n handler: Handler;\n /** Which optional operations this handler supports. */\n capabilities: HandlerCapability[];\n}\n\nexport type BlueprintLoadCause =\n | 'no-handler-file'\n | 'import-failed'\n | 'no-default-export'\n | 'invalid-handler-shape'\n | 'kind-mismatch';\n\nexport interface BlueprintLoadError {\n /** Absolute path to the blueprint folder. */\n folder: string;\n /** The folder basename — used to identify the failed blueprint even if its declared kind is wrong. */\n kind: string;\n /** Tagged cause for programmatic handling. */\n cause: BlueprintLoadCause;\n /** Human-readable message naming the file and what is wrong. */\n message: string;\n}\n\nexport interface BlueprintLoadResult {\n blueprints: LoadedBlueprint[];\n errors: BlueprintLoadError[];\n}\n\n/**\n * Discover and load every blueprint under `<project.root>/.macroscope/blueprints/`.\n *\n * Each subfolder is one blueprint. We look for `handler.ts | .mjs | .js` inside\n * it, import the default export via jiti (so users can write plain TypeScript\n * with no build step), and validate the shape against the Handler interface.\n *\n * Per-blueprint failures are collected in `errors` instead of thrown. A single\n * broken handler does not blind the rest of the catalog.\n */\nexport async function loadBlueprints(project: Project): Promise<BlueprintLoadResult> {\n const blueprintsDir = join(project.root, '.macroscope', 'blueprints');\n if (!existsSync(blueprintsDir)) {\n return { blueprints: [], errors: [] };\n }\n\n let entries: Dirent<string>[];\n try {\n entries = await readdir(blueprintsDir, { withFileTypes: true, encoding: 'utf8' });\n } catch {\n return { blueprints: [], errors: [] };\n }\n\n const blueprints: LoadedBlueprint[] = [];\n const errors: BlueprintLoadError[] = [];\n const jiti = createJiti(import.meta.url);\n\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const folder = join(blueprintsDir, entry.name);\n // Normalize to NFC. macOS HFS+/APFS may return NFD-decomposed names from\n // readdir; user handler code typically declares `kind` in NFC. Comparing\n // raw bytes would silently fail for blueprints with non-ASCII names.\n const kind = entry.name.normalize('NFC');\n const result = await loadOne(folder, kind, jiti);\n if (result.ok) {\n blueprints.push(result.blueprint);\n } else {\n errors.push(result.error);\n }\n }\n\n blueprints.sort((a, b) => (a.kind < b.kind ? -1 : 1));\n errors.sort((a, b) => (a.kind < b.kind ? -1 : 1));\n return { blueprints, errors };\n}\n\ntype LoadOutcome =\n | { ok: true; blueprint: LoadedBlueprint }\n | { ok: false; error: BlueprintLoadError };\n\nasync function loadOne(\n folder: string,\n kind: string,\n jiti: ReturnType<typeof createJiti>,\n): Promise<LoadOutcome> {\n let file: string | null = null;\n for (const filename of HANDLER_FILENAMES) {\n const candidate = join(folder, filename);\n if (existsSync(candidate)) {\n file = candidate;\n break;\n }\n }\n\n if (!file) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'no-handler-file',\n message: `Blueprint folder ${folder} has no handler file. Expected one of: ${HANDLER_FILENAMES.join(', ')}.`,\n },\n };\n }\n\n let mod: unknown;\n try {\n mod = await jiti.import(file);\n } catch (err) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'import-failed',\n message: `Failed to import ${file}: ${(err as Error).message}`,\n },\n };\n }\n\n const def = extractDefault(mod);\n if (def === undefined) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'no-default-export',\n message: `Blueprint at ${file} has no default export. Use \\`export default { kind: '${kind}', ... } satisfies Handler\\`.`,\n },\n };\n }\n\n if (!isHandler(def)) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'invalid-handler-shape',\n message: `Default export of ${file} is not a valid Handler. It must be an object with a non-empty string \\`kind\\` field and optional async methods (render, test, build, scaffold, describe).`,\n },\n };\n }\n\n if (def.kind !== kind) {\n return {\n ok: false,\n error: {\n folder,\n kind,\n cause: 'kind-mismatch',\n message: `Blueprint at ${file} declares \\`kind: '${def.kind}'\\` but lives in folder \\`${kind}/\\`. The kind field must match the folder name.`,\n },\n };\n }\n\n const handlerRecord = def as unknown as Record<string, unknown>;\n const capabilities = OPERATION_NAMES.filter((op) => typeof handlerRecord[op] === 'function');\n\n return {\n ok: true,\n blueprint: { kind: def.kind, folder, file, handler: def, capabilities },\n };\n}\n\nfunction extractDefault(mod: unknown): unknown {\n if (mod === null || mod === undefined) return undefined;\n if (typeof mod !== 'object') return mod;\n // jiti wraps the namespace in a Proxy that returns the namespace itself when\n // `.default` is accessed but no default export exists. Use hasOwnProperty so\n // we don't mistake a Proxy fallback for a real default.\n if (!Object.prototype.hasOwnProperty.call(mod, 'default')) return undefined;\n return (mod as Record<string, unknown>).default;\n}\n","import { type BlockManifest, BlockManifestSchema } from '@macroscope/contracts';\n\nexport const manifestSchema = BlockManifestSchema;\nexport type Manifest = BlockManifest;\n","import { createHash } from 'node:crypto';\nimport { existsSync } from 'node:fs';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { dirname, join, relative, resolve, sep } from 'node:path';\nimport { parse as parseYaml } from 'yaml';\nimport type { ZodError } from 'zod';\nimport type { Block, BlockManifest } from './handler.js';\nimport { manifestSchema } from './manifest.js';\nimport type { Project } from './project.js';\n\nexport interface ResolvedPaths {\n source?: string;\n docs?: string;\n preview?: string;\n tests?: string[];\n}\n\nexport interface ScannedBlock extends Block {\n /** SHA-256 over the manifest text. Used later by the index for change detection. */\n contentHash: string;\n /**\n * Absolute paths to manifest-referenced files, when present and inside the project.\n * If `manifest.source` is set but the file is missing or outside the project,\n * `resolvedPaths.source` is absent and a corresponding `io` or `validation`\n * ScanError is in `errors[]`. T5 (extractor) should treat a missing\n * `resolvedPaths.source` as a no-op, not an error.\n */\n resolvedPaths?: ResolvedPaths;\n}\n\nexport interface ScanError {\n file: string;\n kind: 'parse' | 'validation' | 'io';\n message: string;\n field?: string;\n}\n\nexport interface ScanResult {\n blocks: ScannedBlock[];\n errors: ScanError[];\n}\n\nexport async function scan(project: Project): Promise<ScanResult> {\n const blocks: ScannedBlock[] = [];\n const errors: ScanError[] = [];\n const ignore = new Set(project.config.ignore);\n const seenIds = new Set<string>();\n\n for (const root of project.config.scanRoots) {\n const start = join(project.root, root);\n if (!existsSync(start)) continue;\n for await (const manifestPath of findManifests(start, ignore)) {\n const result = await parseBlock(manifestPath, project.root);\n if (result.kind === 'ok') {\n errors.push(...result.errors);\n if (seenIds.has(result.block.id)) {\n errors.push({\n file: manifestPath,\n kind: 'validation',\n message: `Duplicate block id \"${result.block.id}\" at ${manifestPath}. Set an explicit \\`id:\\` field to disambiguate.`,\n field: 'id',\n });\n } else {\n seenIds.add(result.block.id);\n blocks.push(result.block);\n }\n } else {\n errors.push(result.error);\n }\n }\n }\n\n blocks.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));\n return { blocks, errors };\n}\n\nasync function* findManifests(dir: string, ignore: Set<string>): AsyncGenerator<string> {\n let entries: import('node:fs').Dirent[];\n try {\n entries = await readdir(dir, { withFileTypes: true });\n } catch {\n return;\n }\n for (const entry of entries) {\n if (entry.isFile() && entry.name === 'macroscope.yaml') {\n yield join(dir, entry.name);\n }\n }\n // Symlinks are skipped. readdir({ withFileTypes: true }) classifies them\n // distinctly from directories (DT_LNK on POSIX), so the isDirectory() check\n // already excludes them. The explicit isSymbolicLink() guard is defence-in-depth\n // in case readdir semantics differ on some platform/filesystem.\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n if (entry.isSymbolicLink()) continue;\n if (ignore.has(entry.name)) continue;\n yield* findManifests(join(dir, entry.name), ignore);\n }\n}\n\ntype ParseOutcome =\n | { kind: 'ok'; block: ScannedBlock; errors: ScanError[] }\n | { kind: 'err'; error: ScanError };\n\nasync function parseBlock(manifestPath: string, projectRoot: string): Promise<ParseOutcome> {\n let raw: string;\n try {\n raw = await readFile(manifestPath, 'utf8');\n } catch (err) {\n return {\n kind: 'err',\n error: {\n file: manifestPath,\n kind: 'io',\n message: `Failed to read manifest at ${manifestPath}: ${(err as Error).message}`,\n },\n };\n }\n\n let yamlValue: unknown;\n try {\n yamlValue = parseYaml(raw);\n } catch (err) {\n return {\n kind: 'err',\n error: {\n file: manifestPath,\n kind: 'parse',\n message: `Invalid YAML in ${manifestPath}: ${(err as Error).message}`,\n },\n };\n }\n\n const parsed = manifestSchema.safeParse(yamlValue);\n if (!parsed.success) {\n const first = firstZodIssue(parsed.error);\n return {\n kind: 'err',\n error: {\n file: manifestPath,\n kind: 'validation',\n message: `Manifest at ${manifestPath} is invalid: field \\`${first.fieldPath}\\` ${first.message}.`,\n field: first.fieldPath,\n },\n };\n }\n\n const manifest = parsed.data as BlockManifest;\n const blockDir = dirname(manifestPath);\n const defaultId = toPosix(relative(projectRoot, blockDir));\n const id = manifest.id ?? defaultId;\n const contentHash = createHash('sha256').update(raw).digest('hex');\n\n const fileErrors: ScanError[] = [];\n const resolvedPaths = resolveManifestPaths(\n manifest,\n blockDir,\n projectRoot,\n manifestPath,\n fileErrors,\n );\n\n return {\n kind: 'ok',\n block: { id, path: blockDir, manifest, contentHash, resolvedPaths },\n errors: fileErrors,\n };\n}\n\nconst FILE_FIELDS = ['source', 'docs', 'preview'] as const;\n\nfunction resolveManifestPaths(\n manifest: BlockManifest,\n blockDir: string,\n projectRoot: string,\n manifestPath: string,\n errors: ScanError[],\n): ResolvedPaths | undefined {\n const testsRaw = manifest.tests;\n const testsArray =\n testsRaw == null ? undefined : typeof testsRaw === 'string' ? [testsRaw] : testsRaw;\n\n const hasAnyField = FILE_FIELDS.some((f) => manifest[f] != null) || testsArray != null;\n if (!hasAnyField) return undefined;\n\n const resolved: ResolvedPaths = {};\n\n for (const field of FILE_FIELDS) {\n const value = manifest[field] as string | undefined;\n if (value == null) continue;\n const abs = resolve(blockDir, value);\n if (!isInsideProject(abs, projectRoot)) {\n errors.push({\n file: manifestPath,\n kind: 'validation',\n field,\n message: `Field \\`${field}\\` in ${manifestPath} resolves to ${abs}, which is outside the project root ${projectRoot}.`,\n });\n continue;\n }\n if (!existsSync(abs)) {\n errors.push({\n file: manifestPath,\n kind: 'io',\n field,\n message: `Field \\`${field}\\` in ${manifestPath} references ${abs}, which does not exist.`,\n });\n continue;\n }\n resolved[field] = abs;\n }\n\n if (testsArray) {\n const resolvedTests: string[] = [];\n for (const t of testsArray) {\n const abs = resolve(blockDir, t);\n if (!isInsideProject(abs, projectRoot)) {\n errors.push({\n file: manifestPath,\n kind: 'validation',\n field: 'tests',\n message: `Field \\`tests\\` in ${manifestPath} resolves to ${abs}, which is outside the project root ${projectRoot}.`,\n });\n continue;\n }\n if (!existsSync(abs)) {\n errors.push({\n file: manifestPath,\n kind: 'io',\n field: 'tests',\n message: `Field \\`tests\\` in ${manifestPath} references ${abs}, which does not exist.`,\n });\n continue;\n }\n resolvedTests.push(abs);\n }\n if (resolvedTests.length > 0) {\n resolved.tests = resolvedTests;\n }\n }\n\n return Object.keys(resolved).length > 0 ? resolved : undefined;\n}\n\nfunction isInsideProject(absPath: string, projectRoot: string): boolean {\n const normalized = resolve(absPath);\n return normalized === projectRoot || normalized.startsWith(projectRoot + sep);\n}\n\nfunction firstZodIssue(err: ZodError): { fieldPath: string; message: string } {\n const issue = err.issues[0];\n if (!issue) return { fieldPath: '(root)', message: 'unknown validation error' };\n const fieldPath = issue.path.length ? issue.path.join('.') : '(root)';\n return { fieldPath, message: issue.message.toLowerCase() };\n}\n\nfunction toPosix(p: string): string {\n return p.split(sep).join('/');\n}\n","import type { ChildProcess, SpawnOptions } from 'node:child_process';\nimport { spawn as nodeSpawn } from 'node:child_process';\n\nexport interface SpawnDeps {\n spawn?: (cmd: string, args: string[], opts: SpawnOptions) => ChildProcess;\n}\n\nexport interface KillDeps {\n kill?: (pid: number, signal?: NodeJS.Signals | number) => void;\n gracePeriodMs?: number;\n}\n\nconst DEFAULT_GRACE_MS = 5_000;\n\n/**\n * Spawn a child as the leader of its own POSIX process group.\n * Grandchildren inherit the group, so killTree(child) takes the whole subtree down.\n */\nexport function spawnDetached(\n cmd: string,\n args: string[],\n opts: SpawnOptions = {},\n deps: SpawnDeps = {},\n): ChildProcess {\n const spawnImpl = deps.spawn ?? nodeSpawn;\n return spawnImpl(cmd, args, { ...opts, detached: true });\n}\n\n/**\n * Kill the child's entire process group with SIGTERM, then escalate to SIGKILL\n * after gracePeriodMs if the child is still alive. ESRCH is swallowed.\n * POSIX only — Windows path is tracked in TODOS.md.\n */\nexport async function killTree(child: ChildProcess, deps: KillDeps = {}): Promise<void> {\n const kill = deps.kill ?? ((pid, sig) => process.kill(pid, sig));\n const grace = deps.gracePeriodMs ?? DEFAULT_GRACE_MS;\n const pid = child.pid;\n if (!pid) return;\n\n const safeKill = (sig: NodeJS.Signals): boolean => {\n try {\n kill(-pid, sig);\n return true;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code === 'ESRCH') return false;\n throw err;\n }\n };\n\n if (!safeKill('SIGTERM')) return;\n await new Promise((r) => setTimeout(r, grace));\n if (child.killed) return;\n safeKill('SIGKILL');\n}\n","import { loadBlueprints } from '../../core/blueprints.js';\nimport type { Block } from '../../core/handler.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\nimport { scan } from '../../core/scanner.js';\n\nexport interface ResolvedCommand {\n ok: true;\n command: string[];\n /** Working directory for the subprocess. Defaults to the project root. */\n cwd: string;\n}\n\nexport interface ResolveError {\n ok: false;\n error: string;\n}\n\nconst COMMAND_RESOLVE_TIMEOUT_MS = 5000;\n\nexport async function resolveTerminalCommand(\n cwd: string,\n blockId: string,\n viewKey: string,\n): Promise<ResolvedCommand | ResolveError> {\n let project: Awaited<ReturnType<typeof findProject>>;\n try {\n project = await findProject(cwd);\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n return { ok: false, error: err.message };\n }\n return { ok: false, error: (err as Error).message };\n }\n\n const [scanResult, blueprintResult] = await Promise.all([scan(project), loadBlueprints(project)]);\n const block = scanResult.blocks.find((b) => b.id === blockId);\n if (!block) {\n return { ok: false, error: `No block found with id \"${blockId}\".` };\n }\n const blueprint = blueprintResult.blueprints.find((bp) => bp.kind === block.manifest.kind);\n if (!blueprint) {\n return { ok: false, error: `No blueprint registered for kind \"${block.manifest.kind}\".` };\n }\n const spec = blueprint.handler.views?.[viewKey];\n if (!spec) {\n return { ok: false, error: `Blueprint \"${blueprint.kind}\" has no view named \"${viewKey}\".` };\n }\n // Terminal views and hybrid views both expose a `command` that the WebSocket\n // route can spawn. Hybrid views additionally have a `url` for the code side\n // (resolved by /api/blocks), but the terminal half lives here.\n if (spec.type !== 'terminal' && spec.type !== 'hybrid') {\n return {\n ok: false,\n error: `View \"${viewKey}\" on \"${blueprint.kind}\" has no terminal command.`,\n };\n }\n\n const blockInput: Block = { id: block.id, path: block.path, manifest: block.manifest };\n let command: string[];\n if (Array.isArray(spec.command)) {\n command = spec.command;\n } else {\n try {\n command = await withTimeout(spec.command(blockInput), COMMAND_RESOLVE_TIMEOUT_MS);\n } catch (err) {\n return { ok: false, error: `Command resolver failed: ${(err as Error).message}` };\n }\n if (!Array.isArray(command) || !command.every((c) => typeof c === 'string')) {\n return { ok: false, error: 'Command resolver did not return a string[].' };\n }\n }\n\n return { ok: true, command, cwd: project.root };\n}\n\nfunction withTimeout<T>(p: Promise<T>, ms: number): Promise<T> {\n return Promise.race([\n p,\n new Promise<T>((_, reject) =>\n setTimeout(() => reject(new Error(`timed out after ${ms}ms`)), ms),\n ),\n ]);\n}\n","import type { ChildProcess } from 'node:child_process';\nimport type { IncomingMessage, Server } from 'node:http';\nimport type { Socket } from 'node:net';\nimport { type WebSocket, WebSocketServer } from 'ws';\nimport { killTree, spawnDetached } from '../../util/process-group.js';\nimport { resolveTerminalCommand } from './terminal-resolver.js';\n\nlet spawnOverride: { command: string[]; cwd?: string } | null = null;\n\n/** Test seam: replace the resolved command with a synthetic one. Only for tests. */\nexport function setSpawnOverride(override: { command: string[]; cwd?: string } | null): void {\n spawnOverride = override;\n}\n\nexport function attachTerminalWs(httpServer: Server, defaultCwd: string): void {\n const wss = new WebSocketServer({ noServer: true });\n\n httpServer.on('upgrade', (req, socket, head) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.pathname !== '/api/terminal') {\n socket.destroy();\n return;\n }\n wss.handleUpgrade(req, socket as Socket, head, (ws) => {\n handleConnection(ws, req, defaultCwd);\n });\n });\n}\n\nasync function handleConnection(\n ws: WebSocket,\n req: IncomingMessage,\n defaultCwd: string,\n): Promise<void> {\n const url = new URL(req.url ?? '/', 'http://localhost');\n const blockId = url.searchParams.get('blockId') ?? '';\n const viewKey = url.searchParams.get('viewKey') ?? '';\n\n let command: string[];\n let cwd: string;\n if (spawnOverride) {\n command = spawnOverride.command;\n cwd = spawnOverride.cwd ?? defaultCwd;\n } else {\n const resolved = await resolveTerminalCommand(defaultCwd, blockId, viewKey);\n if (!resolved.ok) {\n send(ws, { type: 'error', message: resolved.error });\n ws.close();\n return;\n }\n command = resolved.command;\n cwd = resolved.cwd;\n }\n\n if (command.length === 0) {\n send(ws, { type: 'error', message: 'empty command' });\n ws.close();\n return;\n }\n\n send(ws, { type: 'open', command });\n\n const [bin, ...args] = command as [string, ...string[]];\n let child: ChildProcess;\n try {\n child = spawnDetached(bin, args, { cwd, stdio: ['pipe', 'pipe', 'pipe'] });\n } catch (err) {\n send(ws, { type: 'error', message: `failed to spawn: ${(err as Error).message}` });\n ws.close();\n return;\n }\n\n child.stdout?.on('data', (chunk: Buffer) => send(ws, { type: 'out', data: chunk.toString() }));\n child.stderr?.on('data', (chunk: Buffer) => send(ws, { type: 'err', data: chunk.toString() }));\n child.on('exit', (code, signal) => {\n send(ws, { type: 'close', code, signal });\n ws.close();\n });\n child.on('error', (err) => {\n send(ws, { type: 'error', message: err.message });\n ws.close();\n });\n\n ws.on('message', (raw) => {\n let frame: { type: string; data?: string };\n try {\n frame = JSON.parse(raw.toString());\n } catch {\n return;\n }\n if (frame.type === 'in' && typeof frame.data === 'string') {\n child.stdin?.write(frame.data);\n } else if (frame.type === 'eof') {\n child.stdin?.end();\n }\n });\n\n ws.on('close', () => {\n if (!child.killed) void killTree(child);\n });\n}\n\nfunction send(ws: WebSocket, frame: object): void {\n try {\n ws.send(JSON.stringify(frame));\n } catch {\n // Connection closed mid-send. Ignore.\n }\n}\n","#!/usr/bin/env node\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport type { Provider as ProviderId } from '@macroscope/contracts';\nimport { Command, Option } from 'commander';\nimport importLocal from 'import-local';\nimport { runLogin } from './commands/login.js';\nimport { runLogout } from './commands/logout.js';\nimport { runSearch } from './commands/search.js';\nimport { runStatus } from './commands/status.js';\nimport { type BlueprintLoadResult, loadBlueprints } from './core/blueprints.js';\nimport { ProjectNotFoundError, findProject } from './core/project.js';\nimport { VERSION } from './core/version.js';\nimport { startUiServer } from './ui/ui-server.js';\nimport { installLifecycle } from './util/lifecycle.js';\n\nif (importLocal(import.meta.url)) {\n // Defer to a locally-installed macroscope if present.\n} else {\n main();\n}\n\nfunction main(): void {\n const program = new Command();\n\n program\n .name('macroscope')\n .description('Catalogue tooling for AI-collaborative software development')\n .version(VERSION, '-v, --version')\n .option('--json', 'output machine-readable JSON');\n\n program\n .command('hello')\n .description('Placeholder — proves the CLI wiring works')\n .action((_opts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n if (globalOpts.json) {\n process.stdout.write(`${JSON.stringify({ ok: true, message: 'hello from macroscope' })}\\n`);\n } else {\n process.stdout.write('hello from macroscope\\n');\n }\n });\n\n program\n .command('blueprints')\n .description('List the unit blueprints defined in this project (.macroscope/blueprints/)')\n .option('--cwd <path>', 'project search starts here (defaults to current dir)')\n .action(async (cmdOpts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n await runBlueprints({ cwd: cmdOpts.cwd, json: !!globalOpts.json });\n });\n\n program\n .command('ui')\n .description('Open the macroscope web UI in your browser')\n .option('--cwd <path>', 'project search starts here (defaults to current dir)')\n .option('--port <n>', 'port to listen on (default: auto-pick a free port)', (v) =>\n Number.parseInt(v, 10),\n )\n .option('--no-open', \"don't automatically open a browser\")\n .option(\n '--cloud-url <url>',\n 'override the cloud API URL (also: MACROSCOPE_CLOUD_URL env var; defaults to http://localhost:3001)',\n )\n .option(\n '--credentials <path>',\n 'override the credentials file path (defaults to ~/.macroscope/credentials)',\n )\n .action(async (cmdOpts) => {\n await runUi({\n cwd: cmdOpts.cwd,\n port: cmdOpts.port,\n open: cmdOpts.open !== false,\n cloudUrl: cmdOpts.cloudUrl,\n credentialsPath: cmdOpts.credentials,\n });\n });\n\n program\n .command('login')\n .description(\n 'Authenticate with a Git host (GitHub or GitLab) and store credentials at ~/.macroscope/credentials',\n )\n .addOption(\n new Option('--provider <id>', 'identity provider')\n .choices(['github', 'gitlab'])\n .default('github'),\n )\n .action(async (cmdOpts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n const code = await runLogin({\n providerId: cmdOpts.provider as ProviderId,\n json: !!globalOpts.json,\n });\n process.exitCode = code;\n });\n\n program\n .command('logout')\n .description('Delete the stored credentials file at ~/.macroscope/credentials')\n .action(async (_cmdOpts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n const code = await runLogout({ json: !!globalOpts.json });\n process.exitCode = code;\n });\n\n program\n .command('search <query>')\n .description('Search the cloud catalogue and local code in one shot')\n .option('--cwd <path>', 'project search starts here (defaults to current dir)')\n .option('--worktree <id>', 'restrict to one worktree')\n .option('--all-worktrees', 'search across all worktrees (default until T14)')\n .option('--all-repos', 'no repo filter (default)')\n .option('--repo <name>', 'restrict to one repo')\n .option('--kind <k>', 'restrict to one block kind')\n .option('--limit <n>', 'cap results per side', (v) => Number.parseInt(v, 10))\n .action(async (query: string, cmdOpts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n const code = await runSearch({\n query,\n json: !!globalOpts.json,\n cwd: cmdOpts.cwd,\n scope: {\n worktree: cmdOpts.worktree,\n allWorktrees: !!cmdOpts.allWorktrees,\n allRepos: !!cmdOpts.allRepos,\n repo: cmdOpts.repo,\n kind: cmdOpts.kind,\n limit: cmdOpts.limit,\n },\n });\n process.exitCode = code;\n });\n\n program\n .command('status')\n .description('Show worktree + cloud + login state')\n .option('--cwd <path>', 'project search starts here (defaults to current dir)')\n .action(async (cmdOpts, cmd) => {\n const globalOpts = cmd.parent?.opts() ?? {};\n const code = await runStatus({\n json: !!globalOpts.json,\n cwd: cmdOpts.cwd,\n });\n process.exitCode = code;\n });\n\n program.parse(process.argv);\n}\n\nasync function runBlueprints(opts: { cwd?: string; json: boolean }): Promise<void> {\n let project: Awaited<ReturnType<typeof findProject>>;\n try {\n project = await findProject(opts.cwd ?? process.cwd());\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n writeError(err.message, opts.json);\n process.exit(1);\n }\n writeError(`${(err as Error).message}`, opts.json);\n process.exit(1);\n }\n\n const result = await loadBlueprints(project);\n if (opts.json) {\n writeJson(result);\n } else {\n writeHuman(result);\n }\n if (result.errors.length > 0) {\n process.exitCode = 1;\n }\n}\n\nfunction writeHuman(result: BlueprintLoadResult): void {\n if (result.blueprints.length === 0 && result.errors.length === 0) {\n process.stdout.write(\n 'No blueprints found. Create one at .macroscope/blueprints/<kind>/handler.ts.\\n',\n );\n return;\n }\n\n if (result.blueprints.length > 0) {\n for (const bp of result.blueprints) {\n const caps = bp.capabilities.length > 0 ? bp.capabilities.join(', ') : '(no operations)';\n process.stdout.write(`${bp.kind.padEnd(24)} ${caps}\\n`);\n }\n }\n\n if (result.errors.length > 0) {\n process.stderr.write(`\\n${result.errors.length} blueprint error(s):\\n`);\n for (const e of result.errors) {\n process.stderr.write(` [${e.kind}] ${e.message}\\n`);\n }\n }\n}\n\nfunction writeJson(result: BlueprintLoadResult): void {\n const out = {\n blueprints: result.blueprints.map((b) => ({\n kind: b.kind,\n folder: b.folder,\n file: b.file,\n capabilities: b.capabilities,\n })),\n errors: result.errors,\n };\n process.stdout.write(`${JSON.stringify(out, null, 2)}\\n`);\n}\n\nasync function runUi(opts: {\n cwd?: string;\n port?: number;\n open: boolean;\n cloudUrl?: string;\n credentialsPath?: string;\n}): Promise<void> {\n const cwd = opts.cwd ?? process.cwd();\n try {\n await findProject(cwd);\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n process.stderr.write(`${err.message}\\n`);\n process.exit(1);\n }\n throw err;\n }\n\n const here = dirname(fileURLToPath(import.meta.url));\n const staticDir = resolve(here, 'ui');\n\n let server: Awaited<ReturnType<typeof startUiServer>>;\n try {\n server = await startUiServer({\n cwd,\n staticDir,\n port: opts.port,\n open: opts.open,\n cloudUrl: opts.cloudUrl,\n credentialsPath: opts.credentialsPath,\n });\n } catch (err) {\n process.stderr.write(`macroscope ui: ${(err as Error).message}\\n`);\n process.exit(1);\n }\n\n installLifecycle({\n watchStdin: true,\n onShutdown: async (reason) => {\n process.stderr.write(`macroscope shutting down (${reason})\\n`);\n try {\n await server.close();\n } catch (err) {\n process.stderr.write(`shutdown error: ${(err as Error).message}\\n`);\n }\n process.exit(0);\n },\n });\n\n process.stdout.write(`macroscope ui running at ${server.url}\\n`);\n process.stdout.write('Press Ctrl+C to stop.\\n');\n}\n\nfunction writeError(message: string, json: boolean): void {\n if (json) {\n process.stdout.write(`${JSON.stringify({ ok: false, error: message })}\\n`);\n } else {\n process.stderr.write(`${message}\\n`);\n }\n}\n","import type { ErrorEnvelope } from '@macroscope/contracts';\n\nexport type LoginErrorCode =\n | 'login_cancelled'\n | 'state_mismatch'\n | 'token_exchange_failed'\n | 'callback_timeout'\n | 'port_in_use'\n | 'user_info_failed'\n | 'credentials_write_failed';\n\nexport class LoginError extends Error {\n readonly code: LoginErrorCode;\n constructor(code: LoginErrorCode, message: string) {\n super(message);\n this.code = code;\n this.name = 'LoginError';\n }\n toEnvelope(): ErrorEnvelope {\n return { error: { code: this.code, message: this.message } };\n }\n}\n","import { type Server, createServer } from 'node:http';\nimport { LoginError } from './errors.js';\n\nexport const CALLBACK_PORT = 51337;\nexport const CALLBACK_PATH = '/callback';\nexport const REDIRECT_URI = `http://127.0.0.1:${CALLBACK_PORT}${CALLBACK_PATH}`;\n\nexport interface AwaitCallbackOptions {\n expectedState: string;\n timeoutMs: number;\n signal?: AbortSignal;\n}\n\nexport interface AwaitCallbackHandle {\n /** Resolves when the server has emitted `'listening'`; rejects on EADDRINUSE. */\n bound: Promise<void>;\n /** Resolves with the OAuth `code` once the callback arrives. */\n result: Promise<{ code: string }>;\n}\n\nexport function awaitCallback(opts: AwaitCallbackOptions): AwaitCallbackHandle {\n let settled = false;\n let resolveResult!: (v: { code: string }) => void;\n let rejectResult!: (err: unknown) => void;\n let resolveBound!: () => void;\n let rejectBound!: (err: unknown) => void;\n\n const result = new Promise<{ code: string }>((res, rej) => {\n resolveResult = res;\n rejectResult = rej;\n });\n const bound = new Promise<void>((res, rej) => {\n resolveBound = res;\n rejectBound = rej;\n });\n\n const server: Server = createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://127.0.0.1:${CALLBACK_PORT}`);\n if (url.pathname !== CALLBACK_PATH) {\n res.statusCode = 404;\n res.end('not found');\n return;\n }\n const state = url.searchParams.get('state') ?? '';\n const code = url.searchParams.get('code') ?? '';\n if (state !== opts.expectedState) {\n res.statusCode = 400;\n res.end('state mismatch — close this tab and rerun `macroscope login`');\n settle(() =>\n rejectResult(new LoginError('state_mismatch', 'OAuth state parameter did not match')),\n );\n return;\n }\n if (!code) {\n res.statusCode = 400;\n res.end('missing code');\n settle(() =>\n rejectResult(new LoginError('token_exchange_failed', 'callback missing `code` parameter')),\n );\n return;\n }\n res.statusCode = 200;\n res.setHeader('content-type', 'text/html; charset=utf-8');\n res.end(\n '<!doctype html><meta charset=utf-8><title>macroscope</title>' +\n '<p>Login complete. You can close this tab.</p>',\n );\n settle(() => resolveResult({ code }));\n });\n\n const closeServer = (): Promise<void> =>\n new Promise<void>((r) => {\n const s = server as Server & { closeAllConnections?: () => void };\n if (typeof s.closeAllConnections === 'function') s.closeAllConnections();\n server.close(() => r());\n });\n\n function settle(fn: () => void): void {\n if (settled) return;\n settled = true;\n void closeServer().finally(fn);\n }\n\n server.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n const e = new LoginError(\n 'port_in_use',\n `Port ${CALLBACK_PORT} is in use; close the process holding it, or rerun later`,\n );\n rejectBound(e);\n settle(() => rejectResult(e));\n } else {\n rejectBound(err);\n settle(() => rejectResult(err));\n }\n });\n\n let timer: NodeJS.Timeout | undefined;\n server.on('listening', () => {\n resolveBound();\n timer = setTimeout(() => {\n settle(() =>\n rejectResult(\n new LoginError(\n 'callback_timeout',\n `no OAuth callback received within ${opts.timeoutMs}ms`,\n ),\n ),\n );\n }, opts.timeoutMs);\n if (typeof timer.unref === 'function') timer.unref();\n });\n\n server.listen(CALLBACK_PORT, '127.0.0.1');\n\n if (opts.signal) {\n const onAbort = (): void => {\n if (timer) clearTimeout(timer);\n settle(() => rejectResult(new LoginError('login_cancelled', 'login aborted')));\n };\n if (opts.signal.aborted) onAbort();\n else opts.signal.addEventListener('abort', onAbort, { once: true });\n }\n\n // Swallow unhandled-rejection warnings on the sibling chain. The originals\n // still reject when callers `await` them — these catches only mark the\n // rejection as observed so Node/Vitest don't surface a process-level warning\n // when settle() fires before the consumer has attached its handler.\n bound.catch(() => {});\n result.catch(() => {});\n\n return { bound, result };\n}\n","import { chmod, stat as fsStat, mkdir, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { FILESYSTEM_LAYOUT, type OAuthCredentials } from '@macroscope/contracts';\nimport { LoginError } from './errors.js';\n\nexport interface WriteCredentialsOptions {\n /** Override `~`. Defaults to `os.homedir()`. */\n homeDir?: string;\n /** Test seam. */\n _statForTest?: typeof fsStat;\n}\n\nexport function credentialsPath(homeDir: string = homedir()): string {\n return join(homeDir, FILESYSTEM_LAYOUT.user.credentialsFile);\n}\n\nexport async function writeCredentials(\n creds: OAuthCredentials,\n opts: WriteCredentialsOptions = {},\n): Promise<void> {\n const path = credentialsPath(opts.homeDir);\n await mkdir(dirname(path), { recursive: true });\n\n const statFn = opts._statForTest ?? fsStat;\n // Ownership check: if the file already exists, refuse to clobber another user's file.\n try {\n const s = await statFn(path);\n if (process.platform !== 'win32' && typeof process.getuid === 'function') {\n const uid = process.getuid();\n if (s.uid !== uid) {\n throw new LoginError(\n 'credentials_write_failed',\n `${path} is owned by another user (uid ${s.uid}); refusing to overwrite`,\n );\n }\n }\n } catch (err) {\n if (err instanceof LoginError) throw err;\n if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;\n // File doesn't exist — fine, we'll create it.\n }\n\n const json = `${JSON.stringify(creds, null, 2)}\\n`;\n // mode: 0o600 only applies on creation; chmod afterwards covers overwrite.\n await writeFile(path, json, { mode: 0o600 });\n await chmod(path, 0o600);\n}\n","import { createHash, randomBytes } from 'node:crypto';\n\n/** RFC 7636 §4.1 — 43–128 chars from the unreserved set. */\nexport function generateVerifier(): string {\n // 32 random bytes → 43 base64url chars (no padding), comfortably in range.\n return base64url(randomBytes(32));\n}\n\n/** RFC 7636 §4.2 — base64url(SHA256(ASCII(verifier))). */\nexport function challengeFromVerifier(verifier: string): string {\n return base64url(createHash('sha256').update(verifier, 'ascii').digest());\n}\n\nfunction base64url(buf: Buffer): string {\n return buf.toString('base64').replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '');\n}\n","import { randomBytes } from 'node:crypto';\n\nexport function generateState(): string {\n return randomBytes(24)\n .toString('base64')\n .replaceAll('+', '-')\n .replaceAll('/', '_')\n .replaceAll('=', '');\n}\n","import { LoginError } from './errors.js';\nimport type { Provider } from './providers/provider.js';\n\nexport interface TokenResponse {\n accessToken: string;\n refreshToken?: string;\n /** Unix epoch ms; computed from `expires_in` if present. */\n expiresAt?: number;\n}\n\nexport interface ExchangeOptions {\n code: string;\n codeVerifier: string;\n redirectUri: string;\n clientId: string;\n /** Required for GitHub. Omit for GitLab public-client PKCE apps. */\n clientSecret?: string;\n /** Test seam. */\n fetchFn?: typeof fetch;\n}\n\nexport async function exchangeCodeForToken(\n provider: Provider,\n opts: ExchangeOptions,\n): Promise<TokenResponse> {\n const body = new URLSearchParams({\n grant_type: 'authorization_code',\n code: opts.code,\n code_verifier: opts.codeVerifier,\n redirect_uri: opts.redirectUri,\n client_id: opts.clientId,\n });\n const secret = opts.clientSecret ?? provider.clientSecret;\n if (secret) body.set('client_secret', secret);\n\n const fetchFn = opts.fetchFn ?? fetch;\n let res: Response;\n try {\n res = await fetchFn(provider.tokenUrl, {\n method: 'POST',\n headers: {\n accept: 'application/json',\n 'content-type': 'application/x-www-form-urlencoded',\n 'user-agent': 'macroscope',\n },\n body: body.toString(),\n });\n } catch (err) {\n throw new LoginError(\n 'token_exchange_failed',\n `network error talking to ${provider.tokenUrl}: ${(err as Error).message}`,\n );\n }\n\n if (!res.ok) {\n const detail = await res.text().catch(() => '');\n throw new LoginError(\n 'token_exchange_failed',\n `${provider.humanName} token endpoint returned ${res.status}: ${detail.slice(0, 200)}`,\n );\n }\n\n const json = (await res.json()) as {\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n };\n if (!json.access_token) {\n throw new LoginError(\n 'token_exchange_failed',\n `${provider.humanName} token endpoint returned 200 but no access_token`,\n );\n }\n return {\n accessToken: json.access_token,\n refreshToken: json.refresh_token,\n expiresAt:\n typeof json.expires_in === 'number' ? Date.now() + json.expires_in * 1000 : undefined,\n };\n}\n","import { LoginError } from './errors.js';\nimport type { Provider } from './providers/provider.js';\n\nexport async function fetchUserInfo(\n provider: Provider,\n accessToken: string,\n fetchFn: typeof fetch = fetch,\n): Promise<string> {\n let res: Response;\n try {\n res = await fetchFn(provider.userInfoUrl, {\n headers: {\n authorization: `Bearer ${accessToken}`,\n accept: 'application/json',\n 'user-agent': 'macroscope',\n },\n });\n } catch (err) {\n throw new LoginError(\n 'user_info_failed',\n `network error talking to ${provider.userInfoUrl}: ${(err as Error).message}`,\n );\n }\n if (!res.ok) {\n throw new LoginError(\n 'user_info_failed',\n `${provider.humanName} user-info endpoint returned ${res.status}`,\n );\n }\n return provider.parseProviderUserId(await res.json());\n}\n","import type { OAuthCredentials } from '@macroscope/contracts';\nimport { REDIRECT_URI, awaitCallback } from './callback-server.js';\nimport { writeCredentials } from './credentials.js';\nimport { challengeFromVerifier, generateVerifier } from './pkce.js';\nimport type { Provider } from './providers/provider.js';\nimport { generateState } from './state.js';\nimport { exchangeCodeForToken } from './token-exchange.js';\nimport { fetchUserInfo } from './user-info.js';\n\nexport interface LoginOptions {\n provider: Provider;\n clientId: string;\n /** Required for providers whose token endpoint demands it (GitHub). */\n clientSecret?: string;\n /** Override `~`. */\n homeDir?: string;\n /** Hook for testing — receives the full authorize URL. */\n openBrowser?: (url: string) => void | Promise<void>;\n /** Default 5 minutes — long enough to complete consent in a browser. */\n timeoutMs?: number;\n /** AbortSignal for SIGHUP/SIGINT cancellation (wired by callers). */\n signal?: AbortSignal;\n}\n\nexport async function login(opts: LoginOptions): Promise<OAuthCredentials> {\n const { provider, clientId } = opts;\n const verifier = generateVerifier();\n const challenge = challengeFromVerifier(verifier);\n const state = generateState();\n\n const authorizeUrl = new URL(provider.authorizeUrl);\n authorizeUrl.searchParams.set('client_id', clientId);\n authorizeUrl.searchParams.set('redirect_uri', REDIRECT_URI);\n authorizeUrl.searchParams.set('response_type', 'code');\n authorizeUrl.searchParams.set('state', state);\n authorizeUrl.searchParams.set('code_challenge', challenge);\n authorizeUrl.searchParams.set('code_challenge_method', 'S256');\n if (provider.defaultScopes.length > 0) {\n authorizeUrl.searchParams.set('scope', provider.defaultScopes.join(' '));\n }\n\n const { bound, result } = awaitCallback({\n expectedState: state,\n timeoutMs: opts.timeoutMs ?? 5 * 60_000,\n signal: opts.signal,\n });\n\n // Wait for the callback server to be listening before opening the browser —\n // otherwise the redirect can race the listen on a busy box. If `bound`\n // rejects (EADDRINUSE), `result` rejects with the same error; surface it.\n try {\n await bound;\n } catch {\n return await result; // rejects with port_in_use\n }\n\n if (opts.openBrowser) {\n await opts.openBrowser(authorizeUrl.toString());\n } else {\n const open = (await import('open')).default;\n await open(authorizeUrl.toString());\n }\n\n const { code } = await result;\n\n const token = await exchangeCodeForToken(provider, {\n code,\n codeVerifier: verifier,\n redirectUri: REDIRECT_URI,\n clientId,\n clientSecret: opts.clientSecret,\n });\n\n const providerUserId = await fetchUserInfo(provider, token.accessToken);\n\n const creds: OAuthCredentials = {\n provider: provider.id,\n accessToken: token.accessToken,\n refreshToken: token.refreshToken,\n expiresAt: token.expiresAt,\n providerUserId,\n };\n await writeCredentials(creds, { homeDir: opts.homeDir });\n return creds;\n}\n","import type { Provider } from './provider.js';\n\n/**\n * GitHub OAuth App. PKCE is enabled but the token endpoint still requires\n * `client_secret` on exchange — PKCE is defense-in-depth, not a replacement.\n * This matches every shipped CLI (`gh`, `glab`, `vercel`, `supabase`): the\n * \"secret\" is embedded in the distributed binary and PKCE is what actually\n * protects the flow.\n */\nexport const github: Provider = {\n id: 'github',\n humanName: 'GitHub',\n authorizeUrl: 'https://github.com/login/oauth/authorize',\n tokenUrl: 'https://github.com/login/oauth/access_token',\n userInfoUrl: 'https://api.github.com/user',\n defaultScopes: [],\n // Hardcoded fallback is intentionally a placeholder — the release build\n // substitutes the public OAuth-App secret. Env var wins at runtime.\n clientSecret: process.env.MACROSCOPE_GITHUB_CLIENT_SECRET ?? 'REPLACE_AT_BUILD',\n parseProviderUserId(userInfo: unknown): string {\n if (\n typeof userInfo === 'object' &&\n userInfo !== null &&\n 'id' in userInfo &&\n (typeof userInfo.id === 'number' || typeof userInfo.id === 'string')\n ) {\n return String(userInfo.id);\n }\n throw new Error('GitHub /user response missing numeric `id` field');\n },\n};\n","import type { Provider } from './provider.js';\n\n/**\n * GitLab OAuth Application registered as a public client (Confidential OFF).\n * PKCE-only: the token endpoint accepts `code + code_verifier` without a\n * secret. Do NOT add `clientSecret` here.\n */\nexport const gitlab: Provider = {\n id: 'gitlab',\n humanName: 'GitLab',\n authorizeUrl: 'https://gitlab.com/oauth/authorize',\n tokenUrl: 'https://gitlab.com/oauth/token',\n userInfoUrl: 'https://gitlab.com/api/v4/user',\n defaultScopes: ['read_user'],\n parseProviderUserId(userInfo: unknown): string {\n if (\n typeof userInfo === 'object' &&\n userInfo !== null &&\n 'id' in userInfo &&\n (typeof userInfo.id === 'number' || typeof userInfo.id === 'string')\n ) {\n return String(userInfo.id);\n }\n throw new Error('GitLab /api/v4/user response missing `id` field');\n },\n};\n","import type { Provider as ProviderId } from '@macroscope/contracts';\nimport { github } from './github.js';\nimport { gitlab } from './gitlab.js';\nimport type { Provider } from './provider.js';\n\nconst REGISTRY: Record<ProviderId, Provider> = {\n github,\n gitlab,\n};\n\nexport function getProvider(id: ProviderId): Provider {\n const p = REGISTRY[id];\n if (!p) throw new Error(`unknown provider: ${id}`);\n return p;\n}\n\nexport type { Provider } from './provider.js';\n","import type { Provider as ProviderId } from '@macroscope/contracts';\nimport { LoginError } from './errors.js';\nimport { type LoginOptions, login } from './login.js';\nimport { getProvider } from './providers/index.js';\n\ninterface TestOverrides {\n homeDir?: string;\n openBrowser?: LoginOptions['openBrowser'];\n clientId?: string;\n clientSecret?: string;\n write?: (chunk: string) => void;\n}\n\nexport interface RunLoginOptions {\n providerId: ProviderId;\n json: boolean;\n /** Wired by T8 so SIGINT/SIGHUP can cancel mid-flow. */\n signal?: AbortSignal;\n /** Test-only escape hatch. Not in T8's surface. */\n _testOverrides?: TestOverrides;\n}\n\nconst CLIENT_ID_ENV: Record<ProviderId, string> = {\n github: 'MACROSCOPE_GITHUB_CLIENT_ID',\n gitlab: 'MACROSCOPE_GITLAB_CLIENT_ID',\n};\n\n// Placeholder constants. Real build-time substitution lands with the release pipeline.\nconst CLIENT_ID_FALLBACK: Record<ProviderId, string> = {\n github: 'REPLACE_AT_BUILD',\n gitlab: 'REPLACE_AT_BUILD',\n};\n\nexport async function runLoginCommand(opts: RunLoginOptions): Promise<number> {\n const provider = getProvider(opts.providerId);\n const t = opts._testOverrides ?? {};\n const write = t.write ?? ((s: string): void => void process.stdout.write(s));\n\n const clientId =\n t.clientId ??\n process.env[CLIENT_ID_ENV[opts.providerId]] ??\n CLIENT_ID_FALLBACK[opts.providerId];\n const clientSecret =\n opts.providerId === 'github'\n ? (t.clientSecret ?? process.env.MACROSCOPE_GITHUB_CLIENT_SECRET ?? provider.clientSecret)\n : undefined;\n\n try {\n const creds = await login({\n provider,\n clientId,\n clientSecret,\n homeDir: t.homeDir,\n openBrowser: t.openBrowser,\n signal: opts.signal,\n });\n if (opts.json) {\n write(\n `${JSON.stringify({\n ok: true,\n provider: creds.provider,\n providerUserId: creds.providerUserId,\n })}\\n`,\n );\n } else {\n write(`Logged in to ${provider.humanName} as ${creds.providerUserId}\\n`);\n }\n return 0;\n } catch (err) {\n const loginErr =\n err instanceof LoginError\n ? err\n : new LoginError('credentials_write_failed', (err as Error).message);\n if (opts.json) {\n write(`${JSON.stringify(loginErr.toEnvelope())}\\n`);\n } else {\n write(`Error: ${loginErr.message} (${loginErr.code})\\n`);\n }\n return 1;\n }\n}\n","import type { Readable } from 'node:stream';\n\nexport type ShutdownReason =\n | 'SIGINT'\n | 'SIGTERM'\n | 'SIGHUP'\n | 'stdin-eof'\n | 'uncaughtException'\n | 'unhandledRejection';\n\nexport interface LifecycleOptions {\n /** Called once when any termination trigger fires. Must be idempotent-safe. */\n onShutdown: (reason: ShutdownReason) => void | Promise<void>;\n /** Watch stdin for EOF — set true when running attached to a parent shell\n * (e.g. Conductor) that closes our stdin on workspace teardown. */\n watchStdin?: boolean;\n /** Hard deadline for onShutdown before we force-exit. Default 5000ms. */\n hardTimeoutMs?: number;\n /** Test seam. Defaults to the global `process`. */\n proc?: NodeJS.Process;\n /** Test seam. Defaults to `process.stdin`. */\n stdin?: Readable;\n}\n\nexport interface LifecycleHandle {\n uninstall: () => void;\n}\n\nconst SIGNALS: ShutdownReason[] = ['SIGINT', 'SIGTERM', 'SIGHUP'];\n\nexport function installLifecycle(opts: LifecycleOptions): LifecycleHandle {\n const proc = opts.proc ?? process;\n const stdin = opts.stdin ?? proc.stdin;\n const hardTimeoutMs = opts.hardTimeoutMs ?? 5_000;\n let fired = false;\n\n const fire = (reason: ShutdownReason): void => {\n if (fired) return;\n fired = true;\n const hardKill = setTimeout(() => {\n proc.exit(1);\n }, hardTimeoutMs);\n if (typeof hardKill.unref === 'function') hardKill.unref();\n Promise.resolve(opts.onShutdown(reason)).finally(() => {\n clearTimeout(hardKill);\n });\n };\n\n const signalHandlers = new Map<ShutdownReason, () => void>();\n for (const sig of SIGNALS) {\n const h = () => fire(sig);\n signalHandlers.set(sig, h);\n proc.on(sig as NodeJS.Signals, h);\n }\n\n const onUncaught = (_err: unknown) => fire('uncaughtException');\n const onUnhandled = (_err: unknown) => fire('unhandledRejection');\n proc.on('uncaughtException', onUncaught);\n proc.on('unhandledRejection', onUnhandled);\n\n const stdinEnd = () => fire('stdin-eof');\n if (opts.watchStdin) {\n stdin.resume();\n stdin.on('end', stdinEnd);\n stdin.on('close', stdinEnd);\n }\n\n return {\n uninstall: () => {\n for (const [sig, h] of signalHandlers) proc.off(sig as NodeJS.Signals, h);\n proc.off('uncaughtException', onUncaught);\n proc.off('unhandledRejection', onUnhandled);\n if (opts.watchStdin) {\n stdin.off('end', stdinEnd);\n stdin.off('close', stdinEnd);\n }\n },\n };\n}\n","import type { Provider as ProviderId } from '@macroscope/contracts';\nimport { type RunLoginOptions as T9Options, runLoginCommand } from '../auth/cli.js';\nimport {\n type LifecycleHandle,\n type LifecycleOptions,\n installLifecycle,\n} from '../util/lifecycle.js';\n\ntype RunLoginCommandFn = (opts: T9Options) => Promise<number>;\ntype InstallLifecycleFn = (opts: LifecycleOptions) => LifecycleHandle;\n\nexport interface RunLoginOptions {\n providerId: ProviderId;\n json: boolean;\n /** Test seam — inject T9's runLoginCommand. */\n runLoginImpl?: RunLoginCommandFn;\n /** Test seam — inject installLifecycle. */\n installLifecycleImpl?: InstallLifecycleFn;\n}\n\n/**\n * Wires `installLifecycle` to T9's OAuth flow: SIGINT/SIGHUP/stdin-EOF abort\n * the controller, which T9 honours by throwing `LoginError('login_cancelled')`.\n * T9 owns the envelope output on success and failure — this wrapper just\n * installs/uninstalls the lifecycle and propagates the exit code.\n */\nexport async function runLogin(opts: RunLoginOptions): Promise<number> {\n const runLoginImpl = opts.runLoginImpl ?? runLoginCommand;\n const installLifecycleImpl = opts.installLifecycleImpl ?? installLifecycle;\n\n const ac = new AbortController();\n const lifecycle = installLifecycleImpl({\n watchStdin: true,\n onShutdown: () => {\n ac.abort();\n },\n });\n\n try {\n return await runLoginImpl({\n providerId: opts.providerId,\n json: opts.json,\n signal: ac.signal,\n });\n } finally {\n lifecycle.uninstall();\n }\n}\n","import { stat as fsStat, unlink } from 'node:fs/promises';\nimport type { ErrorEnvelope } from '@macroscope/contracts';\nimport { credentialsPath } from '../auth/credentials.js';\n\nexport interface RunLogoutOptions {\n json: boolean;\n /** Override `~`. Defaults to `os.homedir()`. */\n homeDir?: string;\n /** Test seam — capture stdout. Defaults to writing to process.stdout. */\n write?: (chunk: string) => void;\n /** Test seam — override stat(). Mirrors T9's writeCredentials pattern. */\n _statForTest?: typeof fsStat;\n}\n\nexport async function runLogout(opts: RunLogoutOptions): Promise<number> {\n const write = opts.write ?? ((s: string): void => void process.stdout.write(s));\n const statFn = opts._statForTest ?? fsStat;\n const path = credentialsPath(opts.homeDir);\n\n try {\n if (process.platform !== 'win32' && typeof process.getuid === 'function') {\n const s = await statFn(path);\n const uid = process.getuid();\n if (s.uid !== uid) {\n return fail(\n write,\n opts.json,\n 'credentials_foreign_owner',\n `${path} is owned by another user (uid ${s.uid}); refusing to delete`,\n );\n }\n }\n await unlink(path);\n if (opts.json) {\n write(`${JSON.stringify({ ok: true, deleted: path })}\\n`);\n } else {\n write('Logged out\\n');\n }\n return 0;\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code === 'ENOENT') {\n if (opts.json) {\n write(`${JSON.stringify({ ok: true, alreadyLoggedOut: true })}\\n`);\n } else {\n write('Already logged out\\n');\n }\n return 0;\n }\n return fail(write, opts.json, 'logout_failed', e.message);\n }\n}\n\nfunction fail(write: (s: string) => void, json: boolean, code: string, message: string): number {\n if (json) {\n const envelope: ErrorEnvelope = { error: { code, message } };\n write(`${JSON.stringify(envelope)}\\n`);\n } else {\n write(`Error: ${message}\\n`);\n }\n return 1;\n}\n","import { readFile, stat } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport path from 'node:path';\nimport {\n API_ENDPOINTS,\n type DeleteIndexResponse,\n DeleteIndexResponseSchema,\n type ErrorEnvelope,\n ErrorEnvelopeSchema,\n FILESYSTEM_LAYOUT,\n type HealthResponse,\n HealthResponseSchema,\n type IndexBatchRequest,\n IndexBatchRequestSchema,\n type IndexBatchResponse,\n IndexBatchResponseSchema,\n OAuthCredentialsSchema,\n type ScopeTouchRequest,\n ScopeTouchRequestSchema,\n type ScopeTouchResponse,\n ScopeTouchResponseSchema,\n type SearchRequest,\n SearchRequestSchema,\n type SearchResponse,\n SearchResponseSchema,\n} from '@macroscope/contracts';\nimport type { z } from 'zod';\n\nexport type Result<T> =\n | { kind: 'ok'; data: T }\n | { kind: 'error'; envelope: ErrorEnvelope; status: number };\n\nexport interface CloudClientOptions {\n /** Override the cloud base URL. Defaults to env MACROSCOPE_CLOUD_URL, then http://localhost:3001. */\n baseUrl?: string;\n /** Override the credentials path. Defaults to FILESYSTEM_LAYOUT.user.credentialsFile under os.homedir(). */\n credentialsPath?: string;\n /** Test seam — inject a fetch implementation. Defaults to globalThis.fetch. */\n fetchImpl?: typeof fetch;\n}\n\nexport interface CloudClient {\n health(): Promise<Result<HealthResponse>>;\n search(req: SearchRequest): Promise<Result<SearchResponse>>;\n indexBatch(req: IndexBatchRequest): Promise<Result<IndexBatchResponse>>;\n scopeTouch(req: ScopeTouchRequest): Promise<Result<ScopeTouchResponse>>;\n deleteIndex(): Promise<Result<DeleteIndexResponse>>;\n}\n\nconst DEFAULT_BASE_URL = 'http://localhost:3001';\nconst REQUEST_TIMEOUT_MS = 30_000;\nconst MAX_RETRIES = 3;\nconst BASE_BACKOFF_MS = 500;\nconst JITTER_FRACTION = 0.25;\n\nconst isRetryableStatus = (status: number): boolean =>\n status === 429 || (status >= 500 && status <= 599);\n\nconst computeBackoffMs = (attempt: number): number => {\n const exp = BASE_BACKOFF_MS * 2 ** attempt;\n const jitter = exp * JITTER_FRACTION * (Math.random() * 2 - 1);\n return Math.max(0, Math.round(exp + jitter));\n};\n\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nfunction parseRetryAfterMs(header: string | null): number | null {\n if (!header) return null;\n const trimmed = header.trim();\n // Seconds form: a non-negative integer.\n if (/^\\d+$/.test(trimmed)) {\n return Number(trimmed) * 1000;\n }\n // HTTP-date form.\n const ts = Date.parse(trimmed);\n if (Number.isNaN(ts)) return null;\n return Math.max(0, ts - Date.now());\n}\n\nconst notLoggedIn = (message: string): Result<never> => ({\n kind: 'error',\n status: 0,\n envelope: { error: { code: 'not_logged_in', message } },\n});\n\nconst unexpectedResponse = (status: number, statusText: string): Result<never> => ({\n kind: 'error',\n status,\n envelope: {\n error: {\n code: 'unexpected_response',\n message: statusText || `HTTP ${status}`,\n },\n },\n});\n\nconst invalidResponse = (status: number): Result<never> => ({\n kind: 'error',\n status,\n envelope: {\n error: {\n code: 'invalid_response',\n message: 'Server returned a body that did not match the expected schema',\n },\n },\n});\n\nconst resolveCredentialsPath = (override?: string): string =>\n override ?? path.join(homedir(), FILESYSTEM_LAYOUT.user.credentialsFile);\n\nconst resolveBaseUrl = (override?: string): string =>\n override ?? process.env.MACROSCOPE_CLOUD_URL ?? DEFAULT_BASE_URL;\n\nasync function readAccessToken(credPath: string): Promise<string | null> {\n let raw: string;\n try {\n raw = await readFile(credPath, 'utf8');\n } catch {\n return null;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n const result = OAuthCredentialsSchema.safeParse(parsed);\n if (!result.success) return null;\n return result.data.accessToken;\n}\n\nasync function parseErrorBody(res: Response): Promise<Result<never>> {\n let body: unknown;\n try {\n body = await res.json();\n } catch {\n return unexpectedResponse(res.status, res.statusText);\n }\n const envelope = ErrorEnvelopeSchema.safeParse(body);\n if (!envelope.success) {\n return unexpectedResponse(res.status, res.statusText);\n }\n return { kind: 'error', status: res.status, envelope: envelope.data };\n}\n\nfunction clientValidationError(\n issue: z.ZodIssue | undefined,\n fallbackMessage: string,\n): Result<never> {\n return {\n kind: 'error',\n status: 0,\n envelope: {\n error: {\n code: 'validation_failed',\n message: issue?.message ?? fallbackMessage,\n field: issue?.path.join('.') || undefined,\n },\n },\n };\n}\n\nfunction serializeRequest(\n method: 'GET' | 'POST' | 'DELETE',\n data: Record<string, unknown> | null,\n): { query?: string; body?: string } {\n if (data === null) return {};\n if (method === 'GET') {\n const params = new URLSearchParams();\n // ASSUMPTION: every GET request schema in @macroscope/contracts has only\n // primitive fields (string | number | optional thereof). If a future\n // endpoint adds an array or boolean, this `String(v)` will silently\n // misencode it — extend here when that happens. Verified against\n // SearchRequestSchema (currently the only GET with a request body) at\n // T7-time.\n for (const [k, v] of Object.entries(data)) {\n if (v === undefined) continue;\n params.append(k, String(v));\n }\n const qs = params.toString();\n return qs ? { query: `?${qs}` } : {};\n }\n return { body: JSON.stringify(data) };\n}\n\nasync function parseOkBody<T>(res: Response, schema: z.ZodType<T>): Promise<Result<T>> {\n let body: unknown;\n try {\n body = await res.json();\n } catch {\n return invalidResponse(res.status);\n }\n const parsed = schema.safeParse(body);\n if (!parsed.success) {\n return invalidResponse(res.status);\n }\n return { kind: 'ok', data: parsed.data };\n}\n\nexport function createCloudClient(opts: CloudClientOptions = {}): CloudClient {\n const credPath = resolveCredentialsPath(opts.credentialsPath);\n const baseUrl = resolveBaseUrl(opts.baseUrl);\n const fetchImpl = opts.fetchImpl ?? globalThis.fetch;\n\n let cached: { mtimeMs: number; token: string } | null = null;\n\n async function getAccessToken(): Promise<string | null> {\n let mtimeMs: number;\n try {\n mtimeMs = (await stat(credPath)).mtimeMs;\n } catch {\n cached = null;\n return null;\n }\n if (cached && cached.mtimeMs === mtimeMs) {\n return cached.token;\n }\n const token = await readAccessToken(credPath);\n cached = token ? { mtimeMs, token } : null;\n return token;\n }\n\n async function executeRequest<T>(\n endpoint: { method: string; path: string },\n schema: z.ZodType<T>,\n init: { body?: string; query?: string },\n ): Promise<Result<T>> {\n const token = await getAccessToken();\n if (!token) {\n return notLoggedIn(`No valid credentials at ${credPath}. Run \\`macroscope login\\`.`);\n }\n\n const url = `${baseUrl}${endpoint.path}${init.query ?? ''}`;\n const headers: Record<string, string> = {\n Authorization: `Bearer ${token}`,\n };\n if (init.body !== undefined) {\n headers['Content-Type'] = 'application/json';\n }\n\n let lastResponse: Response | null = null;\n let lastNetworkError: unknown = null;\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt += 1) {\n let res: Response;\n try {\n res = await fetchImpl(url, {\n method: endpoint.method,\n headers,\n body: init.body,\n signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),\n });\n } catch (err) {\n // Network-level failure (ECONNREFUSED, DNS, TLS, abort, etc.). The\n // watcher's isRetryable() keys on `upstream_unreachable` to decide\n // whether to queue + emit \"Sync paused — retrying\"; if we let this\n // throw escape, the watcher's outer catch tags it as retryable:false\n // and the pill renders the wrong copy.\n lastNetworkError = err;\n if (attempt === MAX_RETRIES) break;\n await sleep(computeBackoffMs(attempt));\n continue;\n }\n\n if (!isRetryableStatus(res.status)) {\n if (res.status >= 200 && res.status < 300) {\n return parseOkBody(res, schema);\n }\n return parseErrorBody(res);\n }\n\n lastResponse = res;\n lastNetworkError = null;\n if (attempt === MAX_RETRIES) break;\n // Per the brief: Retry-After is honoured only on 429. 5xx uses the\n // standard exponential-backoff schedule even if the server echoes the\n // header.\n const retryAfterMs =\n res.status === 429 ? parseRetryAfterMs(res.headers.get('retry-after')) : null;\n const waitMs = retryAfterMs ?? computeBackoffMs(attempt);\n await sleep(waitMs);\n }\n\n if (lastResponse) {\n return parseErrorBody(lastResponse);\n }\n return {\n kind: 'error',\n status: 0,\n envelope: {\n error: {\n code: 'upstream_unreachable',\n message:\n lastNetworkError instanceof Error ? lastNetworkError.message : 'Network request failed',\n },\n },\n };\n }\n\n return {\n health: () =>\n executeRequest(API_ENDPOINTS.health, HealthResponseSchema, serializeRequest('GET', null)),\n\n search: (req) => {\n const parsed = SearchRequestSchema.safeParse(req);\n if (!parsed.success) {\n return Promise.resolve(\n clientValidationError(\n parsed.error.issues[0],\n 'Invalid search request',\n ) as Result<SearchResponse>,\n );\n }\n return executeRequest(\n API_ENDPOINTS.search,\n SearchResponseSchema,\n serializeRequest('GET', parsed.data),\n );\n },\n\n indexBatch: (req) => {\n const parsed = IndexBatchRequestSchema.safeParse(req);\n if (!parsed.success) {\n return Promise.resolve(\n clientValidationError(\n parsed.error.issues[0],\n 'Invalid index batch request',\n ) as Result<IndexBatchResponse>,\n );\n }\n return executeRequest(\n API_ENDPOINTS.indexBatch,\n IndexBatchResponseSchema,\n serializeRequest('POST', parsed.data),\n );\n },\n\n scopeTouch: (req) => {\n const parsed = ScopeTouchRequestSchema.safeParse(req);\n if (!parsed.success) {\n return Promise.resolve(\n clientValidationError(\n parsed.error.issues[0],\n 'Invalid scope touch request',\n ) as Result<ScopeTouchResponse>,\n );\n }\n return executeRequest(\n API_ENDPOINTS.scopeTouch,\n ScopeTouchResponseSchema,\n serializeRequest('POST', parsed.data),\n );\n },\n\n deleteIndex: () =>\n executeRequest(\n API_ENDPOINTS.deleteIndex,\n DeleteIndexResponseSchema,\n serializeRequest('DELETE', null),\n ),\n };\n}\n","import type { BlockHit, CodeMatch, ErrorEnvelope, SearchRequest } from '@macroscope/contracts';\nimport { credentialsPath } from '../auth/credentials.js';\nimport { type CloudClient, createCloudClient } from '../cloud/client.js';\nimport { ProjectNotFoundError, findProject } from '../core/project.js';\nimport {\n type CodeSearchInput,\n type CodeSearchResult,\n codeSearch as defaultCodeSearch,\n} from '../local/code-search.js';\n\nconst DEFAULT_LIMIT_PER_SIDE = 10;\n\nexport interface SearchScopeOptions {\n worktree?: string;\n allWorktrees?: boolean;\n allRepos?: boolean;\n repo?: string;\n kind?: string;\n limit?: number;\n}\n\nexport interface RunSearchOptions {\n query: string;\n json: boolean;\n cwd?: string;\n homeDir?: string;\n scope: SearchScopeOptions;\n write?: (chunk: string) => void;\n /** Test seam — inject codeSearch. */\n codeSearchImpl?: (input: CodeSearchInput) => Promise<CodeSearchResult>;\n /** Test seam — inject CloudClient. */\n client?: CloudClient;\n}\n\nexport interface SearchOutput {\n blocks: BlockHit[];\n code: CodeMatch[];\n notes: string[];\n}\n\nexport async function runSearch(opts: RunSearchOptions): Promise<number> {\n const write = opts.write ?? ((s: string): void => void process.stdout.write(s));\n const codeSearchFn = opts.codeSearchImpl ?? defaultCodeSearch;\n const limit = opts.scope.limit ?? DEFAULT_LIMIT_PER_SIDE;\n const credPath = credentialsPath(opts.homeDir);\n const client = opts.client ?? createCloudClient({ credentialsPath: credPath });\n\n const notes: string[] = [];\n\n let projectRoot: string | null = null;\n try {\n const p = await findProject(opts.cwd ?? process.cwd());\n projectRoot = p.root;\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n notes.push('local search unavailable: not in a macroscope project');\n } else {\n notes.push(`local search unavailable: ${(err as Error).message}`);\n }\n }\n\n const searchReq: SearchRequest = { q: opts.query, limit };\n if (opts.scope.worktree) searchReq.worktreeId = opts.scope.worktree;\n if (opts.scope.repo) searchReq.repo = opts.scope.repo;\n if (opts.scope.kind) searchReq.kind = opts.scope.kind;\n\n const [cloudRes, codeRes] = await Promise.allSettled([\n client.search(searchReq),\n projectRoot === null\n ? Promise.resolve<CodeSearchResult>({\n kind: 'error',\n envelope: { error: { code: 'not_a_git_repo', message: 'no project' } },\n })\n : codeSearchFn({ query: opts.query, cwd: projectRoot, limit }),\n ]);\n\n let blocks: BlockHit[] = [];\n if (cloudRes.status === 'fulfilled') {\n const r = cloudRes.value;\n if (r.kind === 'ok') {\n blocks = r.data.hits;\n } else if (r.envelope.error.code === 'not_logged_in') {\n notes.push('cloud search unavailable: run `macroscope login` to enable catalogue search');\n } else {\n notes.push(`cloud unreachable: ${r.envelope.error.message}`);\n }\n } else {\n notes.push(`cloud unreachable: ${(cloudRes.reason as Error).message}`);\n }\n\n let codeMatches: CodeMatch[] = [];\n if (codeRes.status === 'fulfilled' && codeRes.value.kind === 'ok') {\n codeMatches = codeRes.value.matches;\n } else if (codeRes.status === 'fulfilled' && codeRes.value.kind === 'error') {\n if (projectRoot !== null) {\n notes.push(`local search failed: ${codeRes.value.envelope.error.message}`);\n }\n } else if (codeRes.status === 'rejected') {\n notes.push(`local search failed: ${(codeRes.reason as Error).message}`);\n }\n\n const cloudFailed = cloudRes.status !== 'fulfilled' || cloudRes.value.kind !== 'ok';\n if (projectRoot === null && cloudFailed) {\n return fail(write, opts.json, 'search_unavailable', notes.join('; ') || 'no project, no creds');\n }\n\n const result: SearchOutput = { blocks, code: codeMatches, notes };\n if (opts.json) {\n write(`${JSON.stringify(result)}\\n`);\n } else {\n writeHuman(write, result);\n }\n return 0;\n}\n\nfunction fail(write: (s: string) => void, json: boolean, code: string, message: string): number {\n if (json) {\n const env: ErrorEnvelope = { error: { code, message } };\n write(`${JSON.stringify(env)}\\n`);\n } else {\n write(`Error: ${message}\\n`);\n }\n return 2;\n}\n\nfunction writeHuman(write: (s: string) => void, r: SearchOutput): void {\n write(`Cloud catalogue (${r.blocks.length} hits):\\n`);\n if (r.blocks.length === 0) {\n write(' (no results)\\n');\n } else {\n for (const b of r.blocks) {\n const name = b.name ?? b.blockId;\n write(` ${name.padEnd(28)} ${b.kind.padEnd(20)} ${b.path}\\n`);\n }\n }\n write(`\\nCode matches (${r.code.length}):\\n`);\n if (r.code.length === 0) {\n write(' (no results)\\n');\n } else {\n for (const m of r.code) {\n const loc = m.column ? `${m.file}:${m.line}:${m.column}` : `${m.file}:${m.line}`;\n write(` ${loc} ${m.preview.trim()}\\n`);\n }\n }\n for (const note of r.notes) {\n write(`\\n(${note})\\n`);\n }\n}\n","import { execFile as execFileCb } from 'node:child_process';\nimport { promisify } from 'node:util';\nimport { type CodeMatch, CodeMatchSchema, type ErrorEnvelope } from '@macroscope/contracts';\n\nconst execFile = promisify(execFileCb);\n\nconst DEFAULT_LIMIT = 100;\nconst MAX_STDOUT_BYTES = 32 * 1024 * 1024;\n\nexport interface CodeSearchInput {\n query: string;\n cwd: string;\n limit?: number;\n}\n\nexport type CodeSearchResult =\n | { kind: 'ok'; matches: CodeMatch[] }\n | { kind: 'error'; envelope: ErrorEnvelope };\n\n/**\n * Run `git grep` in `cwd` and return typed results.\n *\n * Exit semantics: 0 = matches found, 1 = no matches (NOT an error), >1 = error.\n *\n * `--column` emits the 1-based byte offset of the first match. For ASCII\n * sources this equals a column number; for multi-byte UTF-8 it diverges\n * slightly. Acceptable for v1 code search.\n */\nexport async function codeSearch(input: CodeSearchInput): Promise<CodeSearchResult> {\n const limit = input.limit ?? DEFAULT_LIMIT;\n\n const args = [\n 'grep',\n '--no-color',\n '--line-number',\n '--column',\n '--null',\n '--ignore-case',\n '--',\n input.query,\n ];\n\n let stdout: string;\n try {\n const result = await execFile('git', args, {\n cwd: input.cwd,\n maxBuffer: MAX_STDOUT_BYTES,\n encoding: 'utf8',\n });\n stdout = result.stdout;\n } catch (err) {\n const e = err as NodeJS.ErrnoException & {\n stdout?: string;\n stderr?: string;\n code?: number | string;\n };\n\n if (e.code === 'ENOENT') {\n return errorEnvelope('git_unavailable', 'git executable not found on PATH');\n }\n\n const stderr = e.stderr ?? '';\n const exitCode = typeof e.code === 'number' ? e.code : Number.NaN;\n\n if (/not a git repository/i.test(stderr)) {\n return errorEnvelope('not_a_git_repo', `${input.cwd} is not a git repository`);\n }\n\n if (exitCode === 1) {\n return { kind: 'ok', matches: [] };\n }\n\n const firstLine = stderr.split('\\n', 1)[0]?.trim() || 'git grep failed';\n return errorEnvelope('git_grep_failed', firstLine);\n }\n\n return { kind: 'ok', matches: parseGrepOutput(stdout, limit) };\n}\n\n/**\n * `git grep --null --line-number --column` emits per-match records of the form\n * `path\\0line\\0col\\0content\\n`. Records are newline-terminated; ONLY the\n * delimiters between fields are NUL.\n *\n * Pass 1: split on `\\n` to get records. Pass 2: split each record on `\\0` to\n * get the four fields. Splitting only on `\\0` would let one match's content\n * eat the next match's path.\n */\nfunction parseGrepOutput(stdout: string, limit: number): CodeMatch[] {\n const matches: CodeMatch[] = [];\n if (!stdout) return matches;\n\n const records = stdout.split('\\n');\n for (const record of records) {\n if (matches.length >= limit) break;\n if (!record) continue;\n\n const fields = record.split('\\0');\n if (fields.length < 4) continue;\n\n const [file, lineStr, colStr, ...rest] = fields;\n const preview = rest.join('\\0');\n const line = Number.parseInt(lineStr, 10);\n const column = Number.parseInt(colStr, 10);\n if (!Number.isFinite(line) || line <= 0) continue;\n\n const candidate: CodeMatch = {\n file,\n line,\n column: Number.isFinite(column) && column > 0 ? column : undefined,\n preview,\n };\n\n const parsed = CodeMatchSchema.safeParse(candidate);\n if (!parsed.success) continue;\n matches.push(parsed.data);\n }\n\n return matches;\n}\n\nfunction errorEnvelope(\n code: ErrorEnvelope['error']['code'],\n message: string,\n): { kind: 'error'; envelope: ErrorEnvelope } {\n return { kind: 'error', envelope: { error: { code, message } } };\n}\n","import { readFile } from 'node:fs/promises';\nimport { OAuthCredentialsSchema } from '@macroscope/contracts';\nimport { credentialsPath } from '../auth/credentials.js';\nimport { type CloudClient, createCloudClient } from '../cloud/client.js';\nimport { ProjectNotFoundError, findProject } from '../core/project.js';\n\nexport interface StatusReport {\n worktree: string | null;\n cloud: 'reachable' | 'unreachable' | 'not_logged_in';\n login: { provider: 'github' | 'gitlab'; providerUserId?: string } | null;\n lastIndexTime: number | null;\n watcher: 'running' | 'not_running';\n}\n\nexport interface RunStatusOptions {\n json: boolean;\n cwd?: string;\n homeDir?: string;\n write?: (chunk: string) => void;\n /** Test seam — inject a CloudClient (overrides creation). */\n client?: CloudClient;\n /** Test seam — override the 3s health-race timeout. */\n healthTimeoutMs?: number;\n}\n\nconst DEFAULT_HEALTH_TIMEOUT_MS = 3_000;\n\nexport async function runStatus(opts: RunStatusOptions): Promise<number> {\n const write = opts.write ?? ((s: string): void => void process.stdout.write(s));\n const healthTimeoutMs = opts.healthTimeoutMs ?? DEFAULT_HEALTH_TIMEOUT_MS;\n\n const worktree = await resolveWorktree(opts.cwd);\n const credPath = credentialsPath(opts.homeDir);\n const client = opts.client ?? createCloudClient({ credentialsPath: credPath });\n const cloud = await probeCloud(client, healthTimeoutMs);\n const login = await readLogin(credPath);\n\n const report: StatusReport = {\n worktree,\n cloud,\n login,\n lastIndexTime: null,\n watcher: 'not_running',\n };\n\n if (opts.json) {\n write(`${JSON.stringify(report)}\\n`);\n } else {\n writeHuman(write, report);\n }\n return 0;\n}\n\nasync function resolveWorktree(cwd?: string): Promise<string | null> {\n try {\n const project = await findProject(cwd ?? process.cwd());\n return project.root;\n } catch (err) {\n if (err instanceof ProjectNotFoundError) return null;\n return null;\n }\n}\n\nasync function probeCloud(client: CloudClient, timeoutMs: number): Promise<StatusReport['cloud']> {\n const result = await Promise.race([\n client.health().catch(() => null),\n new Promise<null>((resolve) => setTimeout(() => resolve(null), timeoutMs)),\n ]);\n if (result === null) return 'unreachable';\n if (result.kind === 'ok') return 'reachable';\n if (result.envelope.error.code === 'not_logged_in') return 'not_logged_in';\n return 'unreachable';\n}\n\nasync function readLogin(credPath: string): Promise<StatusReport['login']> {\n let raw: string;\n try {\n raw = await readFile(credPath, 'utf8');\n } catch {\n return null;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n const result = OAuthCredentialsSchema.safeParse(parsed);\n if (!result.success) return null;\n return { provider: result.data.provider, providerUserId: result.data.providerUserId };\n}\n\nfunction writeHuman(write: (s: string) => void, r: StatusReport): void {\n const worktree = r.worktree ?? '(not in a macroscope project)';\n const login = r.login\n ? `${r.login.provider}${r.login.providerUserId ? ` (${r.login.providerUserId})` : ''}`\n : 'not logged in';\n const lastIndexed = r.lastIndexTime === null ? 'never' : new Date(r.lastIndexTime).toISOString();\n write(`worktree: ${worktree}\\n`);\n write(`cloud: ${r.cloud}\\n`);\n write(`login: ${login}\\n`);\n write(`last indexed: ${lastIndexed}\\n`);\n write(`watcher: ${r.watcher}\\n`);\n}\n","export const VERSION = '0.0.0';\n","import { existsSync } from 'node:fs';\nimport { readFile } from 'node:fs/promises';\nimport { type IncomingMessage, type ServerResponse, createServer } from 'node:http';\nimport { homedir } from 'node:os';\nimport { extname, join, normalize, resolve } from 'node:path';\nimport { FILESYSTEM_LAYOUT } from '@macroscope/contracts';\nimport { type CloudClient, createCloudClient } from '../cloud/client.js';\nimport { type CatchupProgress, runCatchup } from '../local/catchup.js';\nimport { type WatcherHandle, type WatcherProgressEvents, startWatcher } from '../local/watcher.js';\nimport { handleBlocksRequest } from './api/blocks-handler.js';\nimport { handleBlueprintsRequest } from './api/blueprints-handler.js';\nimport { handleCodeRequest } from './api/code-handler.js';\nimport { handleCodeSearchRequest } from './api/code-search-handler.js';\nimport { handleContextRequest } from './api/context-handler.js';\nimport { handleMarkdownRequest } from './api/markdown-handler.js';\nimport { type ProgressBus, createProgressBus } from './api/progress-stream.js';\nimport { handleCloudProxy, isCloudProxyRoute } from './api/proxy.js';\nimport { ServiceManager } from './api/service-manager.js';\nimport { handleServiceEnsureRequest } from './api/services-handler.js';\n\nconst MIME_TYPES: Record<string, string> = {\n '.html': 'text/html; charset=utf-8',\n '.htm': 'text/html; charset=utf-8',\n '.js': 'application/javascript; charset=utf-8',\n '.mjs': 'application/javascript; charset=utf-8',\n '.css': 'text/css; charset=utf-8',\n '.json': 'application/json; charset=utf-8',\n '.svg': 'image/svg+xml',\n '.png': 'image/png',\n '.jpg': 'image/jpeg',\n '.jpeg': 'image/jpeg',\n '.gif': 'image/gif',\n '.ico': 'image/x-icon',\n '.woff': 'font/woff',\n '.woff2': 'font/woff2',\n '.map': 'application/json; charset=utf-8',\n};\n\nexport interface CloudSyncOptions {\n /** Inject a pre-built CloudClient. Otherwise one is created from cloudUrl + credentialsPath. */\n cloudClient?: CloudClient;\n /** Called for every catchup progress event. */\n onCatchupProgress?: (e: CatchupProgress) => void;\n /** Called for every watcher progress event. */\n onWatcherEvent?: <K extends keyof WatcherProgressEvents>(\n name: K,\n payload: WatcherProgressEvents[K],\n ) => void;\n}\n\nexport interface StartUiServerOptions {\n /** Project root (or any descendant) — used by /api/blueprints to find .macroscope/. */\n cwd: string;\n /** Directory holding the pre-built UI bundle (index.html + assets). */\n staticDir: string;\n /** Port to listen on. 0 picks any free port. */\n port?: number;\n /** Whether to auto-open the system browser. Default true. */\n open?: boolean;\n /** Cloud API URL for the proxy. Falls back to MACROSCOPE_CLOUD_URL env var, then http://localhost:3001. */\n cloudUrl?: string;\n /** Absolute path to the credentials file. Falls back to FILESYSTEM_LAYOUT default. */\n credentialsPath?: string;\n /**\n * Cloud sync wiring. `false` disables catchup + watcher entirely (used by\n * tests + offline diagnostic boots). When `undefined` or an object,\n * `macroscope ui` runs the catch-up scan after the HTTP server is listening,\n * then spawns the watcher.\n */\n cloudSync?: false | CloudSyncOptions;\n}\n\nexport interface RunningUiServer {\n url: string;\n port: number;\n close: () => Promise<void>;\n serviceManager: ServiceManager;\n /** The watcher started after catch-up, or null if cloudSync was disabled or login was missing. */\n watcher: WatcherHandle | null;\n}\n\n/**\n * Start the macroscope web UI server. Serves the pre-built bundle as static\n * files, answers /api/blueprints with the live loader output, runs a catch-up\n * scan against the cloud catalogue, and then spawns the watcher that keeps it\n * current.\n *\n * No Vite at runtime — the bundle ships with the package.\n */\nexport async function startUiServer(opts: StartUiServerOptions): Promise<RunningUiServer> {\n const staticDir = resolve(opts.staticDir);\n if (!existsSync(staticDir)) {\n throw new Error(\n `Macroscope UI build is missing. Expected files at ${staticDir}. Run \\`pnpm build\\` first.`,\n );\n }\n const indexFile = join(staticDir, 'index.html');\n if (!existsSync(indexFile)) {\n throw new Error(`Macroscope UI build is incomplete: ${indexFile} not found.`);\n }\n\n const serviceManager = new ServiceManager();\n const progressBus = createProgressBus();\n\n const credentialsPath =\n opts.credentialsPath ?? join(homedir(), FILESYSTEM_LAYOUT.user.credentialsFile);\n const proxyOpts = { cloudUrl: opts.cloudUrl, credentialsPath };\n\n const server = createServer((req, res) => {\n if (req.url && new URL(req.url, 'http://localhost').pathname === '/api/local/progress') {\n progressBus.handleStream(req, res);\n return;\n }\n void handleRequest(req, res, staticDir, opts.cwd, serviceManager, proxyOpts).catch((err) => {\n respondError(res, 500, err instanceof Error ? err.message : String(err));\n });\n });\n\n const port = await new Promise<number>((resolveListen, reject) => {\n server.once('error', reject);\n server.listen(opts.port ?? 0, '127.0.0.1', () => {\n const addr = server.address();\n if (!addr || typeof addr === 'string') {\n reject(new Error('Server did not start with an address'));\n return;\n }\n resolveListen(addr.port);\n });\n });\n\n const { attachTerminalWs } = await import('./api/terminal-ws.js');\n attachTerminalWs(server, opts.cwd);\n\n const url = `http://localhost:${port}`;\n\n if (opts.open !== false) {\n try {\n const openModule = await import('open');\n const openFn = openModule.default ?? openModule;\n await (openFn as (target: string) => Promise<unknown>)(url);\n } catch {\n // Browser-launch failure is not fatal. The URL still works.\n }\n }\n\n // Cloud sync (catch-up + watcher). Runs AFTER the HTTP server is listening\n // so the browser can render an \"Indexing...\" state in T17.\n const watcher = await maybeStartCloudSync(opts, credentialsPath, progressBus);\n\n let closed = false;\n return {\n url,\n port,\n serviceManager,\n watcher,\n close: async () => {\n if (closed) return;\n closed = true;\n // Stop the watcher first so any in-flight batch flushes before we tear\n // down its parent server.\n if (watcher) {\n await watcher.stop().catch((err: unknown) => {\n console.warn(\n `[macroscope] watcher.stop() failed: ${err instanceof Error ? err.message : String(err)}`,\n );\n });\n }\n // End every active SSE stream cleanly so EventSource clients see a\n // close instead of timing out.\n progressBus.close();\n await serviceManager.shutdown();\n await new Promise<void>((resolveClose, reject) =>\n server.close((err) => (err ? reject(err) : resolveClose())),\n );\n },\n };\n}\n\nasync function maybeStartCloudSync(\n opts: StartUiServerOptions,\n credentialsPath: string,\n progressBus: ProgressBus,\n): Promise<WatcherHandle | null> {\n if (opts.cloudSync === false) return null;\n const sync = opts.cloudSync ?? {};\n const cloudClient =\n sync.cloudClient ?? createCloudClient({ baseUrl: opts.cloudUrl, credentialsPath });\n\n let cloudFatalError: string | null = null;\n try {\n const result = await runCatchup({\n projectRoot: opts.cwd,\n cloudClient,\n onProgress: (e) => {\n sync.onCatchupProgress?.(e);\n progressBus.emit({ source: 'catchup', payload: e });\n if (e.kind === 'error' && !e.retryable) {\n cloudFatalError = e.err.message;\n }\n },\n });\n if (result.upserts > 0 || result.deletes > 0) {\n console.log(\n `[macroscope] catch-up scan complete: ${result.upserts} upserts, ${result.deletes} deletes (${result.durationMs}ms)`,\n );\n }\n } catch (err) {\n cloudFatalError = err instanceof Error ? err.message : String(err);\n }\n\n if (cloudFatalError) {\n console.warn(\n `[macroscope] cloud catalogue disabled: ${cloudFatalError} — local code search still works. Run \\`macroscope login\\` to enable cloud search.`,\n );\n return null;\n }\n\n try {\n const watcher = await startWatcher({\n projectRoot: opts.cwd,\n cloudClient,\n lifecycle: false,\n });\n const userFwd = sync.onWatcherEvent;\n for (const name of ['batchStart', 'batchSent', 'error', 'queueDrained'] as const) {\n watcher.on(name, (payload) => {\n userFwd?.(name, payload);\n progressBus.emit({\n source: 'watcher',\n payload: { event: name, data: payload },\n });\n });\n }\n return watcher;\n } catch (err) {\n console.warn(\n `[macroscope] watcher failed to start: ${err instanceof Error ? err.message : String(err)}`,\n );\n return null;\n }\n}\n\nasync function handleRequest(\n req: IncomingMessage,\n res: ServerResponse,\n staticDir: string,\n cwd: string,\n serviceManager: ServiceManager,\n proxyOpts: { cloudUrl?: string; credentialsPath?: string },\n): Promise<void> {\n const url = new URL(req.url ?? '/', 'http://localhost');\n\n if (isCloudProxyRoute(url.pathname)) {\n await handleCloudProxy(req, res, proxyOpts);\n return;\n }\n\n if (url.pathname === '/api/local/code-search') {\n const result = await handleCodeSearchRequest(cwd, url.searchParams.get('q'));\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n if (url.pathname === '/api/local/context') {\n const result = await handleContextRequest(cwd);\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n if (url.pathname === '/api/blueprints') {\n const result = await handleBlueprintsRequest(cwd);\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n if (url.pathname === '/api/blocks') {\n const result = await handleBlocksRequest(cwd);\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n if (url.pathname === '/api/markdown') {\n const requestedPath = url.searchParams.get('path');\n if (!requestedPath) {\n res.statusCode = 400;\n res.setHeader('content-type', 'text/plain');\n res.end('Missing ?path');\n return;\n }\n const absolute = resolve(cwd, requestedPath);\n if (!absolute.startsWith(resolve(cwd))) {\n res.statusCode = 403;\n res.setHeader('content-type', 'text/plain');\n res.end('Forbidden');\n return;\n }\n const result = await handleMarkdownRequest(absolute);\n res.statusCode = result.status;\n res.setHeader('content-type', result.contentType);\n res.end(result.body);\n return;\n }\n\n if (url.pathname === '/api/code') {\n const requestedPath = url.searchParams.get('path');\n const lang = url.searchParams.get('lang') ?? undefined;\n if (!requestedPath) {\n res.statusCode = 400;\n res.setHeader('content-type', 'text/plain');\n res.end('Missing ?path');\n return;\n }\n const absolute = resolve(cwd, requestedPath);\n if (!absolute.startsWith(resolve(cwd))) {\n res.statusCode = 403;\n res.setHeader('content-type', 'text/plain');\n res.end('Forbidden');\n return;\n }\n const result = await handleCodeRequest(absolute, lang);\n res.statusCode = result.status;\n res.setHeader('content-type', result.contentType);\n res.end(result.body);\n return;\n }\n\n if (url.pathname === '/api/services/ensure' && req.method === 'POST') {\n const raw = await readBody(req);\n let parsed: { blockId?: string; viewKey?: string };\n try {\n parsed = JSON.parse(raw || '{}');\n } catch {\n res.statusCode = 400;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify({ error: 'invalid json' }));\n return;\n }\n const result = await handleServiceEnsureRequest(cwd, serviceManager, {\n blockId: parsed.blockId ?? '',\n viewKey: parsed.viewKey ?? '',\n });\n res.statusCode = result.status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(result.body));\n return;\n }\n\n // Resolve the requested static file, defending against path traversal.\n const requested = url.pathname === '/' ? '/index.html' : url.pathname;\n const absolutePath = normalize(join(staticDir, requested));\n if (!absolutePath.startsWith(staticDir)) {\n respondError(res, 403, 'Forbidden');\n return;\n }\n\n try {\n const content = await readFile(absolutePath);\n res.setHeader('content-type', MIME_TYPES[extname(absolutePath)] ?? 'application/octet-stream');\n res.end(content);\n return;\n } catch {\n // SPA fallback: any unknown route serves index.html so client-side routing works.\n try {\n const indexContent = await readFile(join(staticDir, 'index.html'));\n res.setHeader('content-type', 'text/html; charset=utf-8');\n res.end(indexContent);\n } catch {\n respondError(res, 404, 'Not found');\n }\n }\n}\n\nfunction respondError(res: ServerResponse, status: number, message: string): void {\n res.statusCode = status;\n res.setHeader('content-type', 'text/plain; charset=utf-8');\n res.end(message);\n}\n\nfunction readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolveBody, reject) => {\n const chunks: Buffer[] = [];\n req.on('data', (c: Buffer) => chunks.push(c));\n req.on('end', () => resolveBody(Buffer.concat(chunks).toString()));\n req.on('error', reject);\n });\n}\n","/**\n * T15 — Catch-up scan on startup.\n *\n * Reconciles cloud state against the working tree before the watcher (T14)\n * takes over. Walks the tree, diffs against the local hash cache, and pushes\n * batched upserts + deletes via the CloudClient. On schema-version bump or a\n * missing/legacy cache file the entire catalogue is re-derived; on\n * `upstream_unreachable` the unpushed batches are queued to disk in T14's\n * exact `QueuedBatch` shape so the watcher drains them on its next push.\n *\n * Sequencing per ARCHITECTURE.md: `runCatchup()` runs once, returns, and the\n * caller (T16's `macroscope ui` wiring) then starts the watcher. Never spawn\n * the watcher from here — that's the caller's job.\n */\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, sep } from 'node:path';\nimport { FILESYSTEM_LAYOUT, type MeilisearchDoc, SCHEMA_VERSION } from '@macroscope/contracts';\nimport type { CloudClient, Result } from '../cloud/client.js';\nimport { extractAll } from '../core/extractor.js';\nimport {\n type HashCache,\n filterChangedBlocks,\n hashPayload,\n loadHashCache,\n readSchemaVersion,\n saveHashCache,\n} from '../core/hasher.js';\nimport { findProject } from '../core/project.js';\nimport { scan } from '../core/scanner.js';\nimport { deriveRepoId } from './repo-id.js';\nimport { composeDocId } from './watcher.js';\nimport { deriveWorktreeId, getOrCreateMachineUuid } from './worktree-id.js';\n\nexport type CatchupProgress =\n | { kind: 'start'; total: number }\n | { kind: 'extract'; done: number; total: number }\n | { kind: 'pushed'; batch: number; remaining: number }\n | { kind: 'deleted'; count: number }\n | { kind: 'complete'; durationMs: number; upserts: number; deletes: number }\n | { kind: 'error'; err: Error; retryable: boolean };\n\nexport interface CatchupOptions {\n projectRoot: string;\n cloudClient: CloudClient;\n /** Subscribe to progress for T17's UI. */\n onProgress?: (event: CatchupProgress) => void;\n /** Test seam — overrides homedir (forwarded to getOrCreateMachineUuid). */\n homeDir?: string;\n}\n\nexport interface CatchupResult {\n /** Count of upserts actually sent (excludes queued, excludes mtime-only refreshes). */\n upserts: number;\n /** Count of deletes actually sent. */\n deletes: number;\n /** Count of blocks skipped (cache hit OR same-hash mtime-refresh). */\n skipped: number;\n durationMs: number;\n}\n\n/**\n * Upsert batch size cap. The cloud accepts more, but smaller chunks give finer\n * progress UX and bound the lost work on a mid-flow failure.\n */\nconst CHUNK = 500;\n\n/**\n * Throttle window for `{ kind: 'extract' }` progress events. The extract loop\n * is hot; emitting per-block would flood the UI.\n */\nconst EXTRACT_PROGRESS_INTERVAL_MS = 100;\n\n/**\n * Queue file format — MUST match T14's interface byte-for-byte so the watcher\n * can drain entries T15 enqueued. Kept private to this file; T14 owns the\n * canonical shape.\n */\ninterface QueuedBatch {\n upserts: MeilisearchDoc[];\n deletes: string[];\n queuedAt: number;\n}\n\nconst toPosix = (p: string): string => p.split(sep).join('/');\n\n/**\n * Walk → hash → diff → push. See file header.\n *\n * Never throws to the caller; all failure surfaces via `onProgress({ kind:\n * 'error', ... })` and the returned `CatchupResult` (which reports only what\n * was actually pushed).\n */\nexport async function runCatchup(opts: CatchupOptions): Promise<CatchupResult> {\n const startTime = Date.now();\n const onProgress = opts.onProgress ?? (() => {});\n\n /* ----------------------------- identity ----------------------------- */\n const project = await findProject(opts.projectRoot);\n const machineUuid = await getOrCreateMachineUuid({ homeDir: opts.homeDir });\n const worktreeId = deriveWorktreeId(machineUuid, project.root);\n const repo = await deriveRepoId(project.root);\n\n /* ------------------------------ walk -------------------------------- */\n const scanResult = await scan(project);\n const blocks = scanResult.blocks;\n onProgress({ kind: 'start', total: blocks.length });\n\n /* ------------------------- schema-version --------------------------- */\n // `undefined` covers both \"no file\" and \"legacy flat shape\" — both force a\n // full re-push per the spec.\n const cachedSchemaVersion = await readSchemaVersion({ workspaceRoot: project.root });\n const schemaMismatch = cachedSchemaVersion !== SCHEMA_VERSION;\n\n // When the schema mismatches, throw away the cache entirely: every block\n // becomes \"changed\" AND every cached hash comparison fails, forcing every\n // payload into the upserts batch even if its content happens to match.\n const cache: HashCache = schemaMismatch\n ? {}\n : await loadHashCache({ workspaceRoot: project.root });\n\n /* ----------------------- changed-block extraction ------------------- */\n const changedBlocks = schemaMismatch ? blocks : await filterChangedBlocks(blocks, cache);\n const { payloads } = await extractAll(changedBlocks);\n const payloadById = new Map(payloads.map((p) => [p.blockId, p]));\n\n // Blocks that filterChangedBlocks marked changed BUT whose content hash\n // matches the cached one. We refresh the mtime so future runs skip the\n // stat-based comparison too. Persisted alongside the first successful push.\n const mtimeRefreshes: HashCache = {};\n const upserts: MeilisearchDoc[] = [];\n // Per-upsert cache entries — applied to the on-disk cache only after the\n // batch that contains them succeeds.\n const upsertCacheEntries = new Map<string, { hash: string; mtime: number }>();\n const now = Date.now();\n\n let lastExtractEmit = 0;\n let done = 0;\n\n for (const block of changedBlocks) {\n done += 1;\n const payload = payloadById.get(block.id);\n if (payload) {\n const contentHash = hashPayload(payload);\n const cached = cache[block.id];\n if (cached && cached.hash === contentHash) {\n // Same indexed content; just refresh mtime so the stat-fast-path picks\n // it up next time.\n mtimeRefreshes[block.id] = { hash: contentHash, mtime: now };\n } else {\n const doc: MeilisearchDoc = {\n ...payload,\n contentHash,\n repo,\n worktreeId,\n path: toPosix(relative(project.root, block.path)),\n lastActiveAt: now,\n };\n upserts.push(doc);\n upsertCacheEntries.set(block.id, { hash: contentHash, mtime: now });\n }\n }\n const t = Date.now();\n if (t - lastExtractEmit >= EXTRACT_PROGRESS_INTERVAL_MS || done === changedBlocks.length) {\n onProgress({ kind: 'extract', done, total: changedBlocks.length });\n lastExtractEmit = t;\n }\n }\n\n /* ---------------------------- deletes ------------------------------- */\n const currentIds = new Set(blocks.map((b) => b.id));\n const deletes: string[] = [];\n for (const id of Object.keys(cache)) {\n if (currentIds.has(id)) continue;\n deletes.push(composeDocId(repo, worktreeId, id));\n }\n\n /* --------------------------- batching ------------------------------- */\n const batches: Array<{ upserts: MeilisearchDoc[]; deletes: string[] }> = [];\n for (let i = 0; i < upserts.length; i += CHUNK) {\n batches.push({ upserts: upserts.slice(i, i + CHUNK), deletes: [] });\n }\n if (deletes.length > 0) {\n if (batches.length > 0) batches[batches.length - 1].deletes = deletes;\n else batches.push({ upserts: [], deletes });\n }\n\n // Track the cache state we'll persist. Starts from `cache` (or {} on schema\n // mismatch), gains mtime refreshes immediately on first successful persist,\n // and gains upsert entries batch-by-batch as they push successfully.\n const persistedCache: HashCache = { ...cache, ...mtimeRefreshes };\n // Remove ids slated for deletion — only commit the removal after the batch\n // carrying their delete strings succeeds (handled in the loop).\n let pushedUpserts = 0;\n let pushedDeletes = 0;\n const skipped = blocks.length - upserts.length;\n\n if (batches.length === 0) {\n // Nothing to push. Persist the mtime refreshes (and the new schemaVersion\n // on a fresh/legacy cache) so we don't repeat work next run.\n if (Object.keys(mtimeRefreshes).length > 0 || schemaMismatch) {\n await saveHashCache(persistedCache, { workspaceRoot: project.root });\n }\n const durationMs = Date.now() - startTime;\n onProgress({ kind: 'complete', durationMs, upserts: 0, deletes: 0 });\n return { upserts: 0, deletes: 0, skipped, durationMs };\n }\n\n /* ----------------------------- push --------------------------------- */\n for (let i = 0; i < batches.length; i += 1) {\n const batch = batches[i];\n const res = await opts.cloudClient.indexBatch(batch);\n\n if (res.kind === 'ok') {\n // Apply this batch's cache mutations.\n for (const doc of batch.upserts) {\n const entry = upsertCacheEntries.get(doc.blockId);\n if (entry) persistedCache[doc.blockId] = entry;\n }\n if (batch.deletes.length > 0) {\n for (const id of Object.keys(cache)) {\n if (!currentIds.has(id)) delete persistedCache[id];\n }\n }\n // Incremental persist — survives a mid-flow crash.\n await saveHashCache(persistedCache, { workspaceRoot: project.root });\n pushedUpserts += batch.upserts.length;\n pushedDeletes += batch.deletes.length;\n onProgress({ kind: 'pushed', batch: i + 1, remaining: batches.length - i - 1 });\n if (batch.deletes.length > 0) {\n onProgress({ kind: 'deleted', count: batch.deletes.length });\n }\n continue;\n }\n\n // Error path.\n const retryable = isRetryable(res);\n if (!retryable) {\n // not_logged_in / unauthorized / 4xx — bail without persisting anything\n // not already saved. The caller routes the user to `macroscope login`.\n onProgress({\n kind: 'error',\n err: new Error(res.envelope.error.message),\n retryable: false,\n });\n const durationMs = Date.now() - startTime;\n return { upserts: pushedUpserts, deletes: pushedDeletes, skipped, durationMs };\n }\n\n // Retryable: queue the current AND all subsequent batches in T14's shape\n // so the watcher drains them on next push. Order is preserved.\n const remainingBatches = batches.slice(i);\n await enqueueBatches(project.root, remainingBatches);\n onProgress({\n kind: 'error',\n err: new Error(res.envelope.error.message),\n retryable: true,\n });\n const durationMs = Date.now() - startTime;\n return { upserts: pushedUpserts, deletes: pushedDeletes, skipped, durationMs };\n }\n\n const durationMs = Date.now() - startTime;\n onProgress({ kind: 'complete', durationMs, upserts: pushedUpserts, deletes: pushedDeletes });\n return { upserts: pushedUpserts, deletes: pushedDeletes, skipped, durationMs };\n}\n\n/* --------------------------- queue plumbing --------------------------- */\n\nfunction isRetryable(r: Result<unknown>): boolean {\n if (r.kind !== 'error') return false;\n const code = r.envelope.error.code;\n if (code === 'not_logged_in' || code === 'unauthorized') return false;\n if (code === 'upstream_unreachable') return true;\n if (r.status >= 500 && r.status <= 599) return true;\n return false;\n}\n\nasync function readQueue(queuePath: string): Promise<QueuedBatch[]> {\n try {\n const raw = await readFile(queuePath, 'utf8');\n const parsed = JSON.parse(raw) as unknown;\n if (Array.isArray(parsed)) return parsed as QueuedBatch[];\n return [];\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n return [];\n }\n}\n\nasync function writeQueueAtomic(queuePath: string, q: QueuedBatch[]): Promise<void> {\n await mkdir(dirname(queuePath), { recursive: true });\n const tmp = `${queuePath}.tmp`;\n await writeFile(tmp, JSON.stringify(q), 'utf8');\n await rename(tmp, queuePath);\n}\n\nasync function enqueueBatches(\n projectRoot: string,\n batches: Array<{ upserts: MeilisearchDoc[]; deletes: string[] }>,\n): Promise<void> {\n const queuePath = join(projectRoot, FILESYSTEM_LAYOUT.project.queueFile);\n const existing = await readQueue(queuePath);\n const queuedAt = Date.now();\n for (const b of batches) {\n existing.push({ upserts: b.upserts, deletes: b.deletes, queuedAt });\n }\n await writeQueueAtomic(queuePath, existing);\n}\n","import { readFile } from 'node:fs/promises';\nimport type { SymbolSignature, UploadPayload } from '@macroscope/contracts';\nimport ts from 'typescript';\nimport type { ScannedBlock } from './scanner.js';\n\nconst DEFAULT_README_EXCERPT_MAX = 500;\n\n/** Source file extensions whose symbols we know how to extract. */\nconst TS_EXTENSIONS = new Set(['.ts', '.tsx', '.mts', '.cts']);\n\nexport interface ExtractorOptions {\n /** Cap on README excerpt characters. Default 500. */\n readmeExcerptMax?: number;\n /** Test seam — inject a TS Program factory. Defaults to the real ts.createProgram. */\n programFactory?: (sourceFiles: string[]) => ts.Program;\n}\n\nexport interface ExtractionError {\n blockId: string;\n kind: 'parse' | 'io' | 'symbol';\n message: string;\n}\n\nexport interface ExtractionResult {\n /** One payload per block that had a valid `kind` (the only required manifest field). */\n payloads: UploadPayload[];\n /** Errors collected during extraction. NEVER thrown — bad blocks are skipped. */\n errors: ExtractionError[];\n}\n\nconst DEFAULT_COMPILER_OPTIONS: ts.CompilerOptions = {\n target: ts.ScriptTarget.ES2022,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.Bundler,\n jsx: ts.JsxEmit.ReactJSX,\n allowJs: false,\n noEmit: true,\n skipLibCheck: true,\n esModuleInterop: true,\n allowSyntheticDefaultImports: true,\n strict: false,\n isolatedModules: true,\n};\n\nfunction defaultProgramFactory(rootFiles: string[]): ts.Program {\n return ts.createProgram(rootFiles, DEFAULT_COMPILER_OPTIONS);\n}\n\nexport async function extractAll(\n blocks: ScannedBlock[],\n opts: ExtractorOptions = {},\n): Promise<ExtractionResult> {\n const readmeMax = opts.readmeExcerptMax ?? DEFAULT_README_EXCERPT_MAX;\n const payloads: UploadPayload[] = [];\n const errors: ExtractionError[] = [];\n\n const sourcesToBlocks = new Map<string, ScannedBlock>();\n for (const block of blocks) {\n if (!block.manifest?.kind) continue;\n const src = block.resolvedPaths?.source;\n if (src && isTsSource(src)) {\n sourcesToBlocks.set(src, block);\n }\n }\n\n // Build one TS Program covering every TS source we'll extract from. This is\n // the difference between 100ms and 30s for a 100-block scan. We let TS load\n // transitive .d.ts files from node_modules for *type resolution* — without\n // them, signatureToString renders worse output — but we iterate ONLY the\n // root files when extracting symbols (see processBlock below).\n let program: ts.Program | undefined;\n let checker: ts.TypeChecker | undefined;\n if (sourcesToBlocks.size > 0) {\n const rootFiles = Array.from(sourcesToBlocks.keys());\n const factory = opts.programFactory ?? defaultProgramFactory;\n program = factory(rootFiles);\n checker = program.getTypeChecker();\n }\n\n for (const block of blocks) {\n if (!block.manifest?.kind) continue;\n\n const payload: UploadPayload = {\n blockId: block.id,\n kind: block.manifest.kind,\n symbols: [],\n };\n\n const { name, description, tags } = block.manifest;\n if (typeof name === 'string') payload.name = name;\n if (typeof description === 'string') payload.description = description;\n if (Array.isArray(tags)) payload.tags = tags;\n\n const sourcePath = block.resolvedPaths?.source;\n if (sourcePath && isTsSource(sourcePath) && program && checker) {\n const sourceFile = program.getSourceFile(sourcePath);\n if (!sourceFile) {\n errors.push({\n blockId: block.id,\n kind: 'parse',\n message: `TS Program did not load ${sourcePath} (parse error or missing file)`,\n });\n } else if (hasFatalSyntaxErrors(program, sourceFile)) {\n errors.push({\n blockId: block.id,\n kind: 'parse',\n message: `Source file ${sourcePath} has syntax errors; skipping symbol extraction`,\n });\n } else {\n payload.symbols = extractSymbols(sourceFile, checker);\n }\n }\n\n const docsPath = block.resolvedPaths?.docs;\n if (docsPath) {\n try {\n const raw = await readFile(docsPath, 'utf8');\n payload.readmeExcerpt = formatReadmeExcerpt(raw, readmeMax);\n } catch (err) {\n errors.push({\n blockId: block.id,\n kind: 'io',\n message: `Failed to read docs at ${docsPath}: ${(err as Error).message}`,\n });\n }\n }\n\n payloads.push(payload);\n }\n\n return { payloads, errors };\n}\n\nfunction isTsSource(path: string): boolean {\n const dot = path.lastIndexOf('.');\n if (dot < 0) return false;\n return TS_EXTENSIONS.has(path.slice(dot).toLowerCase());\n}\n\nfunction hasFatalSyntaxErrors(program: ts.Program, sourceFile: ts.SourceFile): boolean {\n const diagnostics = program.getSyntacticDiagnostics(sourceFile);\n return diagnostics.length > 0;\n}\n\nfunction extractSymbols(sourceFile: ts.SourceFile, checker: ts.TypeChecker): SymbolSignature[] {\n const symbols: SymbolSignature[] = [];\n\n for (const statement of sourceFile.statements) {\n visitTopLevel(statement, sourceFile, checker, symbols);\n }\n\n // Dedupe by (name, kind) — re-exports can otherwise show up twice if the\n // local file also names them.\n const seen = new Set<string>();\n return symbols.filter((s) => {\n const key = `${s.kind}\\0${s.name}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n}\n\nfunction visitTopLevel(\n node: ts.Node,\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n out: SymbolSignature[],\n): void {\n // `export default ...`\n if (ts.isExportAssignment(node)) {\n out.push(extractDefaultExport(node, sourceFile, checker));\n return;\n }\n\n // `export { foo, bar } [from './x']`\n if (ts.isExportDeclaration(node)) {\n extractExportDeclaration(node, sourceFile, checker, out);\n return;\n }\n\n if (!hasExportModifier(node)) return;\n\n const isDefault = hasDefaultModifier(node);\n\n if (ts.isFunctionDeclaration(node)) {\n const name = node.name?.text ?? (isDefault ? 'default' : undefined);\n if (!name) return;\n out.push({\n name,\n kind: 'function',\n signature: renderFunctionSignature(node, name, sourceFile, checker),\n });\n return;\n }\n\n if (ts.isClassDeclaration(node)) {\n const name = node.name?.text ?? (isDefault ? 'default' : undefined);\n if (!name) return;\n out.push({ name, kind: 'class', signature: `class ${name}` });\n return;\n }\n\n if (ts.isInterfaceDeclaration(node)) {\n out.push({\n name: node.name.text,\n kind: 'interface',\n signature: oneLineDeclaration(node, sourceFile, `interface ${node.name.text}`),\n });\n return;\n }\n\n if (ts.isTypeAliasDeclaration(node)) {\n out.push({\n name: node.name.text,\n kind: 'type',\n signature: oneLineDeclaration(node, sourceFile, `type ${node.name.text}`),\n });\n return;\n }\n\n if (ts.isEnumDeclaration(node)) {\n out.push({ name: node.name.text, kind: 'enum', signature: `enum ${node.name.text}` });\n return;\n }\n\n if (ts.isVariableStatement(node)) {\n for (const decl of node.declarationList.declarations) {\n if (!ts.isIdentifier(decl.name)) continue;\n const name = decl.name.text;\n out.push({\n name,\n kind: 'const',\n signature: renderVariableSignature(decl, name, checker),\n });\n }\n return;\n }\n}\n\nfunction extractDefaultExport(\n node: ts.ExportAssignment,\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): SymbolSignature {\n const expr = node.expression;\n if (ts.isIdentifier(expr)) {\n const sym = checker.getSymbolAtLocation(expr);\n const type = sym ? checker.getTypeOfSymbolAtLocation(sym, expr) : undefined;\n const signature = type ? checker.typeToString(type) : 'default';\n return { name: 'default', kind: 'const', signature };\n }\n return { name: 'default', kind: 'const', signature: expr.getText(sourceFile) };\n}\n\nfunction extractExportDeclaration(\n node: ts.ExportDeclaration,\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n out: SymbolSignature[],\n): void {\n // `export * from './other'` — expand via the type checker, if possible.\n if (!node.exportClause && node.moduleSpecifier) {\n const moduleSymbol = checker.getSymbolAtLocation(node.moduleSpecifier);\n if (moduleSymbol) {\n for (const exp of checker.getExportsOfModule(moduleSymbol)) {\n out.push(renderExportedSymbol(exp.name, exp, checker, sourceFile));\n }\n }\n return;\n }\n\n if (node.exportClause && ts.isNamedExports(node.exportClause)) {\n for (const spec of node.exportClause.elements) {\n const name = (spec.name as ts.Identifier).text;\n const sym = checker.getSymbolAtLocation(spec.name);\n out.push(renderExportedSymbol(name, sym, checker, sourceFile));\n }\n }\n}\n\nfunction renderExportedSymbol(\n name: string,\n symbol: ts.Symbol | undefined,\n checker: ts.TypeChecker,\n sourceFile: ts.SourceFile,\n): SymbolSignature {\n if (!symbol) return { name, kind: 'const', signature: name };\n const aliased =\n (symbol.flags & ts.SymbolFlags.Alias) !== 0 ? checker.getAliasedSymbol(symbol) : symbol;\n const decl = aliased.declarations?.[0];\n if (decl) {\n if (ts.isFunctionDeclaration(decl) || ts.isMethodDeclaration(decl)) {\n return {\n name,\n kind: 'function',\n signature: renderFunctionSignature(decl, name, sourceFile, checker),\n };\n }\n if (ts.isClassDeclaration(decl)) return { name, kind: 'class', signature: `class ${name}` };\n if (ts.isInterfaceDeclaration(decl)) {\n return {\n name,\n kind: 'interface',\n signature: oneLineDeclaration(decl, decl.getSourceFile(), `interface ${name}`),\n };\n }\n if (ts.isTypeAliasDeclaration(decl)) {\n return {\n name,\n kind: 'type',\n signature: oneLineDeclaration(decl, decl.getSourceFile(), `type ${name}`),\n };\n }\n if (ts.isEnumDeclaration(decl)) return { name, kind: 'enum', signature: `enum ${name}` };\n }\n const type = checker.getTypeOfSymbolAtLocation(aliased, sourceFile);\n return { name, kind: 'const', signature: checker.typeToString(type) };\n}\n\nfunction renderFunctionSignature(\n node: ts.FunctionDeclaration | ts.MethodDeclaration,\n name: string,\n _sourceFile: ts.SourceFile,\n checker: ts.TypeChecker,\n): string {\n const signature = checker.getSignatureFromDeclaration(node);\n if (!signature) return `function ${name}()`;\n return `function ${name}${checker.signatureToString(signature)}`;\n}\n\nfunction renderVariableSignature(\n decl: ts.VariableDeclaration,\n name: string,\n checker: ts.TypeChecker,\n): string {\n const type = checker.getTypeAtLocation(decl);\n return `const ${name}: ${checker.typeToString(type)}`;\n}\n\nfunction oneLineDeclaration(node: ts.Node, sourceFile: ts.SourceFile, fallback: string): string {\n try {\n const text = node.getText(sourceFile);\n const collapsed = text.replace(/\\s+/g, ' ').trim();\n return collapsed.length > 0 ? collapsed : fallback;\n } catch {\n return fallback;\n }\n}\n\nfunction hasExportModifier(node: ts.Node): boolean {\n return (ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Export) !== 0;\n}\n\nfunction hasDefaultModifier(node: ts.Node): boolean {\n return (ts.getCombinedModifierFlags(node as ts.Declaration) & ts.ModifierFlags.Default) !== 0;\n}\n\n/**\n * Turn raw markdown/text into a bounded excerpt safe for embedding similarity:\n * collapse whitespace, strip the markdown formatting that confuses semantic search\n * (`#`, `*`, backticks), and truncate at a word boundary.\n */\nexport function formatReadmeExcerpt(raw: string, max: number): string {\n // Strip formatting characters that distort embedding similarity but keep the words.\n const stripped = raw.replace(/[#*`_~>]/g, '');\n // Collapse runs of any whitespace (incl. newlines/tabs) to single spaces.\n const collapsed = stripped.replace(/\\s+/g, ' ').trim();\n if (collapsed.length <= max) return collapsed;\n\n // Word-boundary truncate: keep the slice if it already ends on a word boundary\n // (i.e. the next char is whitespace), otherwise step back to the last space so\n // we don't break mid-word.\n const slice = collapsed.slice(0, max);\n const nextChar = collapsed.charAt(max);\n if (nextChar === '' || /\\s/.test(nextChar)) return slice;\n const lastSpace = slice.lastIndexOf(' ');\n if (lastSpace > 0) return slice.slice(0, lastSpace);\n return slice;\n}\n","import { createHash } from 'node:crypto';\nimport { mkdir, readFile, rename, stat, writeFile } from 'node:fs/promises';\nimport { dirname, join } from 'node:path';\nimport { FILESYSTEM_LAYOUT, SCHEMA_VERSION, type UploadPayload } from '@macroscope/contracts';\nimport type { ScannedBlock } from './scanner.js';\n\n/**\n * T6 — content hasher + local cache.\n *\n * Substrate for the watcher (T14) and catch-up scan (T15): a deterministic\n * SHA-256 over the UploadPayload, plus a small on-disk cache keyed by blockId.\n *\n * DO NOT change the canonical-JSON algorithm without bumping a cache schema\n * version. Doing so silently invalidates every user's local hash cache AND\n * orphans every `contentHash` on cloud-side MeilisearchDoc records. The\n * fixed-vector test in `test/hasher.test.ts` pins the algorithm.\n */\n\n/**\n * Canonicalise a JSON-serialisable value into a deterministic string.\n *\n * Rules (wire-locked — see hasher.test.ts):\n * - Object keys sorted in code-unit (UTF-16) order, recursively.\n * - Keys with `undefined` values are omitted entirely.\n * - Arrays preserve insertion order.\n * - Strings are NFC-normalised before serialisation so composed vs\n * decomposed unicode produce the same byte output.\n * - Standard JSON escapes only (`\"`, `\\\\`, control chars). Non-ASCII\n * codepoints are emitted raw as UTF-8 — we rely on V8's RFC-8259\n * behaviour for `JSON.stringify` to do this for us.\n *\n * @internal Exposed for direct test access only; not part of the public API.\n * Public callers should use {@link hashPayload}. The canonical form is an\n * implementation detail of the hash and may move under a different name\n * without a major version bump.\n */\nexport function canonicalJSON(value: unknown): string {\n return stringify(value);\n}\n\nfunction stringify(value: unknown): string {\n if (value === null) return 'null';\n if (typeof value === 'string') return JSON.stringify(value.normalize('NFC'));\n if (typeof value === 'number' || typeof value === 'boolean') return JSON.stringify(value);\n if (Array.isArray(value)) {\n const parts = value.map((v) => (v === undefined ? 'null' : stringify(v)));\n return `[${parts.join(',')}]`;\n }\n if (typeof value === 'object') {\n const obj = value as Record<string, unknown>;\n const keys = Object.keys(obj)\n .filter((k) => obj[k] !== undefined)\n .sort();\n const parts = keys.map((k) => `${JSON.stringify(k)}:${stringify(obj[k])}`);\n return `{${parts.join(',')}}`;\n }\n // undefined / function / symbol — UploadPayloadSchema rules these out, so\n // throw loudly if one shows up so tests catch it.\n throw new TypeError(`canonicalJSON: unsupported value type ${typeof value}`);\n}\n\n/**\n * Deterministic SHA-256 over the canonical-JSON serialisation of the payload.\n * Returns 64-character lowercase hex.\n */\nexport function hashPayload(payload: UploadPayload): string {\n const canonical = canonicalJSON(payload);\n return createHash('sha256').update(canonical, 'utf8').digest('hex');\n}\n\nexport interface HasherOptions {\n /** Override the workspace root for tests. Defaults to `process.cwd()`. */\n workspaceRoot?: string;\n}\n\nexport interface CacheEntry {\n /** SHA-256 hex of the canonical-JSON serialisation of the UploadPayload. */\n hash: string;\n /** Max(mtime ms) of the block's manifest + source + docs at hash time. */\n mtime: number;\n}\n\nexport type HashCache = Record<string, CacheEntry>;\n\n/**\n * On-disk envelope. Written as `{ schemaVersion, entries }` from T15 onward;\n * older deployments wrote the bare `HashCache` object. Both shapes are read\n * back into a `HashCache` by {@link loadHashCache}. T15's\n * {@link readSchemaVersion} returns `undefined` for the old flat shape, which\n * the catch-up scan treats as a schema mismatch (forced full re-push).\n */\ninterface HashCacheFile {\n schemaVersion: number;\n entries: HashCache;\n}\n\nfunction resolveHashesPath(opts?: HasherOptions): string {\n const root = opts?.workspaceRoot ?? process.cwd();\n return join(root, FILESYSTEM_LAYOUT.project.hashesFile);\n}\n\nasync function readCacheFile(\n opts?: HasherOptions,\n): Promise<{ schemaVersion: number | undefined; entries: HashCache } | null> {\n const path = resolveHashesPath(opts);\n let raw: string;\n try {\n raw = await readFile(path, 'utf8');\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT') {\n console.warn(`[macroscope] failed to read hash cache at ${path}: ${(err as Error).message}`);\n }\n return null;\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (err) {\n console.warn(`[macroscope] hash cache at ${path} is not valid JSON: ${(err as Error).message}`);\n return null;\n }\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {\n console.warn(`[macroscope] hash cache at ${path} has unexpected shape; ignoring`);\n return null;\n }\n const obj = parsed as Record<string, unknown>;\n // Wrapped format detection: top-level `schemaVersion` (number) AND `entries`\n // (object). Anything else is the old flat shape that T6/T14 originally wrote.\n if (\n typeof obj.schemaVersion === 'number' &&\n obj.entries &&\n typeof obj.entries === 'object' &&\n !Array.isArray(obj.entries)\n ) {\n return { schemaVersion: obj.schemaVersion, entries: obj.entries as HashCache };\n }\n return { schemaVersion: undefined, entries: obj as HashCache };\n}\n\n/**\n * Load the cache from disk. NEVER throws: missing file or malformed JSON\n * return `{}` so the watcher can recover by re-hashing everything. Transparently\n * handles both the wrapped `{ schemaVersion, entries }` shape and the legacy\n * flat shape, returning entries either way.\n */\nexport async function loadHashCache(opts?: HasherOptions): Promise<HashCache> {\n const file = await readCacheFile(opts);\n return file?.entries ?? {};\n}\n\n/**\n * Read the persisted schemaVersion. Returns `undefined` for a missing file,\n * malformed JSON, or the legacy flat shape — all of which T15 treats as a\n * schema mismatch (forces a full re-push). Used by the catch-up scan.\n */\nexport async function readSchemaVersion(opts?: HasherOptions): Promise<number | undefined> {\n const file = await readCacheFile(opts);\n return file?.schemaVersion;\n}\n\n/**\n * Atomically write the cache to disk: write to a sibling `.tmp` file then\n * rename. Same-directory rename is atomic on POSIX filesystems. Throws on\n * real I/O failure — callers (watcher loop) decide whether to surface or\n * swallow the error.\n *\n * The on-disk shape is the wrapped envelope (`schemaVersion` + `entries`);\n * `schemaVersion` defaults to the current `SCHEMA_VERSION` from\n * `@macroscope/contracts` so T14's existing callsites transparently persist it.\n */\nexport async function saveHashCache(\n cache: HashCache,\n opts?: HasherOptions & { schemaVersion?: number },\n): Promise<void> {\n const path = resolveHashesPath(opts);\n const dir = dirname(path);\n await mkdir(dir, { recursive: true });\n const tmp = `${path}.tmp`;\n const envelope: HashCacheFile = {\n schemaVersion: opts?.schemaVersion ?? SCHEMA_VERSION,\n entries: cache,\n };\n const body = `${JSON.stringify(envelope, null, 2)}\\n`;\n await writeFile(tmp, body, 'utf8');\n await rename(tmp, path);\n}\n\n/**\n * Return the subset of blocks whose manifest, source, or docs files have an\n * mtime strictly greater than the cached entry's recorded mtime. Blocks\n * with no cache entry are always returned (first-time extraction needs them).\n *\n * Missing files (e.g. deleted between scan and stat) are treated as \"changed\"\n * — safer to re-process than silently drop. The watcher reconciles deletions\n * separately via \"in cache but not in scan\" diffing.\n */\nexport async function filterChangedBlocks(\n blocks: ScannedBlock[],\n cache: HashCache,\n): Promise<ScannedBlock[]> {\n const changed: ScannedBlock[] = [];\n for (const block of blocks) {\n const cached = cache[block.id];\n if (!cached) {\n changed.push(block);\n continue;\n }\n const maxMtime = await maxFileMtime(block);\n if (maxMtime === undefined || maxMtime > cached.mtime) {\n changed.push(block);\n }\n }\n return changed;\n}\n\nasync function maxFileMtime(block: ScannedBlock): Promise<number | undefined> {\n const paths: string[] = [join(block.path, 'macroscope.yaml')];\n if (block.resolvedPaths?.source) paths.push(block.resolvedPaths.source);\n if (block.resolvedPaths?.docs) paths.push(block.resolvedPaths.docs);\n\n let max: number | undefined;\n for (const p of paths) {\n try {\n const s = await stat(p);\n const m = s.mtimeMs;\n if (max === undefined || m > max) max = m;\n } catch {\n return undefined;\n }\n }\n return max;\n}\n","/**\n * Repo identity for cloud-pushed docs. Per ARCHITECTURE.md: `repo` is the\n * normalised Git remote URL or — when no remote exists — the worktree's\n * directory basename. Sent on every MeilisearchDoc; pairs with `worktreeId`\n * to form the composite primary key.\n *\n * Pure derivation; no caching, no side effects beyond reading git config.\n */\nimport { execFile as execFileCb } from 'node:child_process';\nimport { basename } from 'node:path';\nimport { promisify } from 'node:util';\n\nconst execFile = promisify(execFileCb);\n\nexport class NotAGitRepoError extends Error {\n constructor(path: string) {\n super(\n `Not a git repository: ${path}. The watcher needs a git working tree to derive a repo identity.`,\n );\n this.name = 'NotAGitRepoError';\n }\n}\n\n/**\n * Canonicalise a git remote URL. Examples (locked by repo-id.test.ts):\n *\n * git@github.com:alexspdlr/macroscope.git → github.com/alexspdlr/macroscope\n * https://github.com/alexspdlr/macroscope.git → github.com/alexspdlr/macroscope\n * ssh://git@github.com/alexspdlr/macroscope.git → github.com/alexspdlr/macroscope\n * GIT@GITHUB.COM:alexspdlr/macroscope.git → github.com/alexspdlr/macroscope\n */\nexport function normalizeRemoteUrl(url: string): string {\n let s = url.trim();\n // Lowercase the host portion only after stripping schemes; safest is to\n // lowercase the whole thing because remote URLs are case-insensitive in\n // every form we support (host, scheme, \"git@\" prefix).\n s = s.toLowerCase();\n\n // Strip explicit schemes.\n s = s.replace(/^ssh:\\/\\//, '');\n s = s.replace(/^https?:\\/\\//, '');\n s = s.replace(/^git:\\/\\//, '');\n\n // Strip \"git@\" (or \"<user>@\") prefix used by SCP-style ssh URLs.\n s = s.replace(/^[a-z0-9._-]+@/, '');\n\n // SCP-style separates host from path with a colon; convert to slash.\n // Only the FIRST colon — subsequent path segments shouldn't have colons.\n s = s.replace(':', '/');\n\n // Strip trailing \".git\".\n s = s.replace(/\\.git$/, '');\n\n // Strip trailing slashes.\n s = s.replace(/\\/+$/, '');\n\n return s;\n}\n\n/**\n * Derive `repo` for the given worktree path.\n * 1. Try `git config --get remote.origin.url` → normalise and return.\n * 2. If no remote (git config exits non-zero or empty), return basename(path).\n * 3. If the path is not a git repo at all, throw NotAGitRepoError.\n */\nexport async function deriveRepoId(absolutePath: string): Promise<string> {\n // First confirm this is a git repo. `rev-parse --git-dir` exits 0 inside a\n // working tree (or .git dir) and non-zero otherwise.\n try {\n await execFile('git', ['-C', absolutePath, 'rev-parse', '--git-dir']);\n } catch {\n throw new NotAGitRepoError(absolutePath);\n }\n\n try {\n const { stdout } = await execFile('git', [\n '-C',\n absolutePath,\n 'config',\n '--get',\n 'remote.origin.url',\n ]);\n const url = stdout.trim();\n if (url) return normalizeRemoteUrl(url);\n } catch {\n // git config exits 1 when the key is missing — fall through to basename.\n }\n return basename(absolutePath);\n}\n","/**\n * T14 — Watcher: the only writer into the cloud catalogue.\n *\n * Observes the working tree, debounces filesystem events, computes the\n * UploadPayload + contentHash for each changed block, and pushes via the\n * CloudClient. On cloud-unreachable / 5xx, batches are queued to disk and\n * drained on next successful push. SIGINT/SIGTERM/SIGHUP/stdin-EOF cleanly\n * drain in-flight work via `installLifecycle`.\n *\n * Identity is computed once at startup and cached for the watcher's\n * lifetime: (machineUuid, worktreeId, repo). The composite Meilisearch\n * primary key (`composeDocId`) mirrors `packages/api/src/meili.ts` — fixed\n * by a vector test; DO NOT diverge.\n */\nimport { createHash } from 'node:crypto';\nimport { EventEmitter } from 'node:events';\nimport { mkdir, readFile, rename, writeFile } from 'node:fs/promises';\nimport { dirname, join, relative, sep } from 'node:path';\nimport { FILESYSTEM_LAYOUT, type MeilisearchDoc } from '@macroscope/contracts';\nimport chokidar from 'chokidar';\nimport type { CloudClient, Result } from '../cloud/client.js';\nimport { extractAll } from '../core/extractor.js';\nimport {\n type HashCache,\n filterChangedBlocks,\n hashPayload,\n loadHashCache,\n saveHashCache,\n} from '../core/hasher.js';\nimport { findProject } from '../core/project.js';\nimport { type ScannedBlock, scan } from '../core/scanner.js';\nimport { type LifecycleOptions, installLifecycle } from '../util/lifecycle.js';\nimport { deriveRepoId } from './repo-id.js';\nimport { deriveWorktreeId, getOrCreateMachineUuid } from './worktree-id.js';\n\n/**\n * Composite Meilisearch document id. MUST match\n * `packages/api/src/meili.ts:composeDocId` byte-for-byte — the server uses\n * this as its primary key; if the watcher's delete strings drift, deletes\n * silently no-op cloud-side. Both sides hash the natural composite\n * `${repo}:${worktreeId}:${blockId}` with SHA-256 because Meilisearch\n * primary keys allow ONLY `[a-zA-Z0-9_-]`. Pinned by `composeDocId fixed\n * vector` test below + the matching fixed-vector test in T13a.\n */\nexport const composeDocId = (repo: string, worktreeId: string, blockId: string): string =>\n createHash('sha256').update(`${repo}:${worktreeId}:${blockId}`).digest('hex');\n\n/** Minimal chokidar surface the watcher uses. Lets tests inject a stub. */\nexport interface FsWatcher {\n on(event: string, cb: (...args: unknown[]) => void): this;\n add(paths: string | string[]): this;\n close(): Promise<void>;\n}\n\nexport interface WatcherProgressEvents {\n batchStart: { pendingUpserts: number; pendingDeletes: number };\n batchSent: { accepted: number; deleted: number; durationMs: number };\n error: { err: Error; retryable: boolean };\n queueDrained: { drained: number };\n}\n\ntype EventName = keyof WatcherProgressEvents;\n\nexport interface WatcherHandle {\n /** Idempotent. Resolves when in-flight batches drain (or 30s timeout). */\n stop(): Promise<void>;\n /** Subscribe to progress events. Returns an unsubscribe fn. */\n on<E extends EventName>(event: E, cb: (payload: WatcherProgressEvents[E]) => void): () => void;\n}\n\nexport interface WatcherOptions {\n projectRoot: string;\n cloudClient: CloudClient;\n /** Debounce window for batching filesystem events. Default 500ms. */\n debounceMs?: number;\n /**\n * How often, while a queued backlog exists, to retry draining it without\n * waiting for a filesystem event. This is what makes a cloud that recovered\n * while the user is idle drain on its own (ARCHITECTURE.md \"Cloud-unreachable\n * mode\": queue locally, drain on reconnect). Default 5000ms.\n */\n queueRetryMs?: number;\n /** Test seam — inject chokidar. */\n watcherFactory?: (paths: string[]) => FsWatcher;\n /** Test seam — overrides homedir (forwarded to getOrCreateMachineUuid). */\n homeDir?: string;\n /**\n * Lifecycle wiring. `false` skips auto-install (caller owns shutdown).\n * Otherwise these opts forward to `installLifecycle`; `onShutdown` is\n * always set to `handle.stop()`.\n */\n lifecycle?: false | Omit<LifecycleOptions, 'onShutdown'>;\n}\n\n/** Queue file format. NEVER change without adding a version field. */\ninterface QueuedBatch {\n upserts: MeilisearchDoc[];\n deletes: string[];\n queuedAt: number;\n}\n\n/** Cap on queue file size — drop oldest entries beyond this. */\nconst QUEUE_MAX_BYTES = 1_048_576; // 1 MB\n\n/** Hard timeout for stop() to wait for in-flight batches. */\nconst STOP_DRAIN_TIMEOUT_MS = 30_000;\n\n/**\n * How long startWatcher waits for chokidar's `ready` event before giving up\n * and proceeding anyway. On macOS (FSEvents) ready fires in single-digit ms;\n * on Linux (inotify) over a deep tree it can take longer — generous fallback\n * keeps the watcher functional if `ready` is somehow never emitted, while a\n * real ready (which is almost immediate) short-circuits the wait.\n */\nconst READY_TIMEOUT_MS = 10_000;\n\nconst isRetryable = (r: Result<unknown>): boolean => {\n if (r.kind !== 'error') return false;\n if (r.status >= 500 && r.status <= 599) return true;\n if (r.status === 0 && r.envelope.error.code === 'not_logged_in') return false;\n if (r.envelope.error.code === 'upstream_unreachable') return true;\n return false;\n};\n\nconst toPosix = (p: string): string => p.split(sep).join('/');\n\nexport async function startWatcher(opts: WatcherOptions): Promise<WatcherHandle> {\n const debounceMs = opts.debounceMs ?? 500;\n const queueRetryMs = opts.queueRetryMs ?? 5_000;\n const project = await findProject(opts.projectRoot);\n const machineUuid = await getOrCreateMachineUuid({ homeDir: opts.homeDir });\n const worktreeId = deriveWorktreeId(machineUuid, project.root);\n const repo = await deriveRepoId(project.root);\n\n const queuePath = join(project.root, FILESYSTEM_LAYOUT.project.queueFile);\n const emitter = new EventEmitter();\n\n let stopping = false;\n let stopped = false;\n let flushTimer: ReturnType<typeof setTimeout> | null = null;\n let inFlight: Promise<void> | null = null;\n let retryTimer: ReturnType<typeof setInterval> | null = null;\n\n /* -------------------------- queue persistence ------------------------- */\n\n async function readQueue(): Promise<QueuedBatch[]> {\n try {\n const raw = await readFile(queuePath, 'utf8');\n const parsed = JSON.parse(raw) as unknown;\n if (Array.isArray(parsed)) return parsed as QueuedBatch[];\n return [];\n } catch (err) {\n if ((err as NodeJS.ErrnoException).code === 'ENOENT') return [];\n return [];\n }\n }\n\n async function writeQueue(q: QueuedBatch[]): Promise<void> {\n await mkdir(dirname(queuePath), { recursive: true });\n const tmp = `${queuePath}.tmp`;\n let body = JSON.stringify(q);\n // Defend against pathological growth: drop oldest entries until under cap.\n while (Buffer.byteLength(body, 'utf8') > QUEUE_MAX_BYTES && q.length > 0) {\n q.shift();\n body = JSON.stringify(q);\n // Surface the drop loudly — losing pushes is silent data loss otherwise.\n console.warn(\n `[macroscope] watcher queue exceeded ${QUEUE_MAX_BYTES} bytes; dropping oldest entry`,\n );\n }\n await writeFile(tmp, body, 'utf8');\n await rename(tmp, queuePath);\n }\n\n async function enqueueBatch(batch: Omit<QueuedBatch, 'queuedAt'>): Promise<void> {\n const q = await readQueue();\n q.push({ ...batch, queuedAt: Date.now() });\n await writeQueue(q);\n }\n\n /**\n * Drain the on-disk queue, oldest first. Stops on the first retryable\n * failure and leaves the remaining entries in place for next time.\n */\n async function drainQueue(): Promise<{ drained: number }> {\n const q = await readQueue();\n if (q.length === 0) return { drained: 0 };\n let drained = 0;\n while (q.length > 0) {\n const next = q[0];\n const res = await opts.cloudClient.indexBatch({\n upserts: next.upserts,\n deletes: next.deletes,\n });\n if (res.kind === 'ok') {\n q.shift();\n drained += 1;\n continue;\n }\n if (isRetryable(res)) break;\n // Non-retryable: drop the entry to avoid an infinite poison-queue loop.\n q.shift();\n drained += 1;\n emitter.emit('error', {\n err: new Error(res.envelope.error.message),\n retryable: false,\n });\n }\n await writeQueue(q);\n if (drained > 0) emitter.emit('queueDrained', { drained });\n return { drained };\n }\n\n /* ----------------------------- flush ---------------------------------- */\n\n async function flush(): Promise<void> {\n flushTimer = null;\n if (stopping) return;\n\n const start = Date.now();\n const scanResult = await scan(project);\n const cache = await loadHashCache({ workspaceRoot: project.root });\n const changedBlocks = await filterChangedBlocks(scanResult.blocks, cache);\n const { payloads } = await extractAll(changedBlocks);\n const payloadById = new Map(payloads.map((p) => [p.blockId, p]));\n const blockById = new Map<string, ScannedBlock>(scanResult.blocks.map((b) => [b.id, b]));\n\n const upserts: MeilisearchDoc[] = [];\n const newCache: HashCache = { ...cache };\n const now = Date.now();\n\n for (const block of changedBlocks) {\n const payload = payloadById.get(block.id);\n if (!payload) continue; // block with no `kind` — skipped by extractor\n const contentHash = hashPayload(payload);\n const doc: MeilisearchDoc = {\n ...payload,\n contentHash,\n repo,\n worktreeId,\n path: toPosix(relative(project.root, block.path)),\n lastActiveAt: now,\n };\n upserts.push(doc);\n newCache[block.id] = { hash: contentHash, mtime: now };\n }\n\n // Deletes: blockIds present in the cache but absent from the current scan.\n const currentIds = new Set(scanResult.blocks.map((b) => b.id));\n const deletes: string[] = [];\n for (const id of Object.keys(cache)) {\n if (currentIds.has(id)) continue;\n deletes.push(composeDocId(repo, worktreeId, id));\n delete newCache[id];\n }\n\n if (upserts.length === 0 && deletes.length === 0) {\n // Still try to drain any queued backlog even when nothing changed locally.\n await drainQueue();\n return;\n }\n\n emitter.emit('batchStart', {\n pendingUpserts: upserts.length,\n pendingDeletes: deletes.length,\n });\n\n // Drain any prior backlog first; if it can't drain (still retryable\n // failure), enqueue the new batch behind it so order is preserved.\n const drainBefore = await readQueue();\n if (drainBefore.length > 0) {\n await drainQueue();\n }\n\n const res = await opts.cloudClient.indexBatch({ upserts, deletes });\n if (res.kind === 'ok') {\n await saveHashCache(newCache, { workspaceRoot: project.root });\n emitter.emit('batchSent', {\n accepted: res.data.accepted,\n deleted: deletes.length,\n durationMs: Date.now() - start,\n });\n // Drain again in case the queue grew while we were pushing.\n await drainQueue();\n return;\n }\n\n if (isRetryable(res)) {\n await enqueueBatch({ upserts, deletes });\n // The backlog now needs to go out on reconnect even if the user stops\n // editing — start the periodic retry (no-op if already running).\n ensureQueueRetry();\n emitter.emit('error', {\n err: new Error(res.envelope.error.message),\n retryable: true,\n });\n return;\n }\n\n emitter.emit('error', {\n err: new Error(res.envelope.error.message),\n retryable: false,\n });\n }\n\n function scheduleFlush(): void {\n if (stopping) return;\n if (flushTimer) clearTimeout(flushTimer);\n flushTimer = setTimeout(() => {\n inFlight = flush()\n .catch((err: unknown) => {\n emitter.emit('error', {\n err: err instanceof Error ? err : new Error(String(err)),\n retryable: false,\n });\n })\n .finally(() => {\n inFlight = null;\n });\n }, debounceMs);\n }\n\n /* -------------------------- queue retry timer ------------------------- */\n\n function clearQueueRetry(): void {\n if (retryTimer) {\n clearInterval(retryTimer);\n retryTimer = null;\n }\n }\n\n /**\n * Start the periodic backlog-drain retry, if not already running. Each tick\n * nudges the normal `scheduleFlush()` path rather than draining directly —\n * that keeps ALL draining on the single serialized flush path (no new\n * concurrency to reason about) and a no-local-change flush short-circuits\n * straight to `drainQueue()`. The timer self-clears once the queue is empty,\n * so it never busy-loops when there's nothing to send. `unref` so it never\n * keeps the process alive on its own.\n */\n function ensureQueueRetry(): void {\n if (retryTimer || stopping) return;\n retryTimer = setInterval(() => {\n void (async () => {\n if (stopping) {\n clearQueueRetry();\n return;\n }\n if ((await readQueue()).length === 0) {\n clearQueueRetry();\n return;\n }\n scheduleFlush();\n })();\n }, queueRetryMs);\n if (typeof retryTimer.unref === 'function') retryTimer.unref();\n }\n\n /* ----------------------------- chokidar ------------------------------ */\n\n const factory =\n opts.watcherFactory ??\n ((paths) =>\n chokidar.watch(paths, {\n ignoreInitial: true,\n awaitWriteFinish: { stabilityThreshold: 100, pollInterval: 50 },\n ignored: (p: string) =>\n /(^|[/\\\\])(node_modules|\\.git|dist)([/\\\\]|$)/.test(p) ||\n /([/\\\\])\\.macroscope[/\\\\]cache([/\\\\]|$)/.test(p),\n }) as unknown as FsWatcher);\n\n // Watch the whole project root. Per ARCHITECTURE.md the watcher's job is to\n // notice any block-relevant change (manifest, source, docs, tests). Block\n // manifests live anywhere under the project — narrowing the watch set to\n // `.macroscope/blueprints/` would miss them. The scan-and-diff inside\n // `flush()` is the real filter; the watcher is just an event source.\n const fsWatcher = factory([project.root]);\n for (const event of ['add', 'change', 'unlink', 'addDir', 'unlinkDir']) {\n fsWatcher.on(event, () => scheduleFlush());\n }\n fsWatcher.on('error', (err: unknown) => {\n emitter.emit('error', {\n err: err instanceof Error ? err : new Error(String(err)),\n retryable: false,\n });\n });\n\n // Wait for chokidar's `ready` event — on Linux (inotify) the watcher is not\n // observing the tree until ready fires; returning the handle before then\n // races against callers that immediately write/modify files. macOS hides\n // this with FSEvents being effectively synchronous. We also race against a\n // generous timeout so a stuck `ready` (or a stub that never emits one)\n // doesn't deadlock startup. Listener attaches BEFORE the await so microtask\n // emits from stubs are caught.\n await new Promise<void>((resolve) => {\n let settled = false;\n const settle = (): void => {\n if (settled) return;\n settled = true;\n resolve();\n };\n fsWatcher.on('ready', settle);\n const t = setTimeout(settle, READY_TIMEOUT_MS);\n if (typeof t.unref === 'function') t.unref();\n });\n\n // Try draining the queue at startup so a previous session's backlog goes out\n // immediately, not on first event.\n await drainQueue().catch((err: unknown) => {\n emitter.emit('error', {\n err: err instanceof Error ? err : new Error(String(err)),\n retryable: false,\n });\n });\n // If the cloud was still unreachable at boot, the backlog survives the\n // startup drain — keep retrying it on the timer so it drains on reconnect\n // even if no filesystem event ever follows.\n if ((await readQueue()).length > 0) ensureQueueRetry();\n\n /* ----------------------------- handle -------------------------------- */\n\n async function stop(): Promise<void> {\n if (stopped) return;\n stopping = true;\n if (flushTimer) {\n clearTimeout(flushTimer);\n flushTimer = null;\n }\n clearQueueRetry();\n try {\n await fsWatcher.close();\n } catch {\n // Best-effort.\n }\n if (inFlight) {\n const timeout = new Promise<void>((resolve) => {\n const t = setTimeout(() => {\n console.warn(\n `[macroscope] watcher stop: in-flight batch did not settle within ${STOP_DRAIN_TIMEOUT_MS}ms — giving up`,\n );\n resolve();\n }, STOP_DRAIN_TIMEOUT_MS);\n if (typeof t.unref === 'function') t.unref();\n });\n await Promise.race([inFlight, timeout]);\n }\n stopped = true;\n }\n\n const handle: WatcherHandle = {\n stop,\n on(event, cb) {\n const wrapped = (payload: unknown) => cb(payload as never);\n emitter.on(event, wrapped);\n return () => emitter.off(event, wrapped);\n },\n };\n\n if (opts.lifecycle !== false) {\n installLifecycle({\n ...(opts.lifecycle ?? {}),\n onShutdown: () => handle.stop(),\n });\n }\n\n return handle;\n}\n","/**\n * worktree_id derivation — DO NOT CHANGE.\n *\n * `worktree_id = sha256(machineUuid + \":\" + absolutePath).hex.slice(0, 32)`\n *\n * Changing the input format, hash algorithm, or slice length silently orphans\n * every existing user's pushed docs (their next push lands under a new id while\n * their old docs sit unreachable until the 30-day sweep). The fixed-vector\n * test in `test/local/worktree-id.test.ts` pins this contract.\n *\n * machineUuid is a random UUID generated on first run and persisted at\n * `~/.macroscope/machine-id` (mode 0600). The raw UUID never leaves the\n * machine; only the derived worktreeId is sent to the cloud.\n *\n * Per ARCHITECTURE.md \"Watcher\": if `~/.macroscope/` is wiped, a new UUID is\n * generated and worktrees on this machine are treated as new; previous scopes\n * orphan and are GC'd by the 30-day sweep. This is expected behaviour.\n */\nimport { createHash, randomUUID } from 'node:crypto';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { dirname, join } from 'node:path';\nimport { FILESYSTEM_LAYOUT } from '@macroscope/contracts';\n\nexport interface WorktreeIdOptions {\n /** Override `~`. Tests use a tmpdir. */\n homeDir?: string;\n}\n\n/**\n * Deterministic: same (machineUuid, absolutePath) → same worktreeId. NEVER changes.\n * DO NOT CHANGE the formula — see file header.\n */\nexport function deriveWorktreeId(machineUuid: string, absolutePath: string): string {\n return createHash('sha256').update(`${machineUuid}:${absolutePath}`).digest('hex').slice(0, 32);\n}\n\n/**\n * Reads or creates `~/.macroscope/machine-id`. Persisted; same value on subsequent calls.\n */\nexport async function getOrCreateMachineUuid(opts?: WorktreeIdOptions): Promise<string> {\n const home = opts?.homeDir ?? homedir();\n const path = join(home, FILESYSTEM_LAYOUT.user.machineIdFile);\n try {\n const raw = await readFile(path, 'utf8');\n const trimmed = raw.trim();\n if (trimmed) return trimmed;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException).code;\n if (code !== 'ENOENT') throw err;\n }\n const uuid = randomUUID();\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, `${uuid}\\n`, { encoding: 'utf8', mode: 0o600 });\n return uuid;\n}\n","import { type LoadedBlueprint, loadBlueprints } from '../../core/blueprints.js';\nimport type { Block, Handler, ServiceSpec } from '../../core/handler.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\nimport { type ScannedBlock, scan } from '../../core/scanner.js';\n\nexport interface BlocksResponse {\n status: 200 | 404 | 500;\n body: unknown;\n}\n\nexport type ResolvedView =\n | { type: 'iframe'; key: string; label: string; url: string; service: ServiceMeta | null }\n | { type: 'terminal'; key: string; label: string }\n | {\n type: 'hybrid';\n key: string;\n label: string;\n url: string;\n runLabel: string;\n codeLabel: string;\n terminalLabel: string;\n };\n\nexport interface ServiceMeta {\n /** Display name for the loading UI. Defaults to command[0]. */\n name: string;\n}\n\n/** Per-resolver timeout. Plan-eng-review P1 fix. */\nexport const URL_RESOLVE_TIMEOUT_MS = 5000;\n\nexport async function handleBlocksRequest(cwd: string): Promise<BlocksResponse> {\n try {\n const project = await findProject(cwd);\n const [scanResult, blueprintResult] = await Promise.all([\n scan(project),\n loadBlueprints(project),\n ]);\n const byKind = new Map<string, LoadedBlueprint>();\n for (const bp of blueprintResult.blueprints) byKind.set(bp.kind, bp);\n\n const blocks = await Promise.all(\n scanResult.blocks.map(async (block) => ({\n id: block.id,\n path: block.path,\n manifest: block.manifest,\n contentHash: block.contentHash,\n views: await resolveViewsWithTimeout(\n block,\n byKind.get(block.manifest.kind)?.handler,\n URL_RESOLVE_TIMEOUT_MS,\n ),\n })),\n );\n\n return {\n status: 200,\n body: {\n blocks,\n errors: scanResult.errors,\n blueprintErrors: blueprintResult.errors,\n },\n };\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n return { status: 404, body: { error: err.message } };\n }\n return { status: 500, body: { error: (err as Error).message } };\n }\n}\n\nexport async function resolveViewsWithTimeout(\n block: ScannedBlock | Block,\n handler: Handler | undefined,\n timeoutMs = URL_RESOLVE_TIMEOUT_MS,\n): Promise<ResolvedView[]> {\n if (!handler?.views) return [];\n const blockInput: Block = { id: block.id, path: block.path, manifest: block.manifest };\n const resolved: ResolvedView[] = [];\n for (const [key, spec] of Object.entries(handler.views)) {\n if (spec.type === 'iframe') {\n const service: ServiceMeta | null = spec.service\n ? { name: spec.service.name ?? firstArg(spec.service.command) }\n : null;\n if (typeof spec.url === 'string') {\n resolved.push({ type: 'iframe', key, label: titleize(key), url: spec.url, service });\n continue;\n }\n try {\n const url = await withTimeout(spec.url(blockInput), timeoutMs);\n if (typeof url !== 'string') continue;\n resolved.push({ type: 'iframe', key, label: titleize(key), url, service });\n } catch {\n // Resolver threw OR timed out. Skip this view; block still loads.\n }\n } else if (spec.type === 'terminal') {\n // Terminal commands resolve lazily when the WebSocket opens. The /api/blocks\n // response only carries the view descriptor; the actual command runs server-side\n // when the user clicks the tab.\n resolved.push({ type: 'terminal', key, label: titleize(key) });\n } else if (spec.type === 'hybrid') {\n // Like iframe + terminal combined. The URL is resolved now; the command\n // resolves lazily via the same WebSocket flow as a terminal view.\n const runLabel = spec.runLabel ?? 'Run';\n const codeLabel = spec.codeLabel ?? 'Code';\n const terminalLabel = spec.terminalLabel ?? 'Terminal';\n if (typeof spec.url === 'string') {\n resolved.push({\n type: 'hybrid',\n key,\n label: titleize(key),\n url: spec.url,\n runLabel,\n codeLabel,\n terminalLabel,\n });\n continue;\n }\n try {\n const url = await withTimeout(spec.url(blockInput), timeoutMs);\n if (typeof url !== 'string') continue;\n resolved.push({\n type: 'hybrid',\n key,\n label: titleize(key),\n url,\n runLabel,\n codeLabel,\n terminalLabel,\n });\n } catch {\n // URL resolver failed; skip the view.\n }\n }\n }\n return resolved;\n}\n\nfunction withTimeout<T>(promise: Promise<T>, ms: number): Promise<T> {\n return Promise.race([\n promise,\n new Promise<T>((_, reject) =>\n setTimeout(() => reject(new Error(`url resolver timed out after ${ms}ms`)), ms),\n ),\n ]);\n}\n\nfunction titleize(key: string): string {\n return key.charAt(0).toUpperCase() + key.slice(1).replace(/-/g, ' ');\n}\n\nfunction firstArg(command: ServiceSpec['command']): string {\n if (Array.isArray(command)) return command[0] ?? 'service';\n return 'service';\n}\n","import { loadBlueprints } from '../../core/blueprints.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\n\nexport interface BlueprintsResponse {\n status: 200 | 404 | 500;\n body: unknown;\n}\n\n/**\n * Pure request handler: resolve the project, load blueprints, return a\n * status + JSON-serializable body. Strips the live Handler function from\n * each blueprint before serializing.\n *\n * This is the boundary between the Node-side substrate (filesystem + jiti)\n * and the browser-side UI. Test it without booting Vite.\n */\nexport async function handleBlueprintsRequest(cwd: string): Promise<BlueprintsResponse> {\n try {\n const project = await findProject(cwd);\n const result = await loadBlueprints(project);\n return {\n status: 200,\n body: {\n blueprints: result.blueprints.map((b) => ({\n kind: b.kind,\n folder: b.folder,\n file: b.file,\n capabilities: b.capabilities,\n })),\n errors: result.errors,\n },\n };\n } catch (err) {\n if (err instanceof ProjectNotFoundError) {\n return { status: 404, body: { error: err.message } };\n }\n const message = err instanceof Error ? err.message : String(err);\n return { status: 500, body: { error: message } };\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { codeToHtml } from 'shiki';\n\nexport interface CodeResponse {\n status: 200 | 404 | 500;\n contentType: string;\n body: string;\n}\n\nconst EXT_TO_LANG: Record<string, string> = {\n '.ts': 'typescript',\n '.tsx': 'tsx',\n '.js': 'javascript',\n '.jsx': 'jsx',\n '.mjs': 'javascript',\n '.cjs': 'javascript',\n '.json': 'json',\n '.css': 'css',\n '.html': 'html',\n '.md': 'markdown',\n '.yaml': 'yaml',\n '.yml': 'yaml',\n '.sh': 'shell',\n '.py': 'python',\n '.rs': 'rust',\n '.go': 'go',\n};\n\nexport async function handleCodeRequest(\n absolutePath: string,\n language?: string,\n): Promise<CodeResponse> {\n let raw: string;\n try {\n raw = await readFile(absolutePath, 'utf8');\n } catch {\n return errorResponse(404, `File not found: ${absolutePath}`);\n }\n\n const lang = language ?? EXT_TO_LANG[extname(absolutePath).toLowerCase()] ?? 'text';\n try {\n const inner = await codeToHtml(raw, { lang, theme: 'github-dark' });\n return {\n status: 200,\n contentType: 'text/html; charset=utf-8',\n body: wrap(inner),\n };\n } catch {\n // Unknown language → render as plain text.\n const fallback = `<pre>${escapeHtml(raw)}</pre>`;\n return {\n status: 200,\n contentType: 'text/html; charset=utf-8',\n body: wrap(fallback),\n };\n }\n}\n\nfunction wrap(inner: string): string {\n return `<!doctype html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <title>macroscope · code</title>\n <style>\n body { margin: 0; padding: 0; font-family: ui-monospace, SFMono-Regular, monospace; }\n pre { margin: 0; padding: 1rem; overflow-x: auto; line-height: 1.5; font-size: 13px; }\n </style>\n</head>\n<body>${inner}</body>\n</html>`;\n}\n\nfunction errorResponse(status: 404 | 500, message: string): CodeResponse {\n return {\n status,\n contentType: 'text/html; charset=utf-8',\n body: `<!doctype html><body><pre>${escapeHtml(message)}</pre></body>`,\n };\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' })[c] ?? c);\n}\n","import { type CodeSearchResult, codeSearch } from '../../local/code-search.js';\n\nexport interface CodeSearchHandlerResponse {\n status: 200 | 400;\n body: CodeSearchResult | { error: { code: string; message: string } };\n}\n\nconst MAX_QUERY_LENGTH = 1024;\n\n/**\n * Local code-search endpoint. Browser-side only (no auth needed, same-origin).\n * Wraps T10's `codeSearch` and returns its discriminated-union result verbatim.\n */\nexport async function handleCodeSearchRequest(\n cwd: string,\n query: string | null,\n): Promise<CodeSearchHandlerResponse> {\n if (!query || query.length === 0) {\n return {\n status: 400,\n body: { error: { code: 'invalid_request', message: 'Missing or empty ?q' } },\n };\n }\n if (query.length > MAX_QUERY_LENGTH) {\n return {\n status: 400,\n body: { error: { code: 'invalid_request', message: 'Query too long' } },\n };\n }\n const result = await codeSearch({ query, cwd });\n return { status: 200, body: result };\n}\n","import { findProject } from '../../core/project.js';\nimport { deriveRepoId } from '../../local/repo-id.js';\nimport { deriveWorktreeId, getOrCreateMachineUuid } from '../../local/worktree-id.js';\n\nexport interface WorktreeContext {\n worktreeId: string;\n repo: string;\n}\n\nexport interface WorktreeContextResponse {\n status: 200 | 500;\n body: WorktreeContext | { error: { code: string; message: string } };\n}\n\nexport interface ContextHandlerOptions {\n /** Test seam — overrides homedir (forwarded to getOrCreateMachineUuid). */\n homeDir?: string;\n}\n\n/**\n * Local worktree-context endpoint. Browser-side only (same-origin, no auth).\n *\n * Returns the `(worktreeId, repo)` pair for the worktree this ui-server runs\n * in, derived EXACTLY the way the watcher derives them (`findProject(cwd).root`\n * → `deriveWorktreeId(machineUuid, root)` / `deriveRepoId(root)`). The search\n * store uses this to default its scope to the current worktree, so the default\n * cloud query filters on the same id the watcher pushed docs under.\n *\n * Errors (e.g. not a git repo → no repo identity) come back as a 500 envelope;\n * the store treats that as \"no default available\" and leaves the scope\n * unfiltered, which degrades to the prior all-worktrees behaviour.\n */\nexport async function handleContextRequest(\n cwd: string,\n opts: ContextHandlerOptions = {},\n): Promise<WorktreeContextResponse> {\n try {\n const project = await findProject(cwd);\n const machineUuid = await getOrCreateMachineUuid({ homeDir: opts.homeDir });\n const worktreeId = deriveWorktreeId(machineUuid, project.root);\n const repo = await deriveRepoId(project.root);\n return { status: 200, body: { worktreeId, repo } };\n } catch (err) {\n return {\n status: 500,\n body: {\n error: {\n code: 'context_unavailable',\n message: err instanceof Error ? err.message : String(err),\n },\n },\n };\n }\n}\n","import { readFile } from 'node:fs/promises';\nimport { marked } from 'marked';\n\nexport interface MarkdownResponse {\n status: 200 | 404 | 500;\n contentType: string;\n body: string;\n}\n\nexport async function handleMarkdownRequest(absolutePath: string): Promise<MarkdownResponse> {\n let raw: string;\n try {\n raw = await readFile(absolutePath, 'utf8');\n } catch {\n return errorResponse(404, `File not found: ${absolutePath}`);\n }\n\n try {\n const inner = await marked.parse(raw);\n return {\n status: 200,\n contentType: 'text/html; charset=utf-8',\n body: wrap(inner),\n };\n } catch (err) {\n return errorResponse(500, `Failed to render markdown: ${(err as Error).message}`);\n }\n}\n\nfunction wrap(inner: string): string {\n return `<!doctype html>\n<html>\n<head>\n <meta charset=\"utf-8\" />\n <title>macroscope · markdown</title>\n <style>\n body { font-family: ui-sans-serif, system-ui, sans-serif; max-width: 760px; margin: 2rem auto; padding: 0 1rem; line-height: 1.6; color: #18181b; }\n h1, h2, h3 { margin-top: 1.6em; }\n code { background: #f4f4f5; padding: 0.1em 0.3em; border-radius: 3px; font-size: 0.9em; }\n pre { background: #18181b; color: #fafafa; padding: 1em; border-radius: 6px; overflow-x: auto; }\n pre code { background: transparent; padding: 0; color: inherit; }\n a { color: #2563eb; }\n </style>\n</head>\n<body>${inner}</body>\n</html>`;\n}\n\nfunction errorResponse(status: 404 | 500, message: string): MarkdownResponse {\n return {\n status,\n contentType: 'text/html; charset=utf-8',\n body: `<!doctype html><body><pre>${escapeHtml(message)}</pre></body>`,\n };\n}\n\nfunction escapeHtml(s: string): string {\n return s.replace(/[&<>]/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;' })[c] ?? c);\n}\n","/**\n * T17 — SSE bridge for indexing progress.\n *\n * The local Node process runs catch-up + watcher; the browser is separate.\n * `ProgressBus` accepts emit() calls from the in-process forwarders wired in\n * `ui-server.ts` and fan-outs to every connected EventSource client at\n * `GET /api/local/progress`.\n *\n * SSE wire format (also documented in ARCHITECTURE.md):\n * `Content-Type: text/event-stream`\n * `Cache-Control: no-cache`\n * `Connection: keep-alive`\n * each event: `data: <JSON>\\n\\n`\n * keep-alive: `: heartbeat\\n\\n` every `heartbeatIntervalMs` (default 30s)\n *\n * Keep `ProgressEvent` byte-compatible with the frontend store's mirror in\n * `ui/state/indexing-store.ts`.\n */\nimport type { IncomingMessage, ServerResponse } from 'node:http';\nimport type { CatchupProgress } from '../../local/catchup.js';\nimport type { WatcherProgressEvents } from '../../local/watcher.js';\n\nexport type ProgressEvent =\n | { source: 'catchup'; payload: CatchupProgress }\n | {\n source: 'watcher';\n payload: {\n event: keyof WatcherProgressEvents;\n data: WatcherProgressEvents[keyof WatcherProgressEvents];\n };\n };\n\nexport interface ProgressBus {\n /** Fan out an event to every connected SSE client. No-op after close(). */\n emit(event: ProgressEvent): void;\n /** Wire a new HTTP request as an SSE stream. No-op after close(). */\n handleStream(req: IncomingMessage, res: ServerResponse): void;\n /** End every active stream; subsequent emit/handleStream calls are no-ops. */\n close(): void;\n}\n\nexport interface CreateProgressBusOptions {\n /** Heartbeat cadence in ms. Default 30_000. */\n heartbeatIntervalMs?: number;\n}\n\nconst DEFAULT_HEARTBEAT_MS = 30_000;\n\nexport function createProgressBus(opts: CreateProgressBusOptions = {}): ProgressBus {\n const heartbeatIntervalMs = opts.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_MS;\n const clients = new Set<{ res: ServerResponse; timer: ReturnType<typeof setInterval> }>();\n let closed = false;\n\n return {\n emit(event) {\n if (closed) return;\n const frame = `data: ${JSON.stringify(event)}\\n\\n`;\n for (const c of clients) {\n try {\n c.res.write(frame);\n } catch {\n // Best-effort. Cleanup happens via the `close` listener.\n }\n }\n },\n handleStream(req, res) {\n if (closed) return;\n res.statusCode = 200;\n res.setHeader('content-type', 'text/event-stream');\n res.setHeader('cache-control', 'no-cache');\n res.setHeader('connection', 'keep-alive');\n if (typeof (res as { flushHeaders?: () => void }).flushHeaders === 'function') {\n (res as { flushHeaders: () => void }).flushHeaders();\n }\n const timer = setInterval(() => {\n try {\n res.write(': heartbeat\\n\\n');\n } catch {\n // Stream is dead; cleanup handled by req `close`.\n }\n }, heartbeatIntervalMs);\n if (typeof timer.unref === 'function') timer.unref();\n const entry = { res, timer };\n clients.add(entry);\n const cleanup = (): void => {\n clearInterval(timer);\n clients.delete(entry);\n };\n req.on('close', cleanup);\n res.on('close', cleanup);\n },\n close() {\n if (closed) return;\n closed = true;\n for (const c of clients) {\n clearInterval(c.timer);\n try {\n c.res.end();\n } catch {\n // Best-effort.\n }\n }\n clients.clear();\n },\n };\n}\n","import { readFile, stat } from 'node:fs/promises';\nimport { type IncomingMessage, type ServerResponse, request as httpRequest } from 'node:http';\nimport { request as httpsRequest } from 'node:https';\nimport { OAuthCredentialsSchema } from '@macroscope/contracts';\nimport type { ErrorEnvelope } from '@macroscope/contracts';\n\nconst CLOUD_PREFIX = '/api/cloud';\nconst DEFAULT_CLOUD_URL = 'http://localhost:3001';\nconst MAX_BODY_BYTES = 16 * 1024 * 1024;\n\nexport interface ProxyOptions {\n cloudUrl?: string;\n credentialsPath?: string;\n}\n\nlet cachedToken: string | null = null;\nlet cachedMtime = 0;\n\nexport function isCloudProxyRoute(pathname: string): boolean {\n return pathname.startsWith(`${CLOUD_PREFIX}/`) || pathname === CLOUD_PREFIX;\n}\n\nexport function selectRequestFn(url: URL): typeof httpRequest | typeof httpsRequest {\n return url.protocol === 'https:' ? httpsRequest : httpRequest;\n}\n\nexport async function handleCloudProxy(\n req: IncomingMessage,\n res: ServerResponse,\n opts: ProxyOptions,\n): Promise<void> {\n const url = new URL(req.url ?? '/', 'http://localhost');\n const cloudPath = url.pathname.slice(CLOUD_PREFIX.length);\n const downstream = url.search ? `${cloudPath}${url.search}` : cloudPath;\n\n const cloudBase = opts.cloudUrl ?? process.env.MACROSCOPE_CLOUD_URL ?? DEFAULT_CLOUD_URL;\n const credPath = opts.credentialsPath;\n\n if (!credPath) {\n sendError(res, 401, 'not_logged_in', 'Run `macroscope login` first');\n return;\n }\n\n let token: string;\n try {\n token = await readToken(credPath);\n } catch {\n sendError(res, 401, 'not_logged_in', 'Run `macroscope login` first');\n return;\n }\n\n const { body, tooLarge } = await readBody(req);\n if (tooLarge) {\n sendError(res, 413, 'payload_too_large', `request body exceeds ${MAX_BODY_BYTES} bytes`);\n return;\n }\n\n const targetUrl = new URL(downstream, cloudBase);\n const requestFn = selectRequestFn(targetUrl);\n\n const headers: Record<string, string> = {\n authorization: `Bearer ${token}`,\n };\n if (req.headers['content-type']) {\n headers['content-type'] = req.headers['content-type'];\n }\n\n try {\n await new Promise<void>((resolve, reject) => {\n const proxyReq = requestFn(\n targetUrl,\n { method: req.method ?? 'GET', headers },\n (upstream) => {\n res.statusCode = upstream.statusCode ?? 502;\n const ct = upstream.headers['content-type'];\n if (ct) res.setHeader('content-type', ct);\n upstream.pipe(res);\n upstream.on('end', resolve);\n upstream.on('error', reject);\n },\n );\n proxyReq.on('error', reject);\n if (body.length > 0) proxyReq.write(body);\n proxyReq.end();\n });\n } catch (err) {\n if (!res.headersSent) {\n sendError(res, 502, 'cloud_unreachable', err instanceof Error ? err.message : String(err));\n }\n }\n}\n\nasync function readToken(credPath: string): Promise<string> {\n const s = await stat(credPath);\n\n // Refuse to read group/world-readable credentials (security hygiene).\n // Skip check on Windows where POSIX mode bits don't apply.\n if (process.platform !== 'win32') {\n const groupWorldBits = s.mode & 0o077;\n if (groupWorldBits !== 0) {\n throw new Error(\n `credentials file ${credPath} has mode ${(s.mode & 0o777).toString(8)}; require 0600`,\n );\n }\n }\n\n const mtime = s.mtimeMs;\n if (cachedToken && mtime === cachedMtime) {\n return cachedToken;\n }\n\n const raw = await readFile(credPath, 'utf-8');\n const parsed = OAuthCredentialsSchema.parse(JSON.parse(raw));\n cachedToken = parsed.accessToken;\n cachedMtime = mtime;\n return cachedToken;\n}\n\nfunction readBody(req: IncomingMessage): Promise<{ body: Buffer; tooLarge: boolean }> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let total = 0;\n let tooLarge = false;\n req.on('data', (c: Buffer) => {\n total += c.length;\n if (total > MAX_BODY_BYTES) {\n tooLarge = true;\n return;\n }\n chunks.push(c);\n });\n req.on('end', () => resolve({ body: Buffer.concat(chunks), tooLarge }));\n req.on('error', reject);\n });\n}\n\nfunction sendError(res: ServerResponse, status: number, code: string, message: string): void {\n const envelope: ErrorEnvelope = { error: { code, message } };\n res.statusCode = status;\n res.setHeader('content-type', 'application/json; charset=utf-8');\n res.end(JSON.stringify(envelope));\n}\n","import type { ChildProcess, SpawnOptions } from 'node:child_process';\nimport { spawn as nodeSpawn } from 'node:child_process';\nimport { killTree, spawnDetached } from '../../util/process-group.js';\nimport { pollReadiness as defaultPoll } from './service-readiness.js';\n\nexport type ServiceStatus = 'starting' | 'ready' | 'failed';\n\nexport interface ServiceState {\n status: ServiceStatus;\n logs: string;\n message?: string;\n adopted?: boolean;\n}\n\nexport interface EnsureInput {\n command: string[];\n cwd: string;\n readyUrl: string;\n probeFirst?: boolean;\n startupTimeoutMs?: number;\n}\n\nexport interface ServiceManagerDeps {\n spawn?: (cmd: string, args: string[], opts: SpawnOptions) => ChildProcess;\n pollReadiness?: typeof defaultPoll;\n kill?: (pid: number, signal?: NodeJS.Signals | number) => void;\n killGracePeriodMs?: number;\n}\n\nconst LOG_BUFFER_BYTES = 4096;\n\nexport class ServiceManager {\n private spawn: NonNullable<ServiceManagerDeps['spawn']>;\n private poll: NonNullable<ServiceManagerDeps['pollReadiness']>;\n private kill: ServiceManagerDeps['kill'];\n private killGracePeriodMs: number;\n private services = new Map<\n string,\n { state: ServiceState; child?: ChildProcess; abort: AbortController }\n >();\n\n constructor(deps: ServiceManagerDeps = {}) {\n this.spawn = deps.spawn ?? nodeSpawn;\n this.poll = deps.pollReadiness ?? defaultPoll;\n this.kill = deps.kill;\n this.killGracePeriodMs = deps.killGracePeriodMs ?? 5_000;\n }\n\n keyFor(input: { command: string[]; cwd: string }): string {\n return JSON.stringify({ command: input.command, cwd: input.cwd });\n }\n\n get(key: string): ServiceState | undefined {\n return this.services.get(key)?.state;\n }\n\n async ensure(input: EnsureInput): Promise<ServiceState> {\n const key = this.keyFor(input);\n const existing = this.services.get(key);\n if (existing) return existing.state;\n\n if (input.probeFirst) {\n const probe = await this.poll(input.readyUrl, { timeoutMs: 500, intervalMs: 100 });\n if (probe.ready) {\n const state: ServiceState = { status: 'ready', logs: '', adopted: true };\n this.services.set(key, { state, abort: new AbortController() });\n return state;\n }\n }\n\n const [bin, ...args] = input.command;\n if (!bin) return { status: 'failed', logs: '', message: 'empty command' };\n\n const abort = new AbortController();\n const state: ServiceState = { status: 'starting', logs: '' };\n\n let child: ChildProcess;\n try {\n child = spawnDetached(\n bin,\n args,\n { cwd: input.cwd, stdio: ['ignore', 'pipe', 'pipe'] },\n { spawn: this.spawn },\n );\n } catch (err) {\n return { status: 'failed', logs: '', message: `spawn failed: ${(err as Error).message}` };\n }\n\n this.services.set(key, { state, child, abort });\n\n const appendLog = (chunk: Buffer) => {\n state.logs = (state.logs + chunk.toString()).slice(-LOG_BUFFER_BYTES);\n };\n child.stdout?.on('data', appendLog);\n child.stderr?.on('data', appendLog);\n\n child.on('exit', (code) => {\n if (state.status === 'starting' || state.status === 'ready') {\n state.status = 'failed';\n state.message = `process exited with code ${code}`;\n abort.abort();\n }\n });\n child.on('error', (err) => {\n if (state.status === 'starting') {\n state.status = 'failed';\n state.message = err.message;\n abort.abort();\n }\n });\n\n void this.poll(input.readyUrl, {\n timeoutMs: input.startupTimeoutMs ?? 30_000,\n signal: abort.signal,\n }).then(async (result) => {\n if (state.status !== 'starting') return;\n if (result.ready) {\n state.status = 'ready';\n } else if (!result.aborted) {\n state.status = 'failed';\n state.message = `readiness check failed: ${result.lastError ?? 'timeout'}`;\n if (!child.killed) {\n await killTree(child, { kill: this.kill, gracePeriodMs: this.killGracePeriodMs });\n }\n }\n });\n\n return state;\n }\n\n async shutdown(): Promise<void> {\n const entries = [...this.services.values()];\n this.services.clear();\n await Promise.all(\n entries.map(async (entry) => {\n entry.abort.abort();\n if (entry.child && !entry.child.killed) {\n await killTree(entry.child, {\n kill: this.kill,\n gracePeriodMs: this.killGracePeriodMs,\n });\n }\n }),\n );\n }\n}\n","export interface PollOptions {\n timeoutMs?: number;\n intervalMs?: number;\n signal?: AbortSignal;\n fetch?: typeof fetch;\n}\n\nexport interface PollResult {\n ready: boolean;\n aborted?: boolean;\n lastError?: string;\n}\n\nexport async function pollReadiness(url: string, opts: PollOptions = {}): Promise<PollResult> {\n const timeoutMs = opts.timeoutMs ?? 30_000;\n const intervalMs = opts.intervalMs ?? 250;\n const fetchImpl = opts.fetch ?? fetch;\n const deadline = Date.now() + timeoutMs;\n let lastError = '';\n\n while (Date.now() < deadline) {\n if (opts.signal?.aborted) return { ready: false, aborted: true };\n try {\n const fetchPromise = fetchImpl(url, { signal: opts.signal });\n let onAbort: (() => void) | null = null;\n const signal = opts.signal;\n const abortPromise = signal\n ? new Promise<never>((_, reject) => {\n onAbort = () => {\n reject(new AbortError());\n };\n signal.addEventListener('abort', onAbort, { once: true });\n })\n : new Promise<never>(() => {});\n try {\n const res = await Promise.race([fetchPromise, abortPromise]);\n if (res.status < 500) return { ready: true };\n lastError = `status ${res.status}`;\n } finally {\n if (onAbort && opts.signal) opts.signal.removeEventListener('abort', onAbort);\n }\n } catch (err) {\n if (opts.signal?.aborted || err instanceof AbortError) return { ready: false, aborted: true };\n lastError = err instanceof Error ? err.message : String(err);\n }\n const result = await sleep(intervalMs, opts.signal);\n if (result.aborted) return { ready: false, aborted: true };\n }\n return { ready: false, lastError };\n}\n\nclass AbortError extends Error {\n constructor() {\n super('aborted');\n }\n}\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<{ aborted: boolean }> {\n return new Promise((resolve) => {\n let onAbort: (() => void) | null = null;\n const t = setTimeout(() => {\n if (onAbort && signal) signal.removeEventListener('abort', onAbort);\n resolve({ aborted: false });\n }, ms);\n if (signal?.aborted) {\n clearTimeout(t);\n resolve({ aborted: true });\n return;\n }\n onAbort = () => {\n clearTimeout(t);\n if (signal && onAbort) signal.removeEventListener('abort', onAbort);\n resolve({ aborted: true });\n };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n","import { loadBlueprints } from '../../core/blueprints.js';\nimport type { Block, ServiceSpec } from '../../core/handler.js';\nimport { ProjectNotFoundError, findProject } from '../../core/project.js';\nimport { scan } from '../../core/scanner.js';\nimport type { ServiceManager, ServiceState } from './service-manager.js';\n\nexport interface ServiceEnsureBody {\n blockId: string;\n viewKey: string;\n}\n\nexport interface ServiceEnsureResponse {\n status: 200 | 400 | 404 | 500;\n body: { status?: ServiceState['status']; message?: string; error?: string; logs?: string };\n}\n\nexport async function handleServiceEnsureRequest(\n cwd: string,\n manager: ServiceManager,\n input: ServiceEnsureBody,\n): Promise<ServiceEnsureResponse> {\n if (!input.blockId || !input.viewKey) {\n return { status: 400, body: { error: 'blockId and viewKey are required' } };\n }\n try {\n const project = await findProject(cwd);\n const [scanResult, blueprintResult] = await Promise.all([\n scan(project),\n loadBlueprints(project),\n ]);\n\n const block = scanResult.blocks.find((b) => b.id === input.blockId);\n if (!block) return { status: 404, body: { error: `unknown block: ${input.blockId}` } };\n\n const bp = blueprintResult.blueprints.find((b) => b.kind === block.manifest.kind);\n const viewSpec = bp?.handler.views?.[input.viewKey];\n if (!viewSpec || viewSpec.type !== 'iframe' || !viewSpec.service) {\n return { status: 404, body: { error: `view ${input.viewKey} has no service` } };\n }\n const svc: ServiceSpec = viewSpec.service;\n\n const blockInput: Block = { id: block.id, path: block.path, manifest: block.manifest };\n const command = typeof svc.command === 'function' ? await svc.command(blockInput) : svc.command;\n const cwdResolved =\n typeof svc.cwd === 'function' ? await svc.cwd(blockInput) : (svc.cwd ?? project.root);\n\n const state = await manager.ensure({\n command,\n cwd: cwdResolved,\n readyUrl: svc.readyWhen.url,\n probeFirst: true,\n startupTimeoutMs: svc.startupTimeoutMs,\n });\n\n return {\n status: 200,\n body: {\n status: state.status,\n message: state.message,\n logs: state.status === 'failed' ? state.logs : undefined,\n },\n };\n } catch (err) {\n if (err instanceof ProjectNotFoundError) return { status: 404, body: { error: err.message } };\n return { status: 500, body: { error: (err as Error).message } };\n }\n}\n"],"mappings":"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","names":["z","readFile","dirname","join","z","existsSync","join","createHash","existsSync","readFile","readdir","dirname","join","resolve","parseYaml","pid","withTimeout","dirname","resolve","path","randomBytes","fsStat","fsStat","path","homedir","resolve","ts","fail","readFile","login","writeHuman","resolve","readFile","existsSync","readFile","createServer","homedir","extname","join","resolve","mkdir","readFile","rename","writeFile","dirname","join","relative","sep","readFile","path","createHash","mkdir","readFile","stat","writeFile","dirname","join","path","execFileCb","promisify","execFile","path","createHash","mkdir","readFile","rename","writeFile","dirname","join","relative","sep","createHash","mkdir","readFile","writeFile","homedir","dirname","join","path","createHash","toPosix","sep","join","readQueue","readFile","mkdir","dirname","writeFile","rename","relative","resolve","toPosix","sep","relative","durationMs","isRetryable","readFile","mkdir","dirname","writeFile","rename","join","readFile","readFile","errorResponse","wrap","escapeHtml","readFile","stat","resolve","nodeSpawn","sleep","resolve","nodeSpawn","state","resolve","existsSync","join","credentialsPath","homedir","createServer","attachTerminalWs","readBody","readFile","extname","writeHuman","dirname","resolve"]}