Skip to content
This repository was archived by the owner on Aug 22, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
516e1a1
Merge remote-tracking branch 'origin/main' into development
j-kemble Mar 20, 2026
0f951f8
Add vault explorer filtering by service/username
j-kemble Mar 20, 2026
7eb4951
Add vault credential editing support
j-kemble Mar 20, 2026
5ae8ae8
Add s hotkey for saving generated credentials
j-kemble Mar 20, 2026
ccc29da
Add live slash-based vault quick search
j-kemble Mar 20, 2026
01cfa94
Require double Esc to quit application
j-kemble Mar 20, 2026
6eeefdd
Adjust README vault paths
j-kemble Mar 20, 2026
b101562
Add duplicate-safe save flow for credentials
j-kemble Mar 20, 2026
d3326df
Add configurable security settings for clipboard and vault
j-kemble Mar 20, 2026
968293b
Add note field to credentials
j-kemble Mar 20, 2026
42fe1d7
Update WARP.md with note field support
j-kemble Mar 20, 2026
5cd4217
Update workflows to include development branch
j-kemble Mar 20, 2026
9a5f394
Update Python version requirements to include 3.14
j-kemble Mar 20, 2026
0f0fca7
Fix failing test_parse_import_row_bitwarden_type_handling
j-kemble Mar 20, 2026
f847571
Add hidden note feature with encryption and hotkeys
j-kemble Mar 20, 2026
717285c
Add comprehensive security suite: Bandit, pip-audit, mypy, pre-commit…
j-kemble Mar 20, 2026
77935b8
Fix CI failures: relax mypy settings and fix security tests
j-kemble Mar 20, 2026
535707b
Update README with banner, badges, security section, and dev docs
j-kemble Mar 20, 2026
3b55c2e
Add banner image and update README path
j-kemble Mar 20, 2026
eddd0a0
Fix auto-lock vault unlock bug and add regression test
j-kemble Mar 20, 2026
289fd13
Fix hotkey UI wrapping and cramped layout
j-kemble Mar 20, 2026
ded7f1d
refactor: add Credential dataclass in models.py
j-kemble Jul 10, 2026
2a05a9f
refactor: extract pure helpers into tui_helpers.py
j-kemble Jul 10, 2026
0bad010
refactor: extract modal input dialogs into tui_modal.py
j-kemble Jul 10, 2026
203aec5
refactor: extract presentation/render layer into tui_render.py
j-kemble Jul 10, 2026
8c1b9c8
refactor: extract vault/security input into tui_security.py
j-kemble Jul 10, 2026
97c7e2d
refactor: relocate flat AppState into tui_state.py
j-kemble Jul 10, 2026
3a47260
refactor: extract file/import-export helpers into tui_files.py
j-kemble Jul 10, 2026
35a46f6
refactor: extract CSV export/import logic into tui_csv.py
j-kemble Jul 10, 2026
5c7ef6d
refactor: extract top-level action handlers into tui_flow.py
j-kemble Jul 10, 2026
a5f667c
test: add curses smoke test for TUI entrypoint
j-kemble Jul 10, 2026
c67aa99
perf: Phase 1 quick wins (generator + storage)
j-kemble Jul 10, 2026
2f20e89
security: harden PBKDF2 (480k iters, 32-byte salt), persist params fo…
j-kemble Jul 10, 2026
a4b12dd
refactor: remove redundant _require_unlocked() call in list_credentials
j-kemble Jul 10, 2026
cb47e2d
test: cover Phase 1/2 with edge cases (lru_cache, dedupe, persistence…
j-kemble Jul 10, 2026
d78ffcd
perf: cache TUI modal windows and search results
j-kemble Jul 10, 2026
faf63bf
perf: avoid blocking details-modal feedback
j-kemble Jul 10, 2026
eb4b219
perf: cache dashboard focus items
j-kemble Jul 10, 2026
8579507
perf: share secure word sampling
j-kemble Jul 10, 2026
9c51800
perf: normalize CSV headers once
j-kemble Jul 10, 2026
a7e1b6d
fix: prevent vault reinitialization
j-kemble Jul 10, 2026
1f71352
feat: support storage context management
j-kemble Jul 11, 2026
a5e76f0
refactor: centralize credential decryption
j-kemble Jul 11, 2026
2ddd69e
perf: wait briefly for SQLite locks
j-kemble Jul 11, 2026
e8b1c2d
perf: bound passphrase dedupe set with LRU eviction
j-kemble Jul 11, 2026
19dcbf1
refactor: remove dead seen_usernames and unused imports
j-kemble Jul 11, 2026
f2d6383
refactor: centralize credential encryption
j-kemble Jul 11, 2026
c3d6ebd
refactor: narrow storage exception handling
j-kemble Jul 11, 2026
f1154c8
feat: add rotating file logging module
j-kemble Jul 11, 2026
47c7523
feat: wire logging into StorageManager lifecycle
j-kemble Jul 11, 2026
8674210
feat: log CSV I/O from TUI
j-kemble Jul 11, 2026
eea8e3d
perf: skip dashboard redraw on idle frames
j-kemble Jul 11, 2026
325f523
refactor: narrow TUI exception handling
j-kemble Jul 11, 2026
1fb11f5
test: fix probabilistic flakes and add generator edge-case coverage
j-kemble Jul 11, 2026
ae05028
test: add storage error-path and branch coverage
j-kemble Jul 11, 2026
0143978
test: add end-to-end credential lifecycle integration test
j-kemble Jul 11, 2026
2a7db37
test: add security regression test structure
j-kemble Jul 11, 2026
568a14c
fix: remove implicit cwd wordlist override
j-kemble Jul 11, 2026
2211eeb
fix: mask password entry in username save flow
j-kemble Jul 11, 2026
0a53302
fix: enforce master password policy in storage
j-kemble Jul 11, 2026
2e67127
fix: enforce custom wordlist entropy floor
j-kemble Jul 11, 2026
602c244
fix: mask stored passwords in vault views
j-kemble Jul 11, 2026
df8da7d
fix: enforce private vault file permissions
j-kemble Jul 11, 2026
fe58266
fix: revoke copied secrets on vault lock
j-kemble Jul 11, 2026
17bc82c
fix: create csv exports atomically and privately
j-kemble Jul 11, 2026
f0a2e4b
fix: use secure clipboard and auto-lock defaults
j-kemble Jul 11, 2026
6476343
fix: sanitize untrusted text before curses rendering
j-kemble Jul 11, 2026
a4d5af2
fix: bound and atomically import csv credentials
j-kemble Jul 11, 2026
c67d981
docs: warn about spreadsheet handling of csv exports
j-kemble Jul 11, 2026
861214e
fix: guard modal geometry on small terminals
j-kemble Jul 11, 2026
0415b16
fix: validate persisted kdf parameters strictly
j-kemble Jul 11, 2026
d3f4724
docs: specify versioned vault format migration
j-kemble Jul 11, 2026
01d2ec9
refactor: decrypt vault secrets only on demand
j-kemble Jul 11, 2026
385afa4
ci: enforce blocking security gates
j-kemble Jul 11, 2026
5978793
build: constrain audited ci and release dependencies
j-kemble Jul 11, 2026
3a115d0
docs: align security claims with implementation
j-kemble Jul 11, 2026
a058a56
ci: secure pypi publishing with oidc
j-kemble Jul 11, 2026
85b3c80
docs: add security acceptance matrix
j-kemble Jul 11, 2026
3e84970
feat: implement vault v2 with Argon2id, KEK/DEK, and AEAD
j-kemble Jul 11, 2026
a3711e4
docs: add gemini workflow security design and read-only analysis
j-kemble Jul 11, 2026
3a75570
build: add hash-locked ci and release constraint files
j-kemble Jul 11, 2026
ef2634b
docs: add review-to-commit mapping, remove stale review files
j-kemble Jul 11, 2026
ad6c2c4
docs: fix stale review-file references in vault v2 spec
j-kemble Jul 11, 2026
b84e4be
ci: repair immutable publish action pins
j-kemble Jul 11, 2026
2e1afb7
ci: enforce locked release security gates
j-kemble Jul 11, 2026
ad91627
fix: keep logs private and metadata free
j-kemble Jul 11, 2026
552583e
fix: sanitize all modal rendering
j-kemble Jul 11, 2026
979f684
fix: clear plaintext ui state promptly
j-kemble Jul 11, 2026
2697654
ci: repair immutable publish action pins, enforce locked gates
j-kemble Jul 11, 2026
a7fa5a9
build: pin contributor hooks immutably
j-kemble Jul 11, 2026
03d857e
fix: secure export and migration file creation
j-kemble Jul 11, 2026
26e7edc
fix: bound all csv import rows
j-kemble Jul 11, 2026
441949d
fix: validate vault v2 configuration strictly
j-kemble Jul 11, 2026
6031c59
feat: bind vault v2 secrets to credential metadata
j-kemble Jul 11, 2026
581722e
feat: make hardened vault v2 the default
j-kemble Jul 11, 2026
f75398c
feat: add spreadsheet-safe csv export
j-kemble Jul 11, 2026
602cc36
docs: reconcile security controls with implementation
j-kemble Jul 11, 2026
093518d
docs: map round 2 findings to commits in review-commit.md
j-kemble Jul 11, 2026
bb214d0
fix: remediate all 10 security findings (F-015–F-024)
j-kemble Jul 12, 2026
9782380
chore: add .hermes/ to gitignore
j-kemble Jul 12, 2026
81a77c8
fix: resolve all 7 bandit false positives (0 issues remaining)
j-kemble Jul 12, 2026
73b0090
fix: resolve CI dependency installation failures
j-kemble Jul 12, 2026
73869ba
fix: pin missing transitive deps for CI hash-locked constraints
j-kemble Jul 12, 2026
7ba408c
fix: pin wheel==0.45.1 in release.txt for package build validation
j-kemble Jul 12, 2026
056c396
docs: fix banner link, wordlist stats, and CSV escape docs in README
j-kemble Jul 12, 2026
cb8c18b
docs: rename WARP.md to AGENTS.md for multi-agent framework use
j-kemble Jul 12, 2026
23d3de6
docs: update AGENTS.md intro and refresh report references after rename
j-kemble Jul 12, 2026
17c0bdf
ci: restore Windows test matrix with hashed lockfile
j-kemble Jul 12, 2026
11e14b7
fix(ci): make Windows lockfile Python 3.10 compatible
j-kemble Jul 12, 2026
d6ded4d
docs: mark Windows CI setup complete
j-kemble Jul 12, 2026
d5f572c
docs: correct Windows lockfile counts
j-kemble Jul 12, 2026
99d388e
docs: enable Windows virtualenv activation
j-kemble Jul 12, 2026
f48d4c3
fix: improve master password policy, UI, and entropy rendering
j-kemble Jul 14, 2026
5b232e2
fix: exact entropy bar scaling and clean modal cleanup
j-kemble Jul 14, 2026
05ce01b
fix: proportional entropy bars, wordlist diversity, hotkeys layout
j-kemble Jul 14, 2026
2a6c8e8
Improve vault unlock and AAD migration flow
j-kemble Aug 7, 2026
2c9ea8e
feat: implement development branch improvements (phases 1-6)
j-kemble Aug 12, 2026
bd9dd1a
fix(security): update cryptography to 50.0.0 in constraints
j-kemble Aug 12, 2026
7a2c82e
fix(ci): add exceptiongroup and setuptools>=83.0.0 to constraint lock…
j-kemble Aug 12, 2026
ff34e94
fix(ci): add SecretStorage to release constraints
j-kemble Aug 12, 2026
f13bc83
fix(ci): pin setuptools with hashes in constraints for package valida…
j-kemble Aug 12, 2026
7b40025
fix(security): phase1 Round 3 remediation — AAD v4 migration decoupli…
j-kemble Aug 16, 2026
ffe1a83
chore(version): bump to 0.2.3 (0.2.2 consumed by March 2026 productio…
j-kemble Aug 16, 2026
ad458f1
fix(logging): support Windows log file setup
j-kemble Aug 16, 2026
9c9f2e6
fix(security): phase1 Round 3 remediation — AAD v4 migration decoupli…
j-kemble Aug 16, 2026
558c5de
fix(ci): enforce main-only publish policy in publish.yml
j-kemble Aug 16, 2026
e13721a
fix(ci): enforce main-only publish policy in publish.yml (#2)
j-kemble Aug 16, 2026
fe8e532
chore: consolidate remediation stack with development security model …
j-kemble Aug 16, 2026
3e296a7
fix(tui): resolve PR #3 review findings — constant sync, username-mod…
j-kemble Aug 17, 2026
4062f58
fix(security): complete hardening 0.2.4 — persistent lockout, Argon2 …
j-kemble Aug 21, 2026
871a37a
fix(security): address PR #5 review — wordlist TOCTOU, lockout clock …
j-kemble Aug 21, 2026
f585c71
fix(ci): resolve PR #5 check failures — trailing whitespace, mypy, wi…
j-kemble Aug 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Dependabot configuration for automated dependency updates
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates

version: 2
updates:
# Enable version updates for Python packages
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 10
reviewers:
- "j-kemble"
assignees:
- "j-kemble"
# Labels for pull requests
labels:
- "dependencies"
- "python"
# Group related updates together
groups:
dev-dependencies:
patterns:
- "pytest*"
- "bandit*"
- "mypy*"
- "pre-commit*"
- "pip-audit*"
production-dependencies:
patterns:
- "cryptography*"
- "platformdirs*"
- "pyperclip*"
commit-message:
prefix: "deps"
include: "scope"
# Security updates are handled separately by Dependabot alerts

# Enable version updates for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
open-pull-requests-limit: 5
labels:
- "dependencies"
- "github-actions"
commit-message:
prefix: "ci"
include: "scope"
36 changes: 0 additions & 36 deletions .github/workflows/ci.yml

This file was deleted.

80 changes: 70 additions & 10 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,90 @@ on:
tags:
- "v*"

permissions:
contents: read

jobs:
build:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
persist-credentials: false
fetch-depth: 0

- name: Validate tag is on main (production publish branch)
run: |
if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
echo "Tag ${GITHUB_REF} points to a commit not reachable from main."
echo "PyPI publishes only from main. Refusing to continue."
exit 1
fi
echo "Tag is reachable from main: ${GITHUB_REF}"

- name: Validate tag matches project version
run: |
TAG_VERSION="${GITHUB_REF#refs/tags/v}"
PROJECT_VERSION=$(grep '^version' pyproject.toml | head -1 | sed 's/.*= *"\(.*\)"/\1/')
if [ "$TAG_VERSION" != "$PROJECT_VERSION" ]; then
echo "Tag version ($TAG_VERSION) does not match pyproject.toml version ($PROJECT_VERSION)"
exit 1
fi
echo "Version validated: $TAG_VERSION"

test:
needs: validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
persist-credentials: false

- name: Set up Python
uses: actions/setup-python@v6
- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
with:
python-version: "3.12"

- name: Install dependencies
run: |
python -m pip install --require-hashes -r constraints/ci.txt
python -m pip install --no-deps -e .

- name: Run tests
run: pytest -p no:cacheprovider -q

- name: Security scan
run: bandit -c pyproject.toml -r generate_it/ -ll

- name: Dependency vulnerability scan
run: pip-audit

build-and-publish:
needs: test
runs-on: ubuntu-latest
environment: pypi
permissions:
contents: read
id-token: write # Required for OIDC trusted publishing

steps:
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332
with:
persist-credentials: false

- uses: actions/setup-python@f677139bbe7f9c59b41e40162b753c062f5d49a3 # v5.2.0
with:
python-version: "3.12"

- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install build twine
python -m pip install --require-hashes -r constraints/release.txt
python -m pip install --no-deps -e .

- name: Build distribution
run: python -m build
run: python -m build --no-isolation

- name: Check distribution
run: twine check dist/*

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0 # v1.9.0
184 changes: 184 additions & 0 deletions .github/workflows/security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
name: Security & Quality

on:
push:
branches: [main, development]
pull_request:
branches: [main, development]

# Least-privilege: read-only access to repository contents.
# No write access to issues, PRs, deployments, or other resources.
permissions:
contents: read

jobs:
# Security linting with Bandit (BLOCKING: fails CI on low+ severity findings).
# Uses pyproject.toml for bandit configuration; -ll gates at LOW severity and above.
bandit:
name: Security linting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --require-hashes -r constraints/ci.txt
python -m pip install --no-deps -e .
- name: Run Bandit security scan (blocking)
run: bandit -c pyproject.toml -r generate_it/ -ll
- name: Generate Bandit JSON report
if: always()
run: bandit -c pyproject.toml -r generate_it/ -f json -o bandit-report.json -ll
- name: Upload Bandit report
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
if: always()
with:
name: bandit-report
path: bandit-report.json
if-no-files-found: ignore

# Dependency vulnerability scanning with pip-audit (BLOCKING: fails CI on any vulnerability).
pip-audit:
name: Dependency vulnerability scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --require-hashes -r constraints/ci.txt
python -m pip install --no-deps -e .
- name: Run pip-audit
run: pip-audit --format=json --output=pip-audit-report.json
- name: Display pip-audit report
if: always()
run: pip-audit

# Secrets detection with TruffleHog (BLOCKING: fails CI on verified secrets).
#
# POLICY: This scan runs with --only-verified, meaning only secrets that TruffleHog
# can confirm as valid (by attempting authentication against the provider) will cause
# a CI failure. Unverified matches (heuristic-only) are suppressed. This balances
# security with signal-to-noise: verified secrets are a real breach and must block
# the pipeline; unverified matches are informational and can be reviewed in the job
# log without blocking merges. To audit for unverified findings, re-run locally:
# trufflehog git file://. --since-commit=main --no-verification
# and review the results manually as part of the pre-commit or PR review process.
secrets-scan:
name: Secrets detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
fetch-depth: 0
persist-credentials: false
- name: Run TruffleHog secret scanner
uses: trufflesecurity/trufflehog@27b0417c16317ca9a472a9a8092acce143b49c55 # v3.95.9
with:
path: ./
base: main
head: HEAD
extra_args: --only-verified

# Static type checking with mypy (blocking).
typecheck:
name: Static type check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
fetch-depth: 0
persist-credentials: false
- name: Check for trailing whitespace violations
run: |
if [ "${{ github.event_name }}" = "pull_request" ]; then
git diff --check "${{ github.event.pull_request.base.sha }}...${{ github.sha }}"
elif [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then
git diff --check "$(git hash-object -t tree /dev/null)..${{ github.sha }}"
else
git diff --check "${{ github.event.before }}...${{ github.sha }}"
fi
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install dependencies
run: |
python -m pip install --require-hashes -r constraints/ci.txt
python -m pip install --no-deps -e .
- name: Run mypy type checker
run: mypy generate_it

# Test suite with pytest.
test:
name: Test suite
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.10", "3.12", "3.13"]
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: ${{ matrix.python-version }}
- name: Install Unix dependencies
if: matrix.os != 'windows-latest'
run: python -m pip install --require-hashes -r constraints/ci.txt
- name: Install Windows dependencies
if: matrix.os == 'windows-latest'
run: python -m pip install --require-hashes -r constraints/ci-windows.txt
- name: Install package
run: python -m pip install --no-deps -e .
- name: Run tests
run: pytest tests/ -v --cov=generate_it --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@b9fd7d16f6d7d1b5d2bec1a2887e65ceed900238 # v4.6.0
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.12'
with:
file: ./coverage.xml
fail_ci_if_error: false

# Package build and validation.
build:
name: Package validation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5
with:
persist-credentials: false
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
with:
python-version: "3.12"
- name: Install build tools
run: |
python -m pip install --require-hashes -r constraints/release.txt
python -m pip install --no-deps -e .
- name: Build package
run: |
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct) python -m build --no-isolation
- name: Validate package
run: |
python -m twine check dist/*
- name: Smoke-test built wheel
run: |
python -m venv /tmp/generate-it-wheel-smoke
/tmp/generate-it-wheel-smoke/bin/python -m pip install --require-hashes -r constraints/ci.txt
/tmp/generate-it-wheel-smoke/bin/python -m pip install --no-deps dist/*.whl
cd /tmp
/tmp/generate-it-wheel-smoke/bin/python -c "import generate_it, generate_it.storage, generate_it.tui, generate_it.__main__; from importlib.resources import files; path = str(files('generate_it').joinpath('wordlist.txt')); assert 'site-packages' in generate_it.__file__; assert path.endswith('wordlist.txt'); print(generate_it.__file__)"
- name: Upload build artifacts
uses: actions/upload-artifact@b4b15b8c7c6ac21ea08fcf65892d2ee8f75cf882 # v4.4.3
with:
name: dist
path: dist/
Loading
Loading