jgilfelt/chuck
An in-app HTTP inspector for Android OkHttp clients
Stale — last commit 4y ago
weakest axislast commit was 4y ago; no tests detected…
no tests detected; no CI workflows detected…
Documented and popular — useful reference codebase to read through.
last commit was 4y ago; no CI workflows detected
- ✓6 active contributors
- ✓Apache-2.0 licensed
- ⚠Stale — last commit 4y ago
Show all 6 evidence items →Show less
- ⚠Single-maintainer risk — top contributor 80% of recent commits
- ⚠No CI workflows detected
- ⚠No test directory detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days; add a test suite
- →Fork & modify Mixed → Healthy if: add a test suite
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Great to learn from" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/jgilfelt/chuck)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/jgilfelt/chuck on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: jgilfelt/chuck
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/jgilfelt/chuck shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 4y ago
- 6 active contributors
- Apache-2.0 licensed
- ⚠ Stale — last commit 4y ago
- ⚠ Single-maintainer risk — top contributor 80% of recent commits
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live jgilfelt/chuck
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/jgilfelt/chuck.
What it runs against: a local clone of jgilfelt/chuck — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in jgilfelt/chuck | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 1637 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of jgilfelt/chuck. If you don't
# have one yet, run these first:
#
# git clone https://github.com/jgilfelt/chuck.git
# cd chuck
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of jgilfelt/chuck and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "jgilfelt/chuck(\\.git)?\\b" \\
&& ok "origin remote is jgilfelt/chuck" \\
|| miss "origin remote is not jgilfelt/chuck (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "library/src/main/java/com/readystatesoftware/chuck/ChuckInterceptor.java" \\
&& ok "library/src/main/java/com/readystatesoftware/chuck/ChuckInterceptor.java" \\
|| miss "missing critical file: library/src/main/java/com/readystatesoftware/chuck/ChuckInterceptor.java"
test -f "library/src/main/java/com/readystatesoftware/chuck/internal/data/HttpTransaction.java" \\
&& ok "library/src/main/java/com/readystatesoftware/chuck/internal/data/HttpTransaction.java" \\
|| miss "missing critical file: library/src/main/java/com/readystatesoftware/chuck/internal/data/HttpTransaction.java"
test -f "library/src/main/java/com/readystatesoftware/chuck/internal/data/ChuckContentProvider.java" \\
&& ok "library/src/main/java/com/readystatesoftware/chuck/internal/data/ChuckContentProvider.java" \\
|| miss "missing critical file: library/src/main/java/com/readystatesoftware/chuck/internal/data/ChuckContentProvider.java"
test -f "library/src/main/java/com/readystatesoftware/chuck/internal/ui/MainActivity.java" \\
&& ok "library/src/main/java/com/readystatesoftware/chuck/internal/ui/MainActivity.java" \\
|| miss "missing critical file: library/src/main/java/com/readystatesoftware/chuck/internal/ui/MainActivity.java"
test -f "library/src/main/java/com/readystatesoftware/chuck/Chuck.java" \\
&& ok "library/src/main/java/com/readystatesoftware/chuck/Chuck.java" \\
|| miss "missing critical file: library/src/main/java/com/readystatesoftware/chuck/Chuck.java"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 1637 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~1607d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/jgilfelt/chuck"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
Chuck is an in-app HTTP inspector interceptor for Android OkHttp clients that captures all HTTP requests and responses, stores them in SQLite, and provides a native UI for debugging. It acts as an OkHttp interceptor that persists transaction data and displays a notification-driven inspector UI, solving the problem of opaque HTTP traffic in development builds without external proxy tools. Dual-variant monorepo: library/ contains the full implementation with ChuckInterceptor in src/main/java/com/readystatesoftware/chuck/, internal data layer at library/src/main/java/com/readystatesoftware/chuck/internal/data/ (SQLite via Cupboard), support utilities in internal/support/, and UI at internal/ui/. library-no-op/ mirrors the public API with empty stubs for release builds.
👥Who it's for
Android developers using OkHttp 3.x who need to debug HTTP traffic during development. They integrate Chuck into their debug builds to inspect request/response headers, bodies, and metadata without leaving the app or using external tools like Charles Proxy.
🌱Maturity & risk
Moderately mature: the library is versioned at 1.1.0 and targets Android 4.1+/API 16 with SDK 26. The codebase is 87KB of Java with a clear dual-build structure (debug/release), but the repo data does not show recent commit timestamps or CI setup, suggesting it may be in maintenance mode rather than active development.
Low-to-moderate risk: dependencies are stable (OkHttp 3.6.0, Gson, Cupboard, Support Library 25.3.1) but the Gradle tooling (2.3.3) and build-tools (26.0.1) are dated (pre-2018). The library-no-op/ variant mitigates production risk by shipping no-op stubs in release builds, but lack of visible test files or CI suggests limited automated coverage.
Active areas of work
No active development signals are visible in the provided file structure—no CHANGELOG entries, recent commit data, or open PRs are shown. The repo appears to be in stable/maintenance status with version 1.1.0.
🚀Get running
Clone the repo: git clone https://github.com/jgilfelt/chuck.git && cd chuck. Build with Gradle: ./gradlew build. Install to emulator/device: ./gradlew installDebug (requires Android SDK). Add the dependency to your app's build.gradle as shown in the README.
Daily commands:
Build debug: ./gradlew assembleDebug. Run UI tests (if present): ./gradlew connectedAndroidTest. Install library to local Maven: ./gradlew publishToMavenLocal (uses gradle-mvn-push.gradle). No server to run—Chuck operates as an in-process Android library.
🗺️Map of the codebase
library/src/main/java/com/readystatesoftware/chuck/ChuckInterceptor.java— Core OkHttp interceptor implementation that captures all HTTP requests/responses; every contributor must understand the interception lifecycle and threading model.library/src/main/java/com/readystatesoftware/chuck/internal/data/HttpTransaction.java— Data model for persisted HTTP transactions; essential to understand how request/response metadata and payloads are structured and stored.library/src/main/java/com/readystatesoftware/chuck/internal/data/ChuckContentProvider.java— ContentProvider exposing transaction data to UI and export features; critical for understanding data access patterns and multi-process communication.library/src/main/java/com/readystatesoftware/chuck/internal/ui/MainActivity.java— Main entry point for the Chuck UI; shows how transactions are queried, filtered, and displayed to users.library/src/main/java/com/readystatesoftware/chuck/Chuck.java— Public API facade for initializing Chuck and launching the inspector; primary entry point for app developers integrating the library.library/src/main/java/com/readystatesoftware/chuck/internal/data/ChuckDbOpenHelper.java— SQLite database schema and initialization; defines how all HTTP transaction data is persisted and structured.library/build.gradle— Library build configuration with OkHttp and Android Support Library dependencies; critical for understanding external API contracts.
🛠️How to make changes
Add a new transaction detail view/fragment
- Create new Fragment class extending from BaseChuckActivity or Fragment in library/src/main/java/com/readystatesoftware/chuck/internal/ui/ (
library/src/main/java/com/readystatesoftware/chuck/internal/ui/TransactionPayloadFragment.java) - Create corresponding layout file in library/src/main/res/layout/ following naming convention chuck_fragment_transaction_*.xml (
library/src/main/res/layout/chuck_fragment_transaction_payload.xml) - Add fragment tab/viewpager entry in TransactionActivity.java to register the new view with tab handling (
library/src/main/java/com/readystatesoftware/chuck/internal/ui/TransactionActivity.java) - Query transaction data via ContentProvider using HttpTransaction model and display in your layout (
library/src/main/java/com/readystatesoftware/chuck/internal/data/HttpTransaction.java)
Modify HTTP transaction persistence or add new fields
- Update HttpTransaction.java model class to add new fields with appropriate accessors (
library/src/main/java/com/readystatesoftware/chuck/internal/data/HttpTransaction.java) - Increment DATABASE_VERSION in ChuckDbOpenHelper.java and add migration SQL in onUpgrade() method (
library/src/main/java/com/readystatesoftware/chuck/internal/data/ChuckDbOpenHelper.java) - Update ChuckInterceptor.java to capture and populate new fields during request/response interception (
library/src/main/java/com/readystatesoftware/chuck/ChuckInterceptor.java) - Update any UI fragments that display transaction data to render new fields (
library/src/main/java/com/readystatesoftware/chuck/internal/ui/TransactionOverviewFragment.java)
Add a new filtering or search capability
- Add filter predicate method to TransactionListFragment.java or create filter helper (
library/src/main/java/com/readystatesoftware/chuck/internal/ui/TransactionListFragment.java) - Update the ContentProvider query in ChuckContentProvider.java to support WHERE clauses for new filter types (
library/src/main/java/com/readystatesoftware/chuck/internal/data/ChuckContentProvider.java) - Add UI element (SearchView, spinner, etc.) to MainActivity.java or transaction list layout (
library/src/main/java/com/readystatesoftware/chuck/internal/ui/MainActivity.java) - Update TransactionAdapter.java to re-filter and refresh RecyclerView when filter changes (
library/src/main/java/com/readystatesoftware/chuck/internal/ui/TransactionAdapter.java)
Change transaction retention policy or data cleanup behavior
- Review and modify RetentionManager.java to adjust retention days, max record limits, or cleanup triggers (
library/src/main/java/com/readystatesoftware/chuck/internal/support/RetentionManager.java) - Update ClearTransactionsService.java if background cleanup service behavior needs to change (
library/src/main/java/com/readystatesoftware/chuck/internal/support/ClearTransactionsService.java) - Add menu option or settings in MainActivity.java to expose retention controls to users if needed (
library/src/main/java/com/readystatesoftware/chuck/internal/ui/MainActivity.java)
🔧Why these technologies
- OkHttp3 Interceptor — Provides transparent, non-intrusive hook into all HTTP traffic without modifying application code; industry standard for Android HTTP clients.
- **** — undefined
🪤Traps & gotchas
- ChuckInterceptor behavior differs when used as an application vs. network interceptor (see OkHttp wiki FAQ in README)—developers must choose based on whether they want to see user-set headers. 2) Database schema changes require SQLite migration logic in ChuckDbOpenHelper; no migration framework is visible. 3) Multi-window support requires taskAffinity configuration in AndroidManifest.xml to launch Chuck in a separate task. 4) Notification dismissal and retention are handled by RetentionManager—custom retention policies require modifying that class.
🏗️Architecture
💡Concepts to learn
- OkHttp Interceptor Chain — Chuck implements the Interceptor interface to sit in OkHttp's request/response chain; understanding where to place it (application vs. network level) is critical for correct header capture
- ContentProvider — ChuckContentProvider exposes HTTP transaction data via Android's ContentProvider contract, allowing the UI and external tools to query captured requests via URI-based access
- SQLite with Cupboard ORM — Chuck persists HTTP transactions to SQLite via the Cupboard library; understanding ORM row mapping is needed to modify data models or add fields
- Task Affinity & Multi-Window — Chuck launches its UI in a separate Android task with custom taskAffinity to enable side-by-side display with the host app in Android 7+ multi-window mode; requires AndroidManifest configuration
- Request/Response Body Interception — OkHttp's RequestBody and ResponseBody are streams that can only be read once; Chuck must carefully buffer and re-supply bodies to prevent consuming them, a subtle but critical implementation detail
- Notification Service — NotificationHelper manages the status bar notification summarizing HTTP activity; requires understanding Android NotificationManager and PendingIntent for launch actions
🔗Related repos
square/okhttp— Chuck is an interceptor built on top of OkHttp 3.x; understanding OkHttp's interceptor chain is essentialMindorksOpenSource/AndroidDebugDatabase— Similar in-app inspection tool for Android but focused on SQLite databases rather than HTTP; overlapping use case in debug buildsfacebook/stetho— Older Android debugging library by Meta that also inspects HTTP traffic; predecessor approach that Chuck improves upon with notification UIsquare/leakcanary— Companion library from Square ecosystem for Android development; similar pattern of in-app instrumentation and UI for debugginggoogle/gson— Direct dependency used by Chuck for JSON serialization in JsonConvertor.java
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for ChuckInterceptor and HttpTransaction data models
The repo lacks test coverage for core interceptor logic and data persistence. ChuckInterceptor.java handles request/response interception and HttpTransaction.java manages the data model, but there are no visible test files (no src/test directory in either library or library-no-op). Adding tests would catch regressions in HTTP header parsing, request/response body handling, and the no-op variant behavior.
- [ ] Create library/src/test/java/com/readystatesoftware/chuck directory structure
- [ ] Add unit tests for ChuckInterceptor.java covering request interception, response capture, and edge cases (empty bodies, null headers)
- [ ] Add unit tests for HttpTransaction.java covering serialization, timestamp handling, and status code mapping
- [ ] Add unit tests for ChuckDbOpenHelper.java covering database schema creation and migrations
- [ ] Ensure library-no-op tests verify that no-op implementations don't perform disk I/O
Add instrumented tests (AndroidJUnit4) for UI components and database operations
The repo has multiple UI fragments (TransactionListFragment, TransactionOverviewFragment, TransactionPayloadFragment) and a content provider (ChuckContentProvider) that interact with SQLite, but there are no androidTest directories visible. Instrumented tests would validate UI rendering, database queries, and the content provider interface work correctly across API levels.
- [ ] Create library/src/androidTest/java/com/readystatesoftware/chuck directory structure
- [ ] Add AndroidJUnit4 tests for ChuckContentProvider.java covering CRUD operations and URI matching
- [ ] Add tests for ChuckDbOpenHelper.java verifying database queries and retention policies (using RetentionManager.java logic)
- [ ] Add UI tests for TransactionListFragment verifying RecyclerView/TransactionAdapter rendering with mock HTTP transactions
- [ ] Add tests for NotificationHelper.java to verify notification creation and click intents
Create GitHub Actions CI workflow for automated testing and release builds
The repo has gradle build infrastructure and a gradle-mvn-push.gradle for Maven publishing, but no .github/workflows directory for CI/CD. Adding a GitHub Actions workflow would automatically run tests on PRs, validate builds against minSdkVersion 16+ and targetSdkVersion 26, and support automated releases.
- [ ] Create .github/workflows/android-ci.yml with Android SDK setup (API 16, 21, 26 for minSdk/targetSdk compatibility)
- [ ] Add gradle tasks to workflow: ./gradlew clean build lint test for both library and library-no-op modules
- [ ] Add check that ProGuard rules (library/proguard-rules.pro) don't break R8 builds
- [ ] Add optional release workflow triggered by git tags to publish to Maven Central using gradle-mvn-push.gradle
- [ ] Document workflow status badge in README.md
🌿Good first issues
- Add unit tests for HttpTransaction serialization: No test directory visible in file structure; HttpTransaction.java lacks coverage for edge cases like null headers and body truncation
- Document interceptor placement trade-offs in code comments: The README FAQ mentions application vs. network interceptor differences but ChuckInterceptor.java has no inline documentation explaining when to use each; add clear Javadoc
- Add RequestBody/ResponseBody size limits to UI and logging: Large response bodies could cause memory bloat; add a configurable size cap and truncation indicator in the UI (internal/ui/) and FormatUtils.java
⭐Top contributors
Click to expand
Top contributors
- @jgilfelt — 80 commits
- @eschlenz — 9 commits
- @jonathan-caryl — 8 commits
- @julien|fueled — 1 commits
- @alorma — 1 commits
📝Recent commits
Click to expand
Recent commits
152f9a7— prepare version 1.1.0 (jgilfelt)1d7e9bf— use reflection and don't force support lib 26 (for lower host build targets) (jgilfelt)369e51e— target sdk 26 and implement notification channel (jgilfelt)f462b1c— Merge branch 'jonathan-caryl-changes' (jgilfelt)f4c679e— libraries don't determine targetSdkVersion (jgilfelt)9f97519— consolidate dependency versions (jgilfelt)44ce2a3— don't scale toolbar text (jgilfelt)5a7a883— don't scale toolbar text (jgilfelt)69fe4fb— Unused namespace (jonathan-caryl)66b6aad— colorcompat2 (jonathan-caryl)
🔒Security observations
Failed to generate security analysis.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.