@orkestrel/scaffold 0.0.1
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/LICENSE +21 -0
- package/README.md +114 -0
- package/dist/bin/scaffold.js +1539 -0
- package/dist/bin/scaffold.js.map +1 -0
- package/dist/host/AGENTS.md +939 -0
- package/dist/host/CLAUDE.md +495 -0
- package/dist/host/LICENSE +21 -0
- package/dist/host/claude/agents/builder.md +48 -0
- package/dist/host/claude/agents/checker.md +37 -0
- package/dist/host/claude/agents/composer.md +64 -0
- package/dist/host/claude/agents/grok.md +50 -0
- package/dist/host/claude/agents/orkestrel.md +236 -0
- package/dist/host/claude/agents/planner.md +44 -0
- package/dist/host/claude/agents/researcher.md +38 -0
- package/dist/host/claude/agents/reviewer.md +47 -0
- package/dist/host/claude/agents/scout.md +35 -0
- package/dist/host/claude/agents/verifier.md +34 -0
- package/dist/host/claude/settings.json +26 -0
- package/dist/host/dotfiles/editorconfig +17 -0
- package/dist/host/dotfiles/gitattributes +3 -0
- package/dist/host/dotfiles/gitignore +40 -0
- package/dist/host/dotfiles/oxfmtrc.json +18 -0
- package/dist/host/dotfiles/oxlintignore +20 -0
- package/dist/host/dotfiles/oxlintrc.json +58 -0
- package/dist/host/dotfiles/prettierignore +5 -0
- package/dist/host/github/workflows/ci.yml +64 -0
- package/dist/host/guides/src/guide.md +312 -0
- package/dist/host/guides/src/scaffold.md +2152 -0
- package/dist/host/manifest.json +137 -0
- package/dist/host/scripts/cursor.sh +74 -0
- package/dist/host/scripts/deps.sh +38 -0
- package/dist/host/scripts/ollama.sh +163 -0
- package/dist/src/core/index.cjs +3728 -0
- package/dist/src/core/index.cjs.map +1 -0
- package/dist/src/core/index.d.cts +1941 -0
- package/dist/src/core/index.d.ts +1941 -0
- package/dist/src/core/index.js +3636 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/server/index.cjs +1595 -0
- package/dist/src/server/index.cjs.map +1 -0
- package/dist/src/server/index.d.cts +779 -0
- package/dist/src/server/index.d.ts +779 -0
- package/dist/src/server/index.js +1572 -0
- package/dist/src/server/index.js.map +1 -0
- package/package.json +113 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["#emitter","#host","#ensureAlive","#copy","#write","#assertContained","#destroyed","#manifest","#stub","#manifestLoaded","#manifestEntries","#resolveReal","#DEFAULT_TIMEOUT","#DEFAULT_CONCURRENCY","#DEFAULT_LIMIT","#emitter","#guidesBase","#branch","#guidesTimeout","#registryBase","#registryTimeout","#concurrency","#retries","#strict","#limit","#ensureAlive","#runPool","#shortName","#guideUrl","#fetchText","#toGuideSync","#registryUrl","#toVersionSync","#orgUrl","#toOrgPackages","#toPackument","#toGuideDescription","#combineNote","#assertContained","#destroyed","#normalizeBase","#isRecord","#drain","#readBounded","#transportNote","#causeCode","#parseLatest","#firstBlockquoteParagraph","#resolveReal"],"sources":["../../../src/server/helpers.ts","../../../src/server/Materializer.ts","../../../src/server/Sync.ts","../../../src/server/factories.ts"],"sourcesContent":["import type { Artifact, Blueprint, CatalogEntry, Dependency, Plan } from '@src/core'\nimport type { BlockquoteNode } from '@orkestrel/markdown'\nimport type { ManifestEntry } from './types.js'\nimport {\n\tcopyFileSync,\n\texistsSync,\n\tmkdirSync,\n\treadFileSync,\n\treaddirSync,\n\trmSync,\n\tstatSync,\n\twriteFileSync,\n} from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport {\n\tflattenText,\n\tisBlockquoteNode,\n\tisParagraphNode,\n\tparseDocument,\n\twalkNodes,\n} from '@orkestrel/markdown'\nimport {\n\tblueprint,\n\tDEFAULT_ENGINES,\n\tDEFAULT_VERSION,\n\tdevDependenciesFor,\n\tHOST_PATHS,\n\tScaffoldError,\n} from '@src/core'\n\n// ============================================================================\n// @orkestrel/scaffold/server — helpers.ts (AGENTS §5 source of truth). The\n// server-only helpers `blueprintToPlan`'s green-field target law, the\n// `diffPlan`-feeding target reader, `Sync`'s manifest reader, the\n// `Materializer`'s vendored-host manifest, the vendored-host BUILD staging\n// primitive (`stageHost`, replacing the retired standalone build script), and the\n// `catalog` bin verb depend on: `isVacant`, `readTarget`, `readManifest`,\n// `isRecord`, `readHostManifest`, `listFiles`, `hydratePlan`,\n// `discoverPackages`, `hostRoot`, `deriveBlueprint`, and `catalogPackages`.\n// `selectOrkestrelEntries`, `isManifestEntry`, `locateHostSource`, and\n// `storagePath` are exported module-scope helpers per AGENTS §5's\n// no-nested-functions law — single-call-site status is not an exemption.\n// ============================================================================\n\n/**\n * Locate this MODULE's own installed package root — the nearest ancestor of\n * `import.meta.url` holding a `package.json` — and return its vendored\n * `dist/host` data root. THE single source of truth for the default\n * `Materializer` / `scaffold` bin host: once installed, walking up from the\n * module's own file (not `process.cwd()`, which points at whichever project\n * happens to be running) resolves to `node_modules/@orkestrel/scaffold`, the\n * correct default host — the package ships its vendored data with itself.\n * `dist/host` may not exist yet when this resolves from SOURCE under a test\n * runner; that is fine — existence is checked at the point of use, not here.\n *\n * @returns The absolute vendored `dist/host` path.\n * @throws `ScaffoldError('TARGET', …)` when no ancestor of this module's own\n * location holds a `package.json`.\n *\n * @example\n * ```ts\n * import { hostRoot } from '@orkestrel/scaffold/server'\n *\n * hostRoot() // '/…/node_modules/@orkestrel/scaffold/dist/host'\n * ```\n */\nexport function hostRoot(): string {\n\tlet dir = dirname(fileURLToPath(import.meta.url))\n\tfor (;;) {\n\t\tif (existsSync(join(dir, 'package.json'))) return join(dir, 'dist', 'host')\n\t\tconst parent = dirname(dir)\n\t\tif (parent === dir) {\n\t\t\tthrow new ScaffoldError('TARGET', 'No package root found above the module location', {\n\t\t\t\tmodule: import.meta.url,\n\t\t\t})\n\t\t}\n\t\tdir = parent\n\t}\n}\n\n/**\n * Filter a manifest record's entries down to `@orkestrel/`-prefixed keys with\n * string values — the shared `dependencies` / `peerDependencies` /\n * `devDependencies` reader `deriveBlueprint` uses for every dependency-shaped\n * field.\n *\n * @param value - The candidate manifest field value (e.g. `parsed.dependencies`).\n * @returns The `@orkestrel/`-prefixed `[name, range]` entries; `[]` when\n * `value` is not a plain object (per `isRecord`).\n *\n * @example\n * ```ts\n * import { selectOrkestrelEntries } from '@orkestrel/scaffold/server'\n *\n * selectOrkestrelEntries({ '@orkestrel/core': '^1.0.0', lodash: '^4.0.0' })\n * // [['@orkestrel/core', '^1.0.0']]\n * ```\n */\nexport function selectOrkestrelEntries(value: unknown): readonly (readonly [string, string])[] {\n\tif (!isRecord(value)) return []\n\treturn Object.entries(value).filter(\n\t\t(entry): entry is [string, string] =>\n\t\t\ttypeof entry[1] === 'string' && entry[0].startsWith('@orkestrel/'),\n\t)\n}\n\n/**\n * Reconstruct a `Blueprint` from an EXISTING repo at `target` — the faithful\n * inverse `audit` / `repair` / `mirror` need to diff a live package against\n * its own would-be scaffold, rather than a fresh, dependency-less stand-in.\n *\n * @param target - The existing package directory to derive a `Blueprint` from.\n * @remarks\n * `name` strips the `@orkestrel/` prefix off `manifest.name` — a non-`@orkestrel`\n * name is a coded `TARGET` failure, since this tool derives only `@orkestrel`\n * packages. `surfaces` is read off the LIVE line: every surface the package\n * carries has a `src/<surface>/` directory, so each of `'core' | 'browser' |\n * 'server'` is included iff that directory exists at `target`; a target with\n * NONE of the three is also a coded `TARGET` failure. `dependencies` /\n * `peers` are the `@orkestrel/`-prefixed entries of `manifest.dependencies` /\n * `manifest.peerDependencies` (a peer flagged `peerDependenciesMeta[name]\n * .optional === true` carries `optional: true`). `extras` is EVERY entry of\n * `manifest.devDependencies` (not only `@orkestrel/`-prefixed ones — an\n * external extra like `zod` must round-trip too), EXCLUDING the generated\n * devDependency baseline (`devDependenciesFor([])`'s keys, which already\n * cover `@orkestrel/guide` and `@orkestrel/scaffold`) every scaffolded\n * package already carries, never a package-specific extra. A devDependency\n * ALSO present in\n * `manifest.peerDependencies` or `manifest.dependencies` (e.g. a peer\n * dev-installed for local testing) is likewise excluded from `extras` — it\n * already surfaces as a `peer`/`dependency` above, and double-counting it as\n * an `extra` would land it in `peers ∩ extras`, a blocking `validateBlueprint`\n * gate. `overrides` is always `[]` — derivation cannot know a caller's\n * template-override intent.\n * @returns The reconstructed `Blueprint`.\n * @throws `ScaffoldError('TARGET', …)` when `target`'s manifest is unreadable\n * (via `readManifest`), is not valid JSON, its `name` is not `@orkestrel`-\n * prefixed, or `target` carries none of the three surface directories.\n *\n * @example\n * ```ts\n * import { deriveBlueprint } from '@orkestrel/scaffold/server'\n *\n * deriveBlueprint('./packages/router') // { name: 'router', surfaces: ['core', 'server'], … }\n * ```\n */\nexport function deriveBlueprint(target: string): Blueprint {\n\t// The generated uniform devDependency baseline (every scaffolded package\n\t// carries it) is never a package-specific `extras` entry — excluded from\n\t// the `extras` derived below. Read from the SAME source of truth the\n\t// compiler uses (`devDependenciesFor`, called with `[]` so only its\n\t// baseline keys come back) rather than a duplicated literal, plus\n\t// `@orkestrel/guide` / `@orkestrel/scaffold` per the existing rule (both\n\t// already part of that baseline, restated here for clarity).\n\tconst BASELINE_EXTRAS = new Set([\n\t\t...Object.keys(devDependenciesFor([])),\n\t\t'@orkestrel/guide',\n\t\t'@orkestrel/scaffold',\n\t])\n\tconst text = readManifest(target)\n\tlet parsed: unknown\n\ttry {\n\t\tparsed = JSON.parse(text)\n\t} catch (error) {\n\t\tthrow new ScaffoldError('TARGET', `Manifest at ${target} is not valid JSON`, { target, error })\n\t}\n\tif (!isRecord(parsed)) {\n\t\tthrow new ScaffoldError('TARGET', `Manifest at ${target} is not a JSON object`, { target })\n\t}\n\tconst rawName = parsed.name\n\tif (typeof rawName !== 'string' || !rawName.startsWith('@orkestrel/')) {\n\t\tthrow new ScaffoldError(\n\t\t\t'TARGET',\n\t\t\t`Manifest name \"${String(rawName)}\" is not an @orkestrel package`,\n\t\t\t{ target, name: rawName },\n\t\t)\n\t}\n\tconst name = rawName.slice('@orkestrel/'.length)\n\n\tconst description = typeof parsed.description === 'string' ? parsed.description : undefined\n\tconst keywords =\n\t\tArray.isArray(parsed.keywords) && parsed.keywords.every((word) => typeof word === 'string')\n\t\t\t? parsed.keywords\n\t\t\t: []\n\tconst version = typeof parsed.version === 'string' ? parsed.version : DEFAULT_VERSION\n\tconst engines =\n\t\tisRecord(parsed.engines) && typeof parsed.engines.node === 'string'\n\t\t\t? parsed.engines.node\n\t\t\t: DEFAULT_ENGINES\n\n\tconst surfaces = (['core', 'browser', 'server'] as const).filter((surface) =>\n\t\texistsSync(join(target, 'src', surface)),\n\t)\n\tif (surfaces.length === 0) {\n\t\tthrow new ScaffoldError('TARGET', `No surface directory found under ${target}/src`, { target })\n\t}\n\n\tconst dependencies: Dependency[] = selectOrkestrelEntries(parsed.dependencies).map(\n\t\t([depName, range]) => ({ name: depName, range }),\n\t)\n\n\tconst peersMeta = isRecord(parsed.peerDependenciesMeta) ? parsed.peerDependenciesMeta : undefined\n\tconst peers: Dependency[] = selectOrkestrelEntries(parsed.peerDependencies).map(\n\t\t([depName, range]) => {\n\t\t\tconst meta = peersMeta !== undefined ? peersMeta[depName] : undefined\n\t\t\treturn isRecord(meta) && meta.optional === true\n\t\t\t\t? { name: depName, range, optional: true }\n\t\t\t\t: { name: depName, range }\n\t\t},\n\t)\n\n\t// A devDependency that ALSO appears in peerDependencies or dependencies is\n\t// excluded from extras — it already surfaces as a peer/dependency above,\n\t// and leaving it in extras would land it in `peers ∩ extras`, a blocking\n\t// `validateBlueprint` gate (H3: middleware-shaped packages dev-install a\n\t// peer for local testing).\n\tconst peerAndDependencyNames = new Set([\n\t\t...selectOrkestrelEntries(parsed.peerDependencies).map(([depName]) => depName),\n\t\t...selectOrkestrelEntries(parsed.dependencies).map(([depName]) => depName),\n\t])\n\t// EVERY devDependency, not only `@orkestrel/`-prefixed ones, is a candidate\n\t// `extras` entry — an external extra (e.g. `zod`) must round-trip through\n\t// derivation exactly like an `@orkestrel/`-scoped one, or a package with a\n\t// HAND-ADDED devDependency (recovered here from the manifest's\n\t// devDependencies minus the generated baseline) audits DRIFTED against\n\t// its own manifest.\n\tconst devDependencies = isRecord(parsed.devDependencies) ? parsed.devDependencies : {}\n\tconst extras: Dependency[] = Object.entries(devDependencies)\n\t\t.filter((entry): entry is [string, string] => typeof entry[1] === 'string')\n\t\t.filter(([depName]) => !BASELINE_EXTRAS.has(depName) && !peerAndDependencyNames.has(depName))\n\t\t.map(([depName, range]) => ({ name: depName, range }))\n\n\treturn blueprint(name, {\n\t\tdescription,\n\t\tkeywords,\n\t\tsurfaces,\n\t\tdependencies,\n\t\tpeers,\n\t\textras,\n\t\tversion,\n\t\tengines,\n\t\toverrides: [],\n\t})\n}\n\n/**\n * Whether a target path is absent, empty, or contains nothing but a `.git`\n * directory — the green-field target law `Materializer.materialize` enforces.\n *\n * @param target - The candidate target directory path.\n * @returns `true` when `target` is safe to materialize a fresh package into.\n *\n * @example\n * ```ts\n * import { isVacant } from '@orkestrel/scaffold/server'\n *\n * isVacant('./packages/router-new') // true — absent, empty, or only a .git dir\n * ```\n */\nexport function isVacant(target: string): boolean {\n\tif (!existsSync(target)) return true\n\tif (!statSync(target).isDirectory()) return false\n\tconst entries = readdirSync(target)\n\treturn entries.length === 0 || (entries.length === 1 && entries[0] === '.git')\n}\n\n/**\n * Read a target's current content at a set of relative paths into a\n * `Record<string, string>` — the I/O that feeds the pure `diffPlan`.\n *\n * @param target - The target directory to read from.\n * @param paths - The plan-relative artifact paths to probe.\n * @returns A record keyed by path; a directory entry maps to `''` (presence\n * only — a `host`-origin directory artifact is audited by presence, never\n * content), an absent path is OMITTED entirely (never an empty-string\n * placeholder for a missing file, so `diffPlan` reports it `missing`).\n * @throws `ScaffoldError('TARGET', …)` when an EXISTING path fails to read\n * (e.g. `EACCES` / `EPERM`) — carries the offending relative `path` (and\n * the resolved `full` path) in `context`. An absent path is never an\n * error — it is simply omitted, per the return contract above.\n *\n * @example\n * ```ts\n * import { readTarget } from '@orkestrel/scaffold/server'\n *\n * readTarget('./packages/router', ['package.json', 'src/core/index.ts'])\n * // { 'package.json': '{ \"name\": … }', 'src/core/index.ts': '…' }\n * ```\n */\nexport function readTarget(\n\ttarget: string,\n\tpaths: readonly string[],\n): Readonly<Record<string, string>> {\n\tconst current: Record<string, string> = {}\n\tfor (const path of paths) {\n\t\tconst full = join(target, path)\n\t\tif (!existsSync(full)) continue\n\t\ttry {\n\t\t\tcurrent[path] = statSync(full).isDirectory() ? '' : readFileSync(full, 'utf8')\n\t\t} catch (error) {\n\t\t\tthrow new ScaffoldError('TARGET', `Failed to read target file at ${path}`, {\n\t\t\t\tpath,\n\t\t\t\tfull,\n\t\t\t\terror,\n\t\t\t})\n\t\t}\n\t}\n\treturn current\n}\n\n/**\n * Read `target/package.json` text — the read that feeds `manifestToDependencies`.\n *\n * @param target - The target directory to read the manifest from.\n * @returns The manifest file's raw text.\n * @throws `ScaffoldError('TARGET', …)` when the manifest is absent or\n * unreadable (e.g. `EACCES` / `EPERM`) — carries the resolved `full` path\n * in `context`.\n *\n * @example\n * ```ts\n * import { readManifest } from '@orkestrel/scaffold/server'\n *\n * readManifest('./packages/router') // '{ \"name\": \"@orkestrel/router\", … }'\n * ```\n */\nexport function readManifest(target: string): string {\n\tconst full = join(target, 'package.json')\n\ttry {\n\t\treturn readFileSync(full, 'utf8')\n\t} catch (error) {\n\t\tthrow new ScaffoldError('TARGET', `Failed to read manifest at ${full}`, { target, full, error })\n\t}\n}\n\n/**\n * Whether `value` is a plain object (not `null`, not an array).\n *\n * @param value - The candidate value.\n * @returns `true` when `value` narrows to `Record<string, unknown>`.\n *\n * @example\n * ```ts\n * import { isRecord } from '@orkestrel/scaffold/server'\n *\n * isRecord({ a: 1 }) // true\n * isRecord(null) // false\n * ```\n */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\n/**\n * Whether `value` is a well-formed `host/manifest.json` entry — a string\n * `storage`, a string `destination`, and a boolean `executable`.\n *\n * @param value - The candidate raw manifest entry.\n * @returns `true` when `value` narrows to `ManifestEntry`.\n *\n * @example\n * ```ts\n * import { isManifestEntry } from '@orkestrel/scaffold/server'\n *\n * isManifestEntry({ storage: 'a', destination: 'b', executable: false }) // true\n * isManifestEntry({ storage: 'a', destination: 'b' }) // false — missing `executable`\n * ```\n */\nexport function isManifestEntry(value: unknown): value is ManifestEntry {\n\tif (!isRecord(value)) return false\n\treturn (\n\t\ttypeof value.storage === 'string' &&\n\t\ttypeof value.destination === 'string' &&\n\t\ttypeof value.executable === 'boolean'\n\t)\n}\n\n/**\n * Read and validate a vendored host root's `manifest.json`, when present.\n *\n * @param host - The host root to probe.\n * @returns The parsed entries, or `undefined` when `host` has no\n * `manifest.json` — the raw-repo-root fallback (`Materializer` then maps\n * an artifact's `source` to `host` 1:1, no vendored staging indirection).\n * @throws `ScaffoldError('TARGET', …)` when `manifest.json` exists but is\n * unreadable, is not valid JSON, or is not an array of `ManifestEntry`.\n *\n * @example\n * ```ts\n * import { readHostManifest } from '@orkestrel/scaffold/server'\n *\n * readHostManifest('./dist/host') // readonly ManifestEntry[] | undefined\n * ```\n */\nexport function readHostManifest(host: string): readonly ManifestEntry[] | undefined {\n\tconst full = join(host, 'manifest.json')\n\tif (!existsSync(full)) return undefined\n\tlet text: string\n\ttry {\n\t\ttext = readFileSync(full, 'utf8')\n\t} catch (error) {\n\t\tthrow new ScaffoldError('TARGET', `Failed to read host manifest at ${full}`, {\n\t\t\thost,\n\t\t\tfull,\n\t\t\terror,\n\t\t})\n\t}\n\tlet parsed: unknown\n\ttry {\n\t\tparsed = JSON.parse(text)\n\t} catch (error) {\n\t\tthrow new ScaffoldError('TARGET', `Host manifest at ${full} is not valid JSON`, {\n\t\t\thost,\n\t\t\tfull,\n\t\t\terror,\n\t\t})\n\t}\n\tif (!Array.isArray(parsed) || !parsed.every(isManifestEntry)) {\n\t\tthrow new ScaffoldError(\n\t\t\t'TARGET',\n\t\t\t`Host manifest at ${full} is not an array of manifest entries`,\n\t\t\t{\n\t\t\t\thost,\n\t\t\t\tfull,\n\t\t\t},\n\t\t)\n\t}\n\treturn parsed\n}\n\n/**\n * Recursively list a directory's files as root-relative paths.\n *\n * @param root - The directory to list.\n * @returns Root-relative file paths (posix-style `/` separators), or `[]`\n * when `root` is absent.\n *\n * @example\n * ```ts\n * import { listFiles } from '@orkestrel/scaffold/server'\n *\n * listFiles('./dist/host/.claude/agents') // ['scout.md', 'builder.md', …]\n * ```\n */\nexport function listFiles(root: string): readonly string[] {\n\tif (!existsSync(root)) return []\n\tconst files: string[] = []\n\tfor (const entry of readdirSync(root, { withFileTypes: true })) {\n\t\tconst full = join(root, entry.name)\n\t\tif (entry.isDirectory()) {\n\t\t\tfor (const nested of listFiles(full)) files.push(`${entry.name}/${nested}`)\n\t\t} else {\n\t\t\tfiles.push(entry.name)\n\t\t}\n\t}\n\treturn files\n}\n\n/**\n * Map a repo-relative path to its vendored-host STAGING path, per the\n * dotfile-mapping rule `stageHost` writes into `manifest.json`.\n *\n * @param path - The repo-relative source path (e.g. `.claude/agents/scout.md`).\n * @returns The mapped storage path: a leading-dot TOP-LEVEL FILE maps to\n * `dotfiles/<name-without-dot>`; a leading-dot DIRECTORY segment loses its\n * dot wherever it appears; an undotted path is unchanged.\n *\n * @example\n * ```ts\n * import { storagePath } from '@orkestrel/scaffold/server'\n *\n * storagePath('.gitignore') // 'dotfiles/gitignore'\n * storagePath('.claude/agents/scout.md') // 'claude/agents/scout.md'\n * storagePath('.github/workflows/ci.yml') // 'github/workflows/ci.yml'\n * storagePath('AGENTS.md') // 'AGENTS.md'\n * ```\n */\nexport function storagePath(path: string): string {\n\tconst segments = path.split('/')\n\tif (segments.length === 1) {\n\t\tconst name = segments[0]\n\t\treturn name.startsWith('.') ? `dotfiles/${name.slice(1)}` : name\n\t}\n\treturn segments.map((segment) => (segment.startsWith('.') ? segment.slice(1) : segment)).join('/')\n}\n\n/**\n * Stage the vendored host set (byte-preserved copies + `manifest.json`) from\n * a repo root into an output directory — the BUILD-time primitive the\n * `build:host` npm script now calls directly (replacing a standalone build\n * script); `Materializer.materialize` is the RUNTIME reader of what this\n * writes (via `hostRoot` / `readHostManifest`).\n *\n * @param root - The repo root every `paths` entry resolves against.\n * @param out - The output directory to wipe and stage into (typically `dist/host`).\n * @param paths - The repo-relative file/directory entries to stage; defaults\n * to the package's own vendored set (`HOST_PATHS`) — a caller passes an\n * explicit list only to stage an arbitrary/test set.\n * @remarks\n * `out` is wiped (`rmSync(out, { recursive: true, force: true })`) BEFORE\n * staging, so a stale file left over from a prior run never lingers. Each\n * `paths` entry is walked to its per-file leaves (a directory recursively,\n * via `listFiles`; a file, itself) and copied byte-for-byte\n * (`copyFileSync`) to `<out>/<storagePath(path)>`. The `executable` flag\n * `entries` reports is derived from the `.sh` suffix on `destination` —\n * deterministic on every build platform (Windows `stat` carries no execute\n * bit); all vendored executables are shell scripts by construction.\n * `manifest.json` is written LAST, as `entries` code-unit sorted by\n * `destination`, tab-indented JSON with a trailing newline.\n * @returns The written manifest's entries (`{ storage, destination, executable }`).\n * @throws `ScaffoldError('TARGET', …)` naming the offending path when a\n * `paths` entry has no source under `root`, or naming BOTH colliding\n * destinations when two entries map to the same `storagePath` (the guard\n * run BEFORE `manifest.json` is written).\n *\n * @example\n * ```ts\n * import { stageHost } from '@orkestrel/scaffold/server'\n *\n * const entries = stageHost(process.cwd(), 'dist/host')\n * entries.length // number of files staged\n * ```\n */\nexport function stageHost(\n\troot: string,\n\tout: string,\n\tpaths: readonly string[] = HOST_PATHS,\n): readonly ManifestEntry[] {\n\tconst destinations: string[] = []\n\tfor (const path of paths) {\n\t\tconst absolute = join(root, path)\n\t\tif (!existsSync(absolute)) {\n\t\t\tthrow new ScaffoldError('TARGET', `Missing host source at ${path}`, { path, root })\n\t\t}\n\t\tif (statSync(absolute).isDirectory()) {\n\t\t\tfor (const nested of listFiles(absolute)) destinations.push(`${path}/${nested}`)\n\t\t} else {\n\t\t\tdestinations.push(path)\n\t\t}\n\t}\n\n\trmSync(out, { recursive: true, force: true })\n\n\tconst entries: ManifestEntry[] = []\n\tfor (const destination of destinations) {\n\t\tconst storage = storagePath(destination)\n\t\tconst sourceAbsolute = join(root, destination)\n\t\tconst destinationAbsolute = join(out, storage)\n\t\tmkdirSync(dirname(destinationAbsolute), { recursive: true })\n\t\tcopyFileSync(sourceAbsolute, destinationAbsolute)\n\t\tconst executable = destination.endsWith('.sh')\n\t\tentries.push({ storage, destination, executable })\n\t}\n\tentries.sort((a, b) =>\n\t\ta.destination < b.destination ? -1 : a.destination > b.destination ? 1 : 0,\n\t)\n\n\tconst byStorage = new Map<string, string>()\n\tfor (const entry of entries) {\n\t\tconst existing = byStorage.get(entry.storage)\n\t\tif (existing !== undefined) {\n\t\t\tthrow new ScaffoldError(\n\t\t\t\t'TARGET',\n\t\t\t\t`Storage path collision at \"${entry.storage}\" — destinations \"${existing}\" and \"${entry.destination}\" both map to it`,\n\t\t\t\t{ storage: entry.storage, destinations: [existing, entry.destination] },\n\t\t\t)\n\t\t}\n\t\tbyStorage.set(entry.storage, entry.destination)\n\t}\n\n\tmkdirSync(out, { recursive: true })\n\twriteFileSync(join(out, 'manifest.json'), `${JSON.stringify(entries, null, '\\t')}\\n`)\n\n\treturn entries\n}\n\n/**\n * Resolve the absolute host-storage path for a host-origin artifact's\n * `source`, manifest-aware.\n *\n * @param manifest - The host's parsed `manifest.json` entries, or `undefined`\n * when the host carries none (raw-repo-root fallback).\n * @param source - The artifact's `source` (or `path`) to resolve.\n * @param host - The resolved host root the path is joined against.\n * @returns `join(host, source)` when `manifest` is `undefined` (no vendored\n * staging indirection); when `manifest` is present, `join(host,\n * entries[0].storage)` for the SINGLE manifest entry whose `destination`\n * equals `source`, or `undefined` when zero or more than one entry matches\n * (`source` names a directory, or the manifest is ambiguous — no single\n * storage file to point at).\n *\n * @example\n * ```ts\n * import { locateHostSource } from '@orkestrel/scaffold/server'\n *\n * locateHostSource(undefined, 'package.json', './dist/host') // './dist/host/package.json'\n * locateHostSource([{ storage: 'pkg.tmpl', destination: 'package.json', executable: false }], 'package.json', './dist/host')\n * // './dist/host/pkg.tmpl'\n * ```\n */\nexport function locateHostSource(\n\tmanifest: readonly ManifestEntry[] | undefined,\n\tsource: string,\n\thost: string,\n): string | undefined {\n\tif (manifest === undefined) return join(host, source)\n\tconst entries = manifest.filter((entry) => entry.destination === source)\n\tif (entries.length !== 1) return undefined\n\treturn join(host, entries[0].storage)\n}\n\n/**\n * Rehydrate a `Plan`'s `host`-origin artifacts with their real byte content\n * read from `host` — manifest-aware, via `locateHostSource`.\n *\n * @param plan - The plan to hydrate.\n * @param host - The resolved host root to read from.\n * @returns A new `Plan` whose file-shaped `host` artifacts carry `content`;\n * `template` / `computed` artifacts and directory-shaped `host` artifacts\n * (no single storage file to read) pass through untouched.\n * @throws `ScaffoldError('TARGET', …)` when a resolved, existing host source\n * file fails to read.\n *\n * @example\n * ```ts\n * import { hydratePlan } from '@orkestrel/scaffold/server'\n *\n * const hydrated = hydratePlan(plan, './dist/host')\n * ```\n */\nexport function hydratePlan(plan: Plan, host: string): Plan {\n\tconst manifest = readHostManifest(host)\n\tconst artifacts = plan.artifacts.map((artifact): Artifact => {\n\t\tif (artifact.origin !== 'host') return artifact\n\t\tconst source = artifact.source ?? artifact.path\n\t\tconst full = locateHostSource(manifest, source, host)\n\t\tif (full === undefined || !existsSync(full) || statSync(full).isDirectory()) return artifact\n\t\ttry {\n\t\t\treturn { ...artifact, content: readFileSync(full, 'utf8') }\n\t\t} catch (error) {\n\t\t\tthrow new ScaffoldError('TARGET', `Failed to read host artifact at ${source}`, {\n\t\t\t\tsource,\n\t\t\t\tfull,\n\t\t\t\terror,\n\t\t\t})\n\t\t}\n\t})\n\treturn { ...plan, artifacts }\n}\n\n/**\n * The `prune`-owned directories — a hard allowlist; `pruneTargets` (and the\n * `Materializer.prune` that consumes it) never scans anything outside these two.\n *\n * @example\n * ```ts\n * import { PRUNE_DIRECTORIES } from '@orkestrel/scaffold/server'\n *\n * PRUNE_DIRECTORIES // ['.claude/agents', 'scripts']\n * ```\n */\nexport const PRUNE_DIRECTORIES = ['.claude/agents', 'scripts'] as const\n\n/**\n * The vendored set of destination-relative paths under `directory` (one of\n * `PRUNE_DIRECTORIES`) that `pruneTargets` must NOT report — read from the\n * manifest's `destination`s when `host` has one, else listed straight off\n * `host/<directory>`.\n *\n * @param host - The vendored host root to establish the allowlist from.\n * @param directory - The prune directory (one of `PRUNE_DIRECTORIES`) to scope the allowlist to.\n * @remarks\n * FAIL CLOSED: before returning any allowlist (even an empty one), the\n * vendored source must be POSITIVELY established, or a caller would treat an\n * unresolved host as \"vendors nothing\" and report every file under\n * `target/<directory>` as unexpected. A missing `host` root, or (no\n * `manifest.json` AND no `host/<directory>`), is a coded `TARGET` failure —\n * the distinction this guards is missing-host vs genuinely-empty-vendor: a\n * `host` that EXISTS and vendors zero files in `directory` (an existing empty\n * dir, or a manifest with zero entries for it) remains a valid empty allowlist.\n * @returns The allowed destination-relative paths under `directory`.\n * @throws `ScaffoldError('TARGET', …)` when `host` does not exist, or when\n * `host` has no `manifest.json` and no `host/<directory>` either.\n *\n * @example\n * ```ts\n * import { vendoredPruneSet } from '@orkestrel/scaffold/server'\n *\n * vendoredPruneSet('./dist/host', '.claude/agents') // Set { '.claude/agents/scout.md', … }\n * ```\n */\nexport function vendoredPruneSet(host: string, directory: string): ReadonlySet<string> {\n\tif (!existsSync(host)) {\n\t\tthrow new ScaffoldError(\n\t\t\t'TARGET',\n\t\t\t`Cannot establish vendored source for prune: host root not found at ${host}`,\n\t\t\t{ host, directory },\n\t\t)\n\t}\n\tconst manifest = readHostManifest(host)\n\tif (manifest !== undefined) {\n\t\treturn new Set(\n\t\t\tmanifest\n\t\t\t\t.filter((entry) => entry.destination.startsWith(`${directory}/`))\n\t\t\t\t.map((entry) => entry.destination),\n\t\t)\n\t}\n\tconst hostDirectory = join(host, directory)\n\tif (!existsSync(hostDirectory)) {\n\t\tthrow new ScaffoldError(\n\t\t\t'TARGET',\n\t\t\t`Cannot establish vendored source for prune: no manifest.json and no host directory at ${hostDirectory}`,\n\t\t\t{ host, directory },\n\t\t)\n\t}\n\treturn new Set(listFiles(hostDirectory).map((relative) => `${directory}/${relative}`))\n}\n\n/**\n * List the repo-relative POSIX paths under `target`'s prune directories\n * (`.claude/agents`, `scripts`) that the vendored `host` allowlist does NOT\n * declare — THE single source of truth for prune drift, consumed by both\n * `Materializer.prune` (which deletes exactly these paths) and the bin's\n * audit/preview UX (which now shows them honestly instead of a\n * structurally-always-zero `audit.foreign`).\n *\n * @param target - The target directory to scan for unexpected files.\n * @param host - The vendored host root the allowlist is derived from.\n * @returns The unexpected relative paths (e.g. `.claude/agents/rogue.md`); `[]`\n * when a prune directory is absent under `target`, or when none of its\n * files are unexpected. Pure read — never deletes anything.\n * @throws `ScaffoldError('TARGET', …)` when `host` cannot positively\n * establish a vendored allowlist for a prune directory that DOES exist\n * under `target` (see `vendoredPruneSet`'s fail-closed remarks).\n *\n * @example\n * ```ts\n * import { pruneTargets } from '@orkestrel/scaffold/server'\n *\n * pruneTargets('./packages/router', hostRoot()) // ['.claude/agents/rogue.md']\n * ```\n */\nexport function pruneTargets(target: string, host: string): readonly string[] {\n\tconst paths: string[] = []\n\tfor (const directory of PRUNE_DIRECTORIES) {\n\t\tconst root = join(target, directory)\n\t\tif (!existsSync(root)) continue\n\t\tconst allowed = vendoredPruneSet(host, directory)\n\t\tfor (const relative of listFiles(root)) {\n\t\t\tconst path = `${directory}/${relative}`\n\t\t\tif (!allowed.has(path)) paths.push(path)\n\t\t}\n\t}\n\treturn paths\n}\n\n/**\n * List a fleet root's `@orkestrel/*` package directories.\n *\n * @param root - The fleet root directory to scan.\n * @returns Absolute, code-unit-sorted paths of `root`'s immediate child\n * directories whose `package.json` parses and whose `name` starts with\n * `@orkestrel/`. A child with an unreadable or unparsable `package.json`,\n * or a non-`@orkestrel` name, is skipped silently — it simply is not a\n * fleet member.\n *\n * @example\n * ```ts\n * import { discoverPackages } from '@orkestrel/scaffold/server'\n *\n * discoverPackages('./packages') // ['/abs/packages/router', '/abs/packages/budget']\n * ```\n */\nexport function discoverPackages(root: string): readonly string[] {\n\tconst packages: string[] = []\n\tfor (const entry of readdirSync(root, { withFileTypes: true })) {\n\t\tif (!entry.isDirectory()) continue\n\t\tconst directory = join(root, entry.name)\n\t\tconst manifestPath = join(directory, 'package.json')\n\t\tif (!existsSync(manifestPath)) continue\n\t\tlet parsed: unknown\n\t\ttry {\n\t\t\tparsed = JSON.parse(readFileSync(manifestPath, 'utf8'))\n\t\t} catch {\n\t\t\tcontinue\n\t\t}\n\t\tif (!isRecord(parsed)) continue\n\t\tconst name = parsed.name\n\t\tif (typeof name === 'string' && name.startsWith('@orkestrel/')) packages.push(directory)\n\t}\n\treturn packages.sort()\n}\n\n/**\n * Build the fleet package catalog — one `CatalogEntry` per `@orkestrel/*`\n * package discovered under each root, its description drawn from its own\n * guide's FIRST blockquote.\n *\n * @param roots - The fleet root directories to scan (each walked via `discoverPackages`).\n * @remarks\n * Per discovered package directory: `name` / `version` come from its own\n * `package.json`; `description` is the first paragraph of the guide's opening\n * blockquote — the flattened text of the FIRST `ParagraphNode` among the\n * FIRST `BlockquoteNode` found's (depth-first, pre-order, via `walkNodes`)\n * TOP-LEVEL children in its `guides/src/<short>.md` (`<short>` = `name` with\n * the `@orkestrel/` prefix stripped), parsed with `@orkestrel/markdown`'s\n * `parseDocument` — a multi-paragraph blockquote overview yields only its\n * FIRST paragraph, never the whole quote glued together; embedded newlines\n * collapse to single spaces, and surrounding whitespace trims. A\n * missing/unreadable guide, a guide carrying no blockquote, or a blockquote\n * with no top-level paragraph child, yields `description: ''`, never a\n * thrown error. Entries merge across `roots` (a later root's entry for a\n * repeated `name` wins), then code-unit sort by `name`. An unreadable ROOT\n * itself is NOT wrapped here — whatever `discoverPackages` throws for it\n * propagates as-is; the bin layer is responsible for coding that failure\n * `TARGET`.\n * @returns The merged, sorted `CatalogEntry[]`.\n *\n * @example\n * ```ts\n * import { catalogPackages } from '@orkestrel/scaffold/server'\n *\n * catalogPackages(['/repos']) // [{ name: '@orkestrel/contract', version: '0.0.5', description: '…' }, …]\n * ```\n */\nexport function catalogPackages(roots: readonly string[]): readonly CatalogEntry[] {\n\tconst merged = new Map<string, CatalogEntry>()\n\tfor (const root of roots) {\n\t\tfor (const directory of discoverPackages(root)) {\n\t\t\tlet parsed: unknown\n\t\t\ttry {\n\t\t\t\tparsed = JSON.parse(readFileSync(join(directory, 'package.json'), 'utf8'))\n\t\t\t} catch {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (!isRecord(parsed)) continue\n\t\t\tconst name = parsed.name\n\t\t\tif (typeof name !== 'string' || !name.startsWith('@orkestrel/')) continue\n\t\t\tconst version = typeof parsed.version === 'string' ? parsed.version : DEFAULT_VERSION\n\t\t\tconst short = name.slice('@orkestrel/'.length)\n\t\t\tconst guidePath = join(directory, 'guides', 'src', `${short}.md`)\n\t\t\tlet description = ''\n\t\t\tif (existsSync(guidePath)) {\n\t\t\t\ttry {\n\t\t\t\t\tconst document = parseDocument(readFileSync(guidePath, 'utf8'))\n\t\t\t\t\tlet quote: BlockquoteNode | undefined\n\t\t\t\t\tfor (const node of walkNodes(document)) {\n\t\t\t\t\t\tif (isBlockquoteNode(node)) {\n\t\t\t\t\t\t\tquote = node\n\t\t\t\t\t\t\tbreak\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (quote !== undefined) {\n\t\t\t\t\t\t// Only the FIRST top-level paragraph child of the quote — a\n\t\t\t\t\t\t// multi-paragraph blockquote overview (an opening sentence\n\t\t\t\t\t\t// followed by elaboration) would otherwise flatten its ENTIRE\n\t\t\t\t\t\t// quote into one verbose row; taking just the first paragraph\n\t\t\t\t\t\t// keeps the catalog description concise, one line per package.\n\t\t\t\t\t\tconst paragraph = quote.children.find((child) => isParagraphNode(child))\n\t\t\t\t\t\tif (paragraph !== undefined) {\n\t\t\t\t\t\t\tconst text = flattenText(paragraph)\n\t\t\t\t\t\t\tdescription = text.replace(/\\s+/g, ' ').trim()\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tdescription = ''\n\t\t\t\t}\n\t\t\t}\n\t\t\tmerged.set(name, { name, version, description })\n\t\t}\n\t}\n\treturn [...merged.values()].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))\n}\n","import type {\n\tManifestEntry,\n\tMaterializeResult,\n\tMaterializerEventMap,\n\tMaterializerInterface,\n\tMaterializerOptions,\n} from './types.js'\nimport type { Artifact, Audit, Plan } from '@src/core'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport {\n\tchmodSync,\n\tcpSync,\n\texistsSync,\n\tmkdirSync,\n\trealpathSync,\n\tunlinkSync,\n\twriteFileSync,\n} from 'node:fs'\nimport { dirname, join, relative as relativeOf, resolve, sep } from 'node:path'\nimport { Emitter } from '@orkestrel/emitter'\nimport { ScaffoldError } from '@src/core'\nimport { hostRoot, isVacant, pruneTargets, readHostManifest } from './helpers.js'\n\n/**\n * The materialization entity (server) — the only impure surface in the\n * package, writing a `Plan` to `node:fs` behind an explicit call.\n *\n * @remarks\n * `materialize` is green-field: it refuses any target `isVacant` rejects\n * (`ScaffoldError('TARGET', …)`), then byte-copies each `host` artifact from\n * the `host` root and writes each `template` / `computed` artifact's rendered\n * `content`, failing fast on any write error (`ScaffoldError('WRITE', …)`).\n * `repair` is into-existing: it skips the vacancy check and writes ONLY the\n * `missing` / `stale` artifacts an `Audit` names, leaving `aligned` ones\n * untouched. `prune` deletes stale files under `target/.claude/agents/` and\n * `target/scripts/` that the vendored `host` no longer names — the retired\n * `mirror.sh`/`scaffold.sh` cleanup step, now a method. After `destroy()`\n * every method throws `DESTROYED`; teardown is idempotent, emitter last.\n *\n * @remarks\n * `host`-origin copies are MANIFEST-AWARE: when the resolved `host` root\n * carries a `manifest.json` (this package's own vendored `dist/host`), each\n * artifact's `source` (a destination-relative path) is looked up in the\n * manifest to find its un-dotted STORAGE path plus an `executable` bit\n * (applied via `chmodSync` after the copy) — the vendored-package shape,\n * where storage names avoid leading dots npm would otherwise mangle. When\n * `host` carries no `manifest.json` (a caller-supplied raw repo root, e.g. a\n * sibling checkout or a test fixture), `source` maps to `host` 1:1, exactly\n * as before.\n *\n * @remarks\n * A manifest-present `source` with ZERO matching entries degrades to a stub\n * ONLY when that `source` is a dependency-guide pointer — one that starts\n * with `guides/src/` and ends with `.md` (the `guides/src/<dep>.md` pointer\n * `Compiler` emits for any dependency outside this package's vendored set).\n * That is the ONLY zero-match case that is legitimate: every `HOST_PATHS`\n * source is always staged by `stageHost`, so a non-guide zero-match means a\n * corrupted or truncated `manifest.json`, not an intentionally-unvendored\n * artifact. For a guide pointer, a short stub file is written at the\n * destination and reported exactly like a successful copy, mirroring the\n * READ path (`hydratePlan` leaves such artifacts `content`-undefined, so\n * `diffPlan` audits them by PRESENCE only). For every OTHER zero-match, the\n * fail-closed `ScaffoldError('TARGET', …)` is thrown — degrading an\n * unscoped zero-match would otherwise let a corrupted manifest silently stub\n * an unrecoverable artifact (e.g. `AGENTS.md` — `pull` only ever fetches\n * dependency guides) or write a FILE named `.claude` over what should be a\n * directory artifact. The raw-root fallback (`manifest === undefined`, a\n * caller-supplied `--from`) keeps its own throw regardless: an EXPLICITLY\n * named source failing to resolve is a different, caller-error failure\n * class, not a \"not vendored\" degrade.\n *\n * @remarks\n * Defense in depth at the filesystem trust boundary: EVERY resolved\n * destination (`materialize` and `repair`, both origins) is asserted to stay\n * within `resolve(target)` before any write, and every `host`-origin copy\n * source is asserted to stay within `resolve(host)` before any read — a\n * traversal segment (`../`) in an artifact's `path` or `source` cannot escape\n * either root, even if a gate upstream (e.g. an ungated `Plan` built by hand)\n * let it through. A destination violation throws `ScaffoldError('WRITE', …)`;\n * a source violation throws `ScaffoldError('TARGET', …)`.\n *\n * @remarks\n * The containment check is REAL-PATH aware, not merely lexical: both the\n * root (`target` / `host`) and the candidate destination/source are resolved\n * through `realpathSync` on their DEEPEST EXISTING ancestor before the prefix\n * comparison, so a symlinked subdirectory planted inside an otherwise\n * legitimate root cannot smuggle a write (or read) outside it — `repair`,\n * which has no `isVacant` gate, is covered exactly like `materialize`. A path\n * segment that does not yet exist on disk (the still-to-be-created file/dir\n * a write is about to create) is rejoined onto the resolved existing\n * ancestor rather than realpath'd itself.\n *\n * @example\n * ```ts\n * import { blueprint, blueprintToPlan } from '@orkestrel/scaffold'\n * import { createMaterializer } from '@orkestrel/scaffold/server'\n *\n * const plan = blueprintToPlan(blueprint('budget', { surfaces: ['core'] }))\n * const materializer = createMaterializer()\n * materializer.materialize(plan, './packages/budget-new')\n * materializer.destroy()\n * ```\n */\nexport class Materializer implements MaterializerInterface {\n\treadonly #emitter: Emitter<MaterializerEventMap>\n\treadonly #host: string\n\t#manifestLoaded = false\n\t#manifestEntries: readonly ManifestEntry[] | undefined\n\t#destroyed = false\n\n\tconstructor(options?: MaterializerOptions) {\n\t\tthis.#emitter = new Emitter<MaterializerEventMap>({ on: options?.on, error: options?.error })\n\t\t// The host IS this package's own vendored data unless `options.host`\n\t\t// overrides it — see `hostRoot`'s doc-comment for the resolution law.\n\t\tthis.#host = options?.host ?? hostRoot()\n\t}\n\n\tget emitter(): EmitterInterface<MaterializerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tmaterialize(plan: Plan, target: string): MaterializeResult {\n\t\tthis.#ensureAlive()\n\t\tif (!isVacant(target)) {\n\t\t\tthrow new ScaffoldError('TARGET', 'materialize requires a vacant target', { target })\n\t\t}\n\t\tconst written: string[] = []\n\t\tconst copied: string[] = []\n\t\tfor (const artifact of plan.artifacts) {\n\t\t\tif (artifact.origin === 'host') {\n\t\t\t\tthis.#copy(artifact, target)\n\t\t\t\tcopied.push(artifact.path)\n\t\t\t} else {\n\t\t\t\tthis.#write(artifact, target)\n\t\t\t\twritten.push(artifact.path)\n\t\t\t}\n\t\t}\n\t\tconst result: MaterializeResult = { target, written, copied, skipped: [], removed: [] }\n\t\tthis.#emitter.emit('done', result)\n\t\treturn result\n\t}\n\n\trepair(plan: Plan, audit: Audit, target: string): MaterializeResult {\n\t\tthis.#ensureAlive()\n\t\tconst drifted = new Map(audit.findings.map((finding) => [finding.path, finding.drift]))\n\t\tconst written: string[] = []\n\t\tconst copied: string[] = []\n\t\tconst skipped: string[] = []\n\t\tfor (const artifact of plan.artifacts) {\n\t\t\tconst drift = drifted.get(artifact.path)\n\t\t\tif (drift !== 'missing' && drift !== 'stale') {\n\t\t\t\tskipped.push(artifact.path)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tif (artifact.origin === 'host') {\n\t\t\t\tthis.#copy(artifact, target)\n\t\t\t\tcopied.push(artifact.path)\n\t\t\t} else {\n\t\t\t\tthis.#write(artifact, target)\n\t\t\t\twritten.push(artifact.path)\n\t\t\t}\n\t\t}\n\t\tconst result: MaterializeResult = { target, written, copied, skipped, removed: [] }\n\t\tthis.#emitter.emit('done', result)\n\t\treturn result\n\t}\n\n\t// The unexpected-file scan itself lives in `pruneTargets` (server/helpers.js)\n\t// — the single source of truth both this deletion and the bin's audit/preview\n\t// UX read from; `prune` only deletes exactly what it reports.\n\tprune(target: string): MaterializeResult {\n\t\tthis.#ensureAlive()\n\t\tconst removed: string[] = []\n\t\tfor (const path of pruneTargets(target, this.#host)) {\n\t\t\tconst full = Materializer.#assertContained(target, path, 'WRITE', path)\n\t\t\tunlinkSync(full)\n\t\t\tremoved.push(path)\n\t\t\tthis.#emitter.emit('remove', path)\n\t\t}\n\t\tconst result: MaterializeResult = { target, written: [], copied: [], skipped: [], removed }\n\t\tthis.#emitter.emit('done', result)\n\t\treturn result\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t#copy(artifact: Artifact, target: string): void {\n\t\tconst source = artifact.source ?? artifact.path\n\t\tconst manifest = this.#manifest()\n\t\tif (manifest === undefined) {\n\t\t\tconst from = Materializer.#assertContained(this.#host, source, 'TARGET', artifact.path)\n\t\t\tconst to = Materializer.#assertContained(target, artifact.path, 'WRITE', artifact.path)\n\t\t\ttry {\n\t\t\t\tmkdirSync(dirname(to), { recursive: true })\n\t\t\t\tcpSync(from, to, { recursive: true })\n\t\t\t} catch (error) {\n\t\t\t\tthis.#emitter.emit('error', error)\n\t\t\t\tthrow new ScaffoldError('WRITE', `Failed to copy host artifact at ${artifact.path}`, {\n\t\t\t\t\tpath: artifact.path,\n\t\t\t\t\terror,\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.#emitter.emit('copy', artifact.path)\n\t\t\treturn\n\t\t}\n\t\tconst entries = manifest.filter(\n\t\t\t(entry) => entry.destination === source || entry.destination.startsWith(`${source}/`),\n\t\t)\n\t\tif (entries.length === 0) {\n\t\t\tif (!source.startsWith('guides/src/') || !source.endsWith('.md')) {\n\t\t\t\t// Not a dependency-guide pointer — every HOST_PATHS source is\n\t\t\t\t// always staged by `stageHost`, so a non-guide zero-match means a\n\t\t\t\t// corrupted or truncated manifest, not a legitimate degrade (see\n\t\t\t\t// the class doc comment). Fail closed.\n\t\t\t\tthrow new ScaffoldError(\n\t\t\t\t\t'TARGET',\n\t\t\t\t\t`Manifest entry for \"${source}\" is missing — the vendored manifest may be corrupted or truncated`,\n\t\t\t\t\t{ target, source },\n\t\t\t\t)\n\t\t\t}\n\t\t\t// A dependency-guide pointer — degrade to a stub instead of throwing,\n\t\t\t// mirroring the read path's presence-only treatment of a\n\t\t\t// never-hydrated host artifact (see the class doc comment).\n\t\t\tconst to = Materializer.#assertContained(target, artifact.path, 'WRITE', artifact.path)\n\t\t\ttry {\n\t\t\t\tmkdirSync(dirname(to), { recursive: true })\n\t\t\t\twriteFileSync(to, Materializer.#stub(source), 'utf8')\n\t\t\t} catch (error) {\n\t\t\t\tthis.#emitter.emit('error', error)\n\t\t\t\tthrow new ScaffoldError('WRITE', `Failed to write host artifact stub at ${artifact.path}`, {\n\t\t\t\t\tpath: artifact.path,\n\t\t\t\t\terror,\n\t\t\t\t})\n\t\t\t}\n\t\t\tthis.#emitter.emit('copy', artifact.path)\n\t\t\treturn\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tconst from = Materializer.#assertContained(this.#host, entry.storage, 'TARGET', artifact.path)\n\t\t\tconst to = Materializer.#assertContained(target, entry.destination, 'WRITE', artifact.path)\n\t\t\ttry {\n\t\t\t\tmkdirSync(dirname(to), { recursive: true })\n\t\t\t\tcpSync(from, to)\n\t\t\t\tif (entry.executable) chmodSync(to, 0o755)\n\t\t\t} catch (error) {\n\t\t\t\tthis.#emitter.emit('error', error)\n\t\t\t\tthrow new ScaffoldError('WRITE', `Failed to copy host artifact at ${artifact.path}`, {\n\t\t\t\t\tpath: artifact.path,\n\t\t\t\t\terror,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t\tthis.#emitter.emit('copy', artifact.path)\n\t}\n\n\t// Lazily load + cache `host`'s `manifest.json` (once per instance) —\n\t// `undefined` means `host` has no manifest and callers fall back to the\n\t// 1:1 raw-root mapping.\n\t#manifest(): readonly ManifestEntry[] | undefined {\n\t\tif (!this.#manifestLoaded) {\n\t\t\tthis.#manifestEntries = readHostManifest(this.#host)\n\t\t\tthis.#manifestLoaded = true\n\t\t}\n\t\treturn this.#manifestEntries\n\t}\n\n\t#write(artifact: Artifact, target: string): void {\n\t\tconst to = Materializer.#assertContained(target, artifact.path, 'WRITE', artifact.path)\n\t\ttry {\n\t\t\tmkdirSync(dirname(to), { recursive: true })\n\t\t\twriteFileSync(to, artifact.content ?? '', 'utf8')\n\t\t} catch (error) {\n\t\t\tthis.#emitter.emit('error', error)\n\t\t\tthrow new ScaffoldError('WRITE', `Failed to write artifact at ${artifact.path}`, {\n\t\t\t\tpath: artifact.path,\n\t\t\t\terror,\n\t\t\t})\n\t\t}\n\t\tthis.#emitter.emit('write', artifact.path)\n\t}\n\n\t// Resolve `join(root, relative)` and assert it stays within `resolve(root)`\n\t// — a prefix check against the REAL-PATH-resolved root PLUS a path\n\t// separator, never naive `startsWith` on the raw joined string. `code` is\n\t// `'WRITE'` for a destination escape (asserted against `target`) and\n\t// `'TARGET'` for a source escape (asserted against `host`), per the Errors\n\t// section's coded semantics.\n\tstatic #assertContained(\n\t\troot: string,\n\t\trelative: string,\n\t\tcode: 'WRITE' | 'TARGET',\n\t\tpath: string,\n\t): string {\n\t\tconst resolvedRoot = Materializer.#resolveReal(resolve(root))\n\t\tconst resolvedCandidate = Materializer.#resolveReal(resolve(root, relative))\n\t\tif (resolvedCandidate !== resolvedRoot && !resolvedCandidate.startsWith(resolvedRoot + sep)) {\n\t\t\tconst boundary = code === 'WRITE' ? 'target' : 'host'\n\t\t\tthrow new ScaffoldError(code, `Artifact path \"${path}\" escapes the ${boundary} root`, {\n\t\t\t\tpath,\n\t\t\t\troot,\n\t\t\t})\n\t\t}\n\t\treturn resolve(root, relative)\n\t}\n\n\t// A short, friendly stand-in for a not-yet-fetched dependency guide — the\n\t// scaffolded package's own guides-parity test (`tests/guides/src/\n\t// parity.test.ts`) only walks `guides/README.md`'s manifest (this\n\t// package's OWN concept), never a dependency's `guides/src/<dep>.md`\n\t// mirror, so no structural content is required here; `pull` (`Sync.write`)\n\t// overwrites this stub with the real bytes once fetched. `source` is\n\t// always a `guides/src/<dep>.md` pointer at this call site — the sole\n\t// caller (`#copy`'s zero-match branch) already scoped the degrade to it.\n\tstatic #stub(source: string): string {\n\t\tconst short = source.slice('guides/src/'.length, source.length - '.md'.length)\n\t\treturn `> Vendored guide for @orkestrel/${short} — run \\`scaffold pull\\` to fetch it.\\n`\n\t}\n\n\t// Realpath-resolve the DEEPEST EXISTING ancestor of `path` (following any\n\t// symlink it or its ancestors are), then rejoin the still-nonexistent\n\t// remainder unchanged — so a containment check sees where a symlinked\n\t// segment ACTUALLY points, while a not-yet-created leaf (the file/dir a\n\t// write is about to create) is not itself realpath'd (it does not exist).\n\tstatic #resolveReal(path: string): string {\n\t\tif (existsSync(path)) return realpathSync(path)\n\t\tconst parent = dirname(path)\n\t\tif (parent === path) return path\n\t\treturn join(Materializer.#resolveReal(parent), relativeOf(parent, path))\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) throw new ScaffoldError('DESTROYED', 'Materializer has been destroyed')\n\t}\n}\n","import type { SyncEventMap, SyncInterface, SyncOptions } from './types.js'\nimport type {\n\tCatalogEntry,\n\tDependency,\n\tFreshness,\n\tGuideSync,\n\tSyncReport,\n\tVersionSync,\n} from '@src/core'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { BlockquoteNode } from '@orkestrel/markdown'\nimport { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from 'node:fs'\nimport { dirname, join, relative as relativeOf, resolve, sep } from 'node:path'\nimport { Emitter } from '@orkestrel/emitter'\nimport {\n\tflattenText,\n\tisBlockquoteNode,\n\tisParagraphNode,\n\tparseDocument,\n\twalkNodes,\n} from '@orkestrel/markdown'\nimport { manifestToDependencies, rangeToFreshness, ScaffoldError } from '@src/core'\nimport { readManifest } from './helpers.js'\n\n/**\n * The upstream-synchronization entity (server) — the impure FETCH sibling of\n * `Materializer`, Promise-based and network-only.\n *\n * @remarks\n * Every method reads upstream over HTTPS with a 10-second per-request\n * `AbortSignal.timeout` and bounded `concurrency` (default 6, never an\n * unbounded `Promise.all`). The default COLLECT posture captures each\n * dependency's `freshness` (`404` → `missing`, transport / other non-2xx →\n * `failed`) into the result; `strict` mode instead throws\n * `ScaffoldError('FETCH', …)` naming the failing URL. `guides`'s optional\n * `current` parameter is a caller-supplied local-mirror content map keyed by\n * dependency NAME (the `diffPlan` caller-supplied-reference pattern): WITH the\n * map, a fetched guide byte-equal to its entry verdicts `current`, anything\n * differing or absent from the map verdicts `behind`; WITHOUT the map, every\n * successful fetch verdicts `behind` (no reference means it needs syncing).\n * `pull` builds that map itself from the TARGET's own `guides/src/<short>.md`\n * mirrors, so its verdicts are target-relative; `write` commits only the\n * `behind` guides (never `current`, `missing`, or `failed`, which carries no\n * trustworthy content) under the same realpath-anchored containment law\n * `Materializer` enforces. After `destroy()` every method throws `DESTROYED`;\n * teardown is idempotent, emitter last.\n *\n * @example\n * ```ts\n * import { createSync } from '@orkestrel/scaffold/server'\n *\n * const sync = createSync()\n * const report = await sync.pull('.')\n * if (report.failed === 0) await sync.write(report, '.')\n * sync.destroy()\n * ```\n */\nexport class Sync implements SyncInterface {\n\tstatic readonly #DEFAULT_TIMEOUT = 10_000\n\tstatic readonly #DEFAULT_CONCURRENCY = 6\n\tstatic readonly #DEFAULT_LIMIT = 5_242_880 // 5 MiB\n\n\treadonly #emitter: Emitter<SyncEventMap>\n\treadonly #guidesBase: string\n\treadonly #branch: string\n\treadonly #guidesTimeout: number\n\treadonly #registryBase: string\n\treadonly #registryTimeout: number\n\treadonly #concurrency: number\n\treadonly #retries: number\n\treadonly #strict: boolean\n\treadonly #limit: number\n\t#destroyed = false\n\n\tconstructor(options?: SyncOptions) {\n\t\tthis.#emitter = new Emitter<SyncEventMap>({ on: options?.on, error: options?.error })\n\t\tthis.#guidesBase = options?.guides?.base ?? 'raw.githubusercontent.com'\n\t\tthis.#branch = options?.guides?.branch ?? 'main'\n\t\tthis.#guidesTimeout = options?.guides?.timeout ?? Sync.#DEFAULT_TIMEOUT\n\t\tthis.#registryBase = options?.registry?.base ?? 'registry.npmjs.org'\n\t\tthis.#registryTimeout = options?.registry?.timeout ?? Sync.#DEFAULT_TIMEOUT\n\t\tthis.#concurrency = options?.concurrency ?? Sync.#DEFAULT_CONCURRENCY\n\t\tthis.#retries = options?.retries ?? 0\n\t\tthis.#strict = options?.strict ?? false\n\t\tthis.#limit = options?.limit ?? Sync.#DEFAULT_LIMIT\n\t}\n\n\tget emitter(): EmitterInterface<SyncEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tasync guides(\n\t\tdeps: readonly Dependency[],\n\t\tcurrent?: Readonly<Record<string, string>>,\n\t): Promise<readonly GuideSync[]> {\n\t\tthis.#ensureAlive()\n\t\treturn Sync.#runPool(deps, this.#concurrency, async (dep) => {\n\t\t\tconst short = Sync.#shortName(dep.name)\n\t\t\tconst url = this.#guideUrl(short)\n\t\t\tconst outcome = await Sync.#fetchText(url, this.#guidesTimeout, this.#retries, this.#limit)\n\t\t\tconst guide = Sync.#toGuideSync(dep.name, short, outcome, current)\n\t\t\tif (outcome.kind === 'failed') this.#emitter.emit('error', outcome.error)\n\t\t\tthis.#emitter.emit('guide', dep.name)\n\t\t\tif (this.#strict && (guide.freshness === 'missing' || guide.freshness === 'failed')) {\n\t\t\t\tthrow new ScaffoldError('FETCH', `Failed to fetch guide at ${url}`, {\n\t\t\t\t\turl,\n\t\t\t\t\tname: dep.name,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn guide\n\t\t})\n\t}\n\n\tasync versions(deps: readonly Dependency[]): Promise<readonly VersionSync[]> {\n\t\tthis.#ensureAlive()\n\t\treturn Sync.#runPool(deps, this.#concurrency, async (dep) => {\n\t\t\tconst url = this.#registryUrl(dep.name)\n\t\t\tconst outcome = await Sync.#fetchText(url, this.#registryTimeout, this.#retries, this.#limit)\n\t\t\tconst version = Sync.#toVersionSync(dep, outcome)\n\t\t\tif (outcome.kind === 'failed') this.#emitter.emit('error', outcome.error)\n\t\t\tthis.#emitter.emit('version', dep.name)\n\t\t\tif (this.#strict && (version.freshness === 'missing' || version.freshness === 'failed')) {\n\t\t\t\tthrow new ScaffoldError('FETCH', `Failed to fetch registry version at ${url}`, {\n\t\t\t\t\turl,\n\t\t\t\t\tname: dep.name,\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn version\n\t\t})\n\t}\n\n\t/**\n\t * The fleet package catalog, sourced from the npm registry — the\n\t * AUTHORITATIVE enumeration (never a caller-supplied root).\n\t *\n\t * @returns One {@link CatalogEntry} per `@orkestrel/*` package the registry\n\t * lists, code-unit sorted by `name`.\n\t * @remarks\n\t * Three fetches build each entry: (1) the org's exact package-list\n\t * (`-/org/orkestrel/package`) enumerates every published name — an\n\t * unreachable or malformed response throws a coded `ScaffoldError('FETCH')`\n\t * UNCONDITIONALLY (never gated by `strict`), since without it there is no\n\t * catalog to build; (2) each name's own registry packument supplies\n\t * `version` (`dist-tags.latest`) and a registry-path `description`\n\t * fallback — a failed/malformed packument keeps the entry (degraded:\n\t * `version: ''`) rather than dropping it, since the org list already\n\t * proved the package exists; (3) each name's own guide\n\t * (`guides/src/<short>.md`, same canonical URL as `guides()`, fetched\n\t * unauthenticated — every fleet repo is public) supplies the PREFERRED\n\t * `description` — its first blockquote's first paragraph — falling back\n\t * to the packument description when the guide 404s, faults, or carries no\n\t * blockquote; a 404 STAYS LISTED (it is a reachability signal, not an\n\t * absence) with a note reading `guide unreachable (HTTP 404 — repo\n\t * private or guide missing?)`. Emits `package` once per entry with a\n\t * combined human-readable `note` (empty when both fetches succeeded)\n\t * alongside the existing `error` events for each degraded sub-fetch.\n\t */\n\tasync catalog(): Promise<readonly CatalogEntry[]> {\n\t\tthis.#ensureAlive()\n\t\tconst orgUrl = this.#orgUrl()\n\t\tconst orgOutcome = await Sync.#fetchText(\n\t\t\torgUrl,\n\t\t\tthis.#registryTimeout,\n\t\t\tthis.#retries,\n\t\t\tthis.#limit,\n\t\t)\n\t\tconst names = Sync.#toOrgPackages(orgOutcome, orgUrl)\n\t\tconst entries = await Sync.#runPool(names, this.#concurrency, async (name) => {\n\t\t\tconst packumentOutcome = await Sync.#fetchText(\n\t\t\t\tthis.#registryUrl(name),\n\t\t\t\tthis.#registryTimeout,\n\t\t\t\tthis.#retries,\n\t\t\t\tthis.#limit,\n\t\t\t)\n\t\t\tconst packument = Sync.#toPackument(packumentOutcome)\n\t\t\tconst short = Sync.#shortName(name)\n\t\t\tconst guideOutcome = await Sync.#fetchText(\n\t\t\t\tthis.#guideUrl(short),\n\t\t\t\tthis.#guidesTimeout,\n\t\t\t\tthis.#retries,\n\t\t\t\tthis.#limit,\n\t\t\t)\n\t\t\tconst guide = Sync.#toGuideDescription(guideOutcome)\n\t\t\tif (packumentOutcome.kind === 'failed') this.#emitter.emit('error', packumentOutcome.error)\n\t\t\tif (guideOutcome.kind === 'failed') this.#emitter.emit('error', guideOutcome.error)\n\t\t\tconst description = guide.description ?? packument.description\n\t\t\tconst note = Sync.#combineNote(guide.note, packument.note)\n\t\t\tthis.#emitter.emit('package', name, note)\n\t\t\treturn { name, version: packument.version, description }\n\t\t})\n\t\treturn [...entries].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0))\n\t}\n\n\tasync pull(target: string): Promise<SyncReport> {\n\t\tthis.#ensureAlive()\n\t\tconst deps = manifestToDependencies(readManifest(target))\n\t\tconst current: Record<string, string> = {}\n\t\tfor (const dep of deps) {\n\t\t\tconst short = Sync.#shortName(dep.name)\n\t\t\tconst full = join(target, 'guides', 'src', `${short}.md`)\n\t\t\tif (!existsSync(full)) continue\n\t\t\ttry {\n\t\t\t\tcurrent[dep.name] = readFileSync(full, 'utf8')\n\t\t\t} catch {\n\t\t\t\t// An unreadable local mirror is treated exactly like an absent one —\n\t\t\t\t// the caller-supplied map simply omits the entry.\n\t\t\t}\n\t\t}\n\t\tconst guides = await this.guides(deps, current)\n\t\tconst versions = await this.versions(deps)\n\t\tconst failed = [...guides, ...versions].filter(\n\t\t\t(entry) => entry.freshness === 'missing' || entry.freshness === 'failed',\n\t\t).length\n\t\tconst clean =\n\t\t\tfailed === 0 &&\n\t\t\tguides.every((guide) => guide.freshness === 'current') &&\n\t\t\tversions.every((version) => version.freshness === 'current')\n\t\tconst report: SyncReport = { target, guides, versions, clean, failed }\n\t\tthis.#emitter.emit('done', report)\n\t\treturn report\n\t}\n\n\tasync write(report: SyncReport, target: string): Promise<readonly string[]> {\n\t\tthis.#ensureAlive()\n\t\tconst written: string[] = []\n\t\tfor (const guide of report.guides) {\n\t\t\tif (guide.freshness !== 'behind') continue\n\t\t\tconst to = Sync.#assertContained(target, guide.path)\n\t\t\ttry {\n\t\t\t\tmkdirSync(dirname(to), { recursive: true })\n\t\t\t\twriteFileSync(to, guide.content, 'utf8')\n\t\t\t} catch (error) {\n\t\t\t\tthis.#emitter.emit('error', error)\n\t\t\t\tthrow new ScaffoldError('WRITE', `Failed to write guide at ${guide.path}`, {\n\t\t\t\t\tpath: guide.path,\n\t\t\t\t\terror,\n\t\t\t\t})\n\t\t\t}\n\t\t\twritten.push(guide.path)\n\t\t\tthis.#emitter.emit('write', guide.path)\n\t\t}\n\t\treturn written\n\t}\n\n\tdestroy(): void {\n\t\tif (this.#destroyed) return\n\t\tthis.#destroyed = true\n\t\tthis.#emitter.emit('destroy')\n\t\tthis.#emitter.destroy()\n\t}\n\n\t// The CANONICAL raw.githubusercontent.com form — `/orkestrel/<short>/refs/heads/<branch>/…`\n\t// — never the legacy `/orkestrel/<short>/<branch>/…` shorthand, which the\n\t// host now 301-redirects to this exact canonical form. `redirect: 'manual'`\n\t// (A1) is a deliberate, kept security posture, so building the canonical\n\t// URL directly (never following the redirect) is the fix — not a relaxed\n\t// redirect policy.\n\t#guideUrl(short: string): string {\n\t\treturn `${Sync.#normalizeBase(this.#guidesBase)}/orkestrel/${short}/refs/heads/${this.#branch}/guides/src/${short}.md`\n\t}\n\n\t// npm's canonical scoped-package registry path keeps the literal `@` and\n\t// encodes only the slash (`encodeURIComponent` would also escape the `@`\n\t// into `%40`, which registries accept but which diverges from the\n\t// canonical form). A valid npm package name — `@orkestrel/*` or any other\n\t// scoped/unscoped name (`extras` may now carry either, per\n\t// `EXTRA_NAME_PATTERN`) — has at most one `/` (the single scope\n\t// boundary), so this plain first-occurrence slash replace is exhaustive\n\t// for every name `versions()` is called with, not just `@orkestrel/*`.\n\t#registryUrl(name: string): string {\n\t\treturn `${Sync.#normalizeBase(this.#registryBase)}/${name.replace('/', '%2F')}`\n\t}\n\n\t// The registry's exact-membership org package list — a flat name→access\n\t// map, not a fuzzy relevance search — is `catalog()`'s authoritative\n\t// enumeration source (never `-/v1/search`, whose `scope:` qualifier does\n\t// not filter as its name implies).\n\t#orgUrl(): string {\n\t\treturn `${Sync.#normalizeBase(this.#registryBase)}/-/org/orkestrel/package`\n\t}\n\n\tstatic #normalizeBase(base: string): string {\n\t\treturn /^https?:\\/\\//.test(base) ? base : `https://${base}`\n\t}\n\n\tstatic #shortName(name: string): string {\n\t\tconst prefix = '@orkestrel/'\n\t\treturn name.startsWith(prefix) ? name.slice(prefix.length) : name\n\t}\n\n\tstatic #isRecord(value: unknown): value is Record<string, unknown> {\n\t\treturn typeof value === 'object' && value !== null && !Array.isArray(value)\n\t}\n\n\t// Bounded-concurrency worker pool — never an unbounded `Promise.all` (§12).\n\t// `concurrency` workers pull from a shared cursor over `items`, each\n\t// running `worker` to completion before pulling the next index; results\n\t// land back at their ORIGINAL index, so the returned array preserves\n\t// input order. Fail-fast-SAFELY: the first worker error stops the cursor\n\t// from issuing further items (a `stopped` flag, checked before each pull)\n\t// and every worker is awaited via `Promise.allSettled` — so a sibling's\n\t// later rejection is always observed, never an `unhandledRejection` — then\n\t// the FIRST error is rethrown.\n\tstatic async #runPool<T, R>(\n\t\titems: readonly T[],\n\t\tconcurrency: number,\n\t\tworker: (item: T) => Promise<R>,\n\t): Promise<R[]> {\n\t\tconst results: R[] = new Array(items.length)\n\t\tconst state: {\n\t\t\tcursor: number\n\t\t\tstopped: boolean\n\t\t\tfirstError: { readonly error: unknown } | undefined\n\t\t} = { cursor: 0, stopped: false, firstError: undefined }\n\t\tconst workers = Array.from({ length: Math.min(concurrency, items.length) }, () =>\n\t\t\tSync.#drain({ items, worker, results, state }),\n\t\t)\n\t\tawait Promise.allSettled(workers)\n\t\tif (state.firstError !== undefined) throw state.firstError.error\n\t\treturn results\n\t}\n\n\t// One worker's pull-and-run loop over the shared pool `state` — extracted\n\t// from `#runPool` so no function is declared inside another (§4). `state`\n\t// carries the mutable cursor/stopped/firstError coordination shared by\n\t// every concurrent worker; `items`, `worker`, and `results` are the pool's\n\t// immutable inputs and output sink.\n\tstatic async #drain<T, R>(pool: {\n\t\treadonly items: readonly T[]\n\t\treadonly worker: (item: T) => Promise<R>\n\t\treadonly results: R[]\n\t\treadonly state: {\n\t\t\tcursor: number\n\t\t\tstopped: boolean\n\t\t\tfirstError: { readonly error: unknown } | undefined\n\t\t}\n\t}): Promise<void> {\n\t\tfor (;;) {\n\t\t\tif (pool.state.stopped) return\n\t\t\tconst index = pool.state.cursor\n\t\t\tpool.state.cursor += 1\n\t\t\tif (index >= pool.items.length) return\n\t\t\ttry {\n\t\t\t\tpool.results[index] = await pool.worker(pool.items[index])\n\t\t\t} catch (error) {\n\t\t\t\tif (pool.state.firstError === undefined) pool.state.firstError = { error }\n\t\t\t\tpool.state.stopped = true\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}\n\n\t// One HTTPS GET with a per-request `AbortSignal.timeout` and up to\n\t// `retries` additional attempts on a TRANSPORT fault (a thrown/rejected\n\t// fetch, a non-2xx non-404 response, a manual 3xx redirect (A1), or a body\n\t// exceeding `limit` bytes (R2)) — a `404` is a definitive upstream answer\n\t// and is never retried. Every `failed` outcome carries `note`, the LAST\n\t// attempt's human-readable cause — a transport error message (with an\n\t// `ECONNREFUSED`-style cause code appended when present), an `HTTP\n\t// <status>`, the fixed redirect-blocked string, or the oversized-body\n\t// message — so a caller can tell WHY, not just THAT, the fetch failed.\n\tstatic async #fetchText(\n\t\turl: string,\n\t\ttimeout: number,\n\t\tretries: number,\n\t\tlimit: number,\n\t): Promise<\n\t\t| { readonly kind: 'ok'; readonly text: string }\n\t\t| { readonly kind: 'missing' }\n\t\t| { readonly kind: 'failed'; readonly error: unknown; readonly note: string }\n\t> {\n\t\tlet lastError: unknown\n\t\tlet lastNote = ''\n\t\tfor (let attempt = 0; attempt <= retries; attempt += 1) {\n\t\t\ttry {\n\t\t\t\t// `redirect: 'manual'` (A1) — a compromised/misconfigured endpoint\n\t\t\t\t// must not silently redirect cross-host; any 3xx (or the opaque\n\t\t\t\t// redirect response `redirect: 'manual'` itself resolves) is treated\n\t\t\t\t// as a distinct, named transport fault — never a bare status code.\n\t\t\t\t// Every fetch is unauthenticated (no headers) — every fleet repo is\n\t\t\t\t// public, so reachability alone is the signal.\n\t\t\t\tconst response = await fetch(url, {\n\t\t\t\t\tsignal: AbortSignal.timeout(timeout),\n\t\t\t\t\tredirect: 'manual',\n\t\t\t\t})\n\t\t\t\tif (response.status === 404) return { kind: 'missing' }\n\t\t\t\tif (\n\t\t\t\t\tresponse.type === 'opaqueredirect' ||\n\t\t\t\t\t(response.status >= 300 && response.status < 400)\n\t\t\t\t) {\n\t\t\t\t\tlastNote = 'redirected (redirect following is disabled)'\n\t\t\t\t\tlastError = new Error(`Redirect blocked for ${url}`)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tlastNote = `HTTP ${String(response.status)}`\n\t\t\t\t\tlastError = new Error(`Unexpected HTTP status ${response.status} for ${url}`)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst read = await Sync.#readBounded(response, url, limit)\n\t\t\t\tif (!read.ok) {\n\t\t\t\t\tlastError = read.error\n\t\t\t\t\tlastNote = read.note\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\treturn { kind: 'ok', text: read.text }\n\t\t\t} catch (error) {\n\t\t\t\tlastError = error\n\t\t\t\tlastNote = Sync.#transportNote(error)\n\t\t\t}\n\t\t}\n\t\treturn { kind: 'failed', error: lastError, note: lastNote }\n\t}\n\n\t// A thrown/rejected `fetch`'s message, with the underlying cause's `code`\n\t// (e.g. `ECONNREFUSED`, `ETIMEDOUT`) appended when the runtime attaches\n\t// one — Node's `fetch failed` wraps the real socket error in `.cause`.\n\tstatic #transportNote(error: unknown): string {\n\t\tif (!(error instanceof Error)) return String(error)\n\t\tconst code = Sync.#causeCode(error)\n\t\treturn code !== undefined ? `${error.message}: ${code}` : error.message\n\t}\n\n\tstatic #causeCode(error: Error): string | undefined {\n\t\tconst cause = error.cause\n\t\tif (typeof cause !== 'object' || cause === null) return undefined\n\t\tif (!('code' in cause)) return undefined\n\t\treturn typeof cause.code === 'string' ? cause.code : undefined\n\t}\n\n\t// Reads `response.body` incrementally, counting bytes, aborting past\n\t// `limit` (a declared oversized `Content-Length` short-circuits before any\n\t// read) — an overflow is reported as a transport fault, handled by the\n\t// caller exactly like any other (retry-eligible, then `failed` / strict\n\t// `FETCH`). `response.body` may be `null` (e.g. an empty reply); that\n\t// decodes to an empty string with no reader loop.\n\tstatic async #readBounded(\n\t\tresponse: Response,\n\t\turl: string,\n\t\tlimit: number,\n\t): Promise<\n\t\t| { readonly ok: true; readonly text: string }\n\t\t| { readonly ok: false; readonly error: unknown; readonly note: string }\n\t> {\n\t\tconst declared = response.headers.get('content-length')\n\t\tif (declared !== null) {\n\t\t\tconst declaredBytes = Number(declared)\n\t\t\tif (Number.isFinite(declaredBytes) && declaredBytes > limit) {\n\t\t\t\treturn {\n\t\t\t\t\tok: false,\n\t\t\t\t\terror: new Error(\n\t\t\t\t\t\t`Response body for ${url} declares ${String(declaredBytes)} bytes, exceeding the ${String(limit)}-byte limit`,\n\t\t\t\t\t),\n\t\t\t\t\tnote: `response exceeded limit (${String(limit)} bytes)`,\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconst body = response.body\n\t\tif (body === null) return { ok: true, text: '' }\n\t\tconst reader = body.getReader()\n\t\tconst decoder = new TextDecoder()\n\t\tconst chunks: string[] = []\n\t\tlet total = 0\n\t\ttry {\n\t\t\tfor (;;) {\n\t\t\t\tconst { done, value } = await reader.read()\n\t\t\t\tif (done) break\n\t\t\t\ttotal += value.byteLength\n\t\t\t\tif (total > limit) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tok: false,\n\t\t\t\t\t\terror: new Error(`Response body for ${url} exceeded the ${String(limit)}-byte limit`),\n\t\t\t\t\t\tnote: `response exceeded limit (${String(limit)} bytes)`,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tchunks.push(decoder.decode(value, { stream: true }))\n\t\t\t}\n\t\t\tchunks.push(decoder.decode())\n\t\t} finally {\n\t\t\treader.releaseLock()\n\t\t}\n\t\treturn { ok: true, text: chunks.join('') }\n\t}\n\n\tstatic #toGuideSync(\n\t\tname: string,\n\t\tshort: string,\n\t\toutcome:\n\t\t\t| { readonly kind: 'ok'; readonly text: string }\n\t\t\t| { readonly kind: 'missing' }\n\t\t\t| { readonly kind: 'failed'; readonly error: unknown; readonly note: string },\n\t\tcurrent?: Readonly<Record<string, string>>,\n\t): GuideSync {\n\t\tconst path = `guides/src/${short}.md`\n\t\tif (outcome.kind === 'missing') {\n\t\t\treturn { name, path, content: '', freshness: 'missing', note: 'HTTP 404' }\n\t\t}\n\t\tif (outcome.kind === 'failed') {\n\t\t\treturn { name, path, content: '', freshness: 'failed', note: outcome.note }\n\t\t}\n\t\tconst freshness: Freshness = current?.[name] === outcome.text ? 'current' : 'behind'\n\t\treturn { name, path, content: outcome.text, freshness }\n\t}\n\n\tstatic #toVersionSync(\n\t\tdep: Dependency,\n\t\toutcome:\n\t\t\t| { readonly kind: 'ok'; readonly text: string }\n\t\t\t| { readonly kind: 'missing' }\n\t\t\t| { readonly kind: 'failed'; readonly error: unknown; readonly note: string },\n\t): VersionSync {\n\t\tif (outcome.kind === 'missing') {\n\t\t\treturn {\n\t\t\t\tname: dep.name,\n\t\t\t\trange: dep.range,\n\t\t\t\tlatest: '',\n\t\t\t\tfreshness: 'missing',\n\t\t\t\tnote: 'HTTP 404',\n\t\t\t}\n\t\t}\n\t\tif (outcome.kind === 'failed') {\n\t\t\treturn {\n\t\t\t\tname: dep.name,\n\t\t\t\trange: dep.range,\n\t\t\t\tlatest: '',\n\t\t\t\tfreshness: 'failed',\n\t\t\t\tnote: outcome.note,\n\t\t\t}\n\t\t}\n\t\tconst latest = Sync.#parseLatest(outcome.text)\n\t\tif (latest === undefined) {\n\t\t\treturn {\n\t\t\t\tname: dep.name,\n\t\t\t\trange: dep.range,\n\t\t\t\tlatest: '',\n\t\t\t\tfreshness: 'failed',\n\t\t\t\tnote: 'malformed registry response (missing dist-tags.latest)',\n\t\t\t}\n\t\t}\n\t\treturn {\n\t\t\tname: dep.name,\n\t\t\trange: dep.range,\n\t\t\tlatest,\n\t\t\tfreshness: rangeToFreshness(dep.range, latest),\n\t\t}\n\t}\n\n\t// The org package-list response is the WHOLE reason `catalog()` can claim\n\t// to be authoritative — an unreachable or malformed response means there\n\t// IS no catalog, so this throws unconditionally (never gated by\n\t// `strict`), unlike every other collect-mode FETCH outcome in this class.\n\tstatic #toOrgPackages(\n\t\toutcome:\n\t\t\t| { readonly kind: 'ok'; readonly text: string }\n\t\t\t| { readonly kind: 'missing' }\n\t\t\t| { readonly kind: 'failed'; readonly error: unknown; readonly note: string },\n\t\turl: string,\n\t): readonly string[] {\n\t\tif (outcome.kind === 'missing' || outcome.kind === 'failed') {\n\t\t\tconst note = outcome.kind === 'missing' ? 'HTTP 404' : outcome.note\n\t\t\tthrow new ScaffoldError('FETCH', `Failed to fetch the package list at ${url}`, { url, note })\n\t\t}\n\t\tlet parsed: unknown\n\t\ttry {\n\t\t\tparsed = JSON.parse(outcome.text)\n\t\t} catch {\n\t\t\tthrow new ScaffoldError('FETCH', `Malformed package list response at ${url}`, { url })\n\t\t}\n\t\tif (!Sync.#isRecord(parsed)) {\n\t\t\tthrow new ScaffoldError('FETCH', `Malformed package list response at ${url}`, { url })\n\t\t}\n\t\tconst names = Object.keys(parsed).filter((name) => name.startsWith('@orkestrel/'))\n\t\tif (names.length === 0) {\n\t\t\tthrow new ScaffoldError('FETCH', `Malformed package list response at ${url}`, { url })\n\t\t}\n\t\treturn names\n\t}\n\n\t// A packument fetch that fails or comes back malformed keeps the entry\n\t// (the org list already proved the package exists) rather than dropping\n\t// it — degraded, never absent. The FULL packument (never the abbreviated\n\t// `Accept` form, which omits `description`) supplies both `dist-tags.latest`\n\t// and the top-level `description` — the registry-path fallback description.\n\tstatic #toPackument(\n\t\toutcome:\n\t\t\t| { readonly kind: 'ok'; readonly text: string }\n\t\t\t| { readonly kind: 'missing' }\n\t\t\t| { readonly kind: 'failed'; readonly error: unknown; readonly note: string },\n\t): { readonly version: string; readonly description: string; readonly note: string } {\n\t\tif (outcome.kind === 'missing') return { version: '', description: '', note: 'HTTP 404' }\n\t\tif (outcome.kind === 'failed') {\n\t\t\treturn { version: '', description: '', note: outcome.note }\n\t\t}\n\t\tlet parsed: unknown\n\t\ttry {\n\t\t\tparsed = JSON.parse(outcome.text)\n\t\t} catch {\n\t\t\treturn {\n\t\t\t\tversion: '',\n\t\t\t\tdescription: '',\n\t\t\t\tnote: 'malformed registry response (invalid JSON)',\n\t\t\t}\n\t\t}\n\t\tif (!Sync.#isRecord(parsed)) {\n\t\t\treturn {\n\t\t\t\tversion: '',\n\t\t\t\tdescription: '',\n\t\t\t\tnote: 'malformed registry response (not an object)',\n\t\t\t}\n\t\t}\n\t\tconst distTags = parsed['dist-tags']\n\t\tconst version =\n\t\t\tSync.#isRecord(distTags) && typeof distTags.latest === 'string' ? distTags.latest : ''\n\t\tconst description = typeof parsed.description === 'string' ? parsed.description : ''\n\t\tconst note = version === '' ? 'malformed registry response (missing dist-tags.latest)' : ''\n\t\treturn { version, description, note }\n\t}\n\n\t// The guide-fetch counterpart of `#toPackument` — `description` is\n\t// `undefined` (never `''`) on ANY degradation (404, transport fault, no\n\t// blockquote) so `catalog()`'s caller can cleanly fall back to the\n\t// packument description with `??`. Every fleet repo is public, so a guide\n\t// 404 is a READINESS signal (repo private or guide not yet written), not\n\t// an absence — the entry STAYS LISTED with this exact note text.\n\tstatic #toGuideDescription(\n\t\toutcome:\n\t\t\t| { readonly kind: 'ok'; readonly text: string }\n\t\t\t| { readonly kind: 'missing' }\n\t\t\t| { readonly kind: 'failed'; readonly error: unknown; readonly note: string },\n\t): { readonly description: string | undefined; readonly note: string } {\n\t\tif (outcome.kind === 'missing') {\n\t\t\treturn {\n\t\t\t\tdescription: undefined,\n\t\t\t\tnote: 'guide unreachable (HTTP 404 — repo private or guide missing?)',\n\t\t\t}\n\t\t}\n\t\tif (outcome.kind === 'failed') return { description: undefined, note: outcome.note }\n\t\tconst description = Sync.#firstBlockquoteParagraph(outcome.text)\n\t\treturn description !== undefined\n\t\t\t? { description, note: '' }\n\t\t\t: { description: undefined, note: 'guide has no blockquote description' }\n\t}\n\n\t// The first top-level paragraph of the guide's first blockquote — the\n\t// same extraction `catalogPackages` (server/helpers.ts) performs against a\n\t// LOCAL file's content, applied here to FETCHED text.\n\tstatic #firstBlockquoteParagraph(text: string): string | undefined {\n\t\tlet document: ReturnType<typeof parseDocument>\n\t\ttry {\n\t\t\tdocument = parseDocument(text)\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t\tlet quote: BlockquoteNode | undefined\n\t\tfor (const node of walkNodes(document)) {\n\t\t\tif (isBlockquoteNode(node)) {\n\t\t\t\tquote = node\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif (quote === undefined) return undefined\n\t\tconst paragraph = quote.children.find((child) => isParagraphNode(child))\n\t\tif (paragraph === undefined) return undefined\n\t\tconst flattened = flattenText(paragraph).replace(/\\s+/g, ' ').trim()\n\t\treturn flattened.length > 0 ? flattened : undefined\n\t}\n\n\t// Combines a degraded guide/packument note into one human-readable string\n\t// for `SyncEventMap['package']`'s `note` — empty when both succeeded.\n\tstatic #combineNote(guideNote: string, packumentNote: string): string {\n\t\tconst parts: string[] = []\n\t\tif (packumentNote !== '') parts.push(`version unavailable — ${packumentNote}`)\n\t\tif (guideNote !== '') parts.push(`description from registry — ${guideNote}`)\n\t\treturn parts.join('; ')\n\t}\n\n\tstatic #parseLatest(text: string): string | undefined {\n\t\tlet parsed: unknown\n\t\ttry {\n\t\t\tparsed = JSON.parse(text)\n\t\t} catch {\n\t\t\treturn undefined\n\t\t}\n\t\tif (!Sync.#isRecord(parsed)) return undefined\n\t\tconst distTags = parsed['dist-tags']\n\t\tif (!Sync.#isRecord(distTags)) return undefined\n\t\tconst latest = distTags.latest\n\t\treturn typeof latest === 'string' ? latest : undefined\n\t}\n\n\t// Mirrors `Materializer.#assertContained` — a real-path-anchored prefix\n\t// check against `resolve(target)`, closing the traversal vector a\n\t// hand-built or off-pattern dependency name could open through the\n\t// derived write path.\n\tstatic #assertContained(target: string, relative: string): string {\n\t\tconst resolvedRoot = Sync.#resolveReal(resolve(target))\n\t\tconst resolvedCandidate = Sync.#resolveReal(resolve(target, relative))\n\t\tif (resolvedCandidate !== resolvedRoot && !resolvedCandidate.startsWith(resolvedRoot + sep)) {\n\t\t\tthrow new ScaffoldError('WRITE', `Guide path \"${relative}\" escapes the target root`, {\n\t\t\t\tpath: relative,\n\t\t\t\ttarget,\n\t\t\t})\n\t\t}\n\t\treturn resolve(target, relative)\n\t}\n\n\tstatic #resolveReal(path: string): string {\n\t\tif (existsSync(path)) return realpathSync(path)\n\t\tconst parent = dirname(path)\n\t\tif (parent === path) return path\n\t\treturn join(Sync.#resolveReal(parent), relativeOf(parent, path))\n\t}\n\n\t#ensureAlive(): void {\n\t\tif (this.#destroyed) throw new ScaffoldError('DESTROYED', 'Sync has been destroyed')\n\t}\n}\n","import type {\n\tMaterializerInterface,\n\tMaterializerOptions,\n\tSyncInterface,\n\tSyncOptions,\n} from './types.js'\nimport { Materializer } from './Materializer.js'\nimport { Sync } from './Sync.js'\n\n/**\n * Create a `MaterializerInterface` (server) — the materialization entity,\n * seeded from `MaterializerOptions`.\n *\n * @param options - Optional `host` root override, emitter hooks, and error handler\n * @returns A {@link MaterializerInterface}\n *\n * @example\n * ```ts\n * import { createMaterializer } from '@orkestrel/scaffold/server'\n *\n * const materializer = createMaterializer()\n * materializer.destroy()\n * ```\n */\nexport function createMaterializer(options?: MaterializerOptions): MaterializerInterface {\n\treturn new Materializer(options)\n}\n\n/**\n * Create a `SyncInterface` (server) — the upstream-synchronization entity,\n * seeded from `SyncOptions`.\n *\n * @param options - Optional endpoint bases/branch, concurrency, retries, strict, emitter hooks, and error handler\n * @returns A {@link SyncInterface}\n *\n * @example\n * ```ts\n * import { createSync } from '@orkestrel/scaffold/server'\n *\n * const sync = createSync()\n * sync.destroy()\n * ```\n */\nexport function createSync(options?: SyncOptions): SyncInterface {\n\treturn new Sync(options)\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@orkestrel/scaffold",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Blueprint-to-plan package scaffolding, auditing, dependency guide/version pulling, and fleet-wide shared-file upkeep for the @orkestrel line.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"audit",
|
|
7
|
+
"blueprint",
|
|
8
|
+
"codegen",
|
|
9
|
+
"conformance",
|
|
10
|
+
"fleet",
|
|
11
|
+
"orkestrel",
|
|
12
|
+
"pull",
|
|
13
|
+
"scaffold",
|
|
14
|
+
"typescript"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://github.com/orkestrel/scaffold#readme",
|
|
17
|
+
"bugs": "https://github.com/orkestrel/scaffold/issues",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/orkestrel/scaffold.git"
|
|
22
|
+
},
|
|
23
|
+
"bin": {
|
|
24
|
+
"scaffold": "./dist/bin/scaffold.js"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
30
|
+
"type": "module",
|
|
31
|
+
"sideEffects": [
|
|
32
|
+
"./src/bin/scaffold.ts",
|
|
33
|
+
"./dist/bin/scaffold.js"
|
|
34
|
+
],
|
|
35
|
+
"main": "./dist/src/core/index.cjs",
|
|
36
|
+
"module": "./dist/src/core/index.js",
|
|
37
|
+
"exports": {
|
|
38
|
+
".": {
|
|
39
|
+
"import": {
|
|
40
|
+
"types": "./dist/src/core/index.d.ts",
|
|
41
|
+
"default": "./dist/src/core/index.js"
|
|
42
|
+
},
|
|
43
|
+
"require": {
|
|
44
|
+
"types": "./dist/src/core/index.d.cts",
|
|
45
|
+
"default": "./dist/src/core/index.cjs"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
"./server": {
|
|
49
|
+
"import": {
|
|
50
|
+
"types": "./dist/src/server/index.d.ts",
|
|
51
|
+
"default": "./dist/src/server/index.js"
|
|
52
|
+
},
|
|
53
|
+
"require": {
|
|
54
|
+
"types": "./dist/src/server/index.d.cts",
|
|
55
|
+
"default": "./dist/src/server/index.cjs"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
"./package.json": "./package.json"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
},
|
|
63
|
+
"scripts": {
|
|
64
|
+
"clean": "node -e \"try{require('node:fs').rmSync('dist',{recursive:true,force:true})}catch{}\"",
|
|
65
|
+
"copy": "node -e \"const fs=require('node:fs'),p=require('node:path'),a=process.argv[1],b=process.argv[2];fs.mkdirSync(p.dirname(b),{recursive:true});fs.cpSync(a,b,{force:true});console.log('Copied: '+a+' to '+b)\"",
|
|
66
|
+
"tmp:txt": "node -e \"const fs=require('node:fs'),p=require('node:path');function walk(d){for(const e of fs.readdirSync(d,{withFileTypes:true})){const f=p.join(d,e.name);if(e.isDirectory()){walk(f)}else if(!e.name.endsWith('.md')&&!e.name.endsWith('.txt')){const t=f+'.txt';if(!fs.existsSync(t)){fs.renameSync(f,t)}else{console.warn('Skipping '+f+' — target exists: '+t)}}}}try{walk('tmp')}catch(e){if(e.code!=='ENOENT')throw e}\"",
|
|
67
|
+
"scaffold": "node ./dist/bin/scaffold.js",
|
|
68
|
+
"lint": "oxlint --config .oxlintrc.json --fix .",
|
|
69
|
+
"check": "tsc --noEmit --project tsconfig.json && npm run check:src",
|
|
70
|
+
"check:src": "npm run check:src:core && npm run check:src:server && npm run check:src:bin",
|
|
71
|
+
"check:src:core": "tsc --noEmit -p configs/src/tsconfig.core.json",
|
|
72
|
+
"check:src:server": "tsc --noEmit -p configs/src/tsconfig.server.json",
|
|
73
|
+
"check:src:bin": "tsc --noEmit -p configs/src/tsconfig.bin.json",
|
|
74
|
+
"format": "oxfmt --config .oxfmtrc.json --write .",
|
|
75
|
+
"format:check": "oxfmt --config .oxfmtrc.json --check .",
|
|
76
|
+
"lint:check": "oxlint --config .oxlintrc.json .",
|
|
77
|
+
"test": "npm run test:src && npm run test:guides",
|
|
78
|
+
"test:src": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core --project src:server --project src:bin",
|
|
79
|
+
"test:src:core": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:core",
|
|
80
|
+
"test:src:server": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:server",
|
|
81
|
+
"test:src:bin": "vitest run --config vite.config.ts --no-cache --reporter=dot --project src:bin",
|
|
82
|
+
"test:guides": "vitest run --config vite.config.ts --reporter=dot --project guides",
|
|
83
|
+
"build": "npm run clean && npm run build:src && npm run build:host",
|
|
84
|
+
"build:src": "npm run build:src:core && npm run build:src:server && npm run build:src:bin",
|
|
85
|
+
"build:src:core": "vite build --config configs/src/vite.core.config.ts && npm run copy dist/src/core/index.d.ts dist/src/core/index.d.cts",
|
|
86
|
+
"build:src:server": "vite build --config configs/src/vite.server.config.ts && npm run copy dist/src/server/index.d.ts dist/src/server/index.d.cts",
|
|
87
|
+
"build:src:bin": "vite build --config configs/src/vite.bin.config.ts",
|
|
88
|
+
"build:host": "node -e \"import('./dist/src/server/index.js').then((m)=>{const n=m.stageHost(process.cwd(),'dist/host').length;console.log('build-host: staged '+n+' file(s) into dist/host')})\"",
|
|
89
|
+
"prepublishOnly": "npm run format:check && npm run lint:check && npm run check && npm run build && npm test"
|
|
90
|
+
},
|
|
91
|
+
"dependencies": {
|
|
92
|
+
"@orkestrel/console": "^0.0.3",
|
|
93
|
+
"@orkestrel/contract": "^0.0.5",
|
|
94
|
+
"@orkestrel/emitter": "^0.0.3",
|
|
95
|
+
"@orkestrel/markdown": "^0.0.5",
|
|
96
|
+
"@orkestrel/template": "^0.0.1",
|
|
97
|
+
"@orkestrel/terminal": "^0.0.4"
|
|
98
|
+
},
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"@microsoft/api-extractor": "^7.58.11",
|
|
101
|
+
"@orkestrel/guide": "^0.0.5",
|
|
102
|
+
"@types/node": "^26.1.1",
|
|
103
|
+
"oxfmt": "^0.59.0",
|
|
104
|
+
"oxlint": "^1.74.0",
|
|
105
|
+
"typescript": "^6.0.3",
|
|
106
|
+
"vite": "^8.1.5",
|
|
107
|
+
"vite-plugin-dts": "^5.0.3",
|
|
108
|
+
"vitest": "^4.1.10"
|
|
109
|
+
},
|
|
110
|
+
"engines": {
|
|
111
|
+
"node": ">=22"
|
|
112
|
+
}
|
|
113
|
+
}
|