/* Generated by packages/context-cli/scripts/build-aspect-runtime.ts. Do not edit directly. */
// src/aspect-runtime/index.ts
import path3 from "node:path";
import { fileURLToPath } from "node:url";

// src/aspect-runtime/context.ts
import { readFile, readdir, realpath, stat } from "node:fs/promises";
import path2 from "node:path";
import { pathToFileURL } from "node:url";

// src/aspect-runtime/helpers.ts
import path from "node:path";
import * as ts from "typescript";
function toPosix(value) {
  return value.split(path.sep).join("/");
}
function repoRelative(repoRoot, absPath) {
  const rel = toPosix(path.relative(repoRoot, absPath));
  validateSourcePath(rel);
  return rel;
}
function validateSourcePath(sourcePath) {
  if (sourcePath.length === 0 || sourcePath.includes("\x00") || sourcePath.includes("\\")) {
    throw new Error(`invalid source_path: ${sourcePath}`);
  }
  if (path.posix.isAbsolute(sourcePath)) {
    throw new Error(`source_path must be relative: ${sourcePath}`);
  }
  const parts = sourcePath.split("/");
  if (parts.some((part) => part.length === 0 || part === "." || part === "..")) {
    throw new Error(`source_path must be normalized and stay inside repo_root: ${sourcePath}`);
  }
}
function sourceFileRef(sourcePath) {
  validateSourcePath(sourcePath);
  return {
    path: sourcePath,
    name: path.posix.basename(sourcePath),
    extension: path.posix.extname(sourcePath).toLowerCase()
  };
}
function encodeSourcePath(sourcePath) {
  validateSourcePath(sourcePath);
  return sourcePath.split("/").map((segment) => encodeURIComponent(segment)).join("/");
}
function encodeFragment(fragment) {
  return encodeURIComponent(fragment);
}
function fileSourceRef(sourcePath, artifact, hash) {
  return `file:${encodeSourcePath(sourcePath)}#${encodeFragment(artifact)}@${hash}`;
}
function slugSegment(raw) {
  const segment = raw.trim().replace(/\.[^.]+$/u, "").replace(/\+$/u, "").replace(/([a-z0-9])([A-Z])/gu, "$1-$2").replace(/[^A-Za-z0-9]+/gu, "-").replace(/^-+|-+$/gu, "").toLowerCase();
  return segment.length > 0 ? segment : "untitled";
}
function markdownFence(language, body) {
  const fence = body.includes("```") ? "~~~~" : "```";
  return `${fence}${language}
${body.trimEnd()}
${fence}`;
}
function normalizeSymbolSlug(raw) {
  const cleaned = raw.replace(/\.[^.]+$/u, "").replace(/\+$/u, "").replace(/[^A-Za-z0-9]+/gu, "").toLowerCase();
  return cleaned.length === 0 ? "unknown" : cleaned;
}
function normalizeComponentSlug(raw) {
  return normalizeSymbolSlug(raw);
}
function inferComponentName(source, fallback) {
  const patterns = [
    /\bimport\s*\{[^}]*\b([A-Z][A-Za-z0-9]+)\b[^}]*\}/u,
    /<\s*([A-Z][A-Za-z0-9]+)\b/u,
    /\b([A-Z][A-Za-z0-9]+)\s*\(/u
  ];
  for (const pattern of patterns) {
    const match = source.match(pattern);
    if (match?.[1])
      return match[1];
  }
  return fallback;
}
function artifactFromRelPath(sourcePath) {
  return sourcePath.replace(/\.[^.]+$/u, "");
}
function firstMarkdownHeading(markdown, fallback) {
  const heading = markdown.match(/^#{1,6}\s+(.+)$/mu)?.[1]?.trim();
  return heading && heading.length > 0 ? heading : fallback;
}
function sourceFileFor(fileName, source) {
  const ext = path.extname(fileName).toLowerCase();
  const scriptKind = ext === ".tsx" ? ts.ScriptKind.TSX : ext === ".jsx" ? ts.ScriptKind.JSX : ext === ".js" || ext === ".cjs" || ext === ".mjs" ? ts.ScriptKind.JS : ts.ScriptKind.TS;
  return ts.createSourceFile(fileName, source, ts.ScriptTarget.Latest, true, scriptKind);
}
function propertyNameText(name) {
  if (ts.isIdentifier(name) || ts.isStringLiteral(name) || ts.isNumericLiteral(name))
    return name.text;
  if (ts.isComputedPropertyName(name) && ts.isStringLiteralLike(name.expression)) {
    return name.expression.text;
  }
  return null;
}
function jsxTagNameText(name) {
  if (ts.isIdentifier(name))
    return name.text;
  if (ts.isPropertyAccessExpression(name))
    return name.name.text;
  return null;
}
function pushUnique(out, seen, value) {
  if (!value || seen.has(value))
    return;
  seen.add(value);
  out.push(value);
}
function parseTsxComponentNames(source, fileName) {
  const sf = sourceFileFor(fileName, source);
  const names = [];
  const seen = new Set;
  const isComponentName = (value) => /^[A-Z][A-Za-z0-9]+$/u.test(value);
  function visit(node) {
    if (ts.isImportDeclaration(node) && node.importClause?.namedBindings && ts.isNamedImports(node.importClause.namedBindings)) {
      for (const specifier of node.importClause.namedBindings.elements) {
        const imported = specifier.propertyName?.text ?? specifier.name.text;
        if (isComponentName(imported))
          pushUnique(names, seen, imported);
      }
    }
    if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
      const tag = jsxTagNameText(node.tagName);
      if (tag && isComponentName(tag))
        pushUnique(names, seen, tag);
    }
    if (ts.isCallExpression(node) && ts.isIdentifier(node.expression) && isComponentName(node.expression.text)) {
      pushUnique(names, seen, node.expression.text);
    }
    ts.forEachChild(node, visit);
  }
  visit(sf);
  return names;
}
function parseJsLikeTokenNames(source, fileName, category) {
  const sf = sourceFileFor(fileName, source);
  const names = [];
  const seen = new Set;
  function maybePush(value) {
    if (!value)
      return;
    if (!/^[A-Za-z_$-][A-Za-z0-9_$-]*$/u.test(value))
      return;
    pushUnique(names, seen, value);
  }
  function visit(node) {
    if (ts.isPropertyAssignment(node)) {
      const name = propertyNameText(node.name);
      if (name === "cssVarName" && ts.isStringLiteralLike(node.initializer)) {
        maybePush(node.initializer.text);
      } else {
        maybePush(name);
      }
    } else if (ts.isShorthandPropertyAssignment(node)) {
      maybePush(node.name.text);
    } else if (ts.isStringLiteralLike(node) && (/^--[A-Za-z0-9_-]+$/u.test(node.text) || /^\$[A-Za-z0-9_-]+$/u.test(node.text))) {
      maybePush(node.text);
    }
    ts.forEachChild(node, visit);
  }
  visit(sf);
  return names.sort((a, b) => a.localeCompare(b));
}
function parseScssTokenNames(source) {
  const names = new Set;
  for (const line of source.split(/\r?\n/u)) {
    const trimmed = line.trim();
    if (trimmed.startsWith("//") || trimmed.startsWith("@import") || trimmed.startsWith("@use"))
      continue;
    const variable = trimmed.match(/^(\$[A-Za-z0-9_-]+)\s*:/u)?.[1];
    if (variable)
      names.add(variable);
    const cssVar = trimmed.match(/(--[A-Za-z0-9_-]+)\s*:/u)?.[1];
    if (cssVar)
      names.add(cssVar);
    const property = trimmed.match(/^([A-Za-z-]+)\s*:/u)?.[1];
    if (property && !["if", "for", "each", "include"].includes(property))
      names.add(property);
  }
  return [...names].sort((a, b) => a.localeCompare(b));
}
function codePackages(input) {
  return "code" in input ? input.code.packages : input.code_index?.packages ?? [];
}
function codeSymbols(input) {
  return "code" in input ? input.code.symbols : input.code_index?.symbols ?? [];
}
function resolvePackageNodeSlug(input, packageSlug) {
  return codePackages(input).find((pkg) => pkg.package_slug === packageSlug)?.node_slug ?? packageSlug;
}
function resolveSymbolNodeSlug(input, packageSlug, componentName) {
  const componentSlug = normalizeSymbolSlug(componentName);
  const normalizedExport = componentName.toLowerCase();
  const match = codeSymbols(input).find((symbol) => {
    if (symbol.package_slug !== undefined && symbol.package_slug !== packageSlug)
      return false;
    const nodeLeaf = symbol.node_slug.split("/").at(-1);
    const names = [symbol.export_name, symbol.symbol_name, ...symbol.aliases ?? [], nodeLeaf].filter((name) => typeof name === "string" && name.length > 0);
    return names.some((rawName) => normalizeSymbolSlug(rawName) === componentSlug || rawName.toLowerCase() === normalizedExport);
  });
  return match?.node_slug ?? `${resolvePackageNodeSlug(input, packageSlug)}/symbol/${componentSlug}`;
}

// src/aspect-runtime/context.ts
function defineAspect(plugin) {
  return plugin;
}
async function readHostInput() {
  const chunks = [];
  for await (const chunk of process.stdin) {
    chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
  }
  const input = JSON.parse(Buffer.concat(chunks).toString("utf8"));
  for (const key of ["workspace_root", "repo_root", "aspect", "source_slug", "source_id", "snapshot_id"]) {
    if (typeof input[key] !== "string" || input[key].length === 0) {
      throw new Error(`aspect host input missing ${key}`);
    }
  }
  return input;
}
async function pathExists(absPath) {
  try {
    await stat(absPath);
    return true;
  } catch (err) {
    const code = err.code;
    if (code === "ENOENT" || code === "ENOTDIR")
      return false;
    throw err;
  }
}
function sourceRefFromInput(source) {
  return typeof source === "string" ? source : source.path;
}
function normalizeSourceRoot(root) {
  if (root === undefined || root === "" || root === ".")
    return "";
  const normalized = toPosix(path2.posix.normalize(toPosix(root)));
  validateSourcePath(normalized);
  return normalized;
}
async function resolveRepoPath(repoRoot, sourcePath) {
  validateSourcePath(sourcePath);
  const realRepoRoot = await realpath(repoRoot);
  const realSource = await realpath(path2.resolve(realRepoRoot, sourcePath));
  const rel = path2.relative(realRepoRoot, realSource);
  if (rel.startsWith("..") || path2.isAbsolute(rel)) {
    throw new Error(`source_path escapes repo_root: ${sourcePath}`);
  }
  return realSource;
}
async function readRepoText(repoRoot, source) {
  return readFile(await resolveRepoPath(repoRoot, sourceRefFromInput(source)), "utf8");
}
async function collectRepoFiles(repoRoot, rootRel, extensions, recursive) {
  const normalizedRoot = normalizeSourceRoot(rootRel);
  const realRepoRoot = await realpath(repoRoot);
  let root;
  try {
    root = normalizedRoot.length > 0 ? await resolveRepoPath(realRepoRoot, normalizedRoot) : realRepoRoot;
  } catch (err) {
    const code = err.code;
    if (code === "ENOENT" || code === "ENOTDIR")
      return [];
    throw err;
  }
  if (!await pathExists(root))
    return [];
  const normalizedExtensions = extensions.map((ext) => ext.toLowerCase());
  const out = [];
  async function walk(dir) {
    const entries = await readdir(dir, { withFileTypes: true });
    for (const entry of entries) {
      if (entry.name.startsWith("."))
        continue;
      const absPath = path2.join(dir, entry.name);
      if (entry.isDirectory()) {
        if (recursive)
          await walk(absPath);
        continue;
      }
      if (!entry.isFile())
        continue;
      const ext = path2.extname(entry.name).toLowerCase();
      if (normalizedExtensions.length > 0 && !normalizedExtensions.includes(ext))
        continue;
      out.push(sourceFileRef(repoRelative(realRepoRoot, absPath)));
    }
  }
  await walk(root);
  return out.sort((a, b) => a.path.localeCompare(b.path));
}
function normalizeSection(row) {
  const sourcePath = row.source_path ?? (row.source !== undefined ? sourceRefFromInput(row.source) : undefined);
  if (sourcePath === undefined) {
    throw new Error("ctx.emit.section requires source or source_path");
  }
  validateSourcePath(sourcePath);
  if (row.artifact.trim().length === 0) {
    throw new Error("ctx.emit.section requires a non-empty artifact");
  }
  return {
    node_slug: row.node_slug,
    kind: row.kind,
    ...row.summary !== undefined && row.summary.length > 0 ? { summary: row.summary } : {},
    content: row.content,
    source_path: sourcePath,
    artifact: row.artifact
  };
}
function normalizeNode(row) {
  if (row.node_slug.trim().length === 0) {
    throw new Error("ctx.emit.node requires a non-empty node_slug");
  }
  if (row.title.trim().length === 0) {
    throw new Error("ctx.emit.node requires a non-empty title");
  }
  return {
    node_slug: row.node_slug,
    title: row.title,
    type: row.type ?? "entity",
    tags: [...row.tags ?? ["module"]],
    ...row.summary !== undefined && row.summary.length > 0 ? { summary: row.summary } : {},
    ...row.parent_slug !== undefined && row.parent_slug.length > 0 ? { parent_slug: row.parent_slug } : {},
    ...row.code_package !== undefined && row.code_package.length > 0 ? { code_package: row.code_package } : {},
    ...row.language !== undefined && row.language.length > 0 ? { language: row.language } : {}
  };
}
function findPackage(packages, packageSlug) {
  return packages.find((pkg) => pkg.package_slug === packageSlug);
}
function findSymbol(symbols, packageSlug, symbolName) {
  const target = normalizeComponentSlug(symbolName);
  return symbols.find((symbol) => {
    if (symbol.package_slug !== undefined && symbol.package_slug !== packageSlug)
      return false;
    const nodeLeaf = symbol.node_slug.split("/").at(-1);
    const names = [symbol.export_name, symbol.symbol_name, ...symbol.aliases ?? [], nodeLeaf].filter((name) => typeof name === "string" && name.length > 0);
    return names.some((name) => normalizeComponentSlug(name) === target || name.toLowerCase() === symbolName.toLowerCase());
  });
}
function buildContext(input, nodes, sections, warnings) {
  const packages = input.code_index?.packages ?? [];
  const symbols = input.code_index?.symbols ?? [];
  return {
    aspect: {
      name: input.aspect,
      source_slug: input.source_slug,
      source_id: input.source_id,
      snapshot_id: input.snapshot_id
    },
    source: {
      glob: (options = {}) => collectRepoFiles(input.repo_root, options.root ?? "", options.extensions ?? [], options.recursive ?? true),
      immediateFiles: (root, extensions) => collectRepoFiles(input.repo_root, root, extensions, false),
      exists: async (source) => {
        try {
          await resolveRepoPath(input.repo_root, sourceRefFromInput(source));
          return true;
        } catch (err) {
          const code = err.code;
          if (code === "ENOENT" || code === "ENOTDIR")
            return false;
          return false;
        }
      },
      readText: (source) => readRepoText(input.repo_root, source)
    },
    code: {
      packages,
      symbols,
      findPackage: (packageSlug) => findPackage(packages, packageSlug),
      findSymbol: (packageSlug, symbolName) => findSymbol(symbols, packageSlug, symbolName)
    },
    emit: {
      node: (row) => {
        nodes.push(normalizeNode(row));
      },
      section: (row) => {
        sections.push(normalizeSection(row));
      },
      warning: (message, detail) => {
        warnings.push({
          message,
          ...detail !== undefined ? { detail } : {}
        });
      }
    }
  };
}
async function runAspectPluginForHost(pluginModulePath, input) {
  const nodes = [];
  const sections = [];
  const warnings = [];
  const pluginModule = await import(pathToFileURL(pluginModulePath).href);
  const plugin = pluginModule.default;
  if (plugin === undefined || typeof plugin.capture !== "function") {
    throw new Error(`${pluginModulePath} must export default defineAspect({ capture(ctx) { ... } })`);
  }
  const ctx = buildContext(input, nodes, sections, warnings);
  await plugin.setup?.(ctx);
  try {
    await plugin.capture(ctx);
  } finally {
    await plugin.teardown?.(ctx);
  }
  return {
    type: "aspect-plugin-result.v1",
    nodes,
    sections,
    warnings
  };
}
// src/aspect-runtime/mdx.ts
import { unified } from "unified";
import remarkGfm from "remark-gfm";
import remarkMdx from "remark-mdx";
import remarkParse from "remark-parse";
import remarkStringify from "remark-stringify";
function compactWhitespace(value) {
  return value.replace(/[ \t]+/gu, " ").replace(/\n{3,}/gu, `

`).trim();
}
function normalizeMarkdown(value) {
  return value.replace(/\r\n?/gu, `
`).replace(/\n{3,}/gu, `

`).trim();
}
function cloneNode(node, children) {
  const cloned = { ...node };
  delete cloned.attributes;
  delete cloned.name;
  if (children !== undefined)
    cloned.children = children;
  return cloned;
}
function cloneMarkdownNode(node) {
  return {
    ...node,
    ...node.children !== undefined ? { children: node.children.map(cloneMarkdownNode) } : {}
  };
}
function mdxAttrValueText(value) {
  if (value === null || value === undefined)
    return;
  if (typeof value === "string")
    return value;
  const expression = value.value?.trim();
  if (!expression)
    return;
  return expressionLiteralText(expression) ?? expression;
}
function mdxAttributes(attrs) {
  const out = {};
  for (const attr of attrs ?? []) {
    if (attr.type !== "mdxJsxAttribute" || !attr.name)
      continue;
    const value = mdxAttrValueText(attr.value);
    if (value !== undefined)
      out[attr.name] = value;
  }
  return out;
}
function expressionLiteralText(expression) {
  const trimmed = expression.trim();
  const quote = trimmed.charAt(0);
  if ((quote === '"' || quote === "'" || quote === "`") && trimmed.charAt(trimmed.length - 1) === quote) {
    const body = trimmed.slice(1, -1);
    if (quote === "`" && body.includes("${"))
      return;
    return body;
  }
  return;
}
function markdownText(value) {
  return { type: "text", value };
}
function markdownLink(label, href) {
  return {
    type: "link",
    url: href,
    title: null,
    children: [markdownText(label)]
  };
}
function markdownCodeBlock(code) {
  return {
    type: "code",
    lang: "tsx",
    value: code.trim()
  };
}
function expressionNodes(node, context) {
  const value = expressionLiteralText(node.value ?? "");
  if (value === undefined || value.length === 0)
    return [];
  if (context === "text" && (node.value ?? "").trim().startsWith("`")) {
    return [{ type: "inlineCode", value }];
  }
  return nodesForContext([markdownText(value)], context);
}
function isPhrasing(node) {
  return [
    "break",
    "delete",
    "emphasis",
    "html",
    "image",
    "imageReference",
    "inlineCode",
    "link",
    "linkReference",
    "strong",
    "text"
  ].includes(node.type);
}
function asFlowNodes(nodes) {
  if (nodes.length === 0)
    return [];
  return nodes.every(isPhrasing) ? [{ type: "paragraph", children: nodes }] : nodes;
}
function nodesForContext(nodes, context) {
  return context === "flow" ? asFlowNodes(nodes) : nodes.filter(isPhrasing);
}
function mdxElementNodes(node, context) {
  const attrs = mdxAttributes(node.attributes);
  if (attrs.code) {
    return context === "text" ? [{ type: "inlineCode", value: attrs.code.trim() }] : [markdownCodeBlock(attrs.code)];
  }
  if (attrs.text) {
    return nodesForContext([attrs.href ? markdownLink(attrs.text, attrs.href) : markdownText(attrs.text)], context);
  }
  if (node.name === "br")
    return nodesForContext([{ type: "break" }], context);
  if (node.name === "img" || node.name === "Image") {
    const alt = attrs.alt ?? attrs.title;
    return alt ? nodesForContext([markdownText(alt)], context) : [];
  }
  const childContext = context === "text" ? "text" : "flow";
  const children = transformChildren(node.children ?? [], childContext);
  return nodesForContext(children, context);
}
function transformChildren(children, context) {
  return children.flatMap((child) => transformNode(child, context));
}
function transformNode(node, context) {
  if (node.type === "mdxjsEsm")
    return [];
  if (node.type === "mdxFlowExpression" || node.type === "mdxTextExpression")
    return expressionNodes(node, context);
  if (node.type === "mdxJsxFlowElement" || node.type === "mdxJsxTextElement")
    return mdxElementNodes(node, context);
  if (node.children) {
    const childContext = node.type === "paragraph" || node.type === "heading" ? "text" : "flow";
    return [cloneNode(node, transformChildren(node.children, childContext))];
  }
  return [cloneNode(node, undefined)];
}
function normalizeMdxTree() {
  return (tree) => {
    tree.children = transformChildren(tree.children ?? [], "flow");
  };
}
var mdxProcessor = unified().use(remarkParse).use(remarkMdx).use(remarkGfm).use(normalizeMdxTree).use(remarkStringify, {
  bullet: "-",
  fences: true,
  listItemIndent: "one",
  rule: "-",
  setext: false
});
function markdownBlocks(markdown) {
  const blocks = [];
  let paragraph = [];
  let code = [];
  let codeLanguage = "";
  let readingCode = false;
  function flushParagraph() {
    const text = compactWhitespace(paragraph.join(`
`));
    if (text.length > 0)
      blocks.push({ type: "paragraph", text });
    paragraph = [];
  }
  for (const line of markdown.split(/\r?\n/u)) {
    const fence = line.trim().match(/^(```|~~~)(.*)$/u);
    if (fence) {
      if (readingCode) {
        blocks.push({ type: "code", language: codeLanguage, text: code.join(`
`) });
        code = [];
        codeLanguage = "";
        readingCode = false;
      } else {
        flushParagraph();
        codeLanguage = (fence[2] ?? "").trim();
        readingCode = true;
      }
      continue;
    }
    if (readingCode) {
      code.push(line);
      continue;
    }
    const heading = line.match(/^(#{1,6})\s+(.+)$/u);
    if (heading) {
      flushParagraph();
      blocks.push({ type: "heading", depth: (heading[1] ?? "").length, text: (heading[2] ?? "").trim() });
      continue;
    }
    if (line.trim().length === 0) {
      flushParagraph();
      continue;
    }
    paragraph.push(line);
  }
  flushParagraph();
  return blocks;
}
function plainText(node) {
  if (typeof node.value === "string")
    return node.value;
  return (node.children ?? []).map(plainText).join("");
}
function normalizedHeadingLabel(value) {
  return compactWhitespace(value).toLowerCase();
}
function headingMatchesTitle(node, title) {
  if (title === undefined || node.type !== "heading")
    return false;
  return normalizedHeadingLabel(plainText(node)) === normalizedHeadingLabel(title);
}
function firstHeadingText(nodes) {
  for (const node of nodes) {
    if (node.type === "heading") {
      const text = compactWhitespace(plainText(node));
      if (text.length > 0)
        return text;
    }
    const childHeading = firstHeadingText(node.children ?? []);
    if (childHeading)
      return childHeading;
  }
  return;
}
function stripYamlFrontmatter(raw) {
  const normalized = raw.replace(/\r\n?/gu, `
`);
  if (!normalized.startsWith(`---
`))
    return raw;
  const lines = normalized.split(`
`);
  for (let index = 1;index < lines.length; index += 1) {
    if (lines[index]?.trim() === "---") {
      return lines.slice(index + 1).join(`
`);
    }
  }
  return raw;
}
function clampHeadingLevel(value) {
  return Math.min(6, Math.max(1, Math.trunc(value)));
}
function minHeadingDepth(nodes) {
  let out;
  function visit(node) {
    if (node.type === "heading" && typeof node.depth === "number") {
      out = out === undefined ? node.depth : Math.min(out, node.depth);
    }
    for (const child of node.children ?? [])
      visit(child);
  }
  for (const node of nodes)
    visit(node);
  return out;
}
function shiftHeadingDepths(nodes, offset) {
  return nodes.map((node) => {
    const next = cloneMarkdownNode(node);
    if (next.type === "heading" && typeof next.depth === "number") {
      next.depth = clampHeadingLevel(next.depth + offset);
    }
    if (next.children !== undefined) {
      next.children = shiftHeadingDepths(next.children, offset);
    }
    return next;
  });
}
function sectionBodyMarkdownFromTree(tree, options) {
  const minHeadingLevel = clampHeadingLevel(options.minHeadingLevel ?? 3);
  const removeTitleHeading = options.removeTitleHeading ?? true;
  const children = (tree.children ?? []).map(cloneMarkdownNode);
  const withoutTitle = removeTitleHeading && children[0] !== undefined && headingMatchesTitle(children[0], options.title) ? children.slice(1) : children;
  const minDepth = minHeadingDepth(withoutTitle);
  const headingOffset = minDepth === undefined ? 0 : Math.max(0, minHeadingLevel - minDepth);
  return normalizeMarkdown(mdxProcessor.stringify({
    ...tree,
    children: shiftHeadingDepths(withoutTitle, headingOffset)
  }));
}
function normalizeSectionMarkdown(markdown, options = {}) {
  const source = stripYamlFrontmatter(markdown);
  const tree = mdxProcessor.parse(source);
  const normalized = mdxProcessor.runSync(tree);
  const title = options.title ?? firstHeadingText(normalized.children ?? []);
  return sectionBodyMarkdownFromTree(normalized, {
    ...options,
    ...title !== undefined ? { title } : {}
  });
}
function parseMdxDocument(raw, fallbackTitle) {
  const source = stripYamlFrontmatter(raw);
  const tree = mdxProcessor.parse(source);
  const normalized = mdxProcessor.runSync(tree);
  const markdown = normalizeMarkdown(mdxProcessor.stringify(normalized));
  const blocks = markdownBlocks(markdown);
  const title = firstHeadingText(normalized.children ?? []) ?? fallbackTitle;
  const bodyMarkdown = sectionBodyMarkdownFromTree(normalized, { title });
  return { title, markdown, bodyMarkdown, blocks };
}

// src/aspect-runtime/index.ts
async function runPlugin(pluginModulePath) {
  return runAspectPluginForHost(pluginModulePath, await readHostInput());
}
async function main() {
  const pluginModulePath = process.argv[2];
  if (pluginModulePath === undefined || pluginModulePath.length === 0) {
    throw new Error("usage: aspectRunnerSdk <aspect-plugin-module>");
  }
  const result = await runPlugin(path3.resolve(pluginModulePath));
  process.stdout.write(`${JSON.stringify(result)}
`);
}
if (process.argv[1] !== undefined && path3.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
  main().catch((err) => {
    const message = err instanceof Error ? err.stack ?? err.message : String(err);
    process.stderr.write(`${message}
`);
    process.exitCode = 1;
  });
}
export {
  validateSourcePath,
  toPosix,
  sourceFileRef,
  slugSegment,
  runAspectPluginForHost,
  resolveSymbolNodeSlug,
  resolvePackageNodeSlug,
  repoRelative,
  readHostInput,
  parseTsxComponentNames,
  parseScssTokenNames,
  parseMdxDocument,
  parseJsLikeTokenNames,
  normalizeSymbolSlug,
  normalizeSectionMarkdown,
  normalizeComponentSlug,
  markdownFence,
  inferComponentName,
  firstMarkdownHeading,
  fileSourceRef,
  encodeSourcePath,
  encodeFragment,
  defineAspect,
  compactWhitespace,
  artifactFromRelPath
};
