RepoPilotOpen in app →

chrisjenx/Calligraphy

Custom fonts in Android the easy way...

Mixed

Stale — last commit 2y ago

weakest axis
Use as dependencyMixed

last commit was 2y ago; no tests detected…

Fork & modifyMixed

no tests detected; no CI workflows detected…

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isMixed

last commit was 2y ago; no CI workflows detected

  • 25+ active contributors
  • Apache-2.0 licensed
  • Stale — last commit 2y ago
Show all 6 evidence items →
  • Concentrated ownership — top contributor handles 66% of recent commits
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency MixedHealthy if: 1 commit in the last 365 days; add a test suite
  • Fork & modify MixedHealthy if: add a test suite
  • Deploy as-is MixedHealthy 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.

RepoPilot: Great to learn from
[![RepoPilot: Great to learn from](https://repopilot.app/api/badge/chrisjenx/calligraphy?axis=learn)](https://repopilot.app/r/chrisjenx/calligraphy)

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/chrisjenx/calligraphy on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: chrisjenx/Calligraphy

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:

  1. 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.
  2. 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.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/chrisjenx/Calligraphy 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 2y ago

  • 25+ active contributors
  • Apache-2.0 licensed
  • ⚠ Stale — last commit 2y ago
  • ⚠ Concentrated ownership — top contributor handles 66% 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 chrisjenx/Calligraphy repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/chrisjenx/Calligraphy.

What it runs against: a local clone of chrisjenx/Calligraphy — 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 chrisjenx/Calligraphy | 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 ≤ 777 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>chrisjenx/Calligraphy</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of chrisjenx/Calligraphy. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/chrisjenx/Calligraphy.git
#   cd Calligraphy
#
# 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 chrisjenx/Calligraphy and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "chrisjenx/Calligraphy(\\.git)?\\b" \\
  && ok "origin remote is chrisjenx/Calligraphy" \\
  || miss "origin remote is not chrisjenx/Calligraphy (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 "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java" \\
  && ok "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java" \\
  || miss "missing critical file: calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java"
test -f "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java" \\
  && ok "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java" \\
  || miss "missing critical file: calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java"
test -f "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java" \\
  && ok "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java" \\
  || miss "missing critical file: calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java"
test -f "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java" \\
  && ok "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java" \\
  || miss "missing critical file: calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java"
test -f "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/TypefaceUtils.java" \\
  && ok "calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/TypefaceUtils.java" \\
  || miss "missing critical file: calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/TypefaceUtils.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 777 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~747d)"
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/chrisjenx/Calligraphy"
  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).

</details>

TL;DR

Calligraphy is an Android library that simplifies custom font application by injecting typefaces at runtime through a ContextWrapper, eliminating the need for custom Views or manual ViewTree traversal. It uses XML attributes (e.g., fontPath="fonts/MyFont.ttf") and a configuration singleton to apply custom fonts globally or per-widget. Two-module Gradle project: calligraphy/ is the core library (Java, proguard rules in consumer-proguard-rules.txt), and CalligraphySample/ is a reference app demonstrating usage. Core logic is the ContextWrapper injection pattern in CalligraphyContextWrapper + CalligraphyConfig singleton. Fonts live in CalligraphySample/src/main/assets/fonts/ with examples like Roboto, Oswald, and gtw TTF files.

👥Who it's for

Android developers building apps that need custom typography without boilerplate custom View classes. Specifically, UI engineers who want to apply fonts defined in assets/fonts/ across Activities, Fragments, and individual TextViews declaratively.

🌱Maturity & risk

End-of-life; the README explicitly states 'This version of Calligraphy has reached its end-of-life and is no longer maintained.' The project is archived—version 2.3.0 was the final release, no recent commits are visible, and the maintainer directs users to migrate to Calligraphy 3 (InflationX/Calligraphy). Not production-ready for new projects.

High risk: this library is unmaintained and no longer receives security or compatibility updates. It targets older Android SDK versions (minSdkVersion/targetSdkVersion not visible in snippet but inferred as pre-AndroidX era). Dependencies on com.android.support (not AndroidX) indicate obsolescence. Single-maintainer project (chrisjenx) with no apparent successor activity in this fork.

Active areas of work

Nothing—this repo is in archive/EOL state. The CHANGELOG.md exists but no recent activity is visible. The sample app includes reference implementations (MainActivity, PlaceholderFragment, CustomTextView) but these are historical examples, not active development.

🚀Get running

Clone: git clone https://github.com/chrisjenx/Calligraphy.git. Build: ./gradlew build (or gradle build if Gradle is installed). The sample app will build to CalligraphySample/build/outputs/apk/. No npm/package.json—this is pure Gradle + Android SDK.

Daily commands: No 'dev server'—this is an Android library. To run the sample: open the project in Android Studio, sync Gradle, select CalligraphySample module, and run on an emulator or device. Or via CLI: ./gradlew :CalligraphySample:installDebug after connecting an Android device.

🗺️Map of the codebase

  • calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyContextWrapper.java — Entry point that wraps the Android Context to inject custom fonts into all view inflation—core to the library's hook mechanism
  • calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java — Configuration holder that stores the default font path and per-view font overrides—must be initialized before any Activities are created
  • calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyLayoutInflater.java — Custom LayoutInflater that intercepts view creation to apply fonts via CalligraphyFactory—the mechanism that enables declarative font injection
  • calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java — Factory that creates views and applies Typeface attributes during inflation—implements the actual font application logic
  • calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/TypefaceUtils.java — Utility for caching and retrieving Typeface objects from assets—prevents redundant font file loading and improves performance
  • CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java — Sample application initialization showing how to configure Calligraphy with fonts at app startup
  • calligraphy/src/main/res/values/attrs.xml — Custom XML attributes (e.g., fontPath) that enable declarative font specification in layout files

🛠️How to make changes

Add a Custom Font to Your App

  1. Place your .ttf font file in assets/fonts/ (e.g., assets/fonts/MyFont.ttf) (CalligraphySample/src/main/assets/fonts)
  2. Initialize Calligraphy in your Application class with default or per-activity fonts (CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java)
  3. Wrap the Context in your Activity's attachBaseContext() using CalligraphyContextWrapper (CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/MainActivity.java)
  4. Declare the font in your layout XML using app:fontPath='fonts/MyFont.ttf' attribute (CalligraphySample/src/main/res/layout/fragment_main.xml)

Apply Fonts to Custom Text Views

  1. Have your custom View implement HasTypeface interface with a setTypeface(Typeface) method (calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/HasTypeface.java)
  2. Calligraphy will automatically detect and call setTypeface() during view inflation via CalligraphyFactory (calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyFactory.java)
  3. For views without setTypeface, Calligraphy uses ReflectionUtils to set the private mTypeface field (calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/ReflectionUtils.java)

Configure Per-Activity Font Overrides

  1. Create a CalligraphyConfig with different default fonts for different Activities (calligraphy/src/main/java/uk/co/chrisjenx/calligraphy/CalligraphyConfig.java)
  2. Pass the config to Calligraphy.init() in your Application or Activity onCreate (CalligraphySample/src/main/java/uk/co/chrisjenx/calligraphy/sample/CalligraphyApplication.java)
  3. Override fontPath in individual layout files for specific views using the app:fontPath attribute (CalligraphySample/src/main/res/layout/fragment_main.xml)

🔧Why these technologies

  • Android Context wrapping (CalligraphyContextWrapper) — Intercepts LayoutInflater at the framework level without requiring custom Application class or reflection hacks; works with all Activities automatically
  • LayoutInflater.Factory2 (CalligraphyFactory) — Official Android hook for intercepting view creation during inflation; avoids traversing the ViewTree post-inflation
  • Custom XML attributes (app:fontPath, app:fontAsset) — Enables declarative, compile-time-checked font specifications in layouts without runtime string parsing
  • Typeface caching (TypefaceUtils) — Prevents redundant file I/O and parsing of .ttf files on every view creation; shared across all views using same font
  • Reflection fallback (ReflectionUtils) — Allows font injection into views that don't expose setTypeface() public method (e.g., older custom views)

⚖️Trade-offs already made

  • Context wrapping instead of custom Application base class

    • Why: Reduces boilerplate and doesn't force developers into inheritance hierarchy
    • Consequence: Requires per-Activity attachBaseContext() override or Activity.Factory integration; slightly more ceremony than a base class
  • Reflection access to private mTypeface field as fallback

    • Why: Handles custom views without setTypeface() without forcing them to implement an interface
    • Consequence: Fragile across Android versions due to private field changes; may break on future API levels
  • Typeface caching with file-based keys

    • Why: Amortizes repeated font loading across view hierarchy
    • Consequence: Cache invalidation on font file updates requires app restart; no runtime font swapping
  • Early font loading during view inflation vs. lazy loading

    • Why: Ensures fonts are applied synchronously before onCreateView() returns
    • Consequence: undefined

🪤Traps & gotchas

Namespace quirk: The fontPath attribute intentionally has no XML namespace prefix (note in README: 'The missing namespace, this IS intentional'). IDEs will warn about MissingPrefix; suppress with tools:ignore="MissingPrefix". Android version risk: Uses pre-AndroidX com.android.support libraries; will not work on Android 12+ without migration. Reflection overhead: Font loading uses reflection to instantiate typefaces; may cause startup lag on large apps with many custom fonts. No default behavior: If CalligraphyConfig is not initialized, the library silently applies no fonts.

🏗️Architecture

💡Concepts to learn

  • ContextWrapper injection — Calligraphy's core mechanism—intercepting View inflation by wrapping Context—is a foundational Android pattern for cross-cutting concerns like theming and resource substitution
  • Typeface caching and reflection — The library uses reflection to call Typeface.createFromAsset() at runtime; understanding reflection overhead and Typeface memory management is critical for diagnosing performance issues in font-heavy apps
  • XML attribute inflation — Custom fontPath attributes are parsed during View inflation; understanding how Android's LayoutInflater interprets custom attributes is essential for extending Calligraphy to custom Views
  • ProGuard obfuscation and reflection-safe code — The consumer-proguard-rules.txt prevents obfuscation of reflection targets; critical for minified builds—a gotcha many developers miss when integrating this library
  • Application singleton pattern — CalligraphyConfig is a static singleton holding global font configuration; understanding singleton lifecycle and thread safety in Android is necessary for modifying config at runtime
  • Asset file management in Android — Fonts must live in assets/ (not res/); understanding the distinction and how AssetManager accesses files is crucial for packaging and loading custom typefaces
  • InflationX/Calligraphy — Official maintained successor; this is the actively-developed version users should migrate to (mentioned in README)
  • google/android-fonts — Google's official guidance on custom fonts in Android; modern approach using downloadable fonts instead of bundled TTF files
  • square/retrofit — Ecosystem companion; many apps using Calligraphy also use Retrofit for network calls, often initialized in the same Application class
  • JakeWharton/butterknife — Direct dependency of CalligraphySample; demonstrates integration with another Android DI/view-binding library in the same era

🪄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 CalligraphyUtils and TypefaceUtils

The core utility classes (CalligraphyUtils.java and TypefaceUtils.java) lack test coverage. These are critical for font loading and caching logic. Adding unit tests would catch regressions in typeface resolution, asset loading, and caching behavior—especially important given the library's end-of-life status for backward compatibility validation.

  • [ ] Create calligraphy/src/test/java/uk/co/chrisjenx/calligraphy/CalligraphyUtilsTest.java with tests for font asset loading paths
  • [ ] Create calligraphy/src/test/java/uk/co/chrisjenx/calligraphy/TypefaceUtilsTest.java with tests for typeface caching and retrieval logic
  • [ ] Add mock Android context objects using Robolectric or Mockito to test asset resolution
  • [ ] Verify that edge cases like missing fonts, invalid paths, and null inputs are handled correctly

Add integration tests for CalligraphyContextWrapper and CalligraphyLayoutInflater

The CalligraphyContextWrapper and CalligraphyLayoutInflater are the bridge between XML inflation and font application, but there are no integration tests validating that custom fonts are correctly applied to views during layout inflation. This is critical functionality that could break silently.

  • [ ] Create calligraphy/src/androidTest/java/uk/co/chrisjenx/calligraphy/CalligraphyInflationTest.java
  • [ ] Test that CalligraphyContextWrapper correctly wraps context and applies fonts to standard views (TextView, EditText, etc.)
  • [ ] Test CalligraphyLayoutInflater with sample layouts from CalligraphySample/src/main/res/layout/ to ensure custom font paths and default fonts are applied
  • [ ] Add tests for edge cases: ViewStubs, custom views implementing HasTypeface (CustomTextView.java, CustomViewWithTypefaceSupport.java), and fragments

Document and test the CalligraphyFactory reflection-based approach with Android API version handling

ReflectionUtils.java and CalligraphyFactory.java use reflection to hook into Android's LayoutInflater, which is fragile across API levels. There's no documentation on API-specific behavior or tests validating compatibility. Given the library's age and maintenance status, explicit tests and docs would help contributors understand and maintain this critical integration point.

  • [ ] Create calligraphy/src/test/java/uk/co/chrisjenx/calligraphy/ReflectionUtilsTest.java to test reflection-based field access for LayoutInflater across mock API levels
  • [ ] Add comprehensive inline documentation to ReflectionUtils.java explaining why reflection is necessary and what breaks on different API versions
  • [ ] Create a new doc file ARCHITECTURE.md documenting the reflection-based hooking mechanism, including diagram of CalligraphyActivityFactory → CalligraphyContextWrapper flow
  • [ ] Add tests in CalligraphySample for API compatibility by verifying fonts load correctly on minSdkVersion (currently using support-v4 and appcompat-v7)

🌿Good first issues

  • Add unit tests for CalligraphyConfig singleton initialization and reset behavior in calligraphy/src/test/ (currently no visible test directory); verify that initDefault() correctly caches and reuses Typeface objects across Views.
  • Document the exact steps to add Calligraphy to a pre-existing Activity in README.md, with a code example showing attachBaseContext() override. The current README assumes greenfield setup; many users inherit from libraries that already override this method.
  • Create a migration guide from Calligraphy 2.3.0 to Calligraphy 3 (InflationX version) in MIGRATION.md, listing breaking API changes. The current EOL notice tells users to migrate but provides no bridge documentation.

Top contributors

Click to expand
  • @chrisjenx — 66 commits
  • @bryant1410 — 3 commits
  • [@Sunghoon Kang](https://github.com/Sunghoon Kang) — 3 commits
  • @ZacSweers — 3 commits
  • [@Dmitriy Tarasov](https://github.com/Dmitriy Tarasov) — 3 commits

📝Recent commits

Click to expand
  • 085e441 — Merge pull request #453 from codebutler/patch-1 (chrisjenx)
  • 4394a39 — Added end-of-life note to README (codebutler)
  • 6ae1b00 — Merge pull request #404 from ajarl/fix-toolbar-subtitle-font (chrisjenx)
  • bc98cb9 — Merge pull request #351 from Hesamedin/fix_typo (chrisjenx)
  • ca4e85d — Merge pull request #407 from 0mega/patch-1 (chrisjenx)
  • f8919c3 — Merge pull request #445 from sikrinick/feature/gradle_build_tools_update (chrisjenx)
  • 7405690 — Updated (sikri)
  • fc73fc2 — Update .aar download link in Readme (0mega)
  • bdaa081 — Fix using the same string for Toolbar (sub)title (ajarl)
  • df338f1 — Merge pull request #378 from barnhill/master (chrisjenx)

🔒Security observations

This project has critical security concerns due to its end-of-life status with no ongoing maintenance. All dependencies are significantly outdated, creating multiple potential attack vectors. The project uses deprecated Android Support Libraries instead of modern AndroidX. Immediate action is required: either migrate to Calligraphy 3 or select an actively maintained alternative. For any active deployments, update all dependencies to their latest stable versions and conduct a comprehensive security audit.

  • High · Outdated and End-of-Life Library — Root project - build.gradle, CalligraphySample/build.gradle. The Calligraphy library (version 2.3.0) has reached end-of-life status as stated in the README. The project is no longer maintained, meaning no security patches or updates will be released for discovered vulnerabilities. Fix: Migrate to Calligraphy 3 (https://github.com/InflationX/Calligraphy) or an actively maintained alternative font library
  • High · Outdated Android Support Libraries — CalligraphySample/build.gradle - support library dependencies. The project uses outdated Android Support Libraries (support-v4, appcompat-v7). These libraries are no longer maintained and have been superseded by AndroidX. Known security vulnerabilities may exist in older versions. Fix: Migrate from support libraries to AndroidX equivalents (androidx.appcompat:appcompat, androidx.fragment:fragment, etc.)
  • Medium · Outdated ButterKnife Dependency — CalligraphySample/build.gradle - ButterKnife dependency. ButterKnife version 8.8.1 is outdated (released in 2017). While not a direct security vulnerability, older versions may have compatibility issues with modern Android versions and potential undiscovered vulnerabilities. Fix: Update to the latest stable version of ButterKnife or consider using view binding as a modern replacement
  • Medium · Outdated LeakCanary Dependency — CalligraphySample/build.gradle - LeakCanary dependency. LeakCanary version 1.5 is significantly outdated (released in 2016). This memory leak detection library is no longer actively maintained at this version. Fix: Update to the latest version of LeakCanary (currently 2.x or 3.x series)
  • Medium · ProGuard Minification Configuration Risk — CalligraphySample/build.gradle, CalligraphySample/proguard-rules.txt. Both debug and release builds have minifyEnabled set to true with custom ProGuard rules. If the proguard-rules.txt file is misconfigured, it could expose sensitive code or cause runtime issues. The file content is not visible for review. Fix: Review proguard-rules.txt to ensure it properly protects sensitive code and doesn't expose internal APIs. Consider keeping debug builds without minification for better debugging
  • Low · Missing Security Policy Documentation — Root directory. The project is end-of-life but lacks a SECURITY.md file or security policy documentation, making it difficult for security researchers to report vulnerabilities responsibly. Fix: Add a SECURITY.md file with clear guidance that the project is no longer maintained and direct users to the maintained fork (Calligraphy 3)

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · chrisjenx/Calligraphy — RepoPilot