import type { RunHomeBuildContext } from "./build.js"; /** claude's own import depth cap. */ export declare const MAX_IMPORT_DEPTH = 5; export interface ExpandImportsInput { content: string; filePath: string; tier: "user" | "project" | "local"; /** The trusted project root — the boundary a project or local file's imports may not leave. */ projectRoot: string | null; maxDepth?: number; } export interface ExpandImportsResult { content: string; /** Absolute paths a project/local file named outside the project root, in encounter order. */ dropped: string[]; } /** * Expands `@path` imports with claude's tier rule (F17) — the same algorithm the Winter SDK's own * loader uses (the plan's L1a.4): relative to the containing file, `~/` is `$HOME`, code spans and * fenced blocks are skipped, depth is capped at 5, a user file follows anywhere, a project or local * file only inside `projectRoot`. An unresolved token (missing file, a directory, a cycle, the cap) * stays as literal text; a dropped one stays too, and is reported. */ export declare function expandImports(input: ExpandImportsInput): ExpandImportsResult; /** * Neutralises every `@` that could begin an import, ANYWHERE in the text: `@x` becomes `@x`, which * no import grammar accepts (the path would start with the zero-width space) and a reader does not see. * Only an `@` followed by a possible first character of an import path is touched (see `NEUTRALISABLE_AT`). * * CODE-BLIND, ON PURPOSE (R.3, C1 ii). claude skips imports only inside what a markdown lexer (marked, * `gfm: false`) calls a code block or a code span, and reads an import at an `@` that starts a run of * TEXT or follows whitespace in it. Any per-line guess at "this is code" that disagrees with that lexer * leaves a token raw that claude then follows (MEASURED with marked 18.0.6): a backtick fence whose info * string holds a backtick (not a fence), a tab-led fence (an indented line), mismatched backtick runs (not a code span). And a text * token can START with `@` after an inline token closes — `>@x`, `**x**@x`, `a@x`, `@x`, * `\*@x` — where the source has no whitespace before the `@` at all. So the test is not the import regex * but the character before the `@`: a token boundary never falls between an ASCII letter/digit and an `@` * (marked's text tokens end only before markup or after a non-local-part character), which is why an * e-mail address (`me@example.com`) is left as written. A fuzz of an import extractor built to that * description, over generated markdown strings, found 837 per 100k importing after a whitespace-only neutraliser and none after this one * (1.1M strings with the first rule; the narrowed next-character rule re-fuzzed, lane-L2 report "R.3 touch"). * Inside a real code block the inserted character is invisible too. */ export declare function escapeImportTokens(content: string): string; /** * Builds `/` and the `CLAUDE.md` link, then rewrites the project rules whose * `paths:` need it. Every mode gets the user file; a trusted project's files reach every mode (spec * §3.2 — mode-blind, as today). */ export declare function buildInstructions(context: RunHomeBuildContext): Promise; /** * Re-expresses one glob, written relative to `anchor`, relative to the cwd `anchor/`. Returns the * rewritten glob, or `undefined` when it can only match outside the cwd's subtree. */ export declare function rebaseGlob(glob: string, relSegments: readonly string[]): string | undefined;