vibeguard-cli 1.0.0__tar.gz → 1.0.5__tar.gz

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 (138) hide show
  1. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/.github/workflows/publish.yml +23 -24
  2. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/CLAUDE.md +72 -0
  3. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/PKG-INFO +1 -1
  4. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/docs/progress.md +353 -29
  5. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/pyproject.toml +3 -2
  6. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/__init__.py +1 -1
  7. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/apply.py +11 -1
  8. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/auth_cmd.py +0 -2
  9. vibeguard_cli-1.0.5/src/vibeguard/cli/banners.py +98 -0
  10. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/config_cmd.py +7 -7
  11. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/fix.py +37 -8
  12. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/main.py +1 -0
  13. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/patch.py +60 -8
  14. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/scan.py +7 -0
  15. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/bootstrap.py +16 -2
  16. vibeguard_cli-1.0.5/src/vibeguard/core/bundles.py +303 -0
  17. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/downloader.py +11 -1
  18. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/license.py +79 -1
  19. vibeguard_cli-1.0.5/src/vibeguard/core/telemetry.py +73 -0
  20. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/__init__.py +4 -0
  21. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/trivy.toml +14 -4
  22. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/local.py +26 -1
  23. vibeguard_cli-1.0.5/tests/test_banners.py +234 -0
  24. vibeguard_cli-1.0.5/tests/test_bundles.py +448 -0
  25. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/.github/workflows/vibeguard.yml +0 -0
  26. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/.gitignore +0 -0
  27. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/.vibeguardignore +0 -0
  28. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/CHANGELOG.md +0 -0
  29. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/LICENSE +0 -0
  30. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/README.md +0 -0
  31. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/action.yml +0 -0
  32. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/docs/CI_INTEGRATION.md +0 -0
  33. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/docs/CONTRIBUTING_SCANNERS.md +0 -0
  34. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/docs/context.md +0 -0
  35. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/docs/license.md +0 -0
  36. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/docs/plan.md +0 -0
  37. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/docs/upgrade.md +0 -0
  38. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/__init__.py +0 -0
  39. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/baseline_cmd.py +0 -0
  40. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/display.py +0 -0
  41. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/doctor.py +0 -0
  42. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/import_cmd.py +0 -0
  43. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/init_cmd.py +0 -0
  44. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/keys.py +0 -0
  45. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/live_cmd.py +0 -0
  46. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/cli/report.py +0 -0
  47. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/__init__.py +0 -0
  48. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/auth.py +0 -0
  49. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/baseline.py +0 -0
  50. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/cache.py +0 -0
  51. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/config.py +0 -0
  52. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/dedup.py +0 -0
  53. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/example_detector.py +0 -0
  54. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/exit_codes.py +0 -0
  55. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/ignore.py +0 -0
  56. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/keyring.py +0 -0
  57. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/llm.py +0 -0
  58. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/path_classifier.py +0 -0
  59. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/repo_detector.py +0 -0
  60. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/sarif_import.py +0 -0
  61. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/triage.py +0 -0
  62. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/url_validator.py +0 -0
  63. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/core/validate.py +0 -0
  64. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/models/__init__.py +0 -0
  65. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/models/auth.py +0 -0
  66. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/models/baseline.py +0 -0
  67. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/models/finding.py +0 -0
  68. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/models/patch.py +0 -0
  69. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/models/scan_result.py +0 -0
  70. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/models/triage.py +0 -0
  71. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/__init__.py +0 -0
  72. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/badge.py +0 -0
  73. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/html.py +0 -0
  74. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/sarif.py +0 -0
  75. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/bandit.toml +0 -0
  76. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/cargo_audit.toml +0 -0
  77. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/checkov.toml +0 -0
  78. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/dockle.toml +0 -0
  79. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/gitleaks.toml +0 -0
  80. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/npm_audit.toml +0 -0
  81. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/nuclei.toml +0 -0
  82. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/pip_audit.toml +0 -0
  83. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/semgrep.toml +0 -0
  84. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/trufflehog.toml +0 -0
  85. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/__init__.py +0 -0
  86. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/bandit.py +0 -0
  87. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/cargo_audit.py +0 -0
  88. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/checkov.py +0 -0
  89. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/dockle.py +0 -0
  90. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/gitleaks.py +0 -0
  91. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/npm_audit.py +0 -0
  92. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/nuclei.py +0 -0
  93. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/pip_audit.py +0 -0
  94. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/semgrep.py +0 -0
  95. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/trivy.py +0 -0
  96. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/trufflehog.py +0 -0
  97. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/__init__.py +0 -0
  98. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/base.py +0 -0
  99. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/docker.py +0 -0
  100. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/__init__.py +0 -0
  101. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/conftest.py +0 -0
  102. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_apply_cmd.py +0 -0
  103. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_baseline.py +0 -0
  104. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_baseline_cmd.py +0 -0
  105. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_bootstrap.py +0 -0
  106. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_cache.py +0 -0
  107. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_checkov_parser.py +0 -0
  108. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_ci_mode.py +0 -0
  109. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_cli.py +0 -0
  110. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_dedup.py +0 -0
  111. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_dockle_parser.py +0 -0
  112. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_exit_codes.py +0 -0
  113. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_fix_cmd.py +0 -0
  114. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_keyring.py +0 -0
  115. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_keys_cmd.py +0 -0
  116. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_license.py +0 -0
  117. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_live_cmd.py +0 -0
  118. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_llm.py +0 -0
  119. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_models.py +0 -0
  120. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_nuclei_parser.py +0 -0
  121. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/__init__.py +0 -0
  122. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_bandit.py +0 -0
  123. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_cargo_audit.py +0 -0
  124. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_gitleaks.py +0 -0
  125. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_npm_audit.py +0 -0
  126. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_pip_audit.py +0 -0
  127. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_semgrep.py +0 -0
  128. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_trivy.py +0 -0
  129. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_parsers/test_trufflehog.py +0 -0
  130. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_patch_cmd.py +0 -0
  131. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_patch_model.py +0 -0
  132. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_repo_detector.py +0 -0
  133. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_reporters/__init__.py +0 -0
  134. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_reporters/test_badge.py +0 -0
  135. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_reporters/test_html.py +0 -0
  136. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_reporters/test_sarif.py +0 -0
  137. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_sarif_import.py +0 -0
  138. {vibeguard_cli-1.0.0 → vibeguard_cli-1.0.5}/tests/test_url_validator.py +0 -0
@@ -9,13 +9,9 @@ on:
9
9
  test_pypi:
10
10
  description: 'Publish to TestPyPI instead of PyPI'
11
11
  required: false
12
- default: 'false'
12
+ default: false
13
13
  type: boolean
14
14
 
15
- permissions:
16
- contents: read
17
- id-token: write # Required for OIDC trusted publishing
18
-
19
15
  jobs:
20
16
  test:
21
17
  name: Run Tests
@@ -33,17 +29,16 @@ jobs:
33
29
  python -m pip install --upgrade pip
34
30
  pip install -e ".[dev]"
35
31
 
36
- - name: Run tests
37
- run: pytest -v --ignore=tests/test_ci_mode.py || echo "Some tests failed - continuing with publish"
38
- continue-on-error: true
39
-
40
32
  - name: Run linting
41
- run: ruff check src/vibeguard || echo "Linting warnings - continuing"
42
- continue-on-error: true
33
+ run: ruff check src/vibeguard
43
34
 
44
- - name: Run type checking
45
- run: mypy src/vibeguard --ignore-missing-imports || echo "Type check warnings - continuing"
46
- continue-on-error: true
35
+ - name: Run tests (unit tests only, skip scanner-dependent tests)
36
+ run: >
37
+ pytest -v
38
+ --ignore=tests/test_ci_mode.py
39
+ --ignore=tests/test_cli.py
40
+ --ignore=tests/test_live_cmd.py
41
+ -k "not test_scan"
47
42
 
48
43
  build:
49
44
  name: Build Package
@@ -63,13 +58,13 @@ jobs:
63
58
  - name: Build wheel and sdist
64
59
  run: python -m build
65
60
 
66
- - name: Check dist contents
61
+ - name: Verify package
67
62
  run: |
68
63
  ls -la dist/
69
64
  python -m pip install twine
70
65
  twine check dist/*
71
66
 
72
- - name: Upload artifacts
67
+ - name: Upload build artifacts
73
68
  uses: actions/upload-artifact@v4
74
69
  with:
75
70
  name: dist
@@ -83,8 +78,10 @@ jobs:
83
78
  environment:
84
79
  name: testpypi
85
80
  url: https://test.pypi.org/project/vibeguard-cli/
81
+ permissions:
82
+ id-token: write
86
83
  steps:
87
- - name: Download artifacts
84
+ - name: Download build artifacts
88
85
  uses: actions/download-artifact@v4
89
86
  with:
90
87
  name: dist
@@ -94,18 +91,21 @@ jobs:
94
91
  uses: pypa/gh-action-pypi-publish@release/v1
95
92
  with:
96
93
  repository-url: https://test.pypi.org/legacy/
97
- password: ${{ secrets.TEST_PYPI_API_TOKEN }}
98
94
 
99
95
  publish-pypi:
100
96
  name: Publish to PyPI
101
97
  needs: build
102
98
  runs-on: ubuntu-latest
103
- if: (startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch') && github.event.inputs.test_pypi != 'true'
99
+ if: >
100
+ (startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch')
101
+ && github.event.inputs.test_pypi != 'true'
104
102
  environment:
105
103
  name: pypi
106
104
  url: https://pypi.org/project/vibeguard-cli/
105
+ permissions:
106
+ id-token: write
107
107
  steps:
108
- - name: Download artifacts
108
+ - name: Download build artifacts
109
109
  uses: actions/download-artifact@v4
110
110
  with:
111
111
  name: dist
@@ -113,19 +113,18 @@ jobs:
113
113
 
114
114
  - name: Publish to PyPI
115
115
  uses: pypa/gh-action-pypi-publish@release/v1
116
- with:
117
- password: ${{ secrets.PYPI_API_TOKEN }}
118
116
 
119
117
  create-release:
120
118
  name: Create GitHub Release
121
119
  needs: publish-pypi
122
120
  runs-on: ubuntu-latest
121
+ if: startsWith(github.ref, 'refs/tags/v')
123
122
  permissions:
124
123
  contents: write
125
124
  steps:
126
125
  - uses: actions/checkout@v4
127
126
 
128
- - name: Download artifacts
127
+ - name: Download build artifacts
129
128
  uses: actions/download-artifact@v4
130
129
  with:
131
130
  name: dist
@@ -136,7 +135,7 @@ jobs:
136
135
  run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
137
136
 
138
137
  - name: Create GitHub Release
139
- uses: softprops/action-gh-release@v1
138
+ uses: softprops/action-gh-release@v2
140
139
  with:
141
140
  name: VibeGuard v${{ steps.version.outputs.version }}
142
141
  body: |
@@ -168,6 +168,12 @@ Base 100, deductions: Critical -20, High -10, Medium -5, Low -2. Grades: A+ ≥9
168
168
  2. Update this file (CLAUDE.md) if architecture or commands change
169
169
  3. Commit and push to git
170
170
 
171
+ **Versioning & Release:**
172
+ - After each iteration that is pushed live, bump the version by 0.01 (e.g., 1.0.5 → 1.0.6)
173
+ - Version must be updated in BOTH `pyproject.toml` and `src/vibeguard/__init__.py`
174
+ - To release: `git tag v<version> && git push origin v<version>` (triggers CI/CD)
175
+ - CI/CD pipeline: tests → build → publish to PyPI → create GitHub Release
176
+
171
177
  **Planning:**
172
178
  - Implementation plans are stored in `docs/plan.md`
173
179
  - Use plan mode for non-trivial features before implementation
@@ -192,3 +198,69 @@ ssh -i C:/Users/faheem/.ssh/faheem_ssh ubuntu@<server-ip>
192
198
  - Machine ID: `~/.vibeguard/machine_id`
193
199
  - Auth token: `~/.vibeguard/auth.json`
194
200
  - Bundles: `~/.vibeguard/bundles/`
201
+
202
+ ## Website (vibeguard.co)
203
+
204
+ The VibeGuard marketing website.
205
+
206
+ - **Domain**: vibeguard.co
207
+ - **Local path**: `G:\Downloads 2.0\vibeguard-website-2`
208
+
209
+ ## Panel System
210
+
211
+ User dashboard and admin panel. Implemented as a Turborepo monorepo.
212
+
213
+ **Location**: `C:\Users\faheem\OneDrive\Documents\apps\vibeguard-panel\`
214
+
215
+ | Domain | Purpose | Port (dev) |
216
+ |--------|---------|------------|
217
+ | `app.vibeguard.co` | User dashboard (licenses, machines, billing, settings) | 3000 |
218
+ | `admin.vibeguard.co` | Admin panel (user management, license issuance, audit) | 3001 |
219
+
220
+ ### Tech Stack
221
+ - **Framework**: Next.js 14 (App Router)
222
+ - **Auth**: Clerk
223
+ - **Styling**: Tailwind CSS
224
+ - **Data Fetching**: TanStack Query
225
+ - **Build**: Turborepo + pnpm workspaces
226
+
227
+ ### Panel Commands
228
+ ```bash
229
+ cd C:\Users\faheem\OneDrive\Documents\apps\vibeguard-panel
230
+
231
+ # Install dependencies
232
+ pnpm install
233
+
234
+ # Run all apps
235
+ pnpm dev
236
+
237
+ # Run specific app
238
+ pnpm --filter @vibeguard/user-panel dev
239
+ pnpm --filter @vibeguard/admin dev
240
+
241
+ # Build all
242
+ pnpm build
243
+ ```
244
+
245
+ ### Panel Structure
246
+ ```
247
+ vibeguard-panel/
248
+ ├── apps/
249
+ │ ├── user/ # app.vibeguard.co
250
+ │ │ └── src/app/
251
+ │ │ ├── (auth)/ # Sign-in/up pages
252
+ │ │ └── (dashboard)/ # Dashboard, licenses, machines, billing, settings
253
+ │ └── admin/ # admin.vibeguard.co
254
+ │ └── src/app/
255
+ │ ├── (auth)/ # Admin sign-in
256
+ │ └── (dashboard)/ # Dashboard, users, licenses, payments, audit
257
+ ├── packages/
258
+ │ ├── ui/ # Shared components (Button, Card, Badge, Toggle)
259
+ │ ├── api-client/ # TanStack Query hooks for API calls
260
+ │ └── config/ # Shared ESLint/Tailwind config
261
+ └── README.md
262
+ ```
263
+
264
+ ### Sprint Status
265
+ - **Sprint 1**: Backend payment infrastructure ✅ (webhooks, Stripe provider, atomic fulfillment)
266
+ - **Sprint 2**: Panel auth + dashboard ✅ (Clerk, all pages built, TanStack Query hooks)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vibeguard-cli
3
- Version: 1.0.0
3
+ Version: 1.0.5
4
4
  Summary: Unified security scanner orchestrator for local repos
5
5
  Author: VibeGuard Team
6
6
  License: MIT
@@ -1,8 +1,323 @@
1
1
  # VibeGuard CLI - Development Progress
2
2
 
3
3
  ## Current Status
4
- **Phase**: Option 3A Pro Backend - In Progress
5
- **Last Updated**: 2026-02-03
4
+ **Phase**: Post-Sprint 6 v1.0.5 Scanner Auto-Download + pipx Fix
5
+ **Last Updated**: 2026-02-06
6
+
7
+ ---
8
+
9
+ ## Panel System Development
10
+
11
+ Full implementation log: `vibeguard-panel/docs/panelplan-implementation.md`
12
+
13
+ ### Panel Auth Fix: Clerk JWT → API Flow ✅ FIXED (2026-02-06)
14
+
15
+ **Root cause**: Clerk JWT authentication was completely broken across all three layers (backend, user panel, admin panel). Panels showed empty/zero data because every API call failed auth.
16
+
17
+ **3 issues identified and fixed:**
18
+
19
+ #### 1. Backend missing Clerk env vars (root cause)
20
+ - [x] `CLERK_FRONTEND_API` and `ADMIN_EMAILS` existed in `/opt/vibeguard/.env` but NOT in `/opt/vibeguard/api/.env`
21
+ - [x] Docker Compose only reads `env_file: ./api/.env`, so the API container never received Clerk config
22
+ - [x] `settings.clerk_frontend_api` defaulted to `""`, making JWKS URL `https:///.well-known/jwks.json` (invalid)
23
+ - [x] Every Clerk JWT verification crashed → all panel API calls returned 401/500
24
+ - [x] **Fix**: Added `CLERK_FRONTEND_API=clerk.vibeguard.co` and `ADMIN_EMAILS=faheem@vibeguard.co` to `/opt/vibeguard/api/.env`
25
+ - [x] Restarted API container (cleaned up zombie container holding port 8090)
26
+ - [x] Verified: API healthy, JWKS endpoint reachable, invalid tokens return 401 (not 500)
27
+
28
+ #### 2. User panel not using custom JWT template
29
+ - [x] `providers.tsx` called `getToken()` with no args → returned default Clerk session token
30
+ - [x] Default session token lacks custom claims (`email`, `name`, `role`, `tier`) defined in "vibeguard" JWT template
31
+ - [x] Backend extracts `email` from token for admin checks → `None` caused failures
32
+ - [x] **Fix**: Changed to `getToken({ template: "vibeguard" })` in `apps/user/src/app/providers.tsx`
33
+ - [x] Added automatic token refresh every 50 minutes (template TTL is 60 min)
34
+
35
+ #### 3. Admin panel had zero auth sync
36
+ - [x] `apps/admin/src/app/providers.tsx` had no `AuthSync` component at all
37
+ - [x] No `useAuth()`, no `getToken()`, no `setAuthToken()` — every admin API call sent without `Authorization` header
38
+ - [x] **Fix**: Added full `AuthSync` component with `getToken({ template: "vibeguard" })` + 50-min refresh interval
39
+
40
+ **Clerk JWT Template Config (reference):**
41
+ - Template name: `vibeguard`
42
+ - Token lifetime: 3600s (1 hour)
43
+ - Issuer: `https://clerk.vibeguard.co`
44
+ - JWKS: `https://clerk.vibeguard.co/.well-known/jwks.json`
45
+ - Custom claims: `name`, `role`, `tier`, `email`
46
+
47
+ **Files changed:**
48
+ - `/opt/vibeguard/api/.env` (server) — added 2 env vars
49
+ - `vibeguard-panel/apps/user/src/app/providers.tsx` — template selection + token refresh
50
+ - `vibeguard-panel/apps/admin/src/app/providers.tsx` — full AuthSync added
51
+
52
+ **Status**: Backend deployed. Panel changes need Vercel redeploy.
53
+
54
+ ### v1.0.5: Scanner Auto-Download + pipx Fix (2026-02-06)
55
+
56
+ **Problem**: Users installing via `pipx` had most scanners skipped. Only Gitleaks and TruffleHog worked (standalone binaries). Semgrep, Bandit, pip-audit, Checkov were pip-installed into pipx's isolated venv but their executables weren't found by the runner. Trivy download failed due to non-standard URL naming.
57
+
58
+ **Fixes:**
59
+ - [x] **Trivy auto-download fixed** — added custom `os_map`/`arch_map` to download config
60
+ - Trivy uses `macOS` not `darwin`, `64bit` not `amd64`, `ARM64` not `arm64`
61
+ - New manifest fields: `[install.download.os_map]` and `[install.download.arch_map]`
62
+ - Updated Trivy version to 0.69.1 (latest)
63
+ - Supported on all platforms: macOS ARM64/AMD64, Linux ARM64/AMD64, Windows AMD64
64
+ - [x] **pipx scanner discovery fixed** — runner now checks `sys.prefix/bin/` directory
65
+ - `LocalRunner.is_available()` checks: system PATH → venv bin → `~/.vibeguard/bin/`
66
+ - `bootstrap._is_binary_available()` also checks venv bin
67
+ - Pip-installed tools (Semgrep, Bandit, pip-audit, Checkov) now found in pipx venv
68
+ - [x] Added `os_map`/`arch_map` fields to `DownloadConfig` in both `scanners/__init__.py` and `core/downloader.py`
69
+ - [x] Updated `core/bootstrap.py` to pass new fields through
70
+
71
+ **Files changed:**
72
+ - `src/vibeguard/scanners/manifests/trivy.toml` — download URL + custom OS/arch mapping
73
+ - `src/vibeguard/scanners/__init__.py` — `os_map`/`arch_map` on DownloadConfig + manifest parsing
74
+ - `src/vibeguard/core/downloader.py` — `os_map`/`arch_map` on DownloadConfig + apply in URL building
75
+ - `src/vibeguard/core/bootstrap.py` — pass `os_map`/`arch_map`, check venv bin in `_is_binary_available()`
76
+ - `src/vibeguard/scanners/runners/local.py` — `_get_venv_bin_dir()` + check in `is_available()`
77
+
78
+ **Tests:** 741 passed, ruff clean.
79
+
80
+ ---
81
+
82
+ ### PyPI Publication ✅ PUBLISHED + AUTOMATED (2026-02-06)
83
+
84
+ - [x] **vibeguard-cli v1.0.4 live on PyPI**: https://pypi.org/project/vibeguard-cli/
85
+ - [x] Install: `pip install vibeguard-cli`
86
+ - [x] Both wheel (.whl) and sdist (.tar.gz) uploaded
87
+ - [x] Manual upload via twine for v1.0.0 (initial release)
88
+ - [x] **Automated CI/CD pipeline fully working** (v1.0.4 — all 4 jobs green):
89
+ - Run Tests (1m16s) — unit tests pass, scanner-dependent tests excluded
90
+ - Build Package (17s) — wheel + sdist built and verified
91
+ - Publish to PyPI (16s) — OIDC trusted publishing (no secrets needed)
92
+ - Create GitHub Release (6s) — auto-created with install instructions
93
+ - [x] `.github/workflows/publish.yml` configured:
94
+ - OIDC trusted publishing via `pypa/gh-action-pypi-publish@release/v1`
95
+ - Tests and linting must pass before publish
96
+ - `id-token: write` permission scoped to publish jobs only
97
+ - Triggers on: git tag push (`v*.*.*`) or manual workflow dispatch
98
+ - TestPyPI option via workflow dispatch toggle
99
+ - GitHub Release auto-created on tag push (`softprops/action-gh-release@v2`)
100
+ - Scanner-dependent tests excluded from CI (no semgrep/gitleaks on runner)
101
+
102
+ **CI fixes applied (v1.0.1–v1.0.4):**
103
+ - Added `ignore = ["UP042"]` to ruff config (str+Enum pattern used throughout)
104
+ - Fixed f-string without placeholders (F541) in config_cmd.py and auth_cmd.py
105
+ - Widened `line-length` from 100 to 120 in pyproject.toml
106
+ - Excluded scanner-dependent tests: `test_cli.py`, `test_live_cmd.py`, scan tests
107
+
108
+ **Future releases:** bump version in `pyproject.toml` + `__init__.py`, then:
109
+ ```bash
110
+ git tag v1.1.0 && git push origin v1.1.0
111
+ ```
112
+
113
+ ---
114
+
115
+ ### Sprint 6: Bundle Delivery + Rate Limits + Scan History + Observability ✅ COMPLETE (2026-02-06)
116
+
117
+ **4 features shipped across 3 repos (CLI, API, Panel):**
118
+
119
+ #### Bundle Delivery System (CLI + API)
120
+ - [x] Created `core/bundles.py` - Central bundle fetch, cache, load module
121
+ - `load_cached_bundle()`, `save_bundle()`, `get_cached_version()`
122
+ - `fetch_bundle()` - async, with If-None-Match / ETag conditional fetching
123
+ - `ensure_bundle()` - main entry point, never raises (server → cache → hardcoded fallback)
124
+ - `get_prompt()`, `get_patch_rule()` - bundle value lookup with fallback
125
+ - `get_hardcoded_fallback()` - returns Bundle with current FIX_PROMPT_TEMPLATE
126
+ - Storage: `~/.vibeguard/bundles/current.json` and `~/.vibeguard/bundles/meta.json`
127
+ - [x] Modified `fix.py` - bundle-aware `build_fix_prompt()`
128
+ - Renamed `FIX_PROMPT_TEMPLATE` to `_DEFAULT_FIX_PROMPT`
129
+ - Added `bundle: Bundle | None` keyword parameter
130
+ - Uses `get_prompt(bundle, "fix_prompt", _DEFAULT_FIX_PROMPT)` for template
131
+ - Loads cached bundle in `fix()` command (cache-only, no API fetch for FREE tier)
132
+ - [x] Modified `patch.py` - full bundle integration
133
+ - Added `_load_bundle_for_patch()` helper (fetches from server for Pro users)
134
+ - Passes `bundle` through to `_generate_and_save_patch()` and `build_fix_prompt()`
135
+ - `_generate_patch_async` reads `max_tokens` and `temperature` from bundle
136
+ - [x] Updated API `/v1/bundles/latest` endpoint
137
+ - Returns full bundle JSON inline (not metadata + download URL)
138
+ - Supports `If-None-Match` / ETag for conditional fetching (304 Not Modified)
139
+ - Falls back to filesystem default bundle if no DB bundle
140
+ - Rate limited: 30/min per license
141
+ - [x] Created `tests/test_bundles.py` - 36 tests covering all bundle operations
142
+ - [x] All 68 targeted tests passing, ruff clean
143
+
144
+ #### Granular Rate Limits (API)
145
+ - [x] Extended `ratelimit.py` with per-endpoint limiters:
146
+ - `activate_key`: 10/min per license key hash
147
+ - `activate_ip`: 20/min per client IP
148
+ - `token_refresh`: 30/min per license ID
149
+ - `checkout`: 5/min per clerk_user_id
150
+ - `trial_start`: 1/day per clerk_user_id
151
+ - `webhook`: 1000/min per client IP
152
+ - `bundle_fetch`: 30/min per JWT subject
153
+ - `scan_submit`: 60/min per license ID
154
+ - `scan_read`: 60/min per clerk user ID
155
+ - [x] Added `check_rate_limit()` inline helper for use in endpoint handlers
156
+ - [x] Applied rate limits to all endpoints:
157
+ - `/v1/licenses/activate` (by key hash + client IP)
158
+ - `/v1/licenses/refresh-token` (by license ID)
159
+ - `/v1/bundles/latest` (by license ID)
160
+ - `/v1/scans` (submit: by license ID, read: by clerk user ID)
161
+ - `/v1/user/checkout` (by clerk user ID)
162
+ - `/v1/user/trial` (by clerk user ID)
163
+ - `/v1/webhooks/{provider}` (by client IP)
164
+
165
+ #### Scan History (API + CLI + Panel)
166
+ - [x] Created `scan_history` PostgreSQL table with indexes
167
+ - [x] Added `ScanHistory` SQLAlchemy model
168
+ - [x] Created `routes/scans.py` with 3 endpoints:
169
+ - `POST /v1/scans` - CLI submits scan summary (JWT auth, metadata only)
170
+ - `GET /v1/user/scans` - Panel gets paginated scan history (Clerk auth)
171
+ - `GET /v1/user/scans/stats` - Aggregated stats (total, avg score, trend)
172
+ - [x] Created `core/telemetry.py` - Fire-and-forget scan submission from CLI
173
+ - Only for Pro users (has valid token)
174
+ - Non-blocking, wrapped in try/except (never blocks user)
175
+ - Sends only aggregated metadata: score, grade, counts, scanners, duration
176
+ - [x] Added scan submission call to `scan.py` after cache save
177
+ - [x] Created panel scan history page (`apps/user/src/app/(dashboard)/scans/page.tsx`)
178
+ - Stats cards: Total scans, Avg score, Latest grade, Scans this month
179
+ - Paginated table: date, repo, score/grade badge, findings (C/H/M/L), scanners, duration
180
+ - Grade badges color-coded (A/A+ = green, B = blue, C = amber, D/F = red)
181
+ - Empty state, loading state, pagination
182
+ - [x] Added `useScans()` and `useScanStats()` TanStack Query hooks
183
+ - [x] Added `getScans()` and `getScanStats()` to API client
184
+ - [x] Added "Scans" nav item with BarChart3 icon to dashboard layout
185
+
186
+ #### Observability (API)
187
+ - [x] Enhanced `/healthz` endpoint - checks PostgreSQL and Redis connectivity
188
+ - Returns `{"status": "healthy"|"degraded", "checks": {"postgresql": "ok", "redis": "ok"}}`
189
+ - [x] Added X-Request-ID middleware
190
+ - Generates UUID per request, returns in response header
191
+ - Accepts client-provided `X-Request-ID` for tracing
192
+ - [x] API version bumped to 1.6.0
193
+
194
+ ### Sprint 5: Admin Panel + Polish ✅ COMPLETE (2026-02-05)
195
+ Per panelplan-openai-reinforced-double.md:
196
+ - [x] Admin API endpoints deployed (v1.4.0)
197
+ - `/v1/admin/dashboard` - Dashboard stats (users, licenses, revenue)
198
+ - `/v1/admin/users` - List/search users with ban/unban
199
+ - `/v1/admin/licenses` - List/issue/extend/revoke licenses
200
+ - `/v1/admin/payments` - List payments with refund support
201
+ - `/v1/admin/audit` - Audit log with search
202
+ - Clerk JWT auth + ADMIN_EMAILS whitelist (`faheem@vibeguard.co`)
203
+ - Audit logging for all admin actions
204
+ - [x] Admin API client hooks (TanStack Query)
205
+ - `useAdminDashboard`, `useAdminUsers`, `useAdminUser`
206
+ - `useBanUser`, `useUnbanUser`
207
+ - `useAdminLicenses`, `useIssueLicense`, `useExtendLicense`, `useRevokeLicense`
208
+ - `useAdminPayments`, `useRefundPayment`
209
+ - `useAdminAuditLog`
210
+ - [x] Admin panel pages wired to real API
211
+ - Dashboard: Real stats with loading states
212
+ - Users: Search, pagination, ban/unban actions
213
+ - Licenses: Search, pagination, issue/extend/revoke with modals
214
+ - Payments: Search, pagination, refund action, revenue stats
215
+ - Audit: Search, pagination, action-based icons and colors
216
+ - [x] Rate limiting for admin endpoints (Redis)
217
+ - Created `app/ratelimit.py` - Sliding window rate limiter using Redis sorted sets
218
+ - Three rate limit tiers: `admin_read` (60/min), `admin_write` (20/min), `admin_sensitive` (10/min)
219
+ - Applied to all admin endpoints based on operation type
220
+ - Returns 429 with `Retry-After` header when limit exceeded
221
+ - API v1.5.0 deployed
222
+
223
+ ### Sprint 3: API Integration ✅ COMPLETE (2026-02-05)
224
+ - [x] Add `/v1/user/*` endpoints to vibeguard-api
225
+ - Dashboard stats, licenses, machines, payments, settings, trial
226
+ - Clerk JWT authentication for panel routes
227
+ - API v1.3.0 deployed to api-cli-2.vibeguard.co
228
+ - [x] Vercel deployment for both apps
229
+ - **app.vibeguard.co** - User panel deployed
230
+ - **admin.vibeguard.co** - Admin panel deployed
231
+ - Fixed middleware Edge runtime (NextResponse instead of Response)
232
+ - Added globalEnv to turbo.json for Clerk environment variables
233
+ - Configured vercel.json with `"framework": "nextjs"` for monorepo
234
+ - Created separate Vercel projects (vibeguard-panel, vibeguard-admin)
235
+ - Disabled Vercel Deployment Protection for public access
236
+ - [x] Admin panel security hardening
237
+ - Added ADMIN_EMAILS whitelist for admin access control
238
+ - Created /unauthorized page for non-admin users
239
+ - Production blocks all access if no whitelist configured
240
+ - [x] Audit findings addressed (2026-02-05)
241
+ - **License reveal re-auth**: Added ReAuthModal - users must verify password before revealing license key
242
+ - **Billing wired to API**: Integrated useSubscription, usePayments, useCreateCheckout, useCancelSubscription
243
+ - **Trial start flow**: Added trial banner with "Start 14-Day Free Trial" button and useStartTrial hook
244
+ - **Machine limit from API**: Now reads license.max_activations instead of hardcoded value
245
+ - **Clerk webhook endpoint**: Created /api/webhooks/clerk with svix signature verification
246
+ - Added new hooks: useSubscription, useCancelSubscription, useStartTrial
247
+ - Added trial endpoint to apiClient
248
+ - [x] Clerk webhooks for user sync
249
+ - Created `/api/webhooks/clerk/route.ts` (panel side)
250
+ - Created `/v1/webhooks/clerk/user-sync` and `/v1/webhooks/clerk/user-deleted` (backend)
251
+ - Handles user.created, user.updated, user.deleted events
252
+ - Svix signature verification
253
+ - CLERK_WEBHOOK_SECRET and API_WEBHOOK_KEY configured in Vercel
254
+ - [x] Backend: Add /v1/webhooks/clerk/user-sync endpoint
255
+ - Upserts user by clerk_user_id, syncs email/name/email_verified
256
+ - Links existing users by email if clerk_user_id not found
257
+ - Authenticated via X-Webhook-Key header
258
+ - [x] Backend: Add /v1/webhooks/clerk/user-deleted endpoint
259
+ - Soft-deletes user by setting is_active=False
260
+ - Preserves audit trail
261
+ - [x] Backend: Fix /v1/user/trial endpoint
262
+ - Changed path from `/trial/start` to `/trial` to match frontend
263
+ - Changed response from dict to LicenseResponse object
264
+ - Returns: id, key_prefix, plan, status, entitlements, max_activations, etc.
265
+ - [x] GitHub OAuth redirect URI configuration (Clerk callback URL added to GitHub OAuth App)
266
+
267
+ ### Sprint 4: Subscriptions + Grace Period ✅ COMPLETE (2026-02-05)
268
+ Per panelplan-openai-reinforced-double.md:
269
+ - [x] Database migration for subscription-license linking
270
+ - Added `license_id`, `billing_interval`, `plan_sku` to `subscriptions` table
271
+ - Added `subscription_id` to `licenses` table
272
+ - SQLAlchemy models updated for bidirectional relationship
273
+ - [x] Handle `invoice.paid` for subscription renewals
274
+ - Extends `subscriptions.current_period_end` from invoice period
275
+ - Extends linked `licenses.current_period_end` automatically
276
+ - Records payment in `payments` table with provider details
277
+ - [x] Handle `customer.subscription.deleted`
278
+ - Sets subscription status to `cancelled` with timestamp
279
+ - **License stays active until period end** (no immediate revocation)
280
+ - Sets `auto_renew=False` on license
281
+ - [x] Expiry banner component in CLI (`cli/banners.py`)
282
+ - Grace period banner (yellow, urgent) when `grace.active` entitlement present
283
+ - Critical banner (red) when < 24 hours remaining
284
+ - Approaching banner (yellow) when < 7 days remaining
285
+ - Integrated into `patch` and `apply` commands
286
+ - [x] Grace period implementation (48h standard)
287
+ - `GRACE_PERIOD_HOURS = 48` constant in token generation
288
+ - Token expiry bounded: `min(now + 7_days, license_period_end + 48_hours)`
289
+ - `grace.active` entitlement added to token when `now > license_period_end`
290
+ - `get_license_status_with_grace()` for CLI banner display
291
+ - [x] Tests for CLI banners (21 tests in `test_banners.py`)
292
+ - [x] Pay-early logic (trial days carry over to paid plan)
293
+ - Already implemented in `webhooks.py`: calculates remaining trial days
294
+ - Creates paid license with `plan_days + trial_days`
295
+ - Transfers machine activations, records `trial_days_added` in extra_data
296
+ - [x] Refund request flow
297
+ - Created `refund_requests` table for tracking refund requests
298
+ - Added `charge.refunded` webhook handler
299
+ - Full refund: deactivates license and all machine activations
300
+ - Partial refund: logs event, keeps license active
301
+ - [x] Renewal reminder emails (cron job)
302
+ - Created `/opt/vibeguard/scripts/renewal_reminders.py`
303
+ - Sends reminders for licenses expiring in 7, 3, 1 days
304
+ - Tracks sent reminders in `extra_data` to avoid duplicates
305
+ - Cron job runs daily at 9 AM: `0 9 * * *`
306
+
307
+ ### Sprint 2: Panel Auth + Dashboard ✅ COMPLETE (2026-02-05)
308
+ - Turborepo monorepo at `vibeguard-panel/`
309
+ - User panel (app.vibeguard.co): dashboard, licenses, machines, billing, settings
310
+ - Admin panel (admin.vibeguard.co): dashboard, users, licenses, payments, audit
311
+ - Shared packages: @vibeguard/ui, @vibeguard/api-client, @vibeguard/config
312
+ - Clerk authentication, TanStack Query, Tailwind CSS
313
+
314
+ ### Sprint 1: Payment Backend ✅ COMPLETE (2026-02-03)
315
+ - Database: webhook_events, payments, admin_audit_log tables
316
+ - PaymentProvider abstraction with StripeProvider
317
+ - Idempotent webhook handling with UNIQUE constraint
318
+ - API v1.1.0 deployed to api-cli-2.vibeguard.co
319
+
320
+ ---
6
321
 
7
322
  ### Option 3A Pro Backend - Server Infrastructure (2026-02-03)
8
323
 
@@ -38,41 +353,25 @@ Deployed initial vibeguard-api infrastructure to `https://api-cli-2.vibeguard.co
38
353
  ### Definition of Done Checklist (per upgrade.md line 375-398)
39
354
 
40
355
  #### Server
41
- - [x] `/healthz` returns 200
42
- - [ ] Stripe webhook creates/updates user, customer, subscription, license
356
+ - [x] `/healthz` returns 200 (enhanced: checks PostgreSQL + Redis, returns healthy/degraded)
357
+ - [x] Stripe webhook creates/updates user, customer, subscription, license (Sprint 1+4)
43
358
  - [x] `/v1/licenses/activate` validates, enforces max activations, returns JWT + entitlements
44
359
  - [x] `/v1/licenses/refresh-token` works
45
- - [x] `/v1/bundles/latest` delivers bundle to entitled clients
46
- - [ ] Revocation path exists (admin script OK for v1)
360
+ - [x] `/v1/bundles/latest` delivers bundle to entitled clients (Sprint 6: ETag/304 support)
361
+ - [x] Revocation path exists (Sprint 5: admin panel revoke license)
362
+ - [x] Rate limiting on all endpoints (Sprint 5+6: Redis sliding window)
47
363
 
48
364
  #### CLI
49
365
  - [x] `vibeguard auth login/status/logout` works
50
366
  - [x] Pro commands (`patch`, `apply`) require entitlement token
51
367
  - [x] Offline grace works (tokens valid until expiry, 7-day TTL)
52
- - [ ] Bundles are fetched and cached; patch prompts read from bundle
368
+ - [x] Bundles are fetched and cached; patch prompts read from bundle (Sprint 6)
53
369
 
54
370
  #### Tests
55
371
  - [x] Unit tests for token store + refresh logic (in test_license.py)
56
- - [ ] Unit tests for bundle cache logic
372
+ - [x] Unit tests for bundle cache logic (36 tests in test_bundles.py, Sprint 6)
57
373
  - [ ] CLI integration tests for auth flow (mock server)
58
374
 
59
- ---
60
-
61
- ### Remaining Work
62
-
63
- **Server:**
64
- 1. Connect Stripe webhooks to real Stripe account
65
- 2. Implement revocation admin script
66
- 3. Add rate limiting with Redis (upgrade.md line 265)
67
-
68
- **CLI:**
69
- 1. Bundle fetching and caching in `~/.vibeguard/bundles/` (upgrade.md line 177)
70
- 2. Patch/fix prompts should read from current bundle with fallback (upgrade.md line 232)
71
-
72
- **Tests:**
73
- 1. Bundle cache logic tests
74
- 2. CLI auth flow integration tests with mock server
75
-
76
375
  **Documentation:**
77
376
  - Test license details moved to `docs/license.md` (not in progress.md per data security)
78
377
 
@@ -1136,11 +1435,32 @@ Addressed the core false positive problem where ~530 of 537 findings were noise.
1136
1435
 
1137
1436
  ---
1138
1437
 
1438
+ ## Known Issues (Post-Auth Fix)
1439
+
1440
+ ### Panel Issues
1441
+ 1. ~~**Admin panel shows empty/zero data**~~ ✅ FIXED — Clerk JWT auth flow repaired (2026-02-06)
1442
+ 2. ~~**"Issue License" button appears non-functional**~~ ✅ FIXED — Same root cause (auth), now resolved
1443
+ 3. **No VibeGuard logo** - Both admin and user panels use a Lucide `Shield` icon + text ("VG Admin" / "VibeGuard") as placeholder branding. Need to add real VibeGuard logo image files and update the layout components.
1444
+ - Admin layout: `apps/admin/src/app/(dashboard)/layout.tsx` lines 36-39
1445
+ - User layout: `apps/user/src/app/(dashboard)/layout.tsx` lines 37-40
1446
+ 4. **Panel changes pending Vercel redeploy** — Frontend auth fixes committed but need push + deploy to take effect
1447
+
1448
+ ### Next Steps
1449
+ - [x] Debug Clerk JWT → API auth flow ✅ Fixed (3 root causes identified and resolved)
1450
+ - [ ] Redeploy panels to Vercel (push panel changes, trigger build)
1451
+ - [ ] End-to-end test: CLI scan → API submission → Panel display
1452
+ - [ ] Panel build verification (`pnpm build`)
1453
+ - [ ] Add real VibeGuard logo to both panels
1454
+
1455
+ ---
1456
+
1139
1457
  ## Next Up (Post-90-Day)
1140
1458
  - [x] v1.0 release preparation
1141
1459
  - [x] Option 3A Pro Backend - CLI Foundation (auth commands, token-based licensing)
1142
- - [ ] Option 3A Pro Backend - Server (FastAPI + Postgres + Redis + Stripe)
1143
- - [ ] Option 3A Pro Backend - Bundle delivery (remote prompts, policy updates)
1460
+ - [x] Option 3A Pro Backend - Server (FastAPI + Postgres + Redis + Stripe)
1461
+ - [x] Option 3A Pro Backend - Bundle delivery (remote prompts, policy updates)
1462
+ - [x] Debug panel auth flow (Clerk JWT → API) ✅ Fixed (2026-02-06)
1463
+ - [ ] Add VibeGuard logo assets to panel
1144
1464
  - [ ] GitHub Marketplace listing for GitHub Action
1145
1465
  - [ ] Additional ecosystem scanners based on user feedback
1146
1466
  - [ ] Correlation/confidence scoring (Team tier)
@@ -1217,6 +1537,8 @@ src/vibeguard/
1217
1537
  │ ├── exit_codes.py # CI-friendly exit codes
1218
1538
  │ ├── keyring.py # Encrypted BYOK key storage
1219
1539
  │ ├── auth.py # Token-based auth (machine ID, cache, API client)
1540
+ │ ├── bundles.py # Bundle fetch, cache, load (server prompts)
1541
+ │ ├── telemetry.py # Fire-and-forget scan metadata submission
1220
1542
  │ ├── license.py # Pro feature gating (token-based)
1221
1543
  │ └── llm.py # LLM provider abstraction (litellm)
1222
1544
  └── reporters/
@@ -1309,7 +1631,9 @@ src/vibeguard/
1309
1631
  - Solo founder project - ship working increments weekly
1310
1632
  - Prefer simplest working solution
1311
1633
  - Tests required for every parser + scoring function
1312
- - All 781 tests passing, ruff clean
1634
+ - All tests passing (800+), ruff clean
1313
1635
  - Self-scan achieves 100/100 (A+) security score
1314
1636
  - **90-day roadmap completed on schedule!**
1315
- - Option 3A Pro Backend - CLI foundation complete, server pending
1637
+ - Pro Backend complete: API v1.6.0 deployed (FastAPI + PostgreSQL + Redis)
1638
+ - Panel system: User dashboard (app.vibeguard.co) + Admin panel (admin.vibeguard.co)
1639
+ - Sprint 6 shipped: Bundle delivery, granular rate limits, scan history, observability
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "vibeguard-cli"
7
- version = "1.0.0"
7
+ version = "1.0.5"
8
8
  description = "Unified security scanner orchestrator for local repos"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -52,11 +52,12 @@ vibeguard = "vibeguard.cli.main:app"
52
52
  packages = ["src/vibeguard"]
53
53
 
54
54
  [tool.ruff]
55
- line-length = 100
55
+ line-length = 120
56
56
  target-version = "py311"
57
57
 
58
58
  [tool.ruff.lint]
59
59
  select = ["E", "F", "I", "N", "W", "UP"]
60
+ ignore = ["UP042"] # str+Enum pattern used throughout; migrate to StrEnum later
60
61
 
61
62
  [tool.mypy]
62
63
  python_version = "3.11"
@@ -1,3 +1,3 @@
1
1
  """VibeGuard CLI - Unified security scanner orchestrator."""
2
2
 
3
- __version__ = "1.0.0"
3
+ __version__ = "1.0.5"