Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/engine/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ export type {
RulesTestResult,
} from './rules/index.js'

// Walker (new execution types — will replace runner types in PR 1b)
export type {
ExecutionContext as WalkerExecutionContext,
NodeExecutionRecord,
WalkerCallbacks,
WalkOptions,
WalkResult,
} from './walker/index.js'
Comment on lines +37 to +44
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exporting new walker types changes @ruminaider/flowprint-engine's public API — should we add a .changeset/*.md entry or record a waiver?

Finding type: AI Coding Guidelines | Severity: 🟠 Medium


Want Baz to fix this for you? Activate Fixer

Other fix methods

Fix in Cursor

Prompt for AI Agents:

In packages/engine/src/index.ts around lines 37-44, the new exported walker types
(ExecutionContext as WalkerExecutionContext, NodeExecutionRecord, WalkerCallbacks,
WalkOptions, WalkResult) change the package public API. Add a .changeset entry under
packages/engine/.changeset (for example packages/engine/.changeset/add-walker-types.md)
that states the engine package changed by exporting new walker types, mark the package
bump as a minor release, and include a one-line summary and rationale. If this change is
intentionally waived, instead add a short waiver note in the repo’s changeset/waivers
location referencing this PR and explaining why no changeset is required. Ensure the new
file is committed with the PR so release tooling can pick it up.

Heads up!

Your free trial ends tomorrow.
To keep getting your PRs reviewed by Baz, update your team's subscription


// Codegen
export { generateCode } from './codegen/index.js'
export type { GenerateResult, GenerateOptions, GeneratedFile } from './codegen/index.js'
7 changes: 7 additions & 0 deletions packages/engine/src/walker/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type {
ExecutionContext,
NodeExecutionRecord,
WalkerCallbacks,
WalkOptions,
WalkResult,
} from './types.js'
82 changes: 82 additions & 0 deletions packages/engine/src/walker/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import type {
ActionNode,
SwitchNode,
ParallelNode,
WaitNode,
ErrorNode,
TerminalNode,
TriggerNode,
} from '@ruminaider/flowprint-schema'

/**
* Context passed to each node handler during graph execution.
* Created fresh for each execute() call.
*/
export interface ExecutionContext {
/** Original flow input. Treated as immutable during execution. */
readonly input: Record<string, unknown>
/** Accumulated state from prior nodes. Flat-merged after each node. */
state: Record<string, unknown>
/** Metadata about the currently executing node. */
readonly node: {
readonly id: string
readonly type: string
readonly lane: string
}
/** Cancellation/timeout signal. Handlers should check signal.aborted. */
readonly signal: AbortSignal
}

/**
* Delta-only trace record for a single node execution.
* Stores what the node produced, not a full state snapshot.
*/
export interface NodeExecutionRecord {
nodeId: string
type: string
lane: string
startedAt: number
completedAt: number
/** What this node produced (delta). Full state reconstructable by replaying deltas. */
output: Record<string, unknown>
/** How this node was handled. */
handler: 'expressions' | 'rules' | 'registered' | 'entry_point' | 'native'
/** Present only if the node errored. */
error?: { message: string; stack?: string }
}

/**
* Pluggable callbacks for the generic graph walker.
* TStep is generic so runner, simulator, and engine can each define their own step shape.
*/
export interface WalkerCallbacks<TStep = NodeExecutionRecord> {
onAction(nodeId: string, node: ActionNode, ctx: ExecutionContext): Promise<unknown>
onSwitch(nodeId: string, node: SwitchNode, ctx: ExecutionContext): Promise<string | undefined>
onParallel(nodeId: string, node: ParallelNode, ctx: ExecutionContext): Promise<unknown>
onWait(nodeId: string, node: WaitNode, ctx: ExecutionContext): Promise<unknown>
onError(nodeId: string, node: ErrorNode, ctx: ExecutionContext): Promise<string | undefined>
onTrigger(nodeId: string, node: TriggerNode, ctx: ExecutionContext): Promise<string | undefined>
onTerminal?(nodeId: string, node: TerminalNode, ctx: ExecutionContext): Promise<void>
/** Called after each node completes. Used for trace recording. */
onStep(record: TStep): void
}

/**
* Options for walkGraph.
*/
export interface WalkOptions {
/** AbortController for the entire walk. */
abortController?: AbortController
}

/**
* Result of a complete graph walk.
*/
export interface WalkResult<TStep = NodeExecutionRecord> {
/** Final accumulated state after all nodes. */
output: Record<string, unknown>
/** Ordered list of step records. */
trace: TStep[]
/** Terminal node outcome if reached. */
outcome?: 'success' | 'failure'
}
Loading