vibeguard-cli 1.0.4__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.
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/CLAUDE.md +6 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/PKG-INFO +1 -1
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/docs/progress.md +53 -14
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/pyproject.toml +1 -1
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/__init__.py +1 -1
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/bootstrap.py +16 -2
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/downloader.py +11 -1
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/__init__.py +4 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/trivy.toml +14 -4
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/local.py +26 -1
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/.github/workflows/publish.yml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/.github/workflows/vibeguard.yml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/.gitignore +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/.vibeguardignore +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/CHANGELOG.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/LICENSE +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/README.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/action.yml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/docs/CI_INTEGRATION.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/docs/CONTRIBUTING_SCANNERS.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/docs/context.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/docs/license.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/docs/plan.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/docs/upgrade.md +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/apply.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/auth_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/banners.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/baseline_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/config_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/display.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/doctor.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/fix.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/import_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/init_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/keys.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/live_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/main.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/patch.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/report.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/cli/scan.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/auth.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/baseline.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/bundles.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/cache.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/config.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/dedup.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/example_detector.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/exit_codes.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/ignore.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/keyring.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/license.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/llm.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/path_classifier.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/repo_detector.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/sarif_import.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/telemetry.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/triage.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/url_validator.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/core/validate.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/models/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/models/auth.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/models/baseline.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/models/finding.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/models/patch.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/models/scan_result.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/models/triage.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/badge.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/html.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/reporters/sarif.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/bandit.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/cargo_audit.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/checkov.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/dockle.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/gitleaks.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/npm_audit.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/nuclei.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/pip_audit.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/semgrep.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/trufflehog.toml +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/bandit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/cargo_audit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/checkov.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/dockle.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/gitleaks.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/npm_audit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/nuclei.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/pip_audit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/semgrep.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/trivy.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/parsers/trufflehog.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/base.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/runners/docker.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/conftest.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_apply_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_banners.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_baseline.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_baseline_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_bootstrap.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_bundles.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_cache.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_checkov_parser.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_ci_mode.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_cli.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_dedup.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_dockle_parser.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_exit_codes.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_fix_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_keyring.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_keys_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_license.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_live_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_llm.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_models.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_nuclei_parser.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_bandit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_cargo_audit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_gitleaks.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_npm_audit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_pip_audit.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_semgrep.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_trivy.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_parsers/test_trufflehog.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_patch_cmd.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_patch_model.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_repo_detector.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_reporters/__init__.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_reporters/test_badge.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_reporters/test_html.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_reporters/test_sarif.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_sarif_import.py +0 -0
- {vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/tests/test_url_validator.py +0 -0
|
@@ -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
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# VibeGuard CLI - Development Progress
|
|
2
2
|
|
|
3
3
|
## Current Status
|
|
4
|
-
**Phase**: Post-Sprint 6 —
|
|
4
|
+
**Phase**: Post-Sprint 6 — v1.0.5 Scanner Auto-Download + pipx Fix
|
|
5
5
|
**Last Updated**: 2026-02-06
|
|
6
6
|
|
|
7
7
|
---
|
|
@@ -51,25 +51,64 @@ Full implementation log: `vibeguard-panel/docs/panelplan-implementation.md`
|
|
|
51
51
|
|
|
52
52
|
**Status**: Backend deployed. Panel changes need Vercel redeploy.
|
|
53
53
|
|
|
54
|
-
###
|
|
54
|
+
### v1.0.5: Scanner Auto-Download + pipx Fix (2026-02-06)
|
|
55
55
|
|
|
56
|
-
-
|
|
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/
|
|
57
85
|
- [x] Install: `pip install vibeguard-cli`
|
|
58
86
|
- [x] Both wheel (.whl) and sdist (.tar.gz) uploaded
|
|
59
|
-
- [x] Manual upload via twine (
|
|
60
|
-
- [x]
|
|
61
|
-
-
|
|
62
|
-
-
|
|
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
|
|
63
96
|
- `id-token: write` permission scoped to publish jobs only
|
|
64
97
|
- Triggers on: git tag push (`v*.*.*`) or manual workflow dispatch
|
|
65
98
|
- TestPyPI option via workflow dispatch toggle
|
|
66
|
-
- GitHub Release auto-created
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
**
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
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
|
+
```
|
|
73
112
|
|
|
74
113
|
---
|
|
75
114
|
|
|
@@ -6,6 +6,7 @@ import subprocess # nosec B404 # noqa: S404 # needed for pip install
|
|
|
6
6
|
import sys
|
|
7
7
|
from dataclasses import dataclass
|
|
8
8
|
from enum import Enum
|
|
9
|
+
from pathlib import Path
|
|
9
10
|
|
|
10
11
|
from vibeguard.core.downloader import DownloadConfig, download_binary, get_cached_binary
|
|
11
12
|
from vibeguard.scanners import ScannerManifest, load_manifest
|
|
@@ -68,8 +69,19 @@ class BootstrapSummary:
|
|
|
68
69
|
|
|
69
70
|
|
|
70
71
|
def _is_binary_available(binary_name: str) -> bool:
|
|
71
|
-
"""Check if a binary is available in PATH."""
|
|
72
|
-
|
|
72
|
+
"""Check if a binary is available in PATH or the current venv's bin directory."""
|
|
73
|
+
if shutil.which(binary_name) is not None:
|
|
74
|
+
return True
|
|
75
|
+
|
|
76
|
+
# Check current Python environment's bin directory (handles pipx installs)
|
|
77
|
+
prefix = Path(sys.prefix)
|
|
78
|
+
bin_dir = prefix / ("Scripts" if sys.platform == "win32" else "bin")
|
|
79
|
+
if bin_dir.is_dir():
|
|
80
|
+
for ext in ("", ".exe"):
|
|
81
|
+
if (bin_dir / f"{binary_name}{ext}").is_file():
|
|
82
|
+
return True
|
|
83
|
+
|
|
84
|
+
return False
|
|
73
85
|
|
|
74
86
|
|
|
75
87
|
def _is_docker_available() -> bool:
|
|
@@ -102,6 +114,8 @@ async def _try_download(manifest: ScannerManifest) -> bool:
|
|
|
102
114
|
archive_type=manifest.download_config.archive_type,
|
|
103
115
|
windows_archive_type=manifest.download_config.windows_archive_type,
|
|
104
116
|
windows_arch=manifest.download_config.windows_arch,
|
|
117
|
+
os_map=manifest.download_config.os_map,
|
|
118
|
+
arch_map=manifest.download_config.arch_map,
|
|
105
119
|
)
|
|
106
120
|
|
|
107
121
|
binary_path = await download_binary(dl_config)
|
|
@@ -82,6 +82,8 @@ class DownloadConfig(BaseModel):
|
|
|
82
82
|
archive_type: str = "tar.gz"
|
|
83
83
|
windows_archive_type: str | None = None # Override for Windows
|
|
84
84
|
windows_arch: str | None = None # Override arch for Windows (e.g., "x64" instead of "amd64")
|
|
85
|
+
os_map: dict[str, str] | None = None # Custom OS name mapping (e.g., {"darwin": "macOS"})
|
|
86
|
+
arch_map: dict[str, str] | None = None # Custom arch name mapping (e.g., {"amd64": "64bit"})
|
|
85
87
|
|
|
86
88
|
|
|
87
89
|
class PlatformInfo(NamedTuple):
|
|
@@ -148,6 +150,14 @@ async def download_binary(config: DownloadConfig) -> Path | None:
|
|
|
148
150
|
# Determine archive type and arch (Windows may use different values)
|
|
149
151
|
archive_type = config.archive_type
|
|
150
152
|
arch = platform_info.arch
|
|
153
|
+
os_name = platform_info.os
|
|
154
|
+
|
|
155
|
+
# Apply custom OS/arch mappings if provided (e.g., Trivy uses "macOS" not "darwin")
|
|
156
|
+
if config.os_map:
|
|
157
|
+
os_name = config.os_map.get(os_name, os_name)
|
|
158
|
+
if config.arch_map:
|
|
159
|
+
arch = config.arch_map.get(arch, arch)
|
|
160
|
+
|
|
151
161
|
if platform_info.os == "windows":
|
|
152
162
|
if config.windows_archive_type:
|
|
153
163
|
archive_type = config.windows_archive_type
|
|
@@ -157,7 +167,7 @@ async def download_binary(config: DownloadConfig) -> Path | None:
|
|
|
157
167
|
# Build download URL
|
|
158
168
|
url = config.url_template.format(
|
|
159
169
|
version=config.version,
|
|
160
|
-
os=
|
|
170
|
+
os=os_name,
|
|
161
171
|
arch=arch,
|
|
162
172
|
)
|
|
163
173
|
# Handle Windows archive type in URL if different from default
|
|
@@ -24,6 +24,8 @@ class DownloadConfig(BaseModel):
|
|
|
24
24
|
archive_type: str = "tar.gz"
|
|
25
25
|
windows_archive_type: str | None = None # Override for Windows
|
|
26
26
|
windows_arch: str | None = None # Override arch for Windows (e.g., "x64")
|
|
27
|
+
os_map: dict[str, str] | None = None # Custom OS name mapping (e.g., darwin → macOS)
|
|
28
|
+
arch_map: dict[str, str] | None = None # Custom arch name mapping (e.g., amd64 → 64bit)
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class PipConfig(BaseModel):
|
|
@@ -89,6 +91,8 @@ def load_manifest(name: str) -> ScannerManifest:
|
|
|
89
91
|
archive_type=download_data.get("archive_type", "tar.gz"),
|
|
90
92
|
windows_archive_type=download_data.get("windows_archive_type"),
|
|
91
93
|
windows_arch=download_data.get("windows_arch"),
|
|
94
|
+
os_map=download_data.get("os_map"),
|
|
95
|
+
arch_map=download_data.get("arch_map"),
|
|
92
96
|
)
|
|
93
97
|
|
|
94
98
|
# Parse pip config if present
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
[scanner]
|
|
5
5
|
name = "trivy"
|
|
6
6
|
display_name = "Trivy"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.69.1"
|
|
8
8
|
tier = "core"
|
|
9
9
|
categories = ["vulnerability", "sca"]
|
|
10
10
|
languages = ["*"]
|
|
@@ -20,13 +20,23 @@ binary_name = "trivy"
|
|
|
20
20
|
|
|
21
21
|
[install.download]
|
|
22
22
|
# Auto-download binary from GitHub releases
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
url_template = "https://github.com/aquasecurity/trivy/releases/download/v{version}/trivy_{version}_{os}-
|
|
23
|
+
# Trivy naming: trivy_{version}_{os}-{arch}.tar.gz
|
|
24
|
+
# e.g., trivy_0.69.1_macOS-ARM64.tar.gz, trivy_0.69.1_Linux-64bit.tar.gz
|
|
25
|
+
url_template = "https://github.com/aquasecurity/trivy/releases/download/v{version}/trivy_{version}_{os}-{arch}.tar.gz"
|
|
26
26
|
binary_name = "trivy"
|
|
27
27
|
archive_type = "tar.gz"
|
|
28
28
|
windows_archive_type = "zip"
|
|
29
29
|
|
|
30
|
+
# Trivy uses non-standard platform names
|
|
31
|
+
[install.download.os_map]
|
|
32
|
+
linux = "Linux"
|
|
33
|
+
darwin = "macOS"
|
|
34
|
+
windows = "windows"
|
|
35
|
+
|
|
36
|
+
[install.download.arch_map]
|
|
37
|
+
amd64 = "64bit"
|
|
38
|
+
arm64 = "ARM64"
|
|
39
|
+
|
|
30
40
|
[install.docker]
|
|
31
41
|
image = "aquasec/trivy:latest"
|
|
32
42
|
mount_mode = "ro"
|
|
@@ -10,6 +10,22 @@ from vibeguard.core.downloader import VIBEGUARD_BIN_DIR
|
|
|
10
10
|
from vibeguard.scanners.runners.base import BaseRunner, RunResult
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
def _get_venv_bin_dir() -> Path | None:
|
|
14
|
+
"""Get the bin/Scripts directory of the current Python environment.
|
|
15
|
+
|
|
16
|
+
This handles pipx installs where pip-installed tools end up in the
|
|
17
|
+
isolated venv's bin directory, not on the system PATH.
|
|
18
|
+
"""
|
|
19
|
+
prefix = Path(sys.prefix)
|
|
20
|
+
if sys.platform == "win32":
|
|
21
|
+
bin_dir = prefix / "Scripts"
|
|
22
|
+
else:
|
|
23
|
+
bin_dir = prefix / "bin"
|
|
24
|
+
if bin_dir.is_dir():
|
|
25
|
+
return bin_dir
|
|
26
|
+
return None
|
|
27
|
+
|
|
28
|
+
|
|
13
29
|
class LocalRunner(BaseRunner):
|
|
14
30
|
"""Run scanners using locally installed binaries."""
|
|
15
31
|
|
|
@@ -29,12 +45,21 @@ class LocalRunner(BaseRunner):
|
|
|
29
45
|
return "local"
|
|
30
46
|
|
|
31
47
|
def is_available(self) -> bool:
|
|
32
|
-
"""Check if binary is available in PATH or downloaded cache."""
|
|
48
|
+
"""Check if binary is available in PATH, venv bin, or downloaded cache."""
|
|
33
49
|
# First check system PATH
|
|
34
50
|
self._binary_path = shutil.which(self.binary_name)
|
|
35
51
|
if self._binary_path:
|
|
36
52
|
return True
|
|
37
53
|
|
|
54
|
+
# Check current Python environment's bin directory (handles pipx installs)
|
|
55
|
+
venv_bin = _get_venv_bin_dir()
|
|
56
|
+
if venv_bin:
|
|
57
|
+
for ext in ("", ".exe"):
|
|
58
|
+
candidate = venv_bin / f"{self.binary_name}{ext}"
|
|
59
|
+
if candidate.is_file():
|
|
60
|
+
self._binary_path = str(candidate)
|
|
61
|
+
return True
|
|
62
|
+
|
|
38
63
|
# Check downloaded binaries in ~/.vibeguard/bin/
|
|
39
64
|
if self.version:
|
|
40
65
|
downloaded = self._find_downloaded_binary()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/cargo_audit.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vibeguard_cli-1.0.4 → vibeguard_cli-1.0.5}/src/vibeguard/scanners/manifests/trufflehog.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|