/** * The slice of `node:path` this rule needs. * * Injected with no default, and this module imports no `node:*` builtin: it is * reached from the browser entry through `core/plugin`, so a `node:path` * import here lands in the Vue bundle (Codex on #3017). The server passes its * own `path`; tests pass `path.win32` to reach the case below. */ export interface PathRules { relative: (from: string, to: string) => string; isAbsolute: (p: string) => boolean; sep: string; } /** * The wire ref for an absolute path inside a stories root, or `null` when it * is not inside one. * * Pure, and taking its path rules as an argument, because the case that * matters is unreachable on the machine this is written on. `path.relative` * says "not under the base" in TWO ways and only one looks like an escape: * `../…` is the familiar one, and across Windows DRIVES there is no relative * path at all, so `relative("C:\\base", "D:\\x")` answers `"D:\\x"` — * absolute, with no `..` for the escape check to catch. That minted * `stories/D:/anything`, a wire ref that reads back as a DIFFERENT file, which * is the substitution this function exists to refuse. Only Windows CI caught * it; here there is one root and always a relative route (#3015 post-merge). */ /** * The path INSIDE a stories root that a wire path names, or null when it does * not name one. * * The default root's FileOps is rooted one level up, at `/artifacts`, * so there the wire path and the FileOps path are the SAME string and nothing * is stripped. A named root's FileOps is rooted at the stories directory * itself — which is what a host naturally writes, having registered exactly * that directory in `extraRoots` — so the `stories/` prefix has to come off, * or the write lands in `/stories/` while the read looks in * `/` and the two are different files (#3020 review H1). */ export declare function storiesRelativePath(wirePath: string): string | null; export declare function storyRefWithin(base: string, absolutePath: string, rules: PathRules): string | null; /** Lowercase-hyphen slug, capped, leading/trailing hyphens stripped; falls back * to `fallback` for empty/undefined/non-ASCII input. */ export declare function slugify(title: string | undefined, fallback?: string): string; /** Build a fresh, collision-safe story path for a new script — * `stories/-.json`, valid as both the FileOps-relative * write path and the wire `filePath`. */ export declare function storyFilePath(slugSource: string, now?: Date): string; /** * Normalize a caller-supplied wire path to the canonical * `stories/` form, or null when it can't be trusted. Accepts the * canonical `stories/foo.json` convention, bare `foo.json` (the host route * historically allowed either), and the workspace-relative spelling * `artifacts/stories/foo.json` — the tool description called `filePath` * "workspace-relative" for a long time, so agents legitimately send it. * A leading `artifacts` segment is dropped only when `stories` follows; * a bare `artifacts/foo.json` keeps its historical meaning (a file named * `artifacts/foo.json` under the stories dir). Rejects absolute paths, * backslashes, and any empty / `.` / `..` segment — the lexical guard * before every `files.artifacts` read/write (FileOps re-checks * containment as defence-in-depth). */ export declare function normalizeStoryPath(filePath: string): string | null; /** Extensions the tool's `filePath` argument may name. */ export declare const STORY_SCRIPT_EXTENSIONS: readonly [".json"]; /** * Extensions a wire path may carry once the server mints one, i.e. the script * itself plus every generated artifact mulmocast writes beside it (`.mp4` for * the assembled movie and animated beats, `.mov` for per-beat clips, `.pdf` * for the handout). Closed on purpose: a format this list does not know is * refused loudly at the download route rather than resolved by a looser rule. */ export declare const STORY_TARGET_EXTENSIONS: readonly [".json", ".mp4", ".mov", ".pdf"]; /** * True when `value` is the absolute form — safe to open AS NAMED. * * Lexical only, and platform-independent by design (`classifyFilePath` * recognises `C:\proj\x.json` on POSIX too), because the value may arrive from * a remote host. Whether the path is absolute on THIS machine is the server's * question, answered where the path meets the filesystem: `resolveStory` * requires native absoluteness and a real regular file. */ export declare function isAbsoluteStoryPath(value: string, extensions?: readonly string[]): boolean; //# sourceMappingURL=paths.d.ts.map