@eduardbar/drift 1.0.0 → 1.2.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.
Files changed (105) hide show
  1. package/.github/actions/drift-scan/README.md +61 -0
  2. package/.github/actions/drift-scan/action.yml +65 -0
  3. package/.github/workflows/publish-vscode.yml +3 -1
  4. package/.github/workflows/review-pr.yml +61 -0
  5. package/AGENTS.md +53 -11
  6. package/README.md +106 -1
  7. package/dist/analyzer.d.ts +6 -2
  8. package/dist/analyzer.js +116 -3
  9. package/dist/badge.js +40 -22
  10. package/dist/ci.js +32 -18
  11. package/dist/cli.js +179 -6
  12. package/dist/diff.d.ts +0 -7
  13. package/dist/diff.js +26 -25
  14. package/dist/fix.d.ts +4 -0
  15. package/dist/fix.js +59 -47
  16. package/dist/git/trend.js +1 -0
  17. package/dist/git.d.ts +0 -9
  18. package/dist/git.js +25 -19
  19. package/dist/index.d.ts +7 -1
  20. package/dist/index.js +4 -0
  21. package/dist/map.d.ts +4 -0
  22. package/dist/map.js +191 -0
  23. package/dist/metrics.d.ts +4 -0
  24. package/dist/metrics.js +176 -0
  25. package/dist/plugins.d.ts +6 -0
  26. package/dist/plugins.js +74 -0
  27. package/dist/printer.js +20 -0
  28. package/dist/report.js +34 -0
  29. package/dist/reporter.js +85 -2
  30. package/dist/review.d.ts +15 -0
  31. package/dist/review.js +80 -0
  32. package/dist/rules/comments.d.ts +4 -0
  33. package/dist/rules/comments.js +45 -0
  34. package/dist/rules/complexity.d.ts +4 -0
  35. package/dist/rules/complexity.js +51 -0
  36. package/dist/rules/coupling.d.ts +4 -0
  37. package/dist/rules/coupling.js +19 -0
  38. package/dist/rules/magic.d.ts +4 -0
  39. package/dist/rules/magic.js +33 -0
  40. package/dist/rules/nesting.d.ts +5 -0
  41. package/dist/rules/nesting.js +82 -0
  42. package/dist/rules/phase0-basic.js +14 -7
  43. package/dist/rules/phase1-complexity.d.ts +6 -30
  44. package/dist/rules/phase1-complexity.js +7 -276
  45. package/dist/rules/phase2-crossfile.d.ts +0 -4
  46. package/dist/rules/phase2-crossfile.js +52 -39
  47. package/dist/rules/phase3-arch.d.ts +0 -8
  48. package/dist/rules/phase3-arch.js +26 -23
  49. package/dist/rules/phase3-configurable.d.ts +6 -0
  50. package/dist/rules/phase3-configurable.js +97 -0
  51. package/dist/rules/phase8-semantic.d.ts +0 -5
  52. package/dist/rules/phase8-semantic.js +30 -29
  53. package/dist/rules/promise.d.ts +4 -0
  54. package/dist/rules/promise.js +24 -0
  55. package/dist/saas.d.ts +83 -0
  56. package/dist/saas.js +321 -0
  57. package/dist/snapshot.d.ts +19 -0
  58. package/dist/snapshot.js +119 -0
  59. package/dist/types.d.ts +75 -0
  60. package/dist/utils.d.ts +2 -1
  61. package/dist/utils.js +1 -0
  62. package/docs/AGENTS.md +146 -0
  63. package/docs/PRD.md +157 -0
  64. package/package.json +1 -1
  65. package/packages/eslint-plugin-drift/src/index.ts +1 -1
  66. package/packages/vscode-drift/package.json +1 -1
  67. package/packages/vscode-drift/src/analyzer.ts +2 -0
  68. package/packages/vscode-drift/src/code-actions.ts +53 -0
  69. package/packages/vscode-drift/src/extension.ts +98 -63
  70. package/packages/vscode-drift/src/statusbar.ts +13 -5
  71. package/packages/vscode-drift/src/treeview.ts +2 -0
  72. package/src/analyzer.ts +144 -12
  73. package/src/badge.ts +38 -16
  74. package/src/ci.ts +38 -17
  75. package/src/cli.ts +206 -7
  76. package/src/diff.ts +36 -30
  77. package/src/fix.ts +77 -53
  78. package/src/git/trend.ts +3 -2
  79. package/src/git.ts +31 -22
  80. package/src/index.ts +31 -1
  81. package/src/map.ts +219 -0
  82. package/src/metrics.ts +200 -0
  83. package/src/plugins.ts +76 -0
  84. package/src/printer.ts +20 -0
  85. package/src/report.ts +35 -0
  86. package/src/reporter.ts +95 -2
  87. package/src/review.ts +98 -0
  88. package/src/rules/comments.ts +56 -0
  89. package/src/rules/complexity.ts +57 -0
  90. package/src/rules/coupling.ts +23 -0
  91. package/src/rules/magic.ts +38 -0
  92. package/src/rules/nesting.ts +88 -0
  93. package/src/rules/phase0-basic.ts +14 -7
  94. package/src/rules/phase1-complexity.ts +8 -302
  95. package/src/rules/phase2-crossfile.ts +68 -40
  96. package/src/rules/phase3-arch.ts +34 -30
  97. package/src/rules/phase3-configurable.ts +132 -0
  98. package/src/rules/phase8-semantic.ts +33 -29
  99. package/src/rules/promise.ts +29 -0
  100. package/src/saas.ts +433 -0
  101. package/src/snapshot.ts +175 -0
  102. package/src/types.ts +81 -1
  103. package/src/utils.ts +3 -1
  104. package/tests/new-features.test.ts +180 -0
  105. package/tests/saas-foundation.test.ts +107 -0
package/dist/types.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import type { SourceFile } from 'ts-morph';
1
2
  export interface DriftIssue {
2
3
  rule: string;
3
4
  severity: 'error' | 'warning' | 'info';
@@ -24,6 +25,36 @@ export interface DriftReport {
24
25
  infos: number;
25
26
  byRule: Record<string, number>;
26
27
  };
28
+ quality: RepoQualityScore;
29
+ maintenanceRisk: MaintenanceRiskMetrics;
30
+ }
31
+ export interface RepoQualityScore {
32
+ overall: number;
33
+ dimensions: {
34
+ architecture: number;
35
+ complexity: number;
36
+ 'ai-patterns': number;
37
+ testing: number;
38
+ };
39
+ }
40
+ export interface RiskHotspot {
41
+ file: string;
42
+ driftScore: number;
43
+ complexityIssues: number;
44
+ hasNearbyTests: boolean;
45
+ changeFrequency: number;
46
+ risk: number;
47
+ reasons: string[];
48
+ }
49
+ export interface MaintenanceRiskMetrics {
50
+ score: number;
51
+ level: 'low' | 'medium' | 'high' | 'critical';
52
+ hotspots: RiskHotspot[];
53
+ signals: {
54
+ highComplexityFiles: number;
55
+ filesWithoutNearbyTests: number;
56
+ frequentChangeFiles: number;
57
+ };
27
58
  }
28
59
  export interface AIOutput {
29
60
  summary: {
@@ -32,8 +63,17 @@ export interface AIOutput {
32
63
  total_issues: number;
33
64
  files_affected: number;
34
65
  files_clean: number;
66
+ ai_likelihood: number;
67
+ ai_code_smell_score: number;
35
68
  };
69
+ files_suspected: Array<{
70
+ path: string;
71
+ ai_likelihood: number;
72
+ triggers: string[];
73
+ }>;
36
74
  priority_order: AIIssue[];
75
+ maintenance_risk: MaintenanceRiskMetrics;
76
+ quality: RepoQualityScore;
37
77
  context_for_ai: {
38
78
  project_type: string;
39
79
  scan_path: string;
@@ -75,6 +115,41 @@ export interface ModuleBoundary {
75
115
  export interface DriftConfig {
76
116
  layers?: LayerDefinition[];
77
117
  modules?: ModuleBoundary[];
118
+ plugins?: string[];
119
+ architectureRules?: {
120
+ controllerNoDb?: boolean;
121
+ serviceNoHttp?: boolean;
122
+ maxFunctionLines?: number;
123
+ };
124
+ saas?: {
125
+ freeUserThreshold?: number;
126
+ maxRunsPerWorkspacePerMonth?: number;
127
+ maxReposPerWorkspace?: number;
128
+ retentionDays?: number;
129
+ };
130
+ }
131
+ export interface PluginRuleContext {
132
+ projectRoot: string;
133
+ filePath: string;
134
+ config?: DriftConfig;
135
+ }
136
+ export interface DriftPluginRule {
137
+ name: string;
138
+ severity?: DriftIssue['severity'];
139
+ weight?: number;
140
+ detect: (file: SourceFile, context: PluginRuleContext) => DriftIssue[];
141
+ }
142
+ export interface DriftPlugin {
143
+ name: string;
144
+ rules: DriftPluginRule[];
145
+ }
146
+ export interface LoadedPlugin {
147
+ id: string;
148
+ plugin: DriftPlugin;
149
+ }
150
+ export interface PluginLoadError {
151
+ pluginId: string;
152
+ message: string;
78
153
  }
79
154
  export interface FileDiff {
80
155
  path: string;
package/dist/utils.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { DriftIssue } from './types.js';
2
- export interface Grade {
2
+ interface Grade {
3
3
  badge: string;
4
4
  label: string;
5
5
  }
@@ -7,4 +7,5 @@ export declare function scoreToGrade(score: number): Grade;
7
7
  export declare function scoreToGradeText(score: number): Grade;
8
8
  export declare function severityIcon(s: DriftIssue['severity']): string;
9
9
  export declare function scoreBar(score: number, width?: number): string;
10
+ export {};
10
11
  //# sourceMappingURL=utils.d.ts.map
package/dist/utils.js CHANGED
@@ -1,3 +1,4 @@
1
+ // drift-ignore-file
1
2
  import kleur from 'kleur';
2
3
  export function scoreToGrade(score) {
3
4
  if (score === 0)
package/docs/AGENTS.md ADDED
@@ -0,0 +1,146 @@
1
+ # AGENTS - Guia Operativa para drift
2
+
3
+ ## 1) Proposito
4
+
5
+ Esta guia define como colaborar en `drift` para mantener calidad tecnica, consistencia de arquitectura y foco en producto.
6
+
7
+ `drift` existe para detectar deuda tecnica asociada a codigo IA en proyectos TypeScript y convertir esa senial en acciones concretas.
8
+
9
+ ## 2) Stack y estructura principal
10
+
11
+ ### Stack real
12
+
13
+ - Runtime: Node.js 18+
14
+ - Lenguaje: TypeScript (`type: module`)
15
+ - Analisis AST: `ts-morph`
16
+ - CLI: `commander`
17
+ - Output en consola: `kleur`
18
+ - Testing: `vitest`
19
+
20
+ ### Estructura clave
21
+
22
+ - `src/analyzer.ts`: motor principal de reglas y score
23
+ - `src/rules/*`: reglas por fases y helpers de deteccion
24
+ - `src/reporter.ts`: armado de reporte y salidas para markdown/AI
25
+ - `src/printer.ts`: salida CLI y sugerencias de fix
26
+ - `src/cli.ts`: entrypoint y subcomandos
27
+ - `src/fix.ts`, `src/report.ts`, `src/ci.ts`, `src/diff.ts`: comandos operativos
28
+ - `packages/eslint-plugin-drift`: plugin ESLint
29
+ - `packages/vscode-drift`: extension VSCode
30
+
31
+ ## 3) Comandos de desarrollo
32
+
33
+ Usar los comandos del repo (fuente: `package.json`):
34
+
35
+ ```bash
36
+ npm run build
37
+ npm run dev
38
+ npm start
39
+ npm test
40
+ npm run test:watch
41
+ npm run test:coverage
42
+ ```
43
+
44
+ Comandos de uso de producto (referencia):
45
+
46
+ ```bash
47
+ npx @eduardbar/drift scan ./src
48
+ npx @eduardbar/drift scan ./src --ai
49
+ npx @eduardbar/drift scan ./src --min-score 60
50
+ ```
51
+
52
+ ## 4) Reglas de contribucion
53
+
54
+ - Mantener cambios pequenos, enfocados y trazables.
55
+ - No editar `dist/` manualmente.
56
+ - No introducir `any` sin justificacion tecnica fuerte.
57
+ - Reusar utilidades existentes (`utils.ts`) antes de duplicar logica.
58
+ - Si agregas una regla nueva, actualizar:
59
+ - peso en `RULE_WEIGHTS`
60
+ - deteccion AST
61
+ - sugerencia de fix
62
+ - documentacion (README/AGENTS/PRD segun aplique)
63
+
64
+ ## 5) Convencion de commits
65
+
66
+ Se usa Conventional Commits.
67
+
68
+ Formato:
69
+
70
+ ```text
71
+ type(scope): descripcion corta
72
+ ```
73
+
74
+ Tipos recomendados:
75
+
76
+ - `feat`: nueva capacidad de producto
77
+ - `fix`: correccion de bug
78
+ - `refactor`: cambio interno sin impacto funcional
79
+ - `test`: mejoras o nuevos tests
80
+ - `docs`: documentacion
81
+ - `chore`: mantenimiento
82
+
83
+ Ejemplos:
84
+
85
+ - `feat(review): add PR score and markdown output`
86
+ - `fix(analyzer): prevent false positive in dead-file rule`
87
+ - `docs(prd): define v1.2 architecture roadmap`
88
+
89
+ ## 6) Flujo para proponer e implementar features del PRD
90
+
91
+ ### Paso 1 - Definir alcance MVP
92
+
93
+ - Explicar objetivo de negocio y usuario.
94
+ - Delimitar que entra y que queda fuera.
95
+ - Agregar criterios de aceptacion verificables.
96
+
97
+ ### Paso 2 - Disenar impacto tecnico
98
+
99
+ - Identificar comandos, modulos y reglas afectados.
100
+ - Definir formato de salida (CLI/JSON/AI).
101
+ - Evaluar costo de performance en repos grandes.
102
+
103
+ ### Paso 3 - Implementar por incrementos
104
+
105
+ - Primero contrato de tipos y salida.
106
+ - Luego deteccion/reglas/comandos.
107
+ - Finalmente UX de consola y documentacion.
108
+
109
+ ### Paso 4 - Validar
110
+
111
+ - Tests unitarios de logica nueva.
112
+ - Tests de integracion de CLI cuando aplique.
113
+ - Verificacion manual de casos reales.
114
+
115
+ ## 7) Criterios minimos de calidad y testing
116
+
117
+ Antes de merge, cada cambio debe cumplir:
118
+
119
+ - Tests pasando (`npm test`).
120
+ - Cobertura razonable en paths nuevos (`npm run test:coverage` cuando aplique).
121
+ - Sin regresiones en salida JSON/AI (contratos estables).
122
+ - Errores y mensajes de CLI claros y accionables.
123
+ - Performance aceptable para el alcance del cambio.
124
+
125
+ ## 8) Seguridad y manejo de informacion
126
+
127
+ - Nunca commitear secretos (`.env`, tokens, credenciales, llaves).
128
+ - No incluir datos sensibles en fixtures ni snapshots.
129
+ - Si una feature requiere integracion externa, usar variables de entorno y documentar setup sin exponer valores.
130
+ - Mantener principio de minimo privilegio en scripts y flujos CI.
131
+
132
+ ## 9) Criterios de aceptacion para features nuevas
133
+
134
+ Una feature se considera lista cuando:
135
+
136
+ - Resuelve un objetivo explicitado en `docs/PRD.md`.
137
+ - Tiene MVP funcional y criterios de aceptacion cumplidos.
138
+ - Incluye tests y documentacion operativa.
139
+ - Es compatible con flujo CLI existente y CI.
140
+
141
+ ## 10) Practicas recomendadas para agentes/colaboradores
142
+
143
+ - Priorizar cambios que mejoren senial sobre ruido.
144
+ - Favorecer reportes accionables por sobre analisis abstracto.
145
+ - Evitar humo en roadmap: cada entrega debe mapear a comando, salida y test.
146
+ - Dejar decisiones registradas en la documentacion del repo.
package/docs/PRD.md ADDED
@@ -0,0 +1,157 @@
1
+ # PRD - drift
2
+
3
+ Version: 1.2.0
4
+ Estado: Activo
5
+ Producto: `@eduardbar/drift`
6
+
7
+ ## 1) Contexto
8
+
9
+ `drift` es un CLI de analisis estatico para TypeScript que detecta deuda tecnica asociada a codigo generado por IA y calcula score por archivo y por repositorio.
10
+
11
+ Con release `v1.2.0`, el producto entrega comandos operativos, analisis AST, reglas de arquitectura configurables, salida accionable, workflow CI para PR comments, y foundations SaaS (`drift cloud ingest|summary|dashboard`) con politica free-until-7500.
12
+
13
+ ## 2) Vision de producto
14
+
15
+ Ser la herramienta de referencia para equipos que usan IA para programar y necesitan detectar, priorizar y corregir deuda tecnica antes de mergear a produccion.
16
+
17
+ ## 3) Killer feature
18
+
19
+ ## AI Code Smell Detector
20
+
21
+ Detectar patrones de olor tecnico vinculados a codigo IA, estimar probabilidad de origen IA y traducir hallazgos en acciones concretas (fixes, review de PR, reglas de arquitectura y reportes).
22
+
23
+ ## 4) Estado de cumplimiento (actualizado)
24
+
25
+ ### Entregado
26
+
27
+ - `drift review` en CLI para analizar diff contra base y producir markdown usable en PR.
28
+ - `drift map` basico para generar `architecture.svg`.
29
+ - Senial de IA en salida (`ai_likelihood` y `files_suspected`).
30
+ - Reglas de arquitectura configurables via `drift.config.ts`.
31
+ - Score y breakdown por dimensiones para lectura ejecutiva y tecnica.
32
+ - Metricas de maintenance risk/hotspots.
33
+ - Plugin system MVP (`drift-plugin-*`) con aislamiento de errores.
34
+ - `drift fix` con modos preview/write.
35
+ - Workflow CI para comentario automatico unico y actualizable de `drift review`.
36
+ - `drift map` con marcado de cycle edges y layer violations en el SVG.
37
+ - VSCode quick actions para fixes de bajo riesgo.
38
+ - Confirmacion interactiva para `drift fix --write` (con `--yes` para CI/no-interactive).
39
+ - `drift report` HTML (`drift-report.html`) sin flag extra.
40
+ - Documentacion y tests del release.
41
+
42
+ ### Parcial
43
+
44
+ - Consolidacion/hardening de API de plugins para ecosistema externo amplio.
45
+
46
+ ### Pendiente
47
+
48
+ - Hardening del contrato de plugins para ecosistema externo amplio.
49
+ - Evolucion del dashboard SaaS foundations a experiencia multi-tenant full (auth, permisos por rol y billing activo post-umbral).
50
+
51
+ ## 5) Criterios de aceptacion vigentes
52
+
53
+ ### 5.1 Entregables cerrados en v1.1.0
54
+
55
+ - `drift review --base <ref>` devuelve score delta de PR, issues nuevos/resueltos y markdown.
56
+ - `drift scan --ai` incluye `ai_likelihood` y ranking `files_suspected`.
57
+ - `drift map <path>` genera `architecture.svg` utilizable sin edicion manual.
58
+ - `drift report [path]` genera HTML self-contained (no requiere `--html`).
59
+ - `drift fix --preview` muestra antes/despues y `drift fix --write` aplica reglas soportadas.
60
+
61
+ ### 5.1.b Entregables cerrados en v1.2 (scope tecnico)
62
+
63
+ - Workflow CI publica/actualiza comentario unico en PR para `drift review`.
64
+ - `drift map` marca visualmente ciclos y violaciones por capa.
65
+ - Extension VSCode expone quick actions para `debug-leftover` y `catch-swallow`.
66
+ - `drift fix --write` pide confirmacion interactiva por defecto y admite `--yes`.
67
+
68
+ ### 5.2 Objetivos aun abiertos (CI/editor/UX)
69
+
70
+ - Hardening del contrato de plugins para compatibilidad de largo plazo (versionado/migraciones).
71
+
72
+ ## 6) Roadmap actualizado
73
+
74
+ ### v1.1 (completado - release 1.1.0)
75
+
76
+ Prioridades cerradas:
77
+ - CLI de review para PR, mapa basico, salida AI, reglas configurables, report HTML, fix preview/write, hotspots, plugin MVP.
78
+
79
+ Done del bloque:
80
+ - Features documentadas.
81
+ - Tests de paths principales.
82
+ - Salidas CLI/JSON/AI consistentes para uso local y CI.
83
+
84
+ ### v1.2 (completado - cierre de pendientes tecnicos)
85
+
86
+ Prioridades cerradas:
87
+ - Comentario automatico actualizable en PR desde workflow CI.
88
+ - Mejora de `drift map` para destacar ciclos y violaciones.
89
+ - UX de seguridad para `drift fix --write` con confirmacion interactiva.
90
+
91
+ Done del bloque:
92
+ - Flujo CI reproducible con comentario unico por PR.
93
+ - Visualizaciones verificables en SVG sobre repos medianos.
94
+ - Confirmacion interactiva implementada para write mode.
95
+
96
+ ### v2 (prioridad: experiencia de editor + extensibilidad)
97
+
98
+ Prioridades:
99
+ - Consolidacion de API de plugins y hardening de compatibilidad.
100
+ - Reglas de plugin versionadas y validacion de contrato avanzada.
101
+
102
+ Criterio de done:
103
+ - Plugins con contrato estable y manejo de errores robusto.
104
+ - Documentacion de versionado para autores de plugins.
105
+
106
+ ### v3 (fundations completadas en v1.2.0)
107
+
108
+ Prioridades cerradas:
109
+ - Base de datos local de snapshots para cloud MVP.
110
+ - Ingestion de reportes en storage local SaaS-like.
111
+ - Summary de uso/threshold y dashboard HTML inicial.
112
+ - Guardrails de fase gratuita por workspace + politica free-until-7500.
113
+
114
+ Siguiente incremento (v3.x):
115
+ - Auth real multi-tenant, permisos por equipo y backend remoto persistente.
116
+ - Activacion de billing cuando el umbral de 7.500 usuarios se cumpla.
117
+
118
+ ## 6.1) Estrategia de monetizacion (aprobada)
119
+
120
+ - Fase gratuita: Drift SaaS gratis hasta alcanzar 7.500 usuarios registrados.
121
+ - Trigger de monetizacion: al alcanzar 7.500 usuarios, activar planes pagos para nuevos usuarios y definir politica de migracion para cohortes gratuitas.
122
+ - Objetivo: priorizar adopcion y proof-of-value temprano sin friccion comercial inicial.
123
+ - Guardrails durante fase gratuita:
124
+ - Limites tecnicos por workspace (runs/mes, retencion de historial, repositorios activos).
125
+ - Instrumentacion de uso desde el dia 1 para evitar abuso y medir unit economics.
126
+ - Feature flags de pricing listas antes del trigger para evitar corte abrupto.
127
+
128
+ ## 7) Fuera de alcance actual
129
+
130
+ - Soporte multi-lenguaje completo fuera de TypeScript/JS.
131
+ - Autofix de reglas de alto riesgo sin confirmacion explicita.
132
+ - Integraciones propietarias cerradas sin API estable.
133
+
134
+ ## 8) KPIs de exito
135
+
136
+ - Reduccion de score promedio en repos activos.
137
+ - % de PRs con feedback drift resuelto antes de merge.
138
+ - Tiempo medio desde deteccion hasta fix aplicado.
139
+ - Adopcion de reglas de arquitectura configurables por equipo.
140
+
141
+ ## 9) Dependencias y riesgos
142
+
143
+ - Performance en repos grandes (AST + cross-file).
144
+ - Calidad de senial en `ai_likelihood` (falsos positivos/negativos).
145
+ - Variabilidad de entornos CI para publicar comentarios de PR.
146
+ - Evolucion de API de plugins sin romper backward compatibility.
147
+
148
+ ## 10) Definition of Done por release
149
+
150
+ Checklist minimo por release:
151
+
152
+ - [ ] Scope del release cerrado y trazable a este PRD.
153
+ - [ ] Comandos/flujo documentados con ejemplos reales.
154
+ - [ ] Tests de regresion en paths principales y casos borde.
155
+ - [ ] Salidas CLI/JSON/AI estables para automatizacion.
156
+ - [ ] Criterios de aceptacion del bloque marcados como cumplidos o movidos a pendiente.
157
+ - [ ] Riesgos y tradeoffs explicitados en notas de release.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eduardbar/drift",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "Detect silent technical debt left by AI-generated code",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -103,7 +103,7 @@ function createRule(ruleName: string): Rule.RuleModule {
103
103
  data: { message: issue.message },
104
104
  })
105
105
  }
106
- } catch {
106
+ } catch { // drift-ignore
107
107
  // Archivo no parseable por ts-morph — silenciar
108
108
  }
109
109
  },
@@ -113,7 +113,7 @@
113
113
  "typescript": "^5.3.0"
114
114
  },
115
115
  "dependencies": {
116
- "@eduardbar/drift": "*",
116
+ "@eduardbar/drift": "1.0.0",
117
117
  "ts-morph": "^23.0.0"
118
118
  }
119
119
  }
@@ -1,3 +1,5 @@
1
+ // drift-ignore-file
2
+
1
3
  import { Project } from 'ts-morph'
2
4
  import type { FileReport } from '@eduardbar/drift'
3
5
 
@@ -0,0 +1,53 @@
1
+ import * as vscode from 'vscode'
2
+
3
+ function buildRemoveLineEdit(document: vscode.TextDocument, line: number): vscode.WorkspaceEdit {
4
+ const edit = new vscode.WorkspaceEdit()
5
+ const targetLine = document.lineAt(line)
6
+ const start = targetLine.range.start
7
+ const end = line < document.lineCount - 1
8
+ ? document.lineAt(line + 1).range.start
9
+ : targetLine.range.end
10
+ edit.delete(document.uri, new vscode.Range(start, end))
11
+ return edit
12
+ }
13
+
14
+ function buildCatchTodoEdit(document: vscode.TextDocument, line: number): vscode.WorkspaceEdit {
15
+ const edit = new vscode.WorkspaceEdit()
16
+ const targetLine = document.lineAt(line)
17
+ const baseIndent = targetLine.text.match(/^\s*/)?.[0] ?? ''
18
+ const indent = `${baseIndent} `
19
+ edit.insert(document.uri, new vscode.Position(line + 1, 0), `${indent}// TODO: handle error\n`)
20
+ return edit
21
+ }
22
+
23
+ export class DriftCodeActionProvider implements vscode.CodeActionProvider {
24
+ provideCodeActions(
25
+ document: vscode.TextDocument,
26
+ _range: vscode.Range,
27
+ context: vscode.CodeActionContext,
28
+ ): vscode.CodeAction[] {
29
+ const actions: vscode.CodeAction[] = []
30
+
31
+ for (const diagnostic of context.diagnostics) {
32
+ if (diagnostic.source !== 'drift') continue
33
+ const rule = String(diagnostic.code ?? '')
34
+ const line = diagnostic.range.start.line
35
+
36
+ if (rule === 'debug-leftover') {
37
+ const quickFix = new vscode.CodeAction('drift: remove debug leftover line', vscode.CodeActionKind.QuickFix)
38
+ quickFix.diagnostics = [diagnostic]
39
+ quickFix.edit = buildRemoveLineEdit(document, line)
40
+ actions.push(quickFix)
41
+ }
42
+
43
+ if (rule === 'catch-swallow') {
44
+ const quickFix = new vscode.CodeAction('drift: add TODO in empty catch', vscode.CodeActionKind.QuickFix)
45
+ quickFix.diagnostics = [diagnostic]
46
+ quickFix.edit = buildCatchTodoEdit(document, line)
47
+ actions.push(quickFix)
48
+ }
49
+ }
50
+
51
+ return actions
52
+ }
53
+ }