@macroscope/cli 0.0.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/README.md +14 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +1473 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/index.d.ts +125 -0
- package/dist/core/index.js +483 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index-BTDioymD.d.ts +177 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/assets/index-ByDfVdzb.css +1 -0
- package/dist/ui/assets/index-D3mfLpRq.js +45 -0
- package/dist/ui/assets/index-D3mfLpRq.js.map +1 -0
- package/dist/ui/index.html +13 -0
- package/package.json +75 -0
package/dist/cli.js.map
ADDED
|
@@ -0,0 +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) => ({ '&': '&', '<': '<', '>': '>' })[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) => ({ '&': '&', '<': '<', '>': '>' })[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"]}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { H as Handler, B as Block } from '../index-BTDioymD.js';
|
|
2
|
+
export { a as BlockManifest, b as BuildResult, R as RenderResult, T as TestResult, V as VERSION, i as isHandler } from '../index-BTDioymD.js';
|
|
3
|
+
import * as zod from 'zod';
|
|
4
|
+
import { z } from 'zod';
|
|
5
|
+
import { BlockManifest } from '@macroscope/contracts';
|
|
6
|
+
|
|
7
|
+
declare const manifestSchema: zod.ZodObject<{
|
|
8
|
+
kind: zod.ZodString;
|
|
9
|
+
id: zod.ZodOptional<zod.ZodString>;
|
|
10
|
+
name: zod.ZodOptional<zod.ZodString>;
|
|
11
|
+
description: zod.ZodOptional<zod.ZodString>;
|
|
12
|
+
tags: zod.ZodOptional<zod.ZodArray<zod.ZodString, "many">>;
|
|
13
|
+
source: zod.ZodOptional<zod.ZodString>;
|
|
14
|
+
preview: zod.ZodOptional<zod.ZodString>;
|
|
15
|
+
docs: zod.ZodOptional<zod.ZodString>;
|
|
16
|
+
tests: zod.ZodOptional<zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>>;
|
|
17
|
+
}, "passthrough", zod.ZodTypeAny, zod.objectOutputType<{
|
|
18
|
+
kind: zod.ZodString;
|
|
19
|
+
id: zod.ZodOptional<zod.ZodString>;
|
|
20
|
+
name: zod.ZodOptional<zod.ZodString>;
|
|
21
|
+
description: zod.ZodOptional<zod.ZodString>;
|
|
22
|
+
tags: zod.ZodOptional<zod.ZodArray<zod.ZodString, "many">>;
|
|
23
|
+
source: zod.ZodOptional<zod.ZodString>;
|
|
24
|
+
preview: zod.ZodOptional<zod.ZodString>;
|
|
25
|
+
docs: zod.ZodOptional<zod.ZodString>;
|
|
26
|
+
tests: zod.ZodOptional<zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>>;
|
|
27
|
+
}, zod.ZodTypeAny, "passthrough">, zod.objectInputType<{
|
|
28
|
+
kind: zod.ZodString;
|
|
29
|
+
id: zod.ZodOptional<zod.ZodString>;
|
|
30
|
+
name: zod.ZodOptional<zod.ZodString>;
|
|
31
|
+
description: zod.ZodOptional<zod.ZodString>;
|
|
32
|
+
tags: zod.ZodOptional<zod.ZodArray<zod.ZodString, "many">>;
|
|
33
|
+
source: zod.ZodOptional<zod.ZodString>;
|
|
34
|
+
preview: zod.ZodOptional<zod.ZodString>;
|
|
35
|
+
docs: zod.ZodOptional<zod.ZodString>;
|
|
36
|
+
tests: zod.ZodOptional<zod.ZodUnion<[zod.ZodString, zod.ZodArray<zod.ZodString, "many">]>>;
|
|
37
|
+
}, zod.ZodTypeAny, "passthrough">>;
|
|
38
|
+
type Manifest = BlockManifest;
|
|
39
|
+
|
|
40
|
+
declare const projectConfigSchema: z.ZodObject<{
|
|
41
|
+
scanRoots: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
42
|
+
ignore: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
43
|
+
}, "strip", z.ZodTypeAny, {
|
|
44
|
+
scanRoots: string[];
|
|
45
|
+
ignore: string[];
|
|
46
|
+
}, {
|
|
47
|
+
scanRoots?: string[] | undefined;
|
|
48
|
+
ignore?: string[] | undefined;
|
|
49
|
+
}>;
|
|
50
|
+
type ProjectConfig = z.infer<typeof projectConfigSchema>;
|
|
51
|
+
interface Project {
|
|
52
|
+
/** Absolute path to the project root (the directory containing .macroscope/). */
|
|
53
|
+
root: string;
|
|
54
|
+
/** Parsed .macroscope/config.yaml, with defaults filled in. */
|
|
55
|
+
config: ProjectConfig;
|
|
56
|
+
}
|
|
57
|
+
declare class ProjectNotFoundError extends Error {
|
|
58
|
+
constructor(startedFrom: string);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Find the project root by walking up from `cwd` looking for a `.macroscope/`
|
|
62
|
+
* directory. The macroscope root is the directory that *contains* `.macroscope`.
|
|
63
|
+
* If config.yaml is present inside, it is parsed; otherwise defaults are used.
|
|
64
|
+
*/
|
|
65
|
+
declare function findProject(cwd?: string): Promise<Project>;
|
|
66
|
+
|
|
67
|
+
/** Optional operation methods on Handler. Order = preferred display order. */
|
|
68
|
+
declare const OPERATION_NAMES: readonly ["render", "test", "build", "scaffold", "describe"];
|
|
69
|
+
type HandlerCapability = (typeof OPERATION_NAMES)[number];
|
|
70
|
+
interface LoadedBlueprint {
|
|
71
|
+
/** Kind name. Equal to the folder basename AND handler.kind (enforced at load time). */
|
|
72
|
+
kind: string;
|
|
73
|
+
/** Absolute path to the blueprint folder. */
|
|
74
|
+
folder: string;
|
|
75
|
+
/** Absolute path to the loaded handler file. */
|
|
76
|
+
file: string;
|
|
77
|
+
/** The validated Handler default export. */
|
|
78
|
+
handler: Handler;
|
|
79
|
+
/** Which optional operations this handler supports. */
|
|
80
|
+
capabilities: HandlerCapability[];
|
|
81
|
+
}
|
|
82
|
+
type BlueprintLoadCause = 'no-handler-file' | 'import-failed' | 'no-default-export' | 'invalid-handler-shape' | 'kind-mismatch';
|
|
83
|
+
interface BlueprintLoadError {
|
|
84
|
+
/** Absolute path to the blueprint folder. */
|
|
85
|
+
folder: string;
|
|
86
|
+
/** The folder basename — used to identify the failed blueprint even if its declared kind is wrong. */
|
|
87
|
+
kind: string;
|
|
88
|
+
/** Tagged cause for programmatic handling. */
|
|
89
|
+
cause: BlueprintLoadCause;
|
|
90
|
+
/** Human-readable message naming the file and what is wrong. */
|
|
91
|
+
message: string;
|
|
92
|
+
}
|
|
93
|
+
interface BlueprintLoadResult {
|
|
94
|
+
blueprints: LoadedBlueprint[];
|
|
95
|
+
errors: BlueprintLoadError[];
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Discover and load every blueprint under `<project.root>/.macroscope/blueprints/`.
|
|
99
|
+
*
|
|
100
|
+
* Each subfolder is one blueprint. We look for `handler.ts | .mjs | .js` inside
|
|
101
|
+
* it, import the default export via jiti (so users can write plain TypeScript
|
|
102
|
+
* with no build step), and validate the shape against the Handler interface.
|
|
103
|
+
*
|
|
104
|
+
* Per-blueprint failures are collected in `errors` instead of thrown. A single
|
|
105
|
+
* broken handler does not blind the rest of the catalog.
|
|
106
|
+
*/
|
|
107
|
+
declare function loadBlueprints(project: Project): Promise<BlueprintLoadResult>;
|
|
108
|
+
|
|
109
|
+
interface ScannedBlock extends Block {
|
|
110
|
+
/** SHA-256 over the manifest text. Used later by the index for change detection. */
|
|
111
|
+
contentHash: string;
|
|
112
|
+
}
|
|
113
|
+
interface ScanError {
|
|
114
|
+
file: string;
|
|
115
|
+
kind: 'parse' | 'validation' | 'io';
|
|
116
|
+
message: string;
|
|
117
|
+
field?: string;
|
|
118
|
+
}
|
|
119
|
+
interface ScanResult {
|
|
120
|
+
blocks: ScannedBlock[];
|
|
121
|
+
errors: ScanError[];
|
|
122
|
+
}
|
|
123
|
+
declare function scan(project: Project): Promise<ScanResult>;
|
|
124
|
+
|
|
125
|
+
export { Block, type BlueprintLoadCause, type BlueprintLoadError, type BlueprintLoadResult, Handler, type HandlerCapability, type LoadedBlueprint, type Manifest, type Project, type ProjectConfig, ProjectNotFoundError, type ScanError, type ScanResult, type ScannedBlock, findProject, loadBlueprints, manifestSchema, projectConfigSchema, scan };
|