/** * @license * Copyright 2026 Steven Roussey * SPDX-License-Identifier: Apache-2.0 */ import type { IExecuteContext, TaskEntitlements } from "@workglow/task-graph"; import { CreateWorkflow } from "@workglow/task-graph"; import type { DataPortSchema } from "@workglow/util/schema"; import type { FileGrepTaskConfig, FileGrepTaskInput, FileGrepTaskOutput, GrepLineMatcher, GrepOptions } from "./FileGrepTask"; import { FileGrepTask as BaseFileGrepTask } from "./FileGrepTask"; export type { FileGrepTaskConfig, FileGrepTaskInput, FileGrepTaskOutput }; /** * Server-only task for grepping documents from the filesystem, on top of the * base task's http(s) handling. * * The file is read as a stream rather than loaded into memory, and split into * lines with a hard per-line cap ({@link DEFAULT_LIMITS.grepMaxLineChars}) — a * longer physical line is truncated to that length and the remainder discarded, * so a file with no line terminator cannot exhaust memory. * * A local path is resolved and realpath'd before it is opened, and constrained * to `config.roots` — which defaults to the process working directory, so a * task with no stated root reads from there and nowhere else. Set * `config.allowAnyRoot` to opt out. Reading requires the `filesystem:read` * entitlement, declared scoped to the resolved path. * * Only available in Node.js and Bun environments. For cross-platform grep * (including browser), use FileGrepTask with an http(s) URL. */ export declare class FileGrepTask extends BaseFileGrepTask { static configSchema(): DataPortSchema; static entitlements(): TaskEntitlements; /** * Declares whichever half of the surface this url actually uses: the fetch * entitlements for http(s), otherwise `filesystem:read` scoped to the * resolved real path. An unknown url fails closed to both, unscoped. * * Never throws — entitlement evaluation runs before `execute()` and must * produce a declaration for any input, so an unresolvable path degrades to * the unscoped declaration and is refused later, at open time. */ entitlements(): TaskEntitlements; /** * Runs regex matching inside a `vm` context under a wall-clock budget, so a * catastrophically backtracking pattern fails instead of wedging the event * loop. Overriding here covers both branches: the http branch reaches * `super.execute`, which uses the matcher this returns. * * `matchBatch` (`RegExp.test`) is not the whole cost: `onlyMatching` then * `exec`s each hit to slice out the substring. A pattern whose left * alternative matches quickly can still backtrack on that global pass, so * `extractBatch` is bounded the same way. * * `fixedString` never enters `vm` — `String.includes` cannot backtrack, and * the `vm` hop would cost ~20x for nothing. */ protected createLineMatcher(pattern: string, options: GrepOptions): GrepLineMatcher; /** * Refuses a path the instance did not declare. Entitlements are evaluated * on the unresolved input, so without this a declare-then-swap would let the * open authorize itself — and a standalone `fileGrep(...)` with no graph and * no enforcer would honour no `roots` at all. */ private assertResolvedPathDeclared; execute(input: FileGrepTaskInput, context: IExecuteContext): Promise; } export declare const fileGrep: (input: FileGrepTaskInput, config?: FileGrepTaskConfig) => Promise<{ exists: boolean; groups: { endLine: number; lines: { line: number; match: boolean; text: string; }[]; startLine: number; }[]; matchCount: number; truncated: boolean; }>; declare module "@workglow/task-graph" { interface Workflow { fileGrep: CreateWorkflow; } }