Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ["3.11", "3.12", "3.13"]
python-version: ["3.10", "3.11", "3.12", "3.13"]
steps:
# Pinned to immutable commit SHAs (not @v4 / @v5) so a compromised tag
# cannot silently swap the underlying action code on this CI runner.
Expand Down
10 changes: 8 additions & 2 deletions launcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,18 @@
directly in-process.
"""

import webview

from app import create_app


def main():
try:
import webview
except ImportError:
raise SystemExit(
"pywebview is not installed. Install the [desktop] extra, e.g.\n"
' pip install -e ".[desktop]"'
) from None

app = create_app()
webview.create_window(
"Cursor Chat Browser",
Expand Down
95 changes: 95 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
[build-system]
requires = ["hatchling>=1.21"]
build-backend = "hatchling.build"

[project]
name = "cppa-cursor-browser"
version = "0.1.0"
description = "Flask web application for browsing and exporting Cursor AI chat histories"
readme = "README.md"
license = { file = "LICENSE" }
authors = [{ name = "C++ Alliance", email = "admin@cppalliance.org" }]
requires-python = ">=3.10"

# Runtime dependencies — bounded on both sides so CI resolves deterministically
# and breaking major releases are caught at install time rather than at runtime.
# Upper bounds are conservative: pin to current known-compatible major version.
# See also: requirements.txt (backward-compat alias; pyproject.toml is canonical).
dependencies = [
"flask>=3.0,<4",
"fpdf2>=2.7,<3",
# Security floor: fpdf2 allows Pillow>=8.3.2, so 9.x can still be resolved.
# CVE-2024-28219 (buffer overflow) fixed in Pillow 10.3.0 — https://nvd.nist.gov/vuln/detail/CVE-2024-28219
"pillow>=10.3.0",
]
Comment thread
coderabbitai[bot] marked this conversation as resolved.

[project.optional-dependencies]
# Desktop launcher (pywebview pulls in heavy system libs — GTK/Qt on Linux —
# so it is intentionally excluded from the web-server and CI installs).
desktop = ["pywebview>=5.0,<6"]

# Development tooling: testing + type checking.
dev = [
"pytest>=8,<9",
"mypy>=1.10,<2",
]

[project.scripts]
# Primary CLI: export Cursor chat histories to Markdown / zip.
# Usage: cursor-chat-export [--since all|last] [--out DIR] [--no-zip] [--help]
cursor-chat-export = "scripts.export:main"

# Desktop launcher (requires the [desktop] extra to be installed).
cursor-chat-browser = "launcher:main"
Comment thread
bradjin8 marked this conversation as resolved.

[project.urls]
Repository = "https://github.com/cppalliance/cppa-cursor-browser"
Issues = "https://github.com/cppalliance/cppa-cursor-browser/issues"

# ── Build configuration ────────────────────────────────────────────────────────
# Flat layout (no src/ directory): enumerate every importable package and the
# two top-level application modules so the installed wheel has the same import
# surface as the repo checkout.
[tool.hatch.build.targets.wheel]
include = [
"api/",
"models/",
"scripts/",
"services/",
"utils/",
"templates/",
"static/",
"app.py",
"launcher.py",
]
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Comment thread
bradjin8 marked this conversation as resolved.

# sdist includes tests + ancillary files; wheel is runtime-only.
[tool.hatch.build.targets.sdist]
include = [
"api/",
"models/",
"scripts/",
"services/",
"utils/",
"tests/",
"templates/",
"static/",
"app.py",
"launcher.py",
"requirements.txt",
"README.md",
"LICENSE",
"cursor-browser.spec",
]

# ── Mypy ──────────────────────────────────────────────────────────────────────
# Mirrors the flags used in .github/workflows/tests.yml so local `mypy .`
# and CI produce identical results.
[tool.mypy]
ignore_missing_imports = true
no_strict_optional = true
pretty = true
# Exclude virtual-env and build artefact directories so that `mypy .` from the
# repo root matches CI behaviour (CI runs in a clean runner without a local venv).
# Anchored regexes — unanchored `venv/` would match any path segment containing "venv/".
exclude = ["^venv/", "^\\.venv/", "^build/", "^dist/"]
13 changes: 10 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
flask>=3.0
fpdf2>=2.7
pywebview>=5.0
# Backward-compatibility shim — mirrors [project.dependencies] in pyproject.toml.
# Keep version specifiers in sync when runtime deps change.
#
# Prefer: pip install -e . (installs the package + runtime deps)
# pip install -e ".[dev]" (+ pytest and mypy)
# pip install -e ".[desktop]" (+ pywebview for the GUI launcher)
flask>=3.0,<4
fpdf2>=2.7,<3
pillow>=10.3.0
# pywebview is desktop-only — install with: pip install -e ".[desktop]"
Loading