codemod 1.1.0-alpha.1 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +179 -861
  2. package/package.json +6 -6
package/README.md CHANGED
@@ -1,946 +1,264 @@
1
+ <p align="center">
2
+ <a href="https://codemod.com">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/codemod/codemod/main/apps/docs/images/intro/codemod-docs-hero-dark.jpg">
5
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/codemod/codemod/main/apps/docs/images/intro/codemod-docs-hero-light.jpg">
6
+ <img alt="Codemod CLI" src="https://raw.githubusercontent.com/codemod/codemod/main/apps/docs/images/intro/codemod-docs-hero-light.jpg">
7
+ </picture>
8
+ </a>
9
+
10
+ <p align="center">
11
+ <br />
12
+ <a href="https://go.codemod.com/app">Platform</a>
13
+ ·
14
+ <a href="https://go.codemod.com/community">Community</a>
15
+ ·
16
+ <a href="https://docs.codemod.com">Docs</a>
17
+ </p>
18
+ </p>
19
+
1
20
  # Codemod CLI
2
21
 
3
- The Codemod CLI is a command-line interface for running and managing Butterflow workflows - a lightweight, self-hostable workflow engine designed for running large-scale code transformation jobs.
22
+ [![Community](https://img.shields.io/badge/slack-join-e9a820)](https://go.codemod.com/community)
23
+ [![License](https://img.shields.io/github/license/codemod/codemod)](https://github.com/codemod/codemod/blob/main/LICENSE)
24
+ [![npm version](https://img.shields.io/npm/v/codemod.svg)](https://www.npmjs.com/package/codemod)
4
25
 
5
- > **NOTE**: This CLI is currently in alpha and may change over time. So be careful when using it in production environments.
6
- > For more information read the [blog post announcing the CLI](https://codemod.com/blog/new-codemod-cli).
7
- > And any feedback is welcome!
26
+ **Codemod CLI** is an open-source command-line tool for building, testing, and running **codemod packages**—automated code transformations that help teams modernize codebases, upgrade frameworks, and refactor at scale.
8
27
 
9
- ## Installation
28
+ Whether you're an individual developer tackling tech debt, an OSS maintainer shipping upgrade paths, or a platform team coordinating migrations across hundreds of services, Codemod CLI gives you the tools to automate repetitive code changes reliably.
10
29
 
11
- ### Building from Source
30
+ ## Installation
12
31
 
13
32
  ```bash
14
- # Clone the repository
15
- git clone https://github.com/codemod-com/codemod.git
16
- cd codemod
17
-
18
- # Build the project
19
- cargo build --release
20
-
21
- # The executable will be available at target/release/codemod
33
+ npm install -g codemod@latest
22
34
  ```
23
35
 
24
- ### From npm registry
36
+ Or use via `npx` without installation:
25
37
 
26
38
  ```bash
27
- npm install -g codemod
39
+ npx codemod@latest <command>
28
40
  ```
29
41
 
30
42
  ## Quick Start
31
43
 
32
- 1. Create a workflow file `workflow.yaml`:
33
-
34
- ```yaml
35
- version: "1"
36
- nodes:
37
- - id: hello-world
38
- name: Hello World
39
- type: automatic
40
- runtime:
41
- type: direct
42
- steps:
43
- - id: hello
44
- name: Say Hello
45
- run: echo "Hello, World!"
46
- ```
47
-
48
- 2. Run the workflow:
49
-
50
- ```bash
51
- codemod run -w workflow.yaml
52
- ```
53
-
54
- ## Commands
55
-
56
- ### `codemod init`
57
-
58
- Initialize a new Butterflow workflow project with interactive setup:
59
-
60
- ```bash
61
- # Initialize a new project in current directory
62
- codemod init
63
-
64
- # Initialize a new project in a specific directory
65
- codemod init my-project/
66
-
67
- # Initialize with a specific name
68
- codemod init --name my-workflow
69
- ```
70
-
71
- **Options:**
72
- - `--name <NAME>`: Set the project name (defaults to directory name)
73
- - `--force`: Overwrite existing files if they exist
74
- - Positional argument: Target directory path (defaults to current directory)
75
-
76
- **Interactive Setup:**
77
-
78
- The init command will prompt you with several questions to customize your project:
79
-
80
- 1. **Project Type Selection:**
81
- ```
82
- ? What type of workflow would you like to create?
83
- ❯ AST-grep with JavaScript/TypeScript rules
84
- AST-grep with YAML rules
85
- Blank workflow (custom commands)
86
- ```
87
-
88
- 2. **Language Selection** (if AST-grep is chosen):
89
- ```
90
- ? Which language would you like to target?
91
- ❯ JavaScript/TypeScript
92
- Python
93
- Rust
94
- Go
95
- Java
96
- C/C++
97
- Other
98
- ```
99
-
100
- 3. **Project Configuration:**
101
- ```
102
- ? Project name: my-codemod
103
- ? Description: Converts legacy API calls to new format
104
- ? Author: Your Name <your.email@example.com>
105
- ```
106
-
107
- **Generated Project Structure:**
108
-
109
- Depending on your selections, the init command creates different project templates:
110
-
111
- #### AST-grep JavaScript Project
112
- ```
113
- my-codemod/
114
- ├── workflow.yaml # Main workflow definition
115
- ├── package.json # Node.js dependencies
116
- ├── rules/
117
- │ └── example-rule.js # JavaScript AST transformation rules
118
- ├── scripts/
119
- │ └── apply-codemod.js # Script to apply transformations
120
- ├── tests/
121
- │ ├── input/ # Test input files
122
- │ └── expected/ # Expected output files
123
- └── README.md # Project documentation
124
- ```
125
-
126
- #### AST-grep YAML Project
127
- ```
128
- my-codemod/
129
- ├── workflow.yaml # Main workflow definition
130
- ├── rules/
131
- │ └── example-rule.yml # YAML AST pattern rules
132
- ├── scripts/
133
- │ └── apply-rules.sh # Shell script to apply rules
134
- ├── tests/
135
- │ ├── input/ # Test input files
136
- │ └── expected/ # Expected output files
137
- └── README.md # Project documentation
138
- ```
139
-
140
- #### Blank Workflow Project
141
- ```
142
- my-workflow/
143
- ├── workflow.yaml # Basic workflow template
144
- ├── scripts/
145
- │ └── example.sh # Example script
146
- └── README.md # Project documentation
147
- ```
148
-
149
- **Example Usage:**
150
-
151
- ```bash
152
- # Create a new AST-grep JavaScript project
153
- $ codemod init my-js-codemod
154
- ? What type of workflow would you like to create? AST-grep with JavaScript/TypeScript rules
155
- ? Which language would you like to target? JavaScript/TypeScript
156
- ? Project name: my-js-codemod
157
- ? Description: Migrate from React class components to hooks
158
- ? Author: John Doe <john@example.com>
159
-
160
- ✓ Created workflow.yaml
161
- ✓ Created package.json with @ast-grep/cli dependency
162
- ✓ Created rules/migrate-to-hooks.js
163
- ✓ Created scripts/apply-codemod.js
164
- ✓ Created test structure
165
- ✓ Created README.md
166
-
167
- Next steps:
168
- cd my-js-codemod
169
- npm install
170
- codemod validate -w workflow.yaml
171
- codemod run -w workflow.yaml
172
- ```
173
-
174
- ### `codemod run`
175
-
176
- Execute a workflow from various sources:
177
-
178
- ```bash
179
- # Run from a specific workflow file
180
- codemod run -w workflow.yaml
181
- codemod run -w path/to/workflow.yaml
182
-
183
- # Run from a workflow bundle directory (containing workflow.yaml)
184
- codemod run ./my-workflow-bundle/
185
-
186
- # Run from a registry (Conceptual)
187
- # codemod run my-registry/react-19-codemods:latest
188
- ```
189
-
190
- **Options:**
191
- - `-w, --workflow <FILE>`: Path to the workflow definition file
192
- - Positional argument: Path to workflow file or bundle directory
193
-
194
- ### `codemod resume`
195
-
196
- Resume a paused workflow or trigger manual tasks:
197
-
198
- ```bash
199
- # Resume a workflow run by ID
200
- codemod resume -i <workflow-run-id>
201
-
202
- # Trigger a specific task by UUID
203
- codemod resume -i <workflow-run-id> -t <task-uuid>
204
-
205
- # Trigger all tasks currently awaiting manual triggers
206
- codemod resume -i <workflow-run-id> --trigger-all
207
- ```
208
-
209
- **Options:**
210
- - `-i, --id <UUID>`: Workflow run ID to resume
211
- - `-t, --task <UUID>`: Specific task UUID to trigger
212
- - `--trigger-all`: Trigger all tasks in `AwaitingTrigger` state
213
-
214
- ### `codemod validate`
215
-
216
- Validate a workflow definition without executing it:
217
-
218
- ```bash
219
- # Validate a workflow file
220
- codemod validate -w workflow.yaml
221
- codemod validate -w path/to/workflow.yaml
222
-
223
- # Validate a workflow bundle
224
- codemod validate ./my-workflow-bundle/
225
- ```
226
-
227
- **Validation Checks:**
228
- - Schema validation
229
- - Node ID uniqueness
230
- - Step ID uniqueness within nodes
231
- - Template ID uniqueness
232
- - Dependency validation
233
- - Cyclic dependency detection
234
- - Template reference validation
235
- - Matrix strategy validation
236
- - State schema validation
237
- - Variable reference syntax validation
238
-
239
- **Example Output:**
240
-
241
- Valid workflow:
242
- ```bash
243
- $ codemod validate -w valid-workflow.yaml
244
- ✓ Workflow definition is valid
245
- Schema validation: Passed
246
- Node dependencies: Valid (3 nodes, 2 dependency relationships)
247
- Template references: Valid (2 templates, 3 references)
248
- Matrix strategies: Valid (1 matrix node)
249
- State schema: Valid (2 schema definitions)
250
- ```
251
-
252
- Invalid workflow:
253
- ```bash
254
- $ codemod validate -w invalid-workflow.yaml
255
- ✗ Workflow definition is invalid
256
- Error at nodes[2].strategy: Matrix strategy requires 'values' or 'from_state' property
257
- Error at nodes[1].depends_on[0]: Referenced node 'non-existent-node' does not exist
258
- Error: Cyclic dependency detected: node-a → node-b → node-a
259
- ```
260
-
261
- ### `codemod login`
262
-
263
- Authenticate with a Butterflow registry to publish and manage codemods:
264
-
265
44
  ```bash
266
- # Login to the default registry
267
- codemod login
268
-
269
- # Login to a specific registry
270
- codemod login --registry https://registry.example.com
271
-
272
- # Login with a token (for CI/CD)
273
- codemod login --token <your-token>
45
+ # 1. Create a codemod package
46
+ npx codemod init my-codemod
47
+ cd my-codemod
274
48
 
275
- # Login with username/password
276
- codemod login --username <username>
277
- ```
49
+ # You can create codemod packages with the help of AI using Codemod MCP or Studio
278
50
 
279
- **Options:**
280
- - `--registry <URL>`: Registry URL (defaults to official Butterflow registry)
281
- - `--token <TOKEN>`: Authentication token (for non-interactive login)
282
- - `--username <USERNAME>`: Username for interactive login
283
- - `--scope <SCOPE>`: Organization or user scope for publishing
51
+ # 2. Run it locally
52
+ npx codemod workflow run -w ./example-codemod -t /abs/path/to/repo
284
53
 
285
- **Interactive Login:**
54
+ # 3. Publish to registry
55
+ npx codemod login
56
+ npx codemod publish
286
57
 
287
- ```bash
288
- $ codemod login
289
- ? Registry URL: https://app.butterflow.com(default)
290
- ? Username: john.doe
291
- ? Password: ********
292
- ? Organization (optional): my-org
293
- ✓ Successfully logged in as john.doe
294
- ✓ Default publish scope set to @my-org
58
+ # 4. Run from registry
59
+ npx codemod @your-org/example-codemod
295
60
  ```
296
61
 
297
- **Token-based Login (for CI/CD):**
62
+ ## What are Codemod Packages?
298
63
 
299
- ```bash
300
- # Set authentication token
301
- export BUTTERFLOW_TOKEN="your-registry-token"
302
- codemod login --token $BUTTERFLOW_TOKEN
303
- ```
64
+ **Codemod packages** are portable, reusable code transformation units that can range from simple find-and-replace operations to complex, multi-step migration workflows. Each package includes:
304
65
 
305
- ### `codemod publish`
66
+ - **Transformation logic** – Written in JavaScript/TypeScript (jssg), YAML ast-grep rules, or shell scripts
67
+ - **Workflow definition** – Orchestrates steps, handles dependencies, and manages execution
68
+ - **Package manifest** – Defines metadata, target languages, and publishing configuration
306
69
 
307
- Publish a codemod to a registry for sharing and reuse:
70
+ Packages are **fully portable**: run them locally during development, in CI/CD pipelines, or share them via the [Codemod Registry](https://go.codemod.com/registry) for your team or the community.
308
71
 
309
- ```bash
310
- # Publish current directory as a codemod
311
- codemod publish
72
+ ## Why Codemod CLI?
312
73
 
313
- # Publish a specific codemod directory
314
- codemod publish ./my-codemod/
74
+ - **🎯 Built for Automation** – Scaffold, test, and publish codemod packages from your terminal
75
+ - **📦 Registry Integration** – Share codemods via the [Codemod Registry](https://go.codemod.com/registry) or run community packages instantly
76
+ - **⚡ Powerful Engines** – Leverage ast-grep (YAML + jssg) for fast, accurate AST-based transformations
77
+ - **🤖 AI-Powered Creation** – Use [Codemod MCP](https://go.codemod.com/mcp-docs) in your IDE or [Codemod Studio](https://go.codemod.com/studio-docs) to build codemods with AI assistance
78
+ - **🧪 Built-in Testing** – Validate codemods with snapshot testing before running on production code
79
+ - **🔧 Flexible Runtime** – Run directly on your machine or in Docker/Podman containers
315
80
 
316
- # Publish with specific version
317
- codemod publish --version 1.2.3
81
+ ## Core Concepts
318
82
 
319
- # Publish to specific registry
320
- codemod publish --registry https://registry.example.com
83
+ ### Codemod Packages
321
84
 
322
- # Dry run (validate without publishing)
323
- codemod publish --dry-run
324
- ```
85
+ A **codemod package** is a directory containing:
325
86
 
326
- **Options:**
327
- - `--version <VERSION>`: Explicit version (overrides manifest version)
328
- - `--registry <URL>`: Target registry URL
329
- - `--tag <TAG>`: Tag for the release (e.g., `beta`, `latest`)
330
- - `--access <LEVEL>`: Access level (`public` or `private`)
331
- - `--dry-run`: Validate and pack without uploading
332
- - `--force`: Override existing version (use with caution)
87
+ - `codemod.yaml` – Package metadata (name, version, description, target languages)
88
+ - `workflow.yaml` Workflow steps and orchestration logic
89
+ - `scripts/` JavaScript/TypeScript codemods (jssg)
90
+ - `rules/` YAML ast-grep rule files
333
91
 
334
- **Publishing Flow:**
92
+ Packages can be as simple as a single transformation or as complex as multi-step migration workflows combining JavaScript codemods, YAML rules, shell scripts, and AI-assisted steps.
335
93
 
336
- ```bash
337
- $ codemod publish
338
- ✓ Validating codemod.yaml manifest
339
- ✓ Validating workflow.yaml
340
- ✓ Running tests (if present)
341
- ✓ Building codemod bundle
342
- ✓ Uploading to registry @my-org/react-hooks-migration@1.0.0
343
- ✓ Published successfully!
344
-
345
- Install with: codemod run @my-org/react-hooks-migration@1.0.0
346
- ```
347
-
348
- ## Codemod Manifest Standard
349
-
350
- Published codemods must include a `codemod.yaml` manifest file that defines metadata, dependencies, and publishing information.
351
-
352
- ### Manifest Schema
353
-
354
- ```yaml
355
- # codemod.yaml
356
- name: react-hooks-migration
357
- version: 1.0.0
358
- description: Migrates React class components to functional components with hooks
359
- author: John Doe <john@example.com>
360
- license: MIT
361
- repository: https://github.com/user/react-hooks-migration
362
-
363
- registry:
364
- access: public
365
-
366
- targets:
367
- languages:
368
- - javascript
369
- - typescript
370
- frameworks:
371
- - react
372
- versions:
373
- react: ">=16.8.0"
374
- ```
375
-
376
- ### Required Fields
377
-
378
- | Field | Type | Description |
379
- |-------|------|-------------|
380
- | `name` | string | Codemod package name (must be unique in scope) |
381
- | `version` | string | Semantic version (e.g., "1.0.0") |
382
- | `description` | string | Brief description of what the codemod does |
383
- | `author` | string | Author name and email |
384
-
385
- ### Optional Fields
386
-
387
- | Field | Type | Description |
388
- |-------|------|-------------|
389
- | `license` | string | License identifier (e.g., "MIT", "Apache-2.0") |
390
- | `repository` | string | Repository URL for the codemod source code |
391
- | `registry.access` | string | Access level: "public" or "private" |
392
- | `targets.languages` | array | Supported programming languages |
393
- | `targets.frameworks` | array | Supported frameworks or libraries |
394
- | `targets.versions` | object | Version constraints for frameworks |
395
-
396
- ### Publishing Examples
397
-
398
- #### Basic Codemod
399
-
400
- ```yaml
401
- name: remove-console-logs
402
- version: 1.0.0
403
- description: Removes console.log statements from JavaScript/TypeScript files
404
- author: Developer <dev@example.com>
405
- license: MIT
406
- repository: https://github.com/dev/remove-console-logs
407
-
408
- targets:
409
- languages: [javascript, typescript]
410
- ```
94
+ [Learn more about codemod packages →](https://docs.codemod.com/cli/packages)
411
95
 
412
- #### Framework-Specific Codemod
96
+ ### jssg (JavaScript ast-grep)
413
97
 
414
- ```yaml
415
- name: api-migration-v2
416
- version: 2.1.0
417
- description: Migrates legacy API calls to new v2 endpoints
418
- author: API Team <api-team@company.com>
419
- license: Apache-2.0
420
- repository: https://github.com/company/api-migration-v2
421
-
422
- registry:
423
- access: private
424
-
425
- targets:
426
- languages: [javascript, typescript]
427
- frameworks: [react, vue, angular]
428
- versions:
429
- react: ">=16.0.0"
430
- vue: ">=3.0.0"
431
- ```
98
+ **jssg** enables you to write codemods in JavaScript/TypeScript that transform code in **any language** supported by ast-grep (JavaScript, TypeScript, Python, Rust, Go, Java, C++, and more).
432
99
 
433
- ## Workflow Sources
100
+ ```typescript
101
+ // Example: Replace console.log with logger.info
102
+ import type { Transform } from "codemod:ast-grep";
103
+ import type TSX from "codemod:ast-grep/langs/tsx";
434
104
 
435
- The CLI supports loading workflows from different sources:
105
+ const transform: Transform<TSX> = (root) => {
106
+ const rootNode = root.root();
436
107
 
437
- ### File Path
438
- ```bash
439
- codemod run -w path/to/your/workflow.yaml
440
- ```
441
- Loads the specific file. The base path for execution is the directory containing this file.
108
+ // Find all console.log calls
109
+ const consoleCalls = rootNode.findAll({
110
+ rule: { pattern: "console.log($$$ARGS)" }
111
+ });
442
112
 
443
- ### Directory Path (Bundle)
444
- ```bash
445
- codemod run path/to/your/bundle/
446
- ```
447
- Butterflow looks for a standard workflow file (e.g., `workflow.yaml`) inside this directory. The base path for execution is this directory.
113
+ if (consoleCalls.length === 0) {
114
+ return null; // No changes needed
115
+ }
448
116
 
449
- ### Registry Identifier
450
- ```bash
451
- # Install and run a published codemod
452
- codemod run @my-org/react-hooks-migration@1.0.0
117
+ // Create edits
118
+ const edits = consoleCalls.map((node) => {
119
+ const args = node.getMatch('ARGS')?.text() || '';
120
+ return node.replace(`logger.info(${args})`);
121
+ });
453
122
 
454
- # Run latest version
455
- codemod run @my-org/react-hooks-migration@latest
123
+ return rootNode.commitEdits(edits);
124
+ };
456
125
 
457
- # Run with custom parameters
458
- codemod run @my-org/api-migration-v2@2.1.0 --param api_base_url=https://staging-api.example.com
126
+ export default transform;
459
127
  ```
460
128
 
461
- When running from a registry, Butterflow:
462
- 1. Downloads the codemod bundle from the registry
463
- 2. Caches it locally for faster subsequent runs
464
- 3. Validates the manifest and workflow
465
- 4. Executes with the bundle directory as the base path
466
-
467
- For your information the defautl registry is `https://app.codemod.com/`. and you can visualize codemods on the [Codemod Registry webapp](https://app.codemod.com/registry).
468
-
469
- ## Workflow Bundles
470
-
471
- A workflow bundle is a directory containing:
472
- 1. The main workflow definition file (e.g., `workflow.yaml`)
473
- 2. Any scripts, binaries, or configuration files referenced by the workflow steps
474
- 3. Additional assets needed by the tasks
475
-
476
- When running from a directory, Butterflow uses that directory as the root for resolving relative paths during execution.
477
-
478
- ## Runtime Execution
479
-
480
- ### Container Runtimes
481
-
482
- The CLI supports multiple execution runtimes:
483
-
484
- - **Docker**: Uses Docker daemon for container execution
485
- - **Podman**: Uses Podman for container execution
486
- - **Direct**: Runs commands directly on the host machine
487
-
488
- When using `runtime: direct`, commands execute with the same working directory as the `codemod` CLI invocation. Use the `$CODEMOD_PATH` environment variable to access files within the workflow bundle.
129
+ jssg combines the power of AST transformations with the flexibility of JavaScript, making complex transformations intuitive and testable.
489
130
 
490
- ### Environment Variables
131
+ [Learn more about jssg →](https://docs.codemod.com/jssg)
491
132
 
492
- The CLI provides several environment variables to running tasks:
133
+ ### Workflow Orchestration
493
134
 
494
- - `$STATE_OUTPUTS`: File descriptor for writing state updates
495
- - `$CODEMOD_PATH`: Absolute path to the workflow bundle root (for `direct` runtime)
496
- - `$BUTTERFLOW_STATE`: Path to state file for programmatic access
497
-
498
- ## Manual Triggers and Resumption
499
-
500
- ### Manual Nodes
501
-
502
- Nodes with `type: manual` or `trigger: { type: manual }` will pause execution and await manual triggers:
135
+ Workflows define how your codemod package runs. They can orchestrate multiple steps, handle dependencies, manage state, and even include manual approval gates:
503
136
 
504
137
  ```yaml
505
- nodes:
506
- - id: deploy-prod
507
- name: Deploy to Production
508
- type: automatic
509
- trigger:
510
- type: manual # Requires manual approval
511
- steps:
512
- - id: deploy
513
- run: ./deploy.sh production
514
- ```
515
-
516
- ### Triggering Manual Tasks
517
-
518
- When a workflow pauses for manual triggers:
519
-
520
- 1. The workflow state is persisted with tasks marked `AwaitingTrigger`
521
- 2. The CLI provides task UUIDs for manual triggering
522
- 3. Use `codemod resume` to trigger specific tasks or all awaiting tasks
523
-
524
- ```bash
525
- # Trigger specific deployment task
526
- codemod resume -i abc123-workflow-run-id -t def456-task-uuid
527
-
528
- # Trigger all awaiting tasks and continue
529
- codemod resume -i abc123-workflow-run-id --trigger-all
530
- ```
531
-
532
- ## Error Handling
533
-
534
- ### Automatic Validation
535
-
536
- Validation is performed automatically when running workflows:
537
-
538
- ```bash
539
- $ codemod run -w invalid-workflow.yaml
540
- ✗ Workflow definition is invalid
541
- Error: Cyclic dependency detected: node-a → node-b → node-a
542
- Workflow execution aborted
543
- ```
544
-
545
- ### Resume After Failures
546
-
547
- If a workflow fails or is interrupted:
548
-
549
- 1. The state is automatically persisted
550
- 2. Use `codemod resume` to continue from the last checkpoint
551
- 3. Failed tasks can be retried while preserving completed work
552
-
553
- ## Examples
554
-
555
- ### Basic Workflow Execution
556
-
557
- ```bash
558
- # Create and run a simple workflow
559
- cat > hello.yaml << EOF
560
138
  version: "1"
561
139
  nodes:
562
- - id: greet
563
- name: Greeting
140
+ - id: transform
141
+ name: Update API Calls
564
142
  type: automatic
565
- runtime:
566
- type: direct
567
143
  steps:
568
- - id: hello
569
- run: echo "Hello from Butterflow!"
570
- EOF
571
-
572
- codemod run -w hello.yaml
573
- ```
574
-
575
- ### Matrix Workflow with Manual Approval
576
-
577
- ```bash
578
- # Run matrix workflow requiring manual triggers
579
- codemod run -w deploy-workflow.yaml
580
-
581
- # When paused, trigger specific environments
582
- codemod resume -i <run-id> -t <staging-task-uuid>
583
- codemod resume -i <run-id> -t <prod-task-uuid>
584
- ```
585
-
586
- ### Workflow Validation and Publishing
587
-
588
- ```bash
589
- # Validate before running
590
- codemod validate -w complex-workflow.yaml
591
-
592
- # Run if validation passes
593
- codemod run -w complex-workflow.yaml
594
-
595
- # Login to registry and publish a codemod
596
- codemod login
597
- codemod publish ./my-codemod/
598
-
599
- # Run published codemod
600
- codemod run @my-org/my-codemod@1.0.0
601
- ```
602
-
603
- ### Publishing Workflow
604
-
605
- ```bash
606
- # Create and publish a new codemod
607
- codemod init my-api-migration
608
- cd my-api-migration
609
-
610
- # Develop and test your codemod
611
- # ... edit workflow.yaml, add rules, scripts, etc.
612
-
613
- # Create manifest
614
- cat > codemod.yaml << EOF
615
- name: my-api-migration
616
- version: 1.0.0
617
- description: Migrates legacy API calls
618
- author: Developer <dev@example.com>
619
- workflow: workflow.yaml
620
- targets:
621
- languages: [javascript, typescript]
622
- EOF
623
-
624
- # Validate and publish
625
- codemod validate
626
- codemod publish --dry-run # Preview
627
- codemod publish # Publish to registry
628
- ```
629
-
630
- ## Global Options
631
-
632
- Most commands support these global options:
633
-
634
- - `--help, -h`: Show help information
635
- - `--version, -V`: Show version information
636
- - `--verbose, -v`: Enable verbose output
637
- - `--quiet, -q`: Suppress non-essential output
638
-
639
- For detailed help on any command, use:
640
-
641
- ```bash
642
- codemod <command> --help
643
- ```
644
-
645
- ## JSSG (JavaScript AST-grep)
646
-
647
- JSSG is a JavaScript/TypeScript codemod runner and testing framework inspired by [ast-grep](https://ast-grep.github.io/). It enables you to write codemods in JavaScript and apply them to codebases with powerful CLI and test automation support.
648
-
649
- ### Running a Codemod
650
-
651
- To run a JavaScript codemod on a target directory:
652
-
653
- ```bash
654
- codemod jssg run my-codemod.js ./src --language javascript
655
- ```
656
-
657
- **Options:**
658
- - `--language <LANG>`: Target language (javascript, typescript, etc.)
659
- - `--extensions <ext1,ext2>`: Comma-separated list of file extensions to process
660
- - `--no-gitignore`: Do not respect .gitignore files
661
- - `--include-hidden`: Include hidden files and directories
662
- - `--max-threads <N>`: Maximum number of concurrent threads
663
- - `--dry-run`: Perform a dry run without making changes
664
-
665
- See `codemod jssg run --help` for all options.
666
-
667
- ### Example
668
-
669
- ```bash
670
- codemod jssg run my-codemod.js ./src --language javascript --dry-run
671
- ```
672
-
673
- ---
674
-
675
- # JSSG Testing Framework Usage Guide
676
-
677
- ## Overview
678
-
679
- The JSSG Testing Framework provides comprehensive testing capabilities for JavaScript codemods with before/after fixture files. It integrates with the existing ExecutionEngine and provides a familiar test runner interface.
680
-
681
- ## Quick Start
682
-
683
- ### 1. Basic Test Structure
684
-
685
- Create a test directory with the following structure:
686
-
687
- ```
688
- tests/
689
- ├── simple-transform/
690
- │ ├── input.js
691
- │ └── expected.js
692
- ├── complex-case/
693
- │ ├── input.ts
694
- │ └── expected.ts
695
- └── multi-file/
696
- ├── input/
697
- │ ├── file1.js
698
- │ └── file2.js
699
- └── expected/
700
- ├── file1.js
701
- └── file2.js
702
- ```
703
-
704
- ### 2. Running Tests
705
-
706
- ```bash
707
- # Basic test run
708
- codemod jssg test my-codemod.js --language javascript
709
-
710
- # With custom test directory
711
- codemod jssg test my-codemod.js --language typescript --test-directory ./my-tests
712
-
713
- # Update snapshots (create/update expected files)
714
- codemod jssg test my-codemod.js --language javascript --update-snapshots
715
-
716
- # Verbose output with detailed diffs
717
- codemod jssg test my-codemod.js --language javascript --verbose
718
-
719
- # Watch mode (re-run tests on file changes)
720
- codemod jssg test my-codemod.js --language javascript --watch
721
- ```
722
-
723
- ## CLI Options
724
-
725
- ### Required Arguments
726
- - `codemod_file`: Path to the codemod JavaScript file
727
- - `--language`: Target language (javascript, typescript, etc.)
728
-
729
- ### Test Discovery
730
- - `--test-directory`: Test directory (default: "tests")
731
- - `--filter`: Run only tests matching pattern
732
-
733
- ### Output Control
734
- - `--reporter`: Output format (console, json, terse)
735
- - `--verbose`: Show detailed output
736
- - `--context-lines`: Number of diff context lines (default: 3)
737
- - `--ignore-whitespace`: Ignore whitespace in comparisons
738
-
739
- ### Test Execution
740
- - `--timeout`: Test timeout in seconds (default: 30)
741
- - `--max-threads`: Maximum concurrent threads
742
- - `--sequential`: Run tests sequentially
743
- - `--fail-fast`: Stop on first failure
744
-
745
- ### Snapshot Management
746
- - `--update-snapshots`: Create/update expected files
747
- - `--expect-errors`: Comma-separated patterns for tests expected to fail
748
-
749
- ### Development
750
- - `--watch`: Watch for changes and re-run tests
751
-
752
- ## Test File Formats
753
-
754
- ### Single File Format
755
- Each test case is a directory with `input.{ext}` and `expected.{ext}` files:
756
-
757
- ```
758
- test-case-name/
759
- ├── input.js # Input code
760
- └── expected.js # Expected output
761
- ```
762
-
763
- ### Multi-File Format
764
- For testing multiple files, use `input/` and `expected/` directories:
765
-
766
- ```
767
- test-case-name/
768
- ├── input/
769
- │ ├── file1.js
770
- │ └── file2.js
771
- └── expected/
772
- ├── file1.js
773
- └── file2.js
774
- ```
775
-
776
- ## Language Support
777
-
778
- The framework automatically detects input files based on language extensions:
779
-
780
- - **JavaScript**: `.js`, `.jsx`, `.mjs`
781
- - **TypeScript**: `.ts`, `.tsx`, `.mts`
782
- - **Other languages**: Determined by `get_extensions_for_language()`
783
-
784
- ## Error Handling
785
-
786
- ### Missing Expected Files
787
- ```bash
788
- # Error: No expected file found
789
- codemod jssg test my-codemod.js --language javascript
790
- # Error: No expected file found for input.js in tests/my-test. Run with --update-snapshots to create it.
791
-
792
- # Solution: Create expected files
793
- codemod jssg test my-codemod.js --language javascript --update-snapshots
794
- # Created expected file for my-test/input.js
144
+ - name: "Run jssg codemod"
145
+ js-ast-grep:
146
+ js_file: "scripts/update-api.ts"
147
+ language: "typescript"
148
+ include:
149
+ - "**/*.ts"
150
+ - "**/*.tsx"
151
+
152
+ - name: "Format code"
153
+ run: npx prettier --write "**/*.{ts,tsx}"
154
+
155
+ - name: "Run tests"
156
+ run: npm test
795
157
  ```
796
158
 
797
- ### Ambiguous Input Files
798
- ```bash
799
- # Error: Multiple input files found
800
- # tests/my-test/input.js and tests/my-test/input.ts both exist
159
+ [Learn more about workflows →](https://docs.codemod.com/cli/packages/building-workflows)
801
160
 
802
- # Solution: Use only one input file or organize into directories
803
- ```
161
+ ## CLI Commands
804
162
 
805
- ### Expected Test Failures
806
- ```bash
807
- # Test cases that should fail
808
- codemod jssg test my-codemod.js --language javascript --expect-errors "error-case,invalid-syntax"
809
- ```
163
+ ### Package Management
810
164
 
811
- ## Output Formats
165
+ | Command | Description |
166
+ |---------|-------------|
167
+ | `npx codemod init [path]` | Create a new codemod package with interactive setup |
168
+ | `npx codemod publish [path]` | Publish package to the Codemod Registry |
169
+ | `npx codemod login` | Authenticate with the registry (browser or API key) |
170
+ | `npx codemod logout` | Logout from registry |
171
+ | `npx codemod whoami` | Show current authentication status |
172
+ | `npx codemod search [query]` | Search for packages in the registry |
173
+ | `npx codemod unpublish <package>` | Remove a package from the registry |
812
174
 
813
- ### Console (Default)
814
- ```
815
- test my-test ... ok
816
- test failing-test ... FAILED
175
+ ### Workflow Commands
817
176
 
818
- failures:
177
+ | Command | Description |
178
+ |---------|-------------|
179
+ | `npx codemod workflow run -w <path>` | Run a codemod workflow on your codebase |
180
+ | `npx codemod workflow validate -w <path>` | Validate workflow syntax and structure |
181
+ | `npx codemod workflow resume -i <id>` | Resume a paused workflow |
182
+ | `npx codemod workflow status -i <id>` | Show workflow execution status |
183
+ | `npx codemod workflow list` | List recent workflow runs |
184
+ | `npx codemod workflow cancel -i <id>` | Cancel a running workflow |
819
185
 
820
- ---- failing-test stdout ----
821
- Output mismatch for file expected.js:
822
- -const x = 1;
823
- +const y = 1;
186
+ ### jssg Commands
824
187
 
825
- test result: FAILED. 1 passed; 1 failed; 0 ignored
826
- ```
188
+ | Command | Description |
189
+ |---------|-------------|
190
+ | `npx codemod jssg run <file> <target> --language <lang>` | Run a jssg codemod directly |
191
+ | `npx codemod jssg test <file> --language <lang>` | Test jssg codemod with fixtures |
827
192
 
828
- ### JSON
829
- ```bash
830
- codemod jssg test my-codemod.js --language javascript --reporter json
831
- ```
193
+ ### Cache Management
832
194
 
833
- ```json
834
- {
835
- "type": "suite",
836
- "event": "started",
837
- "test_count": 2
838
- }
839
- {
840
- "type": "test",
841
- "event": "started",
842
- "name": "my-test"
843
- }
844
- {
845
- "type": "test",
846
- "name": "my-test",
847
- "event": "ok"
848
- }
849
- ```
195
+ | Command | Description |
196
+ |---------|-------------|
197
+ | `npx codemod cache info` | Show cache statistics |
198
+ | `npx codemod cache list` | List all cached packages |
199
+ | `npx codemod cache clear [package]` | Clear cache for package or all |
200
+ | `npx codemod cache prune` | Remove old or unused cache entries |
850
201
 
851
- ### Terse
852
- ```bash
853
- codemod jssg test my-codemod.js --language javascript --reporter terse
854
- ```
202
+ **For detailed options and examples, see the [full CLI reference →](https://docs.codemod.com/cli/cli-reference)**
855
203
 
856
- ```
857
- ..F
204
+ ## Ecosystem & Platform
858
205
 
859
- failures:
860
- ...
861
- ```
206
+ The Codemod CLI is part of a larger ecosystem designed to help teams modernize code at scale:
862
207
 
863
- ## Advanced Features
208
+ ### Open-Source Tools
864
209
 
865
- ### Snapshot Management
866
- ```bash
867
- # Create initial snapshots
868
- codemod jssg test my-codemod.js --language javascript --update-snapshots
210
+ - **[Codemod CLI](https://docs.codemod.com/cli)** (this package) – Build, test, and run codemod packages
211
+ - **[Codemod MCP](https://go.codemod.com/mcp-docs)** – Build codemods with AI assistance in your IDE
212
+ - **[Public Registry](https://go.codemod.com/registry)** – Discover and share community codemods
869
213
 
870
- # Update specific test snapshots
871
- codemod jssg test my-codemod.js --language javascript --filter "specific-test" --update-snapshots
872
- ```
214
+ ### Enterprise Platform Features
873
215
 
874
- ### Test Filtering
875
- ```bash
876
- # Run tests matching pattern
877
- codemod jssg test my-codemod.js --language javascript --filter "transform"
216
+ For teams coordinating migrations across multiple repositories:
878
217
 
879
- # Run specific test
880
- codemod jssg test my-codemod.js --language javascript --filter "my-specific-test"
881
- ```
218
+ - **[Codemod Studio](https://go.codemod.com/studio)** – AI-powered web interface for creating codemods
219
+ - **[Campaigns](https://docs.codemod.com/migrations)** Multi-repo orchestration with progress tracking
220
+ - **[Insights](https://docs.codemod.com/insights)** – Analytics dashboards for measuring migration impact
221
+ - **Private Registry** – Secure, organization-scoped codemod packages
882
222
 
883
- ### Performance Tuning
884
- ```bash
885
- # Limit concurrent threads
886
- codemod jssg test my-codemod.js --language javascript --max-threads 2
223
+ [Learn more about the platform →](https://app.codemod.com)
887
224
 
888
- # Run sequentially for debugging
889
- codemod jssg test my-codemod.js --language javascript --sequential
225
+ ## Resources
890
226
 
891
- # Set custom timeout
892
- codemod jssg test my-codemod.js --language javascript --timeout 60
893
- ```
227
+ ### Documentation
228
+ - **[Full Documentation](https://docs.codemod.com)** Comprehensive guides and tutorials
229
+ - **[CLI Reference](https://docs.codemod.com/cli/cli-reference)** – Detailed command documentation
230
+ - **[Codemod Packages](https://docs.codemod.com/cli/packages)** – Learn more about codemod packages and workflows
231
+ - **[jssg Documentation](https://docs.codemod.com/jssg)** – JavaScript ast-grep reference
894
232
 
895
- ### Diff Customization
896
- ```bash
897
- # More context in diffs
898
- codemod jssg test my-codemod.js --language javascript --context-lines 5
233
+ ### Get Help
234
+ - **[Slack Community](https://go.codemod.com/community)** – Ask questions and share codemods
235
+ - **[GitHub Discussions](https://github.com/codemod/codemod/discussions)** Long-form Q&A
236
+ - **[GitHub Issues](https://github.com/codemod/codemod/issues)** Report bugs or request features
899
237
 
900
- # Ignore whitespace differences
901
- codemod jssg test my-codemod.js --language javascript --ignore-whitespace
902
- ```
238
+ ### Explore
239
+ - **[Codemod Registry](https://go.codemod.com/registry)** Browse community codemods
240
+ - **[Codemod Studio](https://go.codemod.com/studio)** – Try creating codemods with AI
241
+ - **[Example Codemods](https://github.com/codemod/codemod/tree/main/test-codemods)** – Reference implementations
903
242
 
904
- ## Integration with Development Workflow
243
+ ## Contributing
905
244
 
906
- ### CI/CD Integration
907
- ```yaml
908
- # GitHub Actions example
909
- - name: Run codemod tests
910
- run: codemod jssg test my-codemod.js --language javascript --reporter json
911
- ```
245
+ Contributions are welcome! Help make codemod automation better for everyone.
912
246
 
913
- ### IDE Integration
914
- The framework outputs standard test results that can be consumed by IDEs and test runners.
247
+ **Ways to contribute:**
248
+ - 🐛 Report bugs via [GitHub Issues](https://github.com/codemod/codemod/issues)
249
+ - 💡 Suggest features on [Feedback Board](https://feedback.codemod.com)
250
+ - 📝 Improve documentation
251
+ - 🔧 Submit pull requests
252
+ - 🌟 Star the repo and spread the word
915
253
 
916
- ### Watch Mode Development
917
- ```bash
918
- # Continuous testing during development
919
- codemod jssg test my-codemod.js --language javascript --watch --verbose
920
- ```
921
-
922
- ## Best Practices
923
-
924
- 1. **Organize tests by functionality**: Group related test cases in descriptive directories
925
- 2. **Use meaningful test names**: Directory names become test names in output
926
- 3. **Start with --update-snapshots**: Generate initial expected files, then review and commit
927
- 4. **Use --expect-errors for negative tests**: Test error conditions explicitly
928
- 5. **Leverage --filter during development**: Focus on specific tests while developing
929
- 6. **Use --watch for rapid iteration**: Get immediate feedback on changes
930
-
931
- ## Troubleshooting
254
+ Read our [Contributing Guide](https://github.com/codemod/codemod/blob/main/CONTRIBUTING.md) and [Code of Conduct](https://github.com/codemod/codemod/blob/main/CODE_OF_CONDUCT.md).
932
255
 
933
- ### Common Issues
256
+ ## License
934
257
 
935
- 1. **No tests found**: Check test directory path and file extensions
936
- 2. **Ambiguous input files**: Ensure only one input file per test case
937
- 3. **Timeout errors**: Increase timeout for complex codemods
938
- 4. **Memory issues**: Reduce max-threads for large test suites
258
+ MIT License - see [LICENSE](https://github.com/codemod/codemod/blob/main/LICENSE) for details.
939
259
 
940
- ### Debug Mode
941
- ```bash
942
- # Verbose output for debugging
943
- codemod jssg test my-codemod.js --language javascript --verbose --sequential
944
- ```
260
+ ---
945
261
 
946
- This framework provides a robust foundation for testing JavaScript codemods with familiar tooling and comprehensive features.
262
+ <p align="center">
263
+ <strong>Built with ❤️ by <a href="https://codemod.com">Codemod</a> and the <a href="https://github.com/codemod/codemod/graphs/contributors">open-source community</a></strong>
264
+ </p>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codemod",
3
- "version": "1.1.0-alpha.1",
3
+ "version": "1.1.1",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -29,11 +29,11 @@
29
29
  "postinstall": "node postinstall.js"
30
30
  },
31
31
  "optionalDependencies": {
32
- "@codemod.com/cli-darwin-arm64": "1.1.0-alpha.1",
33
- "@codemod.com/cli-darwin-x64": "1.1.0-alpha.1",
34
- "@codemod.com/cli-linux-arm64-gnu": "1.1.0-alpha.1",
35
- "@codemod.com/cli-linux-x64-gnu": "1.1.0-alpha.1",
36
- "@codemod.com/cli-win32-x64-msvc": "1.1.0-alpha.1"
32
+ "@codemod.com/cli-darwin-arm64": "1.1.1",
33
+ "@codemod.com/cli-darwin-x64": "1.1.1",
34
+ "@codemod.com/cli-linux-arm64-gnu": "1.1.1",
35
+ "@codemod.com/cli-linux-x64-gnu": "1.1.1",
36
+ "@codemod.com/cli-win32-x64-msvc": "1.1.1"
37
37
  },
38
38
  "bin": {
39
39
  "codemod": "codemod"