import type { McpServer, ResourceLink, ServerContext, ServerNotifier } from "@modelcontextprotocol/server"; import type { PersistedRunState } from "@automatalabs/workflows"; import { WorkflowManager } from "@automatalabs/workflows"; import type { RunEventLogRecord } from "@automatalabs/shared-types"; import { type RunStoreRouter } from "./project-registry.js"; import type { WorkflowRunLatestActivity } from "./workflow-tool-output.js"; export declare const SCRIPT_RESOURCE_MIME_TYPE = "text/javascript"; export declare const RESULT_RESOURCE_MIME_TYPE = "application/json"; export declare const SCRIPT_RESOURCE_LIST_LIMIT = 50; export declare const EVENTS_RESOURCE_MIME_TYPE = "application/json"; export declare const WORKFLOW_RUN_EVENTS_SCHEMA_VERSION: 1; /** The `file://` URI of a run's editable script: its store copy, or the caller's `scriptPath`. */ export declare function workflowScriptFileUri(location: string): string; export declare function workflowResultUri(runId: string): string; export declare function workflowRunIdFromResultUri(uri: string): string | undefined; export declare function workflowRunEventsUri(runId: string): string; export interface SerializedWorkflowResult { uri: string; text: string; bytes: number; } export interface WorkflowRunEventsResourceDocument { schemaVersion: typeof WORKFLOW_RUN_EVENTS_SCHEMA_VERSION; runId: string; streamId: string; workflowName: string; status: PersistedRunState["status"]; finalized: boolean; after: number; cursor: number; endCursor: number; hasMore: boolean; events: RunEventLogRecord[]; } export interface ParsedWorkflowRunEventsUri { runId: string; canonical: boolean; after?: number; limit?: number; streamId?: string; normalizedUri: string; } export declare function parseWorkflowRunEventsUri(uri: string): ParsedWorkflowRunEventsUri | undefined; /** * Persistence-backed MCP script resources. Run content is read directly from the * engine store for every request; the only process-local state is protocol bookkeeping. */ export declare class WorkflowScriptResources { private readonly mcp; private readonly modernNotifier?; private readonly router; private readonly detachRunDeleted; private readonly detachRunEventPersisted; private readonly subscriptions; /** Subscribed script file URIs by run, so a deleted run drops its subscription without a lookup. */ private readonly scriptSubscriptions; /** Script URIs whose run was deleted while subscribed: unsubscribe stays idempotent for them. */ private readonly deletedScriptUris; private readonly externalReaders; private readonly eventSubscriptions; private readonly deletedRunIds; private readonly silentDeletionRunIds; private readonly onRunDeleted; constructor(mcp: McpServer, source: WorkflowManager | { router: RunStoreRouter; }, modernNotifier?: ServerNotifier | undefined); /** The persistence store containing runId, if any known project store holds it. */ private persistenceFor; /** * Reconcile a run orphaned by a dead owner before reading its events. `status`/`stop` already do * this (server.ts), but the events read path did not: a run left "running" with a frozen journal * by a daemon that exited stayed status "running", so buildEventsDocument reported finalized:false * forever and the run-monitor panel polled it without end. Mirror the tool paths — only reconcile * when nothing live in THIS process owns the run — and let a failed reconcile fall through to * reporting the run's current persisted state. */ private reconcileDeadRunForEvents; /** Load a persisted run from whichever project store holds it. */ private loadState; /** Tombstones keep deleted-resource subscriptions recognizable until unsubscribe. */ private loadTombstone; /** * Serve a fixed, non-run resource (exact URI match) through this class's resources/read * router. Needed because registerProtocolSurface replaces the SDK's default read dispatch. */ registerExternalResourceReader(uri: string, read: () => { contents: Array<{ uri: string; mimeType: string; text: string; }>; }, available?: (ctx: ServerContext) => boolean): void; /** Announce a resource only after the server has read its admitted record back successfully. */ notifyRunAdmitted(runId: string): void; /** * Delete through the composition boundary so subscription state and list notifications stay in * sync. Failed-admission cleanup passes notify=false because that resource was never announced. */ deleteRun(runId: string, notify?: boolean): boolean; /** Exact persisted result metadata, available only for completed runs with a JSON value. */ serializedResult(runId: string): SerializedWorkflowResult; availableResultUri(runId: string): string | undefined; /** Canonical events URI when the persisted row belongs to the durable event-log era. */ availableEventsUri(runId: string): string | undefined; resultLink(runId: string): ResourceLink | undefined; eventsLink(runId: string): ResourceLink | undefined; /** * Fold the validated durable stream into one compact latest sample per logical call. The * append-only events resource remains the detailed transcript and cursor authority. */ latestActivity(runId: string): WorkflowRunLatestActivity[] | undefined; /** Absolute path of the run's editable script file; undefined for an unknown run. */ scriptPath(runId: string): string | undefined; /** The `file://` URI of the run's editable script. The run must exist and its store must keep script files. */ scriptUri(runId: string): string; /** * Map a script file URI back to the run that owns that location. Only a file a run recorded as * its script is addressable: an inline copy inside a known store, or a run's exact `scriptPath`. * Any other path, including an unowned file inside the store, is not a resource. */ private runIdForScriptUri; scriptLink(runId: string): ResourceLink | undefined; private recentRuns; private registerProtocolSurface; private subscribeEvents; private drainEventWatcher; private markEventSubscriptionDirty; private sendEventUpdate; private closeEventSubscription; /** * Shared events-page builder used by both the `workflow://runs/{runId}/events` resource and * the app-only `workflow-events` tool. `streamId` defaults to the run's current stream and * `after` to 0, so a UI consumer can bootstrap the full log without a prior head read. * Throws McpError (unavailable) or RunEventLogError (cursor/stream faults) — callers map. */ readEventsPage(request: { runId: string; after?: number; limit?: number; streamId?: string; }): WorkflowRunEventsResourceDocument; /** Canonical (query-less) resource read: the tail window of the current stream. */ private readEventsTail; private buildEventsDocument; private readEventsResource; private readResultResource; /** Serve the current text of a run's script file, never an arbitrary path. */ private readScriptResource; } //# sourceMappingURL=workflow-resources.d.ts.map