import type { ToolCall } from "../types.js"; import type { TaskEvidence } from "../store/plan.js"; /** Successful non-meta work under the open plan task (typed evidence for done). */ export type TaskClass = "explore" | "scaffold" | "install" | "implement" | "verify" | "recon" | "exploit" | "report" | "generic"; export interface TaskWorkLedger extends TaskEvidence { taskId: string; } /** Rehydrate the live task ledger from durable plan evidence after a resume. */ export declare function ledgerFromTaskEvidence(taskId: string, evidence?: TaskEvidence | undefined): TaskWorkLedger; /** Store only serializable evidence on the plan; the task id is already its key. */ export declare function taskEvidenceFromLedger(ledger: TaskWorkLedger): TaskEvidence; /** Optional signals recorded from a successful tool call. */ export interface TaskWorkSignals { sourceWrite?: boolean; featureWrite?: boolean; installOk?: boolean; scaffoldOk?: boolean; devServerStart?: boolean; localHttpProbeOk?: boolean; serverReady?: boolean; portListening?: boolean; remoteReconOk?: boolean; remoteActiveTestOk?: boolean; } export declare function isMetaPlanTool(name: string): boolean; /** Tools that count as real work/verify evidence for the open task. */ export declare function isEvidenceWorkTool(name: string): boolean; export declare function isPentestPlanKind(kind: string | undefined): boolean; export declare function classifyTaskTitle(title: string, opts?: { planKind?: string | undefined; }): TaskClass; /** Successful work observed this turn without a credited open task. */ export interface LooseWorkReceipt { readonly toolName: string; readonly signals?: TaskWorkSignals | undefined; } /** * Whether a successful tool can satisfy a task of the given class. * Used to retroactively credit preflight work (tool.check before in_progress). */ export declare function toolFitsTaskClass(toolName: string, taskTitle: string, opts?: { planKind?: string | undefined; signals?: TaskWorkSignals | undefined; }): boolean; /** * Fold turn-level loose successes into a task ledger so preflight work * (tool.check / fs.list before in_progress) can satisfy explore/check tasks. */ export declare function absorbLooseWorkIntoLedger(ledger: TaskWorkLedger | null, taskId: string, taskTitle: string, loose: readonly LooseWorkReceipt[], opts?: { planKind?: string | undefined; }): TaskWorkLedger | null; export declare function recordTaskWorkSuccess(ledger: TaskWorkLedger | null, taskId: string | undefined, toolName: string, signals?: TaskWorkSignals): TaskWorkLedger | null; export declare function openTaskLedger(taskId: string): TaskWorkLedger; export interface CanMarkTaskDoneOpts { taskTitle?: string | undefined; /** User asked for a product feature app (todo/blog/…). */ featureAppRequired?: boolean | undefined; /** Session-level flag: feature write observed any time this turn. */ sessionFeatureSeen?: boolean | undefined; /** A real project root was discovered, so a scaffold checkpoint is already satisfied. */ existingProject?: boolean | undefined; /** An earlier plan task already proved the local server is ready and running. */ runtimeVerified?: boolean | undefined; /** Plan kind: coding | pentest | general — selects domain gates. */ planKind?: string | undefined; /** Any plan task already has successful remote recon/active test evidence. */ remoteWorkVerified?: boolean | undefined; } /** Local app runtime is proven by any strong independent signal. */ export declare function hasLocalRuntimeProof(evidence?: Pick | null): boolean; export declare function hasRemoteWorkProof(evidence?: Pick | null): boolean; /** Dev-server job log shows ready + local URL. */ export declare function isServerReadyOutput(output: string): boolean; /** lsof/ss (or similar) shows a process LISTENing on a local port. */ export declare function isPortListeningOutput(command: string, output: string): boolean; /** * Leave/keep-running observational tasks may inherit already-proven runtime. * "for user to test" must NOT block inheritance (prior brittle exclusion of "test"). */ export declare function isRuntimeObservationTask(title: string): boolean; /** Report / residual documentation that can inherit prior remote evidence. */ export declare function isRemoteObservationTask(title: string): boolean; /** * Typed evidence gate: base rule is ≥1 successful work tool; implement/install/verify * (and pentest recon) require stronger signals when classified. Existing project and * already-proven runtime/remote facts satisfy corresponding observational tasks. */ export declare function canMarkTaskDone(ledger: TaskWorkLedger | null, taskId: string, opts?: CanMarkTaskDoneOpts): { ok: true; } | { ok: false; reason: string; }; /** True when a tool call is remote recon (not local app tooling). */ export declare function isRemoteReconToolCall(call: ToolCall): boolean; /** Active/offensive test (not passive recon). */ export declare function isRemoteActiveTestCall(call: ToolCall): boolean; /** One-shot scaffolders — must NEVER be treated as "start the dev server". Stack-agnostic. */ export declare function isScaffoldCreateCommand(cmd: string): boolean; /** * True only for actually running a long-lived dev server — not create-vite / * npm create which merely contain the word "vite". */ export declare function isDevServerCall(call: ToolCall): boolean; /** Inspect tools allowed without opening a plan task. */ export declare function isPlanPreflightTool(name: string): boolean; /** Read-only recon tools that may run without an in_progress task on pentest plans. */ export declare function isReadOnlyReconTool(name: string): boolean; /** * Tools whose failure must NOT cancel later siblings in the same model turn. * Plan bookkeeping failures (task.update done-gate, etc.) and independent * recon lookups should never wipe a whole batch of http.fetch / dns calls. */ export declare function isBatchSoftFailTool(name: string): boolean; /** Tools allowed on a coding build turn before plan.create exists. */ export declare function isBuildPrePlanAllowedTool(name: string): boolean; /** * Commands that legitimately sit quiet for minutes (npm install, create-next-app). * Must not be killed by the short "no output" stall watchdog. */ export declare function isLongQuietInstallOrScaffoldCommand(cmd: string): boolean; /** * Commands that are long-running but produce output (tests, builds, lint). * These need a longer hard timeout than the 40s default, but should still * be killed by the stall watchdog if they go quiet. */ export declare function isLongRunningTestOrBuildCommand(cmd: string): boolean; /** Default wall-clock budget for every tool unless the model overrides it. */ export declare const DEFAULT_TOOL_TIMEOUT_MS = 40000; /** * Silence cancellation leaves a short margin for a tool's own timeout handler * to return its richer result. The hard wall-clock watchdog still enforces the * exact model-selected deadline. */ export declare function toolStallBudgetMs(call: { name: string; args: Record; }): number; /** * Hard wall-clock watchdog for every tool call. Local implementations enforce * the selected deadline; this outer fallback waits through the same short * settlement margin so their timeout/abort handlers can return a rich result * before the runner force-settles an ignored AbortSignal. */ export declare function toolHardBudgetMs(call: { name: string; args: Record; }): number; /** Grace period after abort before force-settling a hung tool promise. */ export declare const TOOL_ABORT_GRACE_MS = 2500; /** Harmless version/which probes models use instead of tool.check before planning. */ export declare function isReadOnlyVersionProbeCommand(cmd: string): boolean; /** * Multi-step coding builds must plan before mutate (scaffold/write/install). * Trivial one-liners and non-build prompts skip this. */ export declare function codingBuildRequiresPlan(prompt: string, opts?: { informational?: boolean; idle?: boolean; pentest?: boolean; }): boolean; export declare function looksLikeInstallTaskTitle(title: string): boolean; export declare function looksLikeScaffoldTaskTitle(title: string): boolean; export declare function isPackageInstallCommand(cmd: string): boolean; /** * Choose which pending plan task should own this tool call (auto-start). * Prevents npm install from being attributed to "localStorage" / style tasks. */ export declare function pickPendingTaskForToolCall(pending: T[], call: ToolCall, _allTitles?: string[]): T | undefined; /** * User asked for a product feature app (todo, blog, …), not "just scaffold framework X". * Stack-agnostic: detects intent, not a particular framework. */ export declare function userAskedForFeatureApp(prompt: string): boolean; /** Paths that look like application source (not lockfiles / build output). */ export declare function isAppSourcePath(path: string): boolean; export declare function extractWritePathsFromCall(call: ToolCall): string[]; /** Default framework starter / marketing copy — not the product feature. */ export declare function looksLikeStarterBoilerplate(content: string): boolean; /** Content that looks like real product UI/logic for common feature apps. */ export declare function looksLikeFeatureProductCode(content: string): boolean; /** * True when a successful tool call implements product feature code (not only scaffold). * Starter boilerplate alone does not count. */ export declare function isFeatureImplementationCall(call: ToolCall): boolean; /** * User said work belongs on the Desktop (or similar). Returns absolute path. */ export declare function resolveUserDestinationHint(prompt: string, home?: string): string | undefined; /** * Default shell cwd when the model omitted it but a project root / Desktop hint exists. */ export declare function applyDestinationCwd(call: ToolCall, destinationHint: string | undefined): ToolCall;