import { ToolRegistry } from "./tool_registry"; import { ENCODE_METHOD, DECODE_METHOD } from "../utils/encoder_symbols"; import { SpooledArtifact } from "./spooled_artifact"; import type { Root } from 'mdast'; import type { AdkEncodableSnapshot } from "./encodable"; import type { SpoolReader } from "../contracts/spool_reader"; import type { ToolMethodDescriptor } from "./spooled_artifact"; import type { DispatchContext } from "../contracts/dispatch_context"; /** * A single heading entry in the document's structural index. * * @remarks * `startLine` is the 0-based line of the heading itself. `endLine` is the 0-based index of the * last line belonging to this section (inclusive) — the line immediately before the next heading * of equal or lesser depth, or the last line of the document. */ export interface MarkdownHeadingEntry { /** ATX heading depth: 1 (`#`) through 6 (`######`). */ depth: 1 | 2 | 3 | 4 | 5 | 6; /** The heading text with the leading `#` prefix stripped and trimmed. */ text: string; /** 0-based line index of the heading line itself. */ startLine: number; /** 0-based line index of the last line in this section (inclusive). */ endLine: number; } /** * A single fenced code block entry in the document's structural index. */ export interface MarkdownCodeEntry { /** The language identifier immediately after the opening fence, or `null` when absent. */ lang: string | null; /** 0-based line index of the opening fence line. */ startLine: number; /** 0-based line index of the closing fence line. */ endLine: number; } /** * A section of a markdown document as returned by {@link SpooledMarkdownArtifact.md_sections}. * * @remarks * Contains only line-range metadata — no content is fetched until the caller explicitly * requests it via `cat(bodyStartLine, bodyEndLine + 1)`. */ export interface MarkdownSection { /** ATX heading depth: 1 (`#`) through 6 (`######`). */ depth: 1 | 2 | 3 | 4 | 5 | 6; /** The heading text. */ heading: string; /** 0-based line of the heading itself. */ headingLine: number; /** 0-based line of the first body line (heading line + 1). */ bodyStartLine: number; /** 0-based line of the last body line (inclusive). */ bodyEndLine: number; } /** * A {@link @nhtio/adk!SpooledArtifact} specialisation that adds markdown-aware structural queries. * * @remarks * Designed for large markdown documents where loading the full content into memory is * impractical. The structural index (heading positions, code block positions) is built by a * single line-by-line scan of the {@link @nhtio/adk!SpoolReader} without retaining any content. Only the * tiny metadata index and the parsed frontmatter object are cached. * * Content retrieval is always bounded — use `cat(start, end)` or the `startLine`/`endLine` * parameters on inline methods to fetch only the lines you need. * * Inline methods (`md_links`, `md_images`, `md_text`, `md_ast`) accept optional line-range * arguments. Without a range they read the full document — documented trade-off, caller * responsibility to bound the range for large documents. * * The processor always applies `remark-gfm` (tables, task lists, strikethrough, autolinks) * in addition to standard CommonMark and YAML frontmatter. */ export declare class SpooledMarkdownArtifact extends SpooledArtifact { #private; /** * @param reader - The backing store to read from. */ constructor(reader: SpoolReader); /** * Returns `true` if `value` is a {@link SpooledMarkdownArtifact} instance. * * @remarks * Uses the cross-realm-safe {@link @nhtio/adk!isInstanceOf} guard: `instanceof` first, then * `Symbol.hasInstance`, then a `constructor.name` fallback. Matches the pattern used by every * other class guard in the ADK; safe against the dual-module-copy case where two distinct * `SpooledMarkdownArtifact` classes coexist in the same realm. */ static isSpooledMarkdownArtifact(value: unknown): value is SpooledMarkdownArtifact; /** * The markdown-specific artifact-query descriptors this class adds on top of the base set. * * @remarks * Lists `artifact_md_frontmatter`, `artifact_md_headings`, `artifact_md_code_blocks`, * `artifact_md_sections`, `artifact_md_links`, `artifact_md_images`, `artifact_md_text`, * `artifact_md_ast`. The base seven descriptors (`artifact_head`, etc.) are NOT included * here — they are forged separately by {@link SpooledMarkdownArtifact.forgeTools}, which * calls `SpooledArtifact.forgeTools(ctx)` to produce the base-narrowed tools and then * registers its own markdown tools on the result. Downstream consumers building custom * subclasses should follow the same pattern: own only your own descriptors; override * `forgeTools` to compose with the base output. */ static toolMethods: ReadonlyArray; /** * Forges base-class tools plus markdown-specific tools narrowed to * {@link SpooledMarkdownArtifact}. * * @remarks * Standard subclass extension pattern: call `SpooledArtifact.forgeTools(ctx)` to produce * the base seven `artifact_*` tools narrowed to any `SpooledArtifact` in the turn, then * register one `ArtifactTool` per markdown-specific descriptor narrowed to markdown * artifacts. Downstream consumers building their own subclasses should follow the same * shape. */ static forgeTools(ctx: DispatchContext): ToolRegistry; /** * Returns the parsed YAML frontmatter, or `undefined` when no frontmatter block is present. * * @remarks * Short-circuits after reading the frontmatter block — never reads the document body. Caches * the result so subsequent calls are free. The result is `undefined` (not an empty object) * when no frontmatter is found, distinguishing "no frontmatter" from "empty frontmatter". */ md_frontmatter(): Promise | undefined>; /** * Returns all headings in document order, optionally filtered by depth. * * @remarks * Uses the cached structural index — no content is fetched from the {@link @nhtio/adk!SpoolReader}. * * @param depth - When provided, only headings at this ATX depth (1–6) are returned. */ md_headings(depth?: 1 | 2 | 3 | 4 | 5 | 6): Promise; /** * Returns all fenced code block entries, optionally filtered by language identifier. * * @remarks * Returns line-range metadata only — no content is fetched. Use `cat(entry.startLine + 1, * entry.endLine)` to retrieve the code body (excluding fence lines). * * @param lang - When provided, only blocks with this exact lang identifier are returned. * Pass an empty string to match blocks with no lang identifier. */ md_code_blocks(lang?: string): Promise; /** * Returns document sections derived from the structural index. * * @remarks * Returns only line-range metadata — body content is never fetched. To retrieve the body of a * section, call `cat(section.bodyStartLine, section.bodyEndLine + 1)`. * * When `depth` is provided, only sections introduced by a heading at that depth are returned; * deeper headings become part of the body. * * @param depth - When provided, only sections at this ATX depth (1–6) are returned. */ md_sections(depth?: 1 | 2 | 3 | 4 | 5 | 6): Promise; /** * Returns the full MDAST Root for the specified line range. * * @remarks * Without a range, reads the full document — for large documents, use * {@link SpooledMarkdownArtifact.md_sections} to locate sections and pass * bounded line ranges here. * * @param startLine - 0-based start line (inclusive). Defaults to `0`. * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`. */ md_ast(startLine?: number, endLine?: number): Promise; /** * Returns all inline and reference links in the specified line range. * * @param startLine - 0-based start line (inclusive). Defaults to `0`. * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`. */ md_links(startLine?: number, endLine?: number): Promise>; /** * Returns all images in the specified line range. * * @param startLine - 0-based start line (inclusive). Defaults to `0`. * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`. */ md_images(startLine?: number, endLine?: number): Promise>; /** * Returns all document text with markup stripped, for the specified line range. * * @remarks * Uses `mdast-util-to-string` to extract plain text from the AST — code, link text, and * alt text are included; markdown syntax is removed. * * @param startLine - 0-based start line (inclusive). Defaults to `0`. * @param endLine - 0-based end line (exclusive). Defaults to `lineCount()`. */ md_text(startLine?: number, endLine?: number): Promise; /** * Serialise this SpooledMarkdownArtifact into an `@nhtio/encoder` snapshot — the reader **handle**. * * @remarks * The structural index and frontmatter caches are derived and not encoded. Round-trips via * {@link SpooledMarkdownArtifact.[DECODE_METHOD]}. * * @returns A snapshot consumed by {@link SpooledMarkdownArtifact.[DECODE_METHOD]}. */ [ENCODE_METHOD](): AdkEncodableSnapshot; /** * Reconstruct a {@link SpooledMarkdownArtifact} from a * {@link SpooledMarkdownArtifact.[ENCODE_METHOD]} snapshot. * * @param data - The snapshot produced by {@link SpooledMarkdownArtifact.[ENCODE_METHOD]}. * @returns A fresh {@link SpooledMarkdownArtifact} backed by a freshly-resolved reader. */ static [DECODE_METHOD](data: AdkEncodableSnapshot): SpooledMarkdownArtifact; }