@eduardbar/drift 1.1.0 → 1.3.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 (66) hide show
  1. package/.github/workflows/publish-vscode.yml +3 -3
  2. package/.github/workflows/publish.yml +3 -3
  3. package/.github/workflows/review-pr.yml +153 -0
  4. package/AGENTS.md +6 -0
  5. package/README.md +192 -4
  6. package/ROADMAP.md +6 -5
  7. package/dist/analyzer.d.ts +2 -2
  8. package/dist/analyzer.js +420 -159
  9. package/dist/benchmark.d.ts +2 -0
  10. package/dist/benchmark.js +185 -0
  11. package/dist/cli.js +509 -23
  12. package/dist/diff.js +74 -10
  13. package/dist/git.js +12 -0
  14. package/dist/index.d.ts +5 -1
  15. package/dist/index.js +3 -0
  16. package/dist/map.d.ts +3 -2
  17. package/dist/map.js +98 -10
  18. package/dist/plugins.d.ts +2 -1
  19. package/dist/plugins.js +177 -28
  20. package/dist/printer.js +4 -0
  21. package/dist/review.js +2 -2
  22. package/dist/rules/comments.js +2 -2
  23. package/dist/rules/complexity.js +2 -7
  24. package/dist/rules/nesting.js +3 -13
  25. package/dist/rules/phase0-basic.js +10 -10
  26. package/dist/rules/shared.d.ts +2 -0
  27. package/dist/rules/shared.js +27 -3
  28. package/dist/saas.d.ts +219 -0
  29. package/dist/saas.js +762 -0
  30. package/dist/trust-kpi.d.ts +9 -0
  31. package/dist/trust-kpi.js +445 -0
  32. package/dist/trust.d.ts +65 -0
  33. package/dist/trust.js +571 -0
  34. package/dist/types.d.ts +160 -0
  35. package/docs/PRD.md +199 -172
  36. package/docs/plugin-contract.md +61 -0
  37. package/docs/trust-core-release-checklist.md +55 -0
  38. package/package.json +5 -3
  39. package/packages/vscode-drift/src/code-actions.ts +53 -0
  40. package/packages/vscode-drift/src/extension.ts +11 -0
  41. package/src/analyzer.ts +484 -155
  42. package/src/benchmark.ts +244 -0
  43. package/src/cli.ts +628 -36
  44. package/src/diff.ts +75 -10
  45. package/src/git.ts +16 -0
  46. package/src/index.ts +63 -0
  47. package/src/map.ts +112 -10
  48. package/src/plugins.ts +354 -26
  49. package/src/printer.ts +4 -0
  50. package/src/review.ts +2 -2
  51. package/src/rules/comments.ts +2 -2
  52. package/src/rules/complexity.ts +2 -7
  53. package/src/rules/nesting.ts +3 -13
  54. package/src/rules/phase0-basic.ts +11 -12
  55. package/src/rules/shared.ts +31 -3
  56. package/src/saas.ts +1031 -0
  57. package/src/trust-kpi.ts +518 -0
  58. package/src/trust.ts +774 -0
  59. package/src/types.ts +177 -0
  60. package/tests/diff.test.ts +124 -0
  61. package/tests/new-features.test.ts +98 -0
  62. package/tests/plugins.test.ts +219 -0
  63. package/tests/rules.test.ts +23 -1
  64. package/tests/saas-foundation.test.ts +464 -0
  65. package/tests/trust-kpi.test.ts +120 -0
  66. package/tests/trust.test.ts +584 -0
@@ -0,0 +1,55 @@
1
+ # Trust Core Tonight - Release Checklist
2
+
3
+ Use this checklist before releasing the trust-core milestone.
4
+
5
+ ## 1) Local validation
6
+
7
+ - [x] `npm ci`
8
+ - [x] `npm test`
9
+ - [x] `npx --no-install tsx ./src/cli.ts trust . --base origin/master --markdown`
10
+ - [x] `npx --no-install tsx ./src/cli.ts trust . --base origin/master --json-output drift-trust.json`
11
+ - [x] `npx --no-install tsx ./src/cli.ts trust-gate drift-trust.json --min-trust 40 --max-risk HIGH`
12
+ - [x] `npx --no-install tsx ./src/cli.ts review --base origin/master --comment`
13
+
14
+ ## 2) CI workflow validation
15
+
16
+ - [x] Open or update a non-fork PR and confirm `.github/workflows/review-pr.yml` runs successfully.
17
+ - [x] Confirm sticky PR comment is updated once (marker: `<!-- drift-review -->`).
18
+ - [x] Confirm PR comment includes both sections in this order: `drift trust` then `drift review`.
19
+ - [x] E2E: `trust-gate` runs from generated `drift-trust.json` in `review-pr` workflow.
20
+ - [x] E2E: `kpi` aggregates over generated trust JSON artifact (`drift-trust-kpi.json`).
21
+ - [x] E2E: `drift-trust-json-pr-<PR_NUMBER>-run-<RUN_ATTEMPT>` artifact now bundles:
22
+ - `drift-trust.json`
23
+ - `drift-trust-gate.txt`
24
+ - `drift-trust-kpi.json`
25
+ - [x] Confirm step summary shows trust KPI values: trust score, merge risk, new issues, resolved issues.
26
+ - [x] E2E: step summary includes aggregate KPI block (matched/parsed/malformed, PR samples, avg trust, high-risk ratio).
27
+
28
+ Smoke PR runbook:
29
+
30
+ - [x] Create a short-lived branch (for example `chore/trust-ci-smoke`) with a docs-only change.
31
+ - [x] Open a PR against `master` and wait for `review-pr` workflow to complete.
32
+ - [x] Verify gate behavior and comment rendering, then close or merge the PR.
33
+ - [x] Delete the short-lived branch after validation.
34
+
35
+ ## 3) Gate behavior acceptance
36
+
37
+ Default trust gate for this milestone:
38
+
39
+ - `--min-trust 40`
40
+ - `--max-risk HIGH`
41
+
42
+ Checks:
43
+
44
+ - [x] PR fails when trust score is below 40.
45
+ - [x] PR fails when merge risk is `CRITICAL`.
46
+ - [x] PR passes when trust score is 40+ and merge risk is `LOW`, `MEDIUM`, or `HIGH`.
47
+
48
+ Calibration evidence from docs-only smoke runs: trust score 49 (PR #11), 46 (PR #12), 41 (PR #13). Gate floor set to 40 to avoid false negatives while still blocking `CRITICAL` risk.
49
+
50
+ ## 4) Narrative and docs acceptance
51
+
52
+ - [x] `README.md` positions drift as an AI Code Audit CLI for merge trust in AI-assisted PRs.
53
+ - [x] `package.json` description matches the same positioning.
54
+ - [x] `src/cli.ts` program description matches the same positioning.
55
+ - [x] `ROADMAP.md` no longer contradicts PRD on core vs premium direction.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@eduardbar/drift",
3
- "version": "1.1.0",
4
- "description": "Detect silent technical debt left by AI-generated code",
3
+ "version": "1.3.0",
4
+ "description": "AI Code Audit CLI for merge trust in AI-assisted PRs",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "bin": {
@@ -14,7 +14,8 @@
14
14
  "prepublishOnly": "npm run build",
15
15
  "test": "vitest run",
16
16
  "test:watch": "vitest",
17
- "test:coverage": "vitest run --coverage"
17
+ "test:coverage": "vitest run --coverage",
18
+ "benchmark": "node --import tsx src/benchmark.ts"
18
19
  },
19
20
  "keywords": [
20
21
  "vibe-coding",
@@ -42,6 +43,7 @@
42
43
  "devDependencies": {
43
44
  "@types/node": "^25.3.0",
44
45
  "@vitest/coverage-v8": "^4.0.18",
46
+ "tsx": "^4.21.0",
45
47
  "typescript": "^5.9.3",
46
48
  "vitest": "^4.0.18"
47
49
  }
@@ -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
+ }
@@ -5,6 +5,7 @@ import { analyzeFilePath } from './analyzer'
5
5
  import { DriftDiagnosticsProvider } from './diagnostics'
6
6
  import { DriftTreeProvider } from './treeview'
7
7
  import { DriftStatusBarItem } from './statusbar'
8
+ import { DriftCodeActionProvider } from './code-actions'
8
9
  import type { FileReport } from '@eduardbar/drift'
9
10
 
10
11
  const SUPPORTED_LANGUAGES = ['typescript', 'typescriptreact', 'javascript', 'javascriptreact']
@@ -87,6 +88,7 @@ export function activate(context: vscode.ExtensionContext): void {
87
88
  const diagnostics = new DriftDiagnosticsProvider()
88
89
  const treeProvider = new DriftTreeProvider()
89
90
  const statusBar = new DriftStatusBarItem()
91
+ const codeActions = new DriftCodeActionProvider()
90
92
 
91
93
  const treeView = vscode.window.createTreeView('driftIssues', {
92
94
  treeDataProvider: treeProvider,
@@ -121,6 +123,14 @@ export function activate(context: vscode.ExtensionContext): void {
121
123
  }
122
124
  )
123
125
 
126
+ const codeActionRegistration = vscode.languages.registerCodeActionsProvider(
127
+ SUPPORTED_LANGUAGES.map((language) => ({ language })),
128
+ codeActions,
129
+ {
130
+ providedCodeActionKinds: [vscode.CodeActionKind.QuickFix],
131
+ },
132
+ )
133
+
124
134
  context.subscriptions.push(
125
135
  { dispose: () => diagnostics.dispose() },
126
136
  { dispose: () => statusBar.dispose() },
@@ -129,6 +139,7 @@ export function activate(context: vscode.ExtensionContext): void {
129
139
  scanCmd,
130
140
  clearCmd,
131
141
  goToCmd,
142
+ codeActionRegistration,
132
143
  )
133
144
  }
134
145