Parameters and Configuration
Parameters make your codemods flexible and reusable by allowing you to pass configuration values at runtime. This enables you to create codemods that adapt their behavior based on user input or different execution contexts.Enterprise Features: In the Codemod app, parameters are configured through a visual UI. The Codemod app provides centralized state management for large-scale refactoring across many repos.
options.params.
Matrix Strategy Integration
Matrix strategies enable you to run the same codemod with different configurations or to split large codebases into manageable chunks for parallel processing. Matrix values are particularly useful for:- Sharding: Distributing work across multiple processes or machines
- Multi-variant transforms: Running the same logic with different parameters
- Team-based processing: Applying different rules based on team ownership
Accessing Matrix Values
Access matrix values viaoptions.matrixValues:
options.matrixValues is only defined when your workflow uses a matrix strategy. Otherwise it is undefined.Matrix Strategy Configuration
Matrix strategy is defined in your workflow:workflow.yaml
Parameters vs Matrix Values:
options.params contains user-configured workflow settings, while options.matrixValues contains values from matrix strategy (e.g., team, shard, shardId from the shards state array). See Matrix Strategy for details.State Management
Thecodemod:workflow module provides shared state that is accessible across all parallel file executions within a step, and can be persisted across workflow steps.
API Reference
<T>(name: string, value: T, persist?: boolean) => void
Sets a named state value. Values are stored as native JavaScript objects (no manual JSON serialization needed). When
persist is true (the default), the value is saved at the end of the execution batch and available to subsequent workflow steps.<T>(name: string) => T | undefined
Gets a named state value, or
undefined if it doesn’t exist.(name: string) => void
Removes a named state value. If the key was persisted, a removal is propagated to persistent storage.
(name: string) => () => void
Acquires a named mutex lock. Returns a
release function that must be called when done. While held, other threads’ getState, setState, and unsetState calls on the same key block until released.Basic Usage
State is shared across all files processed in parallel within a single step:codemod.ts
When to Use Locks
UseacquireLock when you need to read-modify-write shared state from parallel threads. Without it, concurrent getState → setState sequences can overwrite each other:
Simple
setState calls that don’t depend on the current value (e.g., setState("status", "done")) don’t need locking — they are individually atomic.Persisting State Across Workflow Steps
State set withpersist: true (the default) is automatically saved after a js-ast-grep step completes. Subsequent steps in the same workflow node can read this state:
Transient State
Passpersist: false to keep state only for the current step execution (useful for in-memory coordination that doesn’t need to survive across steps):
Runtime Hooks
Thecodemod:runtime module lets a codemod send structured execution signals to the engine without relying on console.log parsing.
- show meaningful progress in workflow task logs
- warn without failing the task
- improve watchdog diagnostics by naming the active unit or file
- fail the current step explicitly instead of returning a generic exception
- stop cooperatively when the task has been canceled
API Reference
(message: string, meta?: RuntimeMeta) => void
Emits a structured progress event. Progress updates appear in task logs and refresh the step heartbeat so long-running transforms can prove they are still alive.
(message: string, meta?: RuntimeMeta) => void
Emits a non-fatal warning event. Warnings are appended to task logs but do not change task state.
(unitId: string, meta?: RuntimeMeta) => void
Overrides the current logical execution unit for diagnostics. For file-based transforms, this is usually the relative file path.
(message: string, meta?: RuntimeMeta) => never
Fails the current file or unit immediately. The runtime currently treats this as terminal for the running task.
(message: string, meta?: RuntimeMeta) => never
Fails the current step immediately. This is always terminal for the running task.
() => boolean
Returns
true if the current task has been canceled. Use it to stop long-running work cooperatively.Example: Report progress and fail explicitly
codemod.ts
When to use hooks vs exceptions
- Use
runtime.progress(...)andruntime.warn(...)for structured observability. - Use
runtime.failStep(...)when the codemod has decided the task should stop immediately. - Plain thrown errors still fail the task if they escape the codemod, but hooks give better logs and clearer intent.
- The engine’s idle timeout is only a backstop for silent hangs. Hooks are the preferred way to report semantic failures.