legacy-modernizer 0.1.0

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.
package/README.md ADDED
@@ -0,0 +1,290 @@
1
+ # ๐Ÿ—๏ธ Legacy Modernizer
2
+
3
+ > AI-powered legacy code modernization for frontend projects โ€” Vue 2โ†’3, JSโ†’TS, Webpackโ†’Vite โ€” with semantic understanding, not just regex replacement.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/legacy-modernizer.svg)](https://www.npmjs.com/package/legacy-modernizer)
6
+ [![license](https://img.shields.io/npm/l/legacy-modernizer.svg)](https://github.com/saqqdy/legacy-modernizer/blob/main/LICENSE)
7
+
8
+ [ไธญๆ–‡ๆ–‡ๆกฃ](README_CN.md)
9
+
10
+ ---
11
+
12
+ ## ๐ŸŽฏ The Problem It Solves
13
+
14
+ | Scenario | Traditional Tools (codemod) | Legacy Modernizer |
15
+ |----------|---------------------------|-------------------|
16
+ | `this.$refs.input` โ†’ ? | Rule: `this.$refs.xxx โ†’ ???` โ€” can't decide ref vs useTemplateRef | AI understands: "this ref is used in mounted for focus()" โ†’ `useTemplateRef('input')` + `onMounted` |
17
+ | Mixin โ†’ Composable | Rule matching only โ€” can't merge overlapping state | AI understands business logic boundaries โ†’ clean composable extraction |
18
+ | `process.env.X` โ†’ ? | Simple find-replace โ†’ `import.meta.env.X` | AI checks what X is and whether it needs `VITE_` prefix |
19
+
20
+ **Core insight**: Migration requires understanding code *intent*, not just syntax patterns.
21
+
22
+ ---
23
+
24
+ ## โœจ Core Features
25
+
26
+ ### ๐Ÿ” Multi-Dimension Scanning
27
+
28
+ Scan your project for legacy patterns across 6 migration dimensions:
29
+
30
+ - **Vue 2โ†’3**: Options API, $refs, $emit, mixins, filters, etc.
31
+ - **JSโ†’TS**: Untyped files, PropTypes, JSDoc types
32
+ - **Webpackโ†’Vite**: Config files, require.context, process.env
33
+ - **Jestโ†’Vitest**: Global functions, config files
34
+ - **Vuexโ†’Pinia**: Store instances, map helpers
35
+ - **ESLint Modernization**: Legacy config formats
36
+
37
+ ### ๐Ÿ“‹ Structured Analysis Report
38
+
39
+ Generate a detailed report with risk assessment and recommended migration order:
40
+
41
+ - Pattern breakdown by dimension and severity
42
+ - Risk level (low/medium/high) with reasoning
43
+ - Recommended migration order
44
+ - Effort estimation (person-days)
45
+
46
+ ### ๐Ÿง  AI Semantic Migration (v0.2.0+)
47
+
48
+ Not just regex โ€” AI understands your code's intent and produces semantically equivalent modern code:
49
+
50
+ - **Options API โ†’ Composition API**: `data()` โ†’ `ref()`, `computed:{}` โ†’ `computed()`, etc.
51
+ - **Mixin โ†’ Composable**: Understands business logic boundaries
52
+ - **Vue 2 APIs โ†’ Vue 3**: `$refs` โ†’ `useTemplateRef`, `$emit` โ†’ `defineEmits`, etc.
53
+
54
+ ### ๐Ÿ”„ Interactive Migration Wizard (v0.7.0+)
55
+
56
+ Step-by-step guided migration with diff preview and confirmation at every step.
57
+
58
+ ---
59
+
60
+ ## ๐Ÿš€ Getting Started
61
+
62
+ ### Option 1: Claude Code Skill (Recommended)
63
+
64
+ This is the core usage โ€” drive migration directly in Claude Code with natural language:
65
+
66
+ ```bash
67
+ cd your-project
68
+ git clone https://github.com/saqqdy/legacy-modernizer.git .legacy-modernizer
69
+ cp -r .legacy-modernizer/.claude/skills/ .claude/skills/
70
+ ```
71
+
72
+ Then in Claude Code:
73
+
74
+ | Command | Description |
75
+ |---------|-------------|
76
+ | `/analyze` | Scan current project for legacy patterns, generate migration report |
77
+ | `/modernize` | Launch interactive migration wizard: scan โ†’ select dimensions โ†’ generate plan โ†’ step-by-step migration |
78
+
79
+ **How it works:**
80
+ 1. Open Claude Code in a Vue 2 legacy project
81
+ 2. Type `/analyze` โ†’ get a full legacy pattern analysis report
82
+ 3. Type `/modernize` โ†’ select migration dimension (e.g. Vue 2โ†’3), confirm diffs file by file
83
+
84
+ ### Option 2: Programmatic Usage
85
+
86
+ ```bash
87
+ pnpm add legacy-modernizer
88
+ ```
89
+
90
+ ```typescript
91
+ import { scanProject, scanFileContent, renderAnalysisReport } from 'legacy-modernizer'
92
+
93
+ // Full project scan
94
+ const report = await scanProject({
95
+ root: process.cwd(),
96
+ include: ['**/*.{vue,js,ts}'],
97
+ exclude: ['node_modules/**', 'dist/**'],
98
+ })
99
+
100
+ console.log(renderAnalysisReport(report))
101
+ // Or access structured data directly
102
+ console.log(`Found ${report.totalPatterns} patterns in ${report.totalFiles} files`)
103
+ console.log(`Risk: ${report.risk.level} โ€” ${report.risk.reason}`)
104
+
105
+ // Single file scan
106
+ const patterns = scanFileContent(content, 'src/components/Counter.vue')
107
+ patterns.forEach(p => console.log(`[${p.severity}] ${p.name}: ${p.suggestion}`))
108
+ ```
109
+
110
+ ### Option 3: Playground
111
+
112
+ Try it online without any installation:
113
+
114
+ ```bash
115
+ # Clone the repo and start Playground
116
+ git clone https://github.com/saqqdy/legacy-modernizer.git
117
+ cd legacy-modernizer
118
+ pnpm install
119
+ pnpm run playground
120
+ ```
121
+
122
+ The Playground ships with built-in legacy code samples so you can:
123
+ - ๐Ÿ“‚ Select different sample files to see scan results
124
+ - โœ๏ธ Edit code and see real-time legacy pattern detection
125
+ - ๐Ÿ“Š View structured analysis reports
126
+ - ๐ŸŒ Toggle Chinese/English report language
127
+
128
+ ---
129
+
130
+ ## ๐Ÿ“ Scan Rules Reference
131
+
132
+ ### Vue 2โ†’3 (15 rules)
133
+
134
+ | Rule ID | Name | Severity | Description |
135
+ |---------|------|----------|-------------|
136
+ | `vue2-options-api` | Options API component | ๐Ÿ”ต info | Rewrite using `<script setup>` + Composition API |
137
+ | `vue2-data-function` | data() option | ๐Ÿ”ต info | Replace with ref() / reactive() |
138
+ | `vue2-computed-option` | computed:{} option | ๐Ÿ”ต info | Replace with computed(() => ...) |
139
+ | `vue2-methods-option` | methods:{} option | ๐Ÿ”ต info | Rewrite as plain functions |
140
+ | `vue2-watch-option` | watch:{} option | ๐Ÿ”ต info | Replace with watch() / watchEffect() |
141
+ | `vue2-this-refs` | this.$refs | ๐ŸŸก warning | Replace with useTemplateRef() |
142
+ | `vue2-this-emit` | this.$emit | ๐ŸŸก warning | Replace with defineEmits() |
143
+ | `vue2-this-router` | this.$router / this.$route | ๐ŸŸก warning | Replace with useRouter() / useRoute() |
144
+ | `vue2-this-store` | this.$store | ๐ŸŸก warning | Replace with useStore() or migrate to Pinia |
145
+ | `vue2-filters` | filters:{} option | ๐Ÿ”ด critical | Vue 3 removed filters โ€” use computed or methods |
146
+ | `vue2-event-bus` | $on / $off / $once | ๐Ÿ”ด critical | Use mitt or tiny-emitter instead |
147
+ | `vue2-destroyed` | destroyed / beforeDestroy | ๐ŸŸก warning | Replace with unmounted / beforeUnmount |
148
+ | `vue2-mixins` | mixins:[] option | ๐ŸŸก warning | Replace with Composables |
149
+ | `vue2-v-bind-sync` | v-bind.sync modifier | ๐Ÿ”ด critical | Replace with v-model:xxx |
150
+ | `vue2-v-on-native` | v-on.native modifier | ๐ŸŸก warning | Declare in emits option instead |
151
+
152
+ ### JSโ†’TS (4 rules)
153
+
154
+ | Rule ID | Name | Severity | Description |
155
+ |---------|------|----------|-------------|
156
+ | `js-prop-types` | PropTypes validation | ๐ŸŸก warning | Replace with TypeScript interface |
157
+ | `js-jsdoc-types` | JSDoc type annotations | ๐Ÿ”ต info | Migrate JSDoc types to inline TypeScript types |
158
+ | `js-commonjs-export` | CommonJS exports | ๐Ÿ”ต info | Replace with ES module export |
159
+ | `js-require-import` | require() import | ๐Ÿ”ต info | Replace with ES import |
160
+
161
+ ### Webpackโ†’Vite (3 rules)
162
+
163
+ | Rule ID | Name | Severity | Description |
164
+ |---------|------|----------|-------------|
165
+ | `webpack-config` | webpack.config file | ๐Ÿ”ต info | Migrate to vite.config.ts |
166
+ | `webpack-require-context` | require.context | ๐ŸŸก warning | Vite uses import.meta.glob instead |
167
+ | `webpack-process-env` | process.env usage | ๐Ÿ”ต info | Vite uses import.meta.env instead |
168
+
169
+ ### Jestโ†’Vitest (2 rules)
170
+
171
+ | Rule ID | Name | Severity | Description |
172
+ |---------|------|----------|-------------|
173
+ | `jest-config` | Jest config detected | ๐Ÿ”ต info | Migrate to vitest.config.ts |
174
+ | `jest-global` | Jest global functions | ๐ŸŸก warning | Replace with vitest imports (vi, describe, it, expect) |
175
+
176
+ ### Vuexโ†’Pinia (2 rules)
177
+
178
+ | Rule ID | Name | Severity | Description |
179
+ |---------|------|----------|-------------|
180
+ | `vuex-store` | Vuex store usage | ๐Ÿ”ต info | Migrate to Pinia defineStore() |
181
+ | `vuex-map-state` | mapState / mapGetters | ๐ŸŸก warning | Pinia uses storeToRefs() instead |
182
+
183
+ ### ESLint Modernization (2 rules)
184
+
185
+ | Rule ID | Name | Severity | Description |
186
+ |---------|------|----------|-------------|
187
+ | `eslint-legacy-config` | Legacy ESLint config format | ๐Ÿ”ต info | Migrate to ESLint 9 flat config |
188
+ | `eslint-override-array` | ESLint overrides array | ๐Ÿ”ต info | Flat config uses multiple config objects |
189
+
190
+ > **Total**: 6 dimensions, 28 detection rules
191
+
192
+ ---
193
+
194
+ ## ๐Ÿ“‹ Version Roadmap
195
+
196
+ | Version | Codename | Theme | Status |
197
+ |---------|----------|-------|--------|
198
+ | v0.1.0 | Daybreak | Plugin skeleton + `/analyze` scanner | โœ… Current |
199
+ | v0.2.0 | Sunrise | Vue 2โ†’3 single-file migration MVP | ๐Ÿ“‹ Planned |
200
+ | v0.3.0 | Dawn | Agent-based batch migration + verification | ๐Ÿ“‹ Planned |
201
+ | v0.4.0 | Ember | JSโ†’TS progressive migration | ๐Ÿ“‹ Planned |
202
+ | v0.5.0 | Catalyst | Webpackโ†’Vite build migration | ๐Ÿ“‹ Planned |
203
+ | v0.6.0 | Forge | Auxiliary migrations (Jestโ†’Vitest, Vuexโ†’Pinia, ESLint) | ๐Ÿ“‹ Planned |
204
+ | v0.7.0 | Compass | Interactive migration wizard | ๐Ÿ“‹ Planned |
205
+ | v0.8.0 | Anchor | Migration logging / rollback / documentation | ๐Ÿ“‹ Planned |
206
+ | v1.0.0 | Lighthouse | Production-ready + marketplace publishing | ๐Ÿ“‹ Planned |
207
+ | v2.0.0 | Horizon | Universal framework + React driver | ๐Ÿ”ฎ Future |
208
+
209
+ ---
210
+
211
+ ## ๐Ÿ—‚๏ธ Project Structure
212
+
213
+ ```
214
+ legacy-modernizer/
215
+ โ”œโ”€โ”€ .claude/skills/legacy-modernizer/ # Skill prompts (core product)
216
+ โ”‚ โ”œโ”€โ”€ skill.md # Main entry + command routing
217
+ โ”‚ โ”œโ”€โ”€ analyze.md # Scan instructions
218
+ โ”‚ โ””โ”€โ”€ modernize.md # Migration wizard instructions
219
+ โ”œโ”€โ”€ src/ # TypeScript source (programmatic API)
220
+ โ”‚ โ”œโ”€โ”€ index.ts # Entry point, public API exports
221
+ โ”‚ โ”œโ”€โ”€ types.ts # Core type definitions
222
+ โ”‚ โ”œโ”€โ”€ scanners/ # Scanners
223
+ โ”‚ โ”‚ โ”œโ”€โ”€ legacy-scanner.ts # Legacy pattern detector
224
+ โ”‚ โ”‚ โ””โ”€โ”€ rules/ # Per-dimension detection rules
225
+ โ”‚ โ”‚ โ”œโ”€โ”€ index.ts # Rules aggregation
226
+ โ”‚ โ”‚ โ”œโ”€โ”€ vue2-to-vue3.ts # 15 Vue 2โ†’3 rules
227
+ โ”‚ โ”‚ โ”œโ”€โ”€ js-to-ts.ts # 4 JSโ†’TS rules
228
+ โ”‚ โ”‚ โ”œโ”€โ”€ webpack-to-vite.ts # 3 Webpackโ†’Vite rules
229
+ โ”‚ โ”‚ โ”œโ”€โ”€ jest-to-vitest.ts # 2 Jestโ†’Vitest rules
230
+ โ”‚ โ”‚ โ”œโ”€โ”€ vuex-to-pinia.ts # 2 Vuexโ†’Pinia rules
231
+ โ”‚ โ”‚ โ””โ”€โ”€ eslint-modernize.ts # 2 ESLint modernization rules
232
+ โ”‚ โ”œโ”€โ”€ reporters/ # Report rendering
233
+ โ”‚ โ”‚ โ”œโ”€โ”€ analysis.ts # Markdown report generation
234
+ โ”‚ โ”‚ โ””โ”€โ”€ locale.ts # Chinese/English labels
235
+ โ”‚ โ””โ”€โ”€ utils/ # Utility functions
236
+ โ”‚ โ”œโ”€โ”€ config.ts # Config merging
237
+ โ”‚ โ””โ”€โ”€ format.ts # Output formatting
238
+ โ”œโ”€โ”€ knowledge/ # Migration knowledge base
239
+ โ”œโ”€โ”€ templates/ # Report templates
240
+ โ”œโ”€โ”€ internal/ # Internal planning docs
241
+ โ”œโ”€โ”€ docs/ # VitePress documentation site
242
+ โ””โ”€โ”€ playground/ # Interactive Playground
243
+ ```
244
+
245
+ ---
246
+
247
+ ## ๐Ÿ› ๏ธ Development
248
+
249
+ ```bash
250
+ pnpm install # Install dependencies
251
+ pnpm run lint # ESLint check + auto-fix
252
+ pnpm run typecheck # TypeScript type check
253
+ pnpm run test # Run tests (vitest)
254
+ pnpm run test:watch # Test watch mode
255
+ pnpm run test:coverage # Test coverage
256
+ pnpm run build # Build (ESM + CJS)
257
+ pnpm run dev # Watch mode development
258
+ pnpm run docs:dev # Start docs dev server
259
+ pnpm run playground # Start Playground
260
+ ```
261
+
262
+ ### Tech Stack
263
+
264
+ - **Language**: TypeScript 5.9+, strict mode
265
+ - **Build**: rolldown
266
+ - **Lint**: @eslint-sets/eslint-config (ESLint 9 flat config)
267
+ - **Formatting**: prettier + prettier-config-common
268
+ - **Testing**: vitest
269
+ - **Docs**: VitePress
270
+ - **Package Manager**: pnpm 9
271
+
272
+ ---
273
+
274
+ ## ๐Ÿ†š Comparison
275
+
276
+ ### vs vue-codemod / gogocode / ast-grep
277
+
278
+ | Dimension | Code Mods | Legacy Modernizer |
279
+ |-----------|-----------|-------------------|
280
+ | Approach | AST rule matching | AI semantic understanding |
281
+ | `this.$refs.xxx` โ†’ ? | Can't decide ref vs useTemplateRef | Understands usage context |
282
+ | Mixin merging | Can only rename, not restructure | Extracts clean composables |
283
+ | Business logic | Ignores it | Recognizes boundaries |
284
+ | Error handling | Rule errors = broken output | Uncertain โ†’ asks for confirmation |
285
+
286
+ ---
287
+
288
+ ## ๐Ÿ“„ License
289
+
290
+ [MIT](./LICENSE)
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Legacy Modernizer โ€” ้—็•™ไปฃ็ ็ŽฐไปฃๅŒ–
3
+ *
4
+ * ๅ…ฅๅฃๆจกๅ—๏ผŒๅฏผๅ‡บๆ‰€ๆœ‰ๅ…ฌๅผ€ API
5
+ */
6
+ export { renderAnalysisReport } from './reporters/analysis';
7
+ export { scanFileContent, scanProject } from './scanners/legacy-scanner';
8
+ export type { ScannerOptions } from './types';
9
+ export type { AnalysisReport, DimensionConfig, DimensionStats, LegacyPattern, MigrationDimension, ModernizerConfig, PatternLine, PatternRule, PatternSeverity, RiskAssessment, RiskLevel, RiskThresholds, } from './types';
10
+ export { createPatternLine, VERSION } from './types';
11
+ export { getDefaultConfig, mergeConfig } from './utils/config';
12
+ export { dimensionLabel, formatDuration, patternToMarkdown, severityBadge, } from './utils/format';