import { FlowContextSnapshotV1 } from "../../core/dist/index.js"; //#region packages/flows/src/types.d.ts /** * @aikit/flows — Type definitions for the pluggable flow system. */ /** A single step in a flow */ interface FlowStep { /** Unique step identifier within the flow (e.g., "spec", "plan", "execute") */ id: string; /** Human-readable step name */ name: string; /** Relative path to the step's instruction file */ instruction: string; /** Artifact filenames this step produces */ produces: string[]; /** Step IDs this step depends on (must be completed first) */ requires: string[]; /** Agent files specific to this step (relative paths) */ agents: string[]; /** Step description */ description: string; } /** Configuration for step content hooks */ interface FlowHookConfig { /** Hook names to disable (e.g., ["knowledge-recall"]) */ disable?: string[]; /** Token budget overrides */ tokenBudget?: { full?: number; brief?: number; }; /** Custom hooks declared by the flow (loaded at runtime from installPath) */ custom?: Array<{ /** Relative path to hook module (from flow install directory) */path: string; /** Execution order (50+ recommended to run after built-in hooks) */ order: number; /** Maximum token budget for this hook */ maxTokens?: number; /** Whether to run in brief mode */ runInBrief?: boolean; /** Whether to only fire once per flow run */ runOnce?: boolean; }>; } /** Flow manifest — the flow.json schema */ interface FlowManifest { /** Flow name (unique identifier) */ name: string; /** Semantic version */ version: string; /** Human-readable description */ description: string; /** Author name or organization */ author?: string; /** Ordered list of steps */ steps: FlowStep[]; /** Flow-level agent files (relative paths) */ agents: string[]; /** Directory for artifacts (default: ".spec") */ artifacts_dir: string; /** External dependencies to install at flow-add time */ install: string[]; /** Optional hook configuration for step content enrichment */ hooks?: FlowHookConfig; } /** Source type for flow installation */ type FlowSourceType = 'builtin' | 'git' | 'local' | 'npm-global' | 'claude-plugin'; /** Detected format of the flow source */ type FlowFormat = 'native' | 'claude-plugin' | 'copilot' | 'openspec'; type ContentTransformFn = (request: { content: string; sourceFormat: FlowFormat; stepName: string; metadata?: Record; }) => Promise; /** Registry entry for an installed flow */ interface FlowRegistryEntry { /** Flow name */ name: string; /** Flow version */ version: string; /** Original source (URL, path, or "builtin") */ source: string; /** How the flow was installed */ sourceType: FlowSourceType; /** Absolute path where flow files are stored */ installPath: string; /** Detected source format */ format: FlowFormat; /** ISO timestamp when registered */ registeredAt: string; /** ISO timestamp of last update */ updatedAt: string; /** Parsed manifest (cached) */ manifest: FlowManifest; /** Git commit SHA of the installed version (git sources only) */ commitSha?: string; } /** Snapshot of a flow definition's registry origin captured at run start */ interface FlowDefinitionOrigin { /** Original source (URL, path, or "builtin") */ source: string; /** How the flow was installed */ sourceType: FlowSourceType; /** Detected source format */ format: FlowFormat; /** Git commit SHA of the installed version (git sources only) */ commitSha?: string; } /** The flow registry file structure */ interface FlowRegistry { /** Schema version */ version: 1; /** Map of flow name → registry entry */ flows: Record; } /** Flow execution state */ type FlowStatus = 'idle' | 'active' | 'completed' | 'abandoned'; /** Execution record for a single step attempt */ interface StepExecutionRecord { /** Step ID */ stepId: string; /** Unique token for this execution attempt */ token: string; /** When the step started */ startedAt: string; /** When the step completed (undefined if still running or crashed) */ completedAt?: string; /** Outcome of the step */ outcome: 'completed' | 'skipped' | 'crashed' | 'in-progress'; } /** Flow execution state for the active run */ interface FlowState { /** Which flow is active (name from registry) */ flow: string; /** Snapshot of the flow definition origin captured at start time */ flowOrigin?: FlowDefinitionOrigin; /** Current status */ status: FlowStatus; /** Current step ID (null if not started) */ currentStep: string | null; /** Token for the currently executing step (set on step start, cleared on completion) */ currentToken?: string; /** Completed step IDs in order */ completedSteps: string[]; /** Completed step execution tokens; normalize missing persisted values to [] for backward compatibility */ completedTokens: string[]; /** Skipped step IDs */ skippedSteps: string[]; /** Log of all step attempts; normalize missing persisted values to [] for backward compatibility */ executionLog: StepExecutionRecord[]; /** Map of artifact name → file path */ artifacts: Record; /** ISO timestamp when flow was started */ startedAt: string; /** ISO timestamp of last state change */ updatedAt: string; /** Slug identifier (directory name under .flows/) */ slug: string; /** Absolute path to .flows/{slug}/ */ runDir: string; /** Human-readable topic */ topic: string; /** Current execution phase */ phase: FlowPhase; /** Whether the current step is an epilogue (injected) step */ isEpilogue: boolean; /** Workspace roots participating in this flow run (multi-root support) */ roots?: string[]; /** The canonical workspace root that owns this flow run */ primaryRoot?: string; /** L1 snapshot objective. Falls back to topic when absent. */ objective?: string; /** L1 snapshot acceptance criteria. */ acceptanceCriteria?: string[]; /** L1 snapshot scope. Falls back to roots when absent. */ scope?: string[]; /** L1 snapshot exclusions. */ exclusions?: string[]; /** L1 snapshot retrieved references. */ retrievedRefs?: string[]; } /** Persisted meta.json for a flow run under .flows/{slug}/ */ interface FlowRunMeta { /** Slug identifier (directory name) */ id: string; /** Flow name from registry (e.g. "aikit:advanced") */ flow: string; /** Flow version at time of start */ flowVersion: string; /** Snapshot of the flow definition origin captured at start time */ flowOrigin?: FlowDefinitionOrigin; /** Human-readable topic */ topic: string; /** Run status */ status: FlowStatus; /** Current step ID (null if completed/abandoned) */ currentStep: string | null; /** Completed step IDs in order */ completedSteps: string[]; /** Skipped step IDs */ skippedSteps: string[]; /** Artifacts subdirectory name from manifest (e.g. ".spec") */ artifactsDir: string; /** Map of artifact name → relative file path */ artifacts: Record; /** ISO timestamp when started */ startedAt: string; /** ISO timestamp of last change */ updatedAt: string; /** Current execution phase: before-epilogue, main flow, or after-epilogue */ phase: FlowPhase; /** Completed epilogue step IDs */ completedEpilogueSteps: string[]; /** Skipped epilogue step IDs */ skippedEpilogueSteps: string[]; /** Workspace roots participating in this flow run (multi-root support). When set, the flow state is synchronized across all listed roots. */ roots?: string[]; /** The canonical workspace root that owns this flow run */ primaryRoot?: string; /** L1 snapshot objective — the goal of this flow run. Falls back to topic when absent. */ objective?: string; /** L1 snapshot acceptance criteria. Empty when not specified at start. */ acceptanceCriteria?: string[]; /** L1 snapshot scope — explicit scope boundaries. Falls back to roots when absent. */ scope?: string[]; /** L1 snapshot exclusions — what's explicitly out of scope. */ exclusions?: string[]; /** L1 snapshot retrieved references — accumulates across steps. */ retrievedRefs?: string[]; /** Salt for SHA-256 lifecycle owner token. Present only in layered mode. */ ownerTokenSalt?: string; /** SHA-256 hash of lifecycle owner token. Present only in layered mode. */ ownerTokenHash?: string; /** Monotonically increasing owner token version for rotation tracking. */ ownerTokenVersion?: number; /** Append-only audit log of lifecycle events. Present only in layered mode. */ auditLog?: Array<{ event: 'claim' | 'backtrack' | 'reset' | 'final-consolidation'; at: string; ownerTokenVersion: number; targetStep?: string; invalidatedExecutionTokens?: string[]; reason?: string; }>; } /** Summary of a flow run for listing */ interface FlowRunSummary { /** Slug identifier */ id: string; /** Flow name */ flow: string; /** Snapshot of the flow definition origin captured at start time */ flowOrigin?: FlowDefinitionOrigin; /** Human-readable topic */ topic: string; /** Run status */ status: FlowStatus; /** Current step ID */ currentStep: string | null; /** ISO timestamp when started */ startedAt: string; /** ISO timestamp of last change */ updatedAt: string; } /** Step action for state machine transitions */ type StepAction = 'next' | 'skip' | 'redo' | 'backtrack'; /** Position of an epilogue step relative to the flow's own steps */ type EpiloguePosition = 'before' | 'after'; /** An epilogue step — mandatory step injected by aikit around every flow */ interface EpilogueStepDef { /** Unique step ID (prefixed with '_', e.g. '_docs-sync') */ id: string; /** Human-readable description */ description: string; /** Position: 'before' = runs before flow's first step, 'after' = runs after last step */ position: EpiloguePosition; /** Skills this step requires the agent to load */ skills?: string[]; } /** Configuration for mandatory epilogue steps */ interface EpilogueConfig { /** Steps injected BEFORE the flow's first step */ before: EpilogueStepDef[]; /** Steps injected AFTER the flow's last step */ after: EpilogueStepDef[]; } /** Execution phase within a flow run */ type FlowPhase = 'before' | 'flow' | 'after'; /** Options passed to format adapter parse */ interface FlowParseOptions { /** When true, force-refresh supporting assets (e.g. on update) */ forceAssetSync?: boolean; /** Optional content transformer for converting foreign step content to native README.md */ transform?: ContentTransformFn; } /** Format adapter interface — converts external formats to FlowManifest */ interface FlowFormatAdapter { /** Format name */ readonly format: FlowFormat; /** Check if a directory matches this format */ detect(sourceDir: string): boolean; /** Parse the source directory into a FlowManifest */ parse(sourceDir: string, options?: FlowParseOptions): Promise; } /** Result of a flow operation */ interface FlowResult { success: boolean; data?: T; error?: string; } //#endregion //#region packages/flows/src/adapters/claude-plugin.d.ts declare class ClaudePluginAdapter implements FlowFormatAdapter { readonly format: "claude-plugin"; detect(sourceDir: string): boolean; parse(sourceDir: string, options?: FlowParseOptions): Promise; private readPluginJson; private readString; private discoverSteps; private readStep; /** * Copy supporting subdirectories (references/, assets/, scripts/) from * skills// to steps// so that relative paths inside the * step README.md resolve correctly at runtime. * * When `force` is true, existing copies are replaced (used during updates). */ private syncStepAssets; private materializeNativeSteps; private buildStepReadme; private discoverAgents; } //#endregion //#region packages/flows/src/adapters/copilot.d.ts declare class CopilotAdapter implements FlowFormatAdapter { readonly format: "copilot"; detect(sourceDir: string): boolean; parse(sourceDir: string, options?: FlowParseOptions): Promise; private getStepId; private materializeSteps; } //#endregion //#region packages/flows/src/adapters/native.d.ts declare class NativeAdapter implements FlowFormatAdapter { readonly format: "native"; detect(sourceDir: string): boolean; parse(sourceDir: string): Promise; } //#endregion //#region packages/flows/src/adapters/openspec.d.ts /** * OpenSpec adapter — detects repos that follow the OpenSpec workflow * (https://github.com/Fission-AI/OpenSpec) and converts them to FlowManifest. * * Detection marker: `openspec/config.yaml` in the source directory. * * Flow steps are derived from the active OpenSpec schema.yaml. */ declare class OpenSpecAdapter implements FlowFormatAdapter { readonly format: "openspec"; detect(sourceDir: string): boolean; parse(sourceDir: string, options?: FlowParseOptions): Promise; /** * Read metadata from package.json if available, otherwise use defaults * derived from the openspec config. */ private readMeta; private readConfigSchema; private resolveSchemaDir; private parseSchemaArtifacts; private loadSchema; private discoverSchemaFromDirectory; private collectMarkdownFiles; private hasFileRecursive; private findSchemaYaml; private toStepIdFromMarkdown; private buildStepsFromSchema; private materializeSteps; private resolveInstructionContent; private normalizeArtifact; private normalizeApply; private readString; private readStringArray; private humanizeStepName; } //#endregion //#region packages/flows/src/builtins.d.ts interface BuiltinFlow { /** Flow manifest */ manifest: FlowManifest; /** Relative path within the monorepo where scaffold files live */ scaffoldDir: string; } /** * Returns all built-in flow definitions bundled with @aikit/flows. * These flows are always available, even without installation via `flow add`. * * scaffoldDir points to the generated preview output (scaffold/_preview/flows/). * Run `node scaffold/generate.mjs --ide flows` to populate it for dev mode. */ declare function getBuiltinFlows(): BuiltinFlow[]; //#endregion //#region packages/flows/src/context-snapshot.d.ts /** * Set of verified, assumed, and unresolved claims for a flow context snapshot. */ interface ClaimSet { verified: string[]; assumed: string[]; unresolved: string[]; decisions: Array<{ id: string; summary: string; rationale: string; }>; } /** * Options for building a flow context snapshot. */ interface BuildSnapshotOptions { claims?: ClaimSet; /** Optional overrides for snapshot fields. When absent, reads from FlowState. */ objective?: string; acceptanceCriteria?: string[]; scope?: string[]; exclusions?: string[]; retrievedRefs?: string[]; } /** * Construct a FlowContextSnapshotV1 from state machine state + resolved artifacts/claims. * * @param state - Current flow execution state * @param manifest - Flow manifest defining steps, hooks, and artifact paths * @param options - Optional claims set * @returns A complete FlowContextSnapshotV1 */ declare function buildSnapshot(state: FlowState, manifest: FlowManifest, options?: BuildSnapshotOptions): FlowContextSnapshotV1; //#endregion //#region packages/flows/src/foundation.d.ts declare class FoundationIntegration { /** * Inject foundation preamble into a file. * Replaces existing preamble if present, otherwise prepends. */ injectPreamble(filePath: string, manifest: FlowManifest): void; /** * Remove foundation preamble from a file. */ removePreamble(filePath: string): void; /** * Get list of IDE instruction files to inject preamble into. */ getTargetFiles(workspaceRoot: string): string[]; } //#endregion //#region packages/flows/src/git.d.ts declare class GitInstaller { private readonly flowsDir; constructor(flowsDir: string); /** * Clone a git repo into the flows directory. * On auth failure, if GCM is available, retries interactively so the * credential manager can open a browser / device-code flow. * Returns the local install path. */ clone(repoUrl: string, token?: string): FlowResult; /** * Update an existing cloned flow repo. */ update(installPath: string): FlowResult; /** * Copy a local directory as a flow source. */ copyLocal(sourcePath: string, name: string): FlowResult; /** * Remove installed flow files. */ remove(installPath: string): FlowResult; /** * Run install dependencies for a flow. * Processes the `install[]` field from flow.json. */ runInstallDeps(installEntries: string[]): FlowResult; /** * Get the current HEAD commit SHA for a local git repo. */ getLocalCommit(installPath: string): string | null; /** * Get the latest commit SHA on the remote default branch. * Uses `git ls-remote` so it doesn't modify the working tree. */ getRemoteCommit(installPath: string): string | null; /** * Check whether the remote has commits newer than the local HEAD. */ hasUpdates(installPath: string): FlowResult<{ localCommit: string; remoteCommit: string; hasUpdates: boolean; }>; /** Extract repo name from git URL */ private repoNameFromUrl; private ensureFlowsDir; } //#endregion //#region packages/flows/src/lifecycle-capability.d.ts /** * Lifecycle owner capability — token generation, validation, and rotation * for flow ownership verification. * * Generates cryptographically random owner tokens, stores only salted SHA-256 * hashes, and validates presented tokens with constant-time comparison. */ /** Configuration for owner capability */ interface OwnerCapabilityConfig { /** Byte length of generated token. 32 = 256-bit. Default: 32. */ tokenBytes?: number; /** Salt byte length. Default: 16. */ saltBytes?: number; } /** * Generate a cryptographically random owner token. * Returns the raw hex token. Store only the salted hash. */ declare function generateOwnerToken(config?: OwnerCapabilityConfig): string; /** * Hash a token with a salt using SHA-256. * Returns hex-encoded hash. */ declare function hashToken(token: string, salt: string): string; /** * Validate a presented token against stored salt + hash. * Uses constant-time comparison for equal-length hashes. * Returns false for length mismatch (safe early exit — no secret data leaked). */ declare function validateToken(presented: string, salt: string, hash: string): boolean; /** * Create a full owner capability record for flow start. */ declare function createOwnerCapability(): { rawToken: string; salt: string; hash: string; version: number; }; /** * Rotate an owner capability: invalidate old, create new. * Returns new raw token (returned once) alongside salt/hash/version. */ declare function rotateOwnerCapability(currentVersion: number): { rawToken: string; salt: string; hash: string; version: number; }; //#endregion //#region packages/flows/src/loader.d.ts declare class FlowLoader { load(sourceDir: string, options?: FlowParseOptions): Promise>; loadWithFormat(sourceDir: string, format: FlowFormat, options?: FlowParseOptions): Promise>; validate(manifest: FlowManifest): FlowResult; } //#endregion //#region packages/flows/src/registry.d.ts declare class FlowRegistryManager { private readonly registryPath; constructor(registryPath: string); /** Load registry from disk, or create empty if missing */ load(): FlowRegistry; /** Save registry to disk */ save(registry: FlowRegistry): void; /** Register a new flow or update an existing one */ register(entry: FlowRegistryEntry): FlowResult; /** Remove a flow from the registry */ unregister(name: string): FlowResult; /** Get a specific flow entry (checks disk registry first, then builtins) */ get(name: string): FlowRegistryEntry | null; /** List all registered flows (disk + builtins, disk overrides builtins) */ list(): FlowRegistryEntry[]; /** Check if a flow is registered (disk or builtin) */ has(name: string): boolean; } //#endregion //#region packages/flows/src/state-machine.d.ts declare class FlowStateMachine { private readonly flowsDir; private readonly epilogueConfig; constructor(flowsDir: string, epilogueConfig?: EpilogueConfig); /** Create a filesystem-safe slug from a human-readable topic */ private slugify; /** Keep the meta.json path within a conservative Windows-safe budget */ private getMaxSlugLength; /** Trim a slug to fit a length budget while keeping separators tidy */ private fitSlugToBudget; /** Allocate a unique run slug for a topic with a MM-DD-YYYY date prefix */ private generateSlug; /** Resolve the meta.json path for a run slug */ private getMetaPath; /** Build the combined step sequence: before-epilogue → flow → after-epilogue */ private buildStepSequence; /** Read a run meta.json from disk */ private readMeta; /** Persist a run meta.json to disk */ private writeMeta; /** Backfill legacy fields for persisted runs created before token/lifecycle tracking existed */ private normalizeMeta; /** Check whether a step already has a completed execution token */ private hasCompletedExecution; /** Mark the current in-progress token as crashed before forcing a fresh attempt */ private markCrashedExecution; /** Finalize the active token and update its execution record */ private finalizeCurrentStep; /** Enter a step, creating a new token unless an existing completion makes it a no-op */ private activateStep; /** Find the currently active run, if any */ private findActiveRun; /** Convert persisted run metadata into the public FlowState shape */ private metaToState; /** Start a new flow */ start(flowName: string, manifest: FlowManifest, topic?: string, flowOrigin?: FlowDefinitionOrigin, flowOptions?: { objective?: string; acceptanceCriteria?: string[]; scope?: string[]; exclusions?: string[]; }): FlowResult; /** Backtrack to a completed step, invalidating all steps after it */ backtrack(targetStep: string, manifest: FlowManifest): FlowResult; /** Advance the flow: next, skip, or redo current step */ step(action: StepAction, manifest: FlowManifest): FlowResult; /** Get current flow status */ getStatus(): FlowResult; /** Reset flow state by abandoning the active run */ reset(): FlowResult; /** Record an artifact produced by a step */ recordArtifact(name: string, path: string): FlowResult; /** Set owner capability fields on the active run (persisted). */ setOwnerCapability(ownerData: { ownerTokenSalt: string; ownerTokenHash: string; ownerTokenVersion: number; }): FlowResult; /** List flow runs, optionally filtered by flow name or status */ listRuns(filter?: { flow?: string; status?: string; }): FlowRunSummary[]; } //#endregion //#region packages/flows/src/symlinks.d.ts declare class SymlinkManager { /** * Create agent symlinks for a flow in the workspace. */ createSymlinks(workspaceRoot: string, flowName: string, flowInstallPath: string, manifest: FlowManifest): void; /** * Remove agent symlinks for a flow. */ removeSymlinks(workspaceRoot: string, flowName: string): void; private getTargets; private getAgentStem; } //#endregion export { type BuildSnapshotOptions, type BuiltinFlow, type ClaimSet, ClaudePluginAdapter, type ContentTransformFn, CopilotAdapter, type EpilogueConfig, type EpiloguePosition, type EpilogueStepDef, type FlowDefinitionOrigin, type FlowFormat, type FlowFormatAdapter, type FlowHookConfig, FlowLoader, type FlowManifest, type FlowParseOptions, type FlowPhase, type FlowRegistry, type FlowRegistryEntry, FlowRegistryManager, type FlowResult, type FlowRunMeta, type FlowRunSummary, type FlowSourceType, type FlowState, FlowStateMachine, type FlowStatus, type FlowStep, FoundationIntegration, GitInstaller, NativeAdapter, OpenSpecAdapter, type OwnerCapabilityConfig, type StepAction, SymlinkManager, buildSnapshot, createOwnerCapability, generateOwnerToken, getBuiltinFlows, hashToken, rotateOwnerCapability, validateToken };