import { z } from 'zod' import { defineApplicationCommandContract, validationCodec, type RuntimeCodec} from './application-command-contract'import type { ArtifactFile } from './artifacts'import type { ExecutionFileEvidenceSummary } from './execution-file-evidence'import type { NotebookRuntimeBindings } from './notebook-runtime'import type { OptionalProjectIdScope, ProjectIdScope } from './project-scope' export const NOTEBOOKS_DIR = 'notebooks'export const NOTEBOOK_RUN_FILE = 'run.json'// Execution authorization canonicalizes omitted control/shell deadlines to the same defaults used// by the MCP schema and process owner. These are runtime constants, not persisted schema fields.export const NOTEBOOK_REPL_DEFAULT_TIMEOUT_MS = 30 * 60 * 1_000 + 15_000export const NOTEBOOK_SHELL_DEFAULT_TIMEOUT_MS = 120_000 export type ShellRuntimeBinding = | Readonly<{ kind: 'powershell' version: '5.1' }> | Readonly<{ kind: 'native-posix' shell: string }> | Readonly<{ kind: 'wsl2-bash' profileId: string distro: string user: string }> // Identifies whether a run was initiated by the agent or by the user terminal.export type NotebookRunSource = 'agent' | 'user' // Exact app-local dispatch methods corresponding to the three approval-gated Notebook MCP tools.export type NotebookExecutionRpcMethod = 'execute' | 'executeControl' | 'executeShell' export type RequestNotebookNetworkAccessRequest = NotebookSessionRequest & { hostname: string reason: string runtime?: 'python' | 'r' | 'repl' | 'bash' command?: string} export type RequestNotebookNetworkAccessResult = Readonly<{ hostname: string status: 'alreadyAllowed' | 'allowedOnce' | 'alwaysAllowed' | 'denied' | 'blocked' | 'unavailable' decisionSource?: 'missing-command-context' | 'aborted' | 'user-decision' | 'approval-surface-unavailable' message?: string}> // Distinguishes regular notebook cells from terminal submissions in the same history.export type NotebookRunInputKind = 'cell' | 'terminal' // Mirrors the lifecycle of one persisted execution record in run.json. 'interrupted' = the process// died (crash / force-quit) while the run was in flight — reconciled from a stale 'running' on the// next startup. 'cancelled' = the run was deliberately aborted (e.g. a force-stop disable).export type NotebookRunStatus = 'queued' | 'running' | 'completed' | 'failed' | 'timeout' | 'interrupted' | 'cancelled' export type NotebookBackgroundRunReceipt = Readonly<{ runId: string executionType: 'python-notebook-run' | 'r-notebook-run' | 'javascript-repl' | 'shell-command' projectId: string sessionId: string status: NotebookRunStatus acceptedAt: number lifecycleScope: 'app-process' submissionIdentity: string shellConcurrency?: Readonly<{ limit: number; slot?: number }>}> export type NotebookBackgroundRunResult = Readonly<{ receipt: NotebookBackgroundRunReceipt run: NotebookRunSummary // Present on Agent queries. Terminal results report whether this query suppressed the fallback // or automatic delivery was already committed; non-terminal snapshots remain `pending`. followUpDelivery?: 'pending' | 'suppressed' | 'committed'}> export type NotebookBackgroundRunErrorDetail = Readonly<{ code: string stage: 'pre-admission' | 'query' | 'cancel' retryable: boolean hint: string runId?: string submissionIdentity?: string}> export class NotebookBackgroundRunError extends Error { readonly name = 'NotebookBackgroundRunError' constructor( readonly detail: NotebookBackgroundRunErrorDetail, message: string ) { super(message) }} export type NotebookBackgroundRunLookupRequest = NotebookSessionRequest & { runId?: string submissionIdentity?: string // The authenticated local RPC bridge overwrites this with its capability-bound Agent Frame. // Renderer Session management supplies the frame recorded on the selected Run. agentFrameId?: string} export type NotebookRunProvenanceContext = { rootFrameId: string agentFrameId: string messageBranchId: string runtimeSegmentId: string promptMessageId: string originMessageId?: string} // Languages a notebook kernel can run in this phase; each runs as a persistent exec-loop process// (no ipykernel/IRkernel involved). Renderer IPC must parse this at runtime — TypeScript unions// do not reject a compromised or stale client.export const NOTEBOOK_LANGUAGES = ['python', 'r'] as constexport type NotebookLanguage = (typeof NOTEBOOK_LANGUAGES)[number]export const notebookLanguageSchema = z.enum(NOTEBOOK_LANGUAGES) export const parseNotebookLanguage = (value: unknown): NotebookLanguage => { const parsed = notebookLanguageSchema.safeParse(value) if (!parsed.success) { throw new Error('Notebook language must be python or r.') } return parsed.data} export const parseOptionalNotebookLanguage = (value: unknown): NotebookLanguage | undefined => { if (value == null) return undefined return parseNotebookLanguage(value)} // JSON RPC encodes omitted optional slots as null. Drop trailing nulls so cancel() and// provision/repair without an operation id stay valid, while a null required language still fails.const omitTrailingNull = (value: unknown): unknown => { if (!Array.isArray(value)) return value const args = [...value] while (args.length > 0 && args[args.length - 1] === null) args.pop() return args} const parsedArgs = <Args extends readonly unknown[]>(schema: z.ZodType<Args>): RuntimeCodec<Args> => Object.freeze({ parse: (value: unknown): Args => schema.parse(omitTrailingNull(value)) }) const languageAndOptionalOperationId = parsedArgs( z.union([z.tuple([notebookLanguageSchema]), z.tuple([notebookLanguageSchema, z.string()])])) const repairArgs = parsedArgs( z.union([ z.tuple([notebookLanguageSchema, z.string().min(1)]), z.tuple([notebookLanguageSchema, z.string().min(1), z.string()]) ])) export const notebookEnvironmentApplicationCommandContracts = Object.freeze({ provision: defineApplicationCommandContract( languageAndOptionalOperationId, validationCodec(z.undefined()) ), repair: defineApplicationCommandContract(repairArgs, validationCodec(z.undefined())), cancel: defineApplicationCommandContract( parsedArgs(z.union([z.tuple([]), z.tuple([notebookLanguageSchema])])), validationCodec(z.undefined()) )}) // Identifies which kernel produced a run: python/r are analysis cells, repl/bash are// control-plane/shell.export type NotebookKernelKind = 'python' | 'r' | 'repl' | 'bash'export type NotebookPersistentKernelKind = Exclude<NotebookKernelKind, 'bash'> export type NotebookPackageSource = | { type: 'github' repository: string ref?: string commit?: string subdirectory?: string } | { type: 'bioconductor' version?: string } export type NotebookEnvironmentPackage = { name: string version?: string versionStatus: 'known' | 'unavailable' ecosystem: 'python' | 'r' | 'native' | 'unknown' evidenceSources: Array< | 'python-importlib-metadata' | 'python-kernel-modules' | 'r-installed-packages' | 'r-session-info' > loadedState?: 'attached' | 'loaded' | 'installed-only' | 'unknown' libraryRank?: number libraryScope?: 'environment' | 'user' | 'system' | 'unknown' builtForRuntime?: string priority?: 'base' | 'recommended' | 'other' source?: NotebookPackageSource} export type NotebookPackageInstaller = | 'conda' | 'pip' | 'uv' | 'poetry' | 'r-install-packages' | 'renv' | 'pak' | 'biocmanager' | 'github' | 'unknown' export type NotebookPackageInstallerAttempt = { groupOrdinal: number installer: NotebookPackageInstaller packages: string[] status: 'succeeded' | 'failed' | 'skipped' mutationRisk: 'none' | 'possible' | 'confirmed' | 'unknown' reason?: | 'package-not-found' | 'solver-failed' | 'installer-unavailable' | 'permission' | 'network' | 'authentication' | 'tls-policy' | 'validation' | 'cancelled' | 'process-unconfirmed' | 'recovery-blocked' | 'unknown'} export type NotebookInventoryRefreshAttempt = { attempt: number trigger: 'terminal' | 'recovery' timestamp: string result: 'published' | 'unchanged' | 'failed' error?: string} export type NotebookEnvironmentPackageChange = { name: string ecosystem: NotebookEnvironmentPackage['ecosystem'] relationship: 'requested' | 'dependency' | 'unattributed' change: 'installed' | 'updated' | 'removed' | 'unchanged' | 'observed' beforeVersion?: string afterVersion?: string libraryRank?: number libraryScope?: NotebookEnvironmentPackage['libraryScope'] source?: NotebookPackageSource} export type NotebookEnvironmentOperation = { operationId: string timestamp: string operation: 'create' | 'install' | 'uninstall' | 'update' packages: string[] result: 'success' | 'failure' attempts: NotebookPackageInstallerAttempt[] fallbackUsed: boolean inventoryRefresh: 'published' | 'unchanged' | 'failed' inventoryRefreshAttempts: NotebookInventoryRefreshAttempt[] packageChanges?: NotebookEnvironmentPackageChange[]} export type NotebookEnvironmentOperationLogTruncation = { omittedCount: number earliestRetainedAt?: string} export const isNotebookEnvironmentOperationLogTruncation = ( value: unknown): value is NotebookEnvironmentOperationLogTruncation => { if (typeof value !== 'object' || value === null || Array.isArray(value)) return false const candidate = value as Record<string, unknown> return ( Number.isInteger(candidate.omittedCount) && Number(candidate.omittedCount) > 0 && (candidate.earliestRetainedAt === undefined || typeof candidate.earliestRetainedAt === 'string') )} export type NotebookEnvironmentManifest = { executionContext?: import('./notebook-execution-context').NotebookExecutionContext schemaVersion: 1 captureKind: 'completed-run' capturedAt: string installedInventory: { capturedAt: string source: 'full-scan' | 'cache-reused' validation: 'full-scan' | 'best-effort' } kernelKind: NotebookLanguage environmentName: string runtimeSource: 'managed' | 'external' runtimeVersion?: string platform?: string architecture?: string inventorySources: Array<'kernel-native' | 'interpreter-native' | 'operation-log'> packages: NotebookEnvironmentPackage[] operationLog?: NotebookEnvironmentOperation[] operationLogTruncation?: NotebookEnvironmentOperationLogTruncation complete: boolean captureStatus: 'complete' | 'partial' warnings?: string[]} export type NotebookRunEnvironmentCapture = | { state: 'available' | 'partial' manifestChecksum: string warnings?: string[] } | { state: 'unavailable' reason: | 'environment-not-supported' | 'environment-capture-failed' | 'environment-manifest-publication-failed' | 'legacy-environment-reference-unavailable' } export type NotebookEnvironmentLockPartialReason = | 'external-interpreter-required' | 'environment-manifest-partial' | 'non-conda-package-detected' | 'non-conda-installer-detected' | 'native-lock-file-best-effort' | 'native-lock-file-rejected' export type NotebookEnvironmentLockDiagnostic = { reason: | 'package-lock-missing' | 'package-version-unresolved' | 'package-version-mismatch' | 'package-not-captured' | 'source-unpinned' | 'source-mismatch' | 'project-selection-unresolved' packageName?: string observedVersion?: string lockedVersion?: string} export type NotebookEnvironmentLockFile = { path: string checksum: string content: string} export type NotebookEnvironmentLockComponent = | { ecosystem: 'conda' format: 'conda-explicit-md5' resolution: 'locked' explicitLock: string packages: string[] } | { ecosystem: 'python' format: 'uv-lock' | 'poetry-lock' | 'pip-requirements' resolution: 'locked' | 'best-effort' files: NotebookEnvironmentLockFile[] } | { ecosystem: 'r' format: 'renv-lock' | 'pak-lock' resolution: 'locked' files: NotebookEnvironmentLockFile[] } export type NotebookEnvironmentLock = { schemaVersion: 1 | 2 // v2 native-only locks restore packages conditionally; they do not provision this runtime. externalRuntime?: { version: string; installerVersion: string } format: 'environment-lock-bundle' kernelKind: NotebookLanguage environmentName: string platform?: string architecture?: string components: NotebookEnvironmentLockComponent[] untrackedPackages?: string[] // Native distributions observed as unused by this run; retained in the full inventory. omittedPackages?: string[] nonCondaInstallers?: NotebookPackageInstaller[]} export type NotebookRunEnvironmentLockCapture = | { state: 'available' | 'partial' format: NotebookEnvironmentLock['format'] lockChecksum: string partialReasons?: NotebookEnvironmentLockPartialReason[] diagnostics?: NotebookEnvironmentLockDiagnostic[] } | { state: 'unavailable' reason: | 'environment-not-managed' | 'conda-prefix-unavailable' | 'micromamba-unavailable' | 'environment-lock-capture-failed' | 'environment-lock-invalid' | 'environment-lock-publication-failed' } export type NotebookLiveEnvironmentOverlay = { executionContext?: import('./notebook-execution-context').NotebookExecutionContext runtimeVersion?: string packages: NotebookEnvironmentPackage[] warnings?: string[]} export type NotebookInputAssociation = 'turn-attached' | 'resolver-accessed'export type NotebookInputAccessEvidence = 'resolver' | 'file-evidence' // Path-independent immutable input identity captured from the trusted main-process registry. The// storage key is persisted only in run.json/evidence; summaries returned to agents and renderers omit// it and resolve previews through main-process IPC.export type NotebookRunInputFile = { inputFileVersionId: string sourceKind: 'upload-version' | 'artifact-version' sourceFileId: string sourceVersionNumber?: number sourceCreatedAt?: string sourceProjectId: string sourceSessionId: string filename: string contentType?: string sizeBytes: number checksum: string storageKey: string association: NotebookInputAssociation accessEvidence?: NotebookInputAccessEvidence} export type NotebookInputFileSummary = Omit<NotebookRunInputFile, 'storageKey'> // Transient model-facing projection of one exact Notebook input Version. The relative path is// materialized under the current Notebook data directory and is never persisted in run history.export type NotebookPromptInput = Pick< NotebookRunInputFile, 'sourceKind' | 'inputFileVersionId' | 'filename'> & { notebookPath: string} export type NotebookInputPreviewIdentity = { projectId: string sourceKind: NotebookRunInputFile['sourceKind'] sourceFileId: string inputFileVersionId: string} const NOTEBOOK_INPUT_PREVIEW_PREFIX = 'notebook-input:' export const createNotebookInputPreviewKey = (identity: NotebookInputPreviewIdentity): string => `${NOTEBOOK_INPUT_PREVIEW_PREFIX}${encodeURIComponent( JSON.stringify([ identity.projectId, identity.sourceKind, identity.sourceFileId, identity.inputFileVersionId ]) )}` export const parseNotebookInputPreviewKey = (key: string): NotebookInputPreviewIdentity => { if (!key.startsWith(NOTEBOOK_INPUT_PREVIEW_PREFIX)) { throw new Error('Invalid Notebook input preview key.') } const parsed = JSON.parse( decodeURIComponent(key.slice(NOTEBOOK_INPUT_PREVIEW_PREFIX.length)) ) as unknown if ( !Array.isArray(parsed) || parsed.length !== 4 || parsed.some((value) => typeof value !== 'string') || (parsed[1] !== 'upload-version' && parsed[1] !== 'artifact-version') ) { throw new Error('Invalid Notebook input preview key.') } return { projectId: parsed[0] as string,Lines 1–500 of 1135. Load more
import { z } from 'zod' import { defineApplicationCommandContract, validationCodec, type RuntimeCodec } from './application-command-contract' import type { ArtifactFile } from './artifacts' import type { ExecutionFileEvidenceSummary } from './execution-file-evidence' import type { NotebookRuntimeBindings } from './notebook-runtime' import type { OptionalProjectIdScope, ProjectIdScope } from './project-scope' export const NOTEBOOKS_DIR = 'notebooks' export const NOTEBOOK_RUN_FILE = 'run.json' // Execution authorization canonicalizes omitted control/shell deadlines to the same defaults used // by the MCP schema and process owner. These are runtime constants, not persisted schema fields. export const NOTEBOOK_REPL_DEFAULT_TIMEOUT_MS = 30 * 60 * 1_000 + 15_000 export const NOTEBOOK_SHELL_DEFAULT_TIMEOUT_MS = 120_000 export type ShellRuntimeBinding = | Readonly<{ kind: 'powershell' version: '5.1' }> | Readonly<{ kind: 'native-posix' shell: string }> | Readonly<{ kind: 'wsl2-bash' profileId: string distro: string user: string }> // Identifies whether a run was initiated by the agent or by the user terminal. export type NotebookRunSource = 'agent' | 'user' // Exact app-local dispatch methods corresponding to the three approval-gated Notebook MCP tools. export type NotebookExecutionRpcMethod = 'execute' | 'executeControl' | 'executeShell' export type RequestNotebookNetworkAccessRequest = NotebookSessionRequest & { hostname: string reason: string runtime?: 'python' | 'r' | 'repl' | 'bash' command?: string } export type RequestNotebookNetworkAccessResult = Readonly<{ hostname: string status: 'alreadyAllowed' | 'allowedOnce' | 'alwaysAllowed' | 'denied' | 'blocked' | 'unavailable' decisionSource?: 'missing-command-context' | 'aborted' | 'user-decision' | 'approval-surface-unavailable' message?: string }> // Distinguishes regular notebook cells from terminal submissions in the same history. export type NotebookRunInputKind = 'cell' | 'terminal' // Mirrors the lifecycle of one persisted execution record in run.json. 'interrupted' = the process // died (crash / force-quit) while the run was in flight — reconciled from a stale 'running' on the // next startup. 'cancelled' = the run was deliberately aborted (e.g. a force-stop disable). export type NotebookRunStatus = 'queued' | 'running' | 'completed' | 'failed' | 'timeout' | 'interrupted' | 'cancelled' export type NotebookBackgroundRunReceipt = Readonly<{ runId: string executionType: 'python-notebook-run' | 'r-notebook-run' | 'javascript-repl' | 'shell-command' projectId: string sessionId: string status: NotebookRunStatus acceptedAt: number lifecycleScope: 'app-process' submissionIdentity: string shellConcurrency?: Readonly<{ limit: number; slot?: number }> }> export type NotebookBackgroundRunResult = Readonly<{ receipt: NotebookBackgroundRunReceipt run: NotebookRunSummary // Present on Agent queries. Terminal results report whether this query suppressed the fallback // or automatic delivery was already committed; non-terminal snapshots remain `pending`. followUpDelivery?: 'pending' | 'suppressed' | 'committed' }> export type NotebookBackgroundRunErrorDetail = Readonly<{ code: string stage: 'pre-admission' | 'query' | 'cancel' retryable: boolean hint: string runId?: string submissionIdentity?: string }> export class NotebookBackgroundRunError extends Error { readonly name = 'NotebookBackgroundRunError' constructor( readonly detail: NotebookBackgroundRunErrorDetail, message: string ) { super(message) } } export type NotebookBackgroundRunLookupRequest = NotebookSessionRequest & { runId?: string submissionIdentity?: string // The authenticated local RPC bridge overwrites this with its capability-bound Agent Frame. // Renderer Session management supplies the frame recorded on the selected Run. agentFrameId?: string } export type NotebookRunProvenanceContext = { rootFrameId: string agentFrameId: string messageBranchId: string runtimeSegmentId: string promptMessageId: string originMessageId?: string } // Languages a notebook kernel can run in this phase; each runs as a persistent exec-loop process // (no ipykernel/IRkernel involved). Renderer IPC must parse this at runtime — TypeScript unions // do not reject a compromised or stale client. export const NOTEBOOK_LANGUAGES = ['python', 'r'] as const export type NotebookLanguage = (typeof NOTEBOOK_LANGUAGES)[number] export const notebookLanguageSchema = z.enum(NOTEBOOK_LANGUAGES) export const parseNotebookLanguage = (value: unknown): NotebookLanguage => { const parsed = notebookLanguageSchema.safeParse(value) if (!parsed.success) { throw new Error('Notebook language must be python or r.') } return parsed.data } export const parseOptionalNotebookLanguage = (value: unknown): NotebookLanguage | undefined => { if (value == null) return undefined return parseNotebookLanguage(value) } // JSON RPC encodes omitted optional slots as null. Drop trailing nulls so cancel() and // provision/repair without an operation id stay valid, while a null required language still fails. const omitTrailingNull = (value: unknown): unknown => { if (!Array.isArray(value)) return value const args = [...value] while (args.length > 0 && args[args.length - 1] === null) args.pop() return args } const parsedArgs = <Args extends readonly unknown[]>(schema: z.ZodType<Args>): RuntimeCodec<Args> => Object.freeze({ parse: (value: unknown): Args => schema.parse(omitTrailingNull(value)) }) const languageAndOptionalOperationId = parsedArgs( z.union([z.tuple([notebookLanguageSchema]), z.tuple([notebookLanguageSchema, z.string()])]) ) const repairArgs = parsedArgs( z.union([ z.tuple([notebookLanguageSchema, z.string().min(1)]), z.tuple([notebookLanguageSchema, z.string().min(1), z.string()]) ]) ) export const notebookEnvironmentApplicationCommandContracts = Object.freeze({ provision: defineApplicationCommandContract( languageAndOptionalOperationId, validationCodec(z.undefined()) ), repair: defineApplicationCommandContract(repairArgs, validationCodec(z.undefined())), cancel: defineApplicationCommandContract( parsedArgs(z.union([z.tuple([]), z.tuple([notebookLanguageSchema])])), validationCodec(z.undefined()) ) }) // Identifies which kernel produced a run: python/r are analysis cells, repl/bash are // control-plane/shell. export type NotebookKernelKind = 'python' | 'r' | 'repl' | 'bash' export type NotebookPersistentKernelKind = Exclude<NotebookKernelKind, 'bash'> export type NotebookPackageSource = | { type: 'github' repository: string ref?: string commit?: string subdirectory?: string } | { type: 'bioconductor' version?: string } export type NotebookEnvironmentPackage = { name: string version?: string versionStatus: 'known' | 'unavailable' ecosystem: 'python' | 'r' | 'native' | 'unknown' evidenceSources: Array< | 'python-importlib-metadata' | 'python-kernel-modules' | 'r-installed-packages' | 'r-session-info' > loadedState?: 'attached' | 'loaded' | 'installed-only' | 'unknown' libraryRank?: number libraryScope?: 'environment' | 'user' | 'system' | 'unknown' builtForRuntime?: string priority?: 'base' | 'recommended' | 'other' source?: NotebookPackageSource } export type NotebookPackageInstaller = | 'conda' | 'pip' | 'uv' | 'poetry' | 'r-install-packages' | 'renv' | 'pak' | 'biocmanager' | 'github' | 'unknown' export type NotebookPackageInstallerAttempt = { groupOrdinal: number installer: NotebookPackageInstaller packages: string[] status: 'succeeded' | 'failed' | 'skipped' mutationRisk: 'none' | 'possible' | 'confirmed' | 'unknown' reason?: | 'package-not-found' | 'solver-failed' | 'installer-unavailable' | 'permission' | 'network' | 'authentication' | 'tls-policy' | 'validation' | 'cancelled' | 'process-unconfirmed' | 'recovery-blocked' | 'unknown' } export type NotebookInventoryRefreshAttempt = { attempt: number trigger: 'terminal' | 'recovery' timestamp: string result: 'published' | 'unchanged' | 'failed' error?: string } export type NotebookEnvironmentPackageChange = { name: string ecosystem: NotebookEnvironmentPackage['ecosystem'] relationship: 'requested' | 'dependency' | 'unattributed' change: 'installed' | 'updated' | 'removed' | 'unchanged' | 'observed' beforeVersion?: string afterVersion?: string libraryRank?: number libraryScope?: NotebookEnvironmentPackage['libraryScope'] source?: NotebookPackageSource } export type NotebookEnvironmentOperation = { operationId: string timestamp: string operation: 'create' | 'install' | 'uninstall' | 'update' packages: string[] result: 'success' | 'failure' attempts: NotebookPackageInstallerAttempt[] fallbackUsed: boolean inventoryRefresh: 'published' | 'unchanged' | 'failed' inventoryRefreshAttempts: NotebookInventoryRefreshAttempt[] packageChanges?: NotebookEnvironmentPackageChange[] } export type NotebookEnvironmentOperationLogTruncation = { omittedCount: number earliestRetainedAt?: string } export const isNotebookEnvironmentOperationLogTruncation = ( value: unknown ): value is NotebookEnvironmentOperationLogTruncation => { if (typeof value !== 'object' || value === null || Array.isArray(value)) return false const candidate = value as Record<string, unknown> return ( Number.isInteger(candidate.omittedCount) && Number(candidate.omittedCount) > 0 && (candidate.earliestRetainedAt === undefined || typeof candidate.earliestRetainedAt === 'string') ) } export type NotebookEnvironmentManifest = { executionContext?: import('./notebook-execution-context').NotebookExecutionContext schemaVersion: 1 captureKind: 'completed-run' capturedAt: string installedInventory: { capturedAt: string source: 'full-scan' | 'cache-reused' validation: 'full-scan' | 'best-effort' } kernelKind: NotebookLanguage environmentName: string runtimeSource: 'managed' | 'external' runtimeVersion?: string platform?: string architecture?: string inventorySources: Array<'kernel-native' | 'interpreter-native' | 'operation-log'> packages: NotebookEnvironmentPackage[] operationLog?: NotebookEnvironmentOperation[] operationLogTruncation?: NotebookEnvironmentOperationLogTruncation complete: boolean captureStatus: 'complete' | 'partial' warnings?: string[] } export type NotebookRunEnvironmentCapture = | { state: 'available' | 'partial' manifestChecksum: string warnings?: string[] } | { state: 'unavailable' reason: | 'environment-not-supported' | 'environment-capture-failed' | 'environment-manifest-publication-failed' | 'legacy-environment-reference-unavailable' } export type NotebookEnvironmentLockPartialReason = | 'external-interpreter-required' | 'environment-manifest-partial' | 'non-conda-package-detected' | 'non-conda-installer-detected' | 'native-lock-file-best-effort' | 'native-lock-file-rejected' export type NotebookEnvironmentLockDiagnostic = { reason: | 'package-lock-missing' | 'package-version-unresolved' | 'package-version-mismatch' | 'package-not-captured' | 'source-unpinned' | 'source-mismatch' | 'project-selection-unresolved' packageName?: string observedVersion?: string lockedVersion?: string } export type NotebookEnvironmentLockFile = { path: string checksum: string content: string } export type NotebookEnvironmentLockComponent = | { ecosystem: 'conda' format: 'conda-explicit-md5' resolution: 'locked' explicitLock: string packages: string[] } | { ecosystem: 'python' format: 'uv-lock' | 'poetry-lock' | 'pip-requirements' resolution: 'locked' | 'best-effort' files: NotebookEnvironmentLockFile[] } | { ecosystem: 'r' format: 'renv-lock' | 'pak-lock' resolution: 'locked' files: NotebookEnvironmentLockFile[] } export type NotebookEnvironmentLock = { schemaVersion: 1 | 2 // v2 native-only locks restore packages conditionally; they do not provision this runtime. externalRuntime?: { version: string; installerVersion: string } format: 'environment-lock-bundle' kernelKind: NotebookLanguage environmentName: string platform?: string architecture?: string components: NotebookEnvironmentLockComponent[] untrackedPackages?: string[] // Native distributions observed as unused by this run; retained in the full inventory. omittedPackages?: string[] nonCondaInstallers?: NotebookPackageInstaller[] } export type NotebookRunEnvironmentLockCapture = | { state: 'available' | 'partial' format: NotebookEnvironmentLock['format'] lockChecksum: string partialReasons?: NotebookEnvironmentLockPartialReason[] diagnostics?: NotebookEnvironmentLockDiagnostic[] } | { state: 'unavailable' reason: | 'environment-not-managed' | 'conda-prefix-unavailable' | 'micromamba-unavailable' | 'environment-lock-capture-failed' | 'environment-lock-invalid' | 'environment-lock-publication-failed' } export type NotebookLiveEnvironmentOverlay = { executionContext?: import('./notebook-execution-context').NotebookExecutionContext runtimeVersion?: string packages: NotebookEnvironmentPackage[] warnings?: string[] } export type NotebookInputAssociation = 'turn-attached' | 'resolver-accessed' export type NotebookInputAccessEvidence = 'resolver' | 'file-evidence' // Path-independent immutable input identity captured from the trusted main-process registry. The // storage key is persisted only in run.json/evidence; summaries returned to agents and renderers omit // it and resolve previews through main-process IPC. export type NotebookRunInputFile = { inputFileVersionId: string sourceKind: 'upload-version' | 'artifact-version' sourceFileId: string sourceVersionNumber?: number sourceCreatedAt?: string sourceProjectId: string sourceSessionId: string filename: string contentType?: string sizeBytes: number checksum: string storageKey: string association: NotebookInputAssociation accessEvidence?: NotebookInputAccessEvidence } export type NotebookInputFileSummary = Omit<NotebookRunInputFile, 'storageKey'> // Transient model-facing projection of one exact Notebook input Version. The relative path is // materialized under the current Notebook data directory and is never persisted in run history. export type NotebookPromptInput = Pick< NotebookRunInputFile, 'sourceKind' | 'inputFileVersionId' | 'filename' > & { notebookPath: string } export type NotebookInputPreviewIdentity = { projectId: string sourceKind: NotebookRunInputFile['sourceKind'] sourceFileId: string inputFileVersionId: string } const NOTEBOOK_INPUT_PREVIEW_PREFIX = 'notebook-input:' export const createNotebookInputPreviewKey = (identity: NotebookInputPreviewIdentity): string => `${NOTEBOOK_INPUT_PREVIEW_PREFIX}${encodeURIComponent( JSON.stringify([ identity.projectId, identity.sourceKind, identity.sourceFileId, identity.inputFileVersionId ]) )}` export const parseNotebookInputPreviewKey = (key: string): NotebookInputPreviewIdentity => { if (!key.startsWith(NOTEBOOK_INPUT_PREVIEW_PREFIX)) { throw new Error('Invalid Notebook input preview key.') } const parsed = JSON.parse( decodeURIComponent(key.slice(NOTEBOOK_INPUT_PREVIEW_PREFIX.length)) ) as unknown if ( !Array.isArray(parsed) || parsed.length !== 4 || parsed.some((value) => typeof value !== 'string') || (parsed[1] !== 'upload-version' && parsed[1] !== 'artifact-version') ) { throw new Error('Invalid Notebook input preview key.') } return { projectId: parsed[0] as string,