RepoPilot

Meituan-Dianping/walle

Android Signature V2 Scheme签名下的新一代渠道包打包神器

Mixed

Stale — last commit 2y ago

MixedDependency

last commit was 2y ago; no tests detected…

HealthyFork & modify

Has a license, tests, and CI — clean foundation to fork and modify.

HealthyLearn from

Documented and popular — useful reference codebase to read through.

MixedDeploy as-is

last commit was 2y ago; Scorecard "Branch-Protection" is 0/10…

  • Stale — last commit 2y ago
  • No CI workflows detected
  • No test directory detected
  • Scorecard: marked unmaintained (0/10)
  • Scorecard: default branch unprotected (0/10)
  • 6 active contributors
  • Distributed ownership (top contributor 46% of recent commits)
  • Apache-2.0 licensed

What would improve this?

  • Use as dependency MixedHealthy if: 1 commit in the last 365 days; add a test suite
  • Deploy as-is MixedHealthy if: 1 commit in the last 180 days; bring "Branch-Protection" to ≥3/10 (see scorecard report)

Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against OpenSSF Scorecard

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 "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/meituan-dianping/walle?axis=fork)](https://repopilot.app/r/meituan-dianping/walle)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card

This card auto-renders when someone shares https://repopilot.app/r/meituan-dianping/walle on X, Slack, or LinkedIn.

Ask AI about meituan-dianping/walle

Grounded in the actual source code. Pick a starter question or write your own.

Or write your own question →

Onboarding doc

Onboarding: Meituan-Dianping/walle

Generated by RepoPilot · 2026-06-24 · Source

🎯Verdict

WAIT — Stale — last commit 2y ago

  • 6 active contributors
  • Distributed ownership (top contributor 46% of recent commits)
  • Apache-2.0 licensed
  • ⚠ Stale — last commit 2y ago
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected
  • ⚠ Scorecard: marked unmaintained (0/10)
  • ⚠ Scorecard: default branch unprotected (0/10)

<sub>Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against OpenSSF Scorecard</sub>

TL;DR

Walle is an Android channel package generation tool that leverages Android Signature V2 Scheme to embed channel metadata directly into the APK Signature Block without re-signing, enabling rapid multi-channel APK generation. It eliminates the time-consuming process of re-signing APKs for each distribution channel by writing channel info into the signature block after the initial signing, reducing build time from hours to seconds. Two-module structure: library/ contains the core WalleChannelReader AAR (com.meituan.android.walle:library) that apps include as a dependency to read channel info at runtime; gradle-plugin/ (inferred, not fully visible) contains the Gradle plugin that integrates into the build process. The app/ directory is a sample application demonstrating integration. Build configuration is in build.gradle files; channel metadata templates are in app/channel and app/config.json.

👥Who it's for

Android app developers and build engineers at companies like Meituan who need to generate and distribute dozens of channel-specific APK variants (for different app stores, OEMs, partners) without the overhead of re-signing each one. They use this via Gradle plugin integration during CI/CD or as a command-line tool for rapid channel package generation.

🌱Maturity & risk

Production-ready and actively maintained by Meituan-Dianping (a major Chinese tech company). The project has a published Gradle plugin (v1.1.7+) on Bintray, Travis CI integration, and comprehensive documentation. Latest evidence suggests ongoing development, though exact commit frequency is not visible in the file manifest provided.

Low risk for Android ecosystem use: the project directly manipulates APK Signature Blocks according to the official Android V2 signature spec, avoiding proprietary hacks. Primary risks are: (1) dependency on Gradle 2.2.0+ and Android Gradle Plugin compatibility, (2) reliance on a single maintainer organization (Meituan), and (3) potential breakage if Android signature format changes in new OS versions—though this is unlikely given the spec maturity.

Active areas of work

No specific recent activity visible in the file manifest. The repo appears stable with documented v1.1.7 as the latest release. Gradle plugin uses latest.integration in buildscript dependencies, suggesting active dependency management.

🚀Get running

Clone the repo and build the sample app:

git clone https://github.com/Meituan-Dianping/walle.git
cd walle
./gradlew clean assembleReleaseChannels

This generates channel-specific APKs to app/build/outputs/channels/ as defined in the Gradle walle block configuration.

Daily commands: Development:

./gradlew clean build

Sample app debug build:

./gradlew clean assembleDebug

Channel package generation (multi-variant):

./gradlew clean assembleReleaseChannels

The plugin task assemble${variantName}Channels is auto-registered after applying the walle plugin.

🗺️Map of the codebase

  • payload_writer/src/main/java/com/meituan/android/walle/PayloadWriter.java — Core engine for writing channel information into APK Signature V2 blocks; fundamental to the entire walle channel packaging mechanism
  • payload_reader/src/main/java/com/meituan/android/walle/PayloadReader.java — Runtime reader for extracting channel metadata from signed APKs; used by all downstream applications
  • plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy — Gradle plugin entry point that orchestrates the entire channel packaging workflow during build time
  • library/src/main/java/com/meituan/android/walle/WalleChannelReader.java — Public API for reading channel info from runtime APK; primary integration point for app developers
  • payload_writer/src/main/java/com/meituan/android/walle/ApkSigningBlock.java — Handles manipulation of APK Signature V2 block structure; critical for preserving signature integrity during channel injection
  • plugin/src/main/groovy/com/meituan/android/walle/ChannelMaker.groovy — Gradle task implementation that orchestrates multi-channel APK generation from a base signed APK
  • app/build.gradle — Sample application demonstrating plugin integration; reference implementation for new users

🛠️How to make changes

Generate Multi-Channel APKs from Base Build

  1. Add Walle plugin dependency to root build.gradle buildscript block (build.gradle)
  2. Apply walle plugin and add library dependency in app/build.gradle (app/build.gradle)
  3. Configure channel names and mappings in app/build.gradle walle extension block (referenced in GradlePlugin.groovy) (app/build.gradle)
  4. Call WalleChannelReader.getChannel(context) in app code to retrieve channel ID at runtime (app/src/main/java/com/meituan/android/walle/sample/MainActivity.java)

Implement Custom Channel Injection Logic

  1. Create new ChannelInfo subclass or modify ChannelInfo.java to support additional metadata (payload_reader/src/main/java/com/meituan/android/walle/ChannelInfo.java)
  2. Update ChannelWriter.java to serialize new fields into APK signature block (payload_writer/src/main/java/com/meituan/android/walle/ChannelWriter.java)
  3. Update ChannelReader.java to deserialize new fields during APK reading (payload_reader/src/main/java/com/meituan/android/walle/ChannelReader.java)

Add Server-Side Channel APK Generation

  1. Integrate PayloadWriter.java as a library dependency in HTTP server application (payload_writer/src/main/java/com/meituan/android/walle/PayloadWriter.java)
  2. Implement REST endpoint that accepts base APK and channel parameters, calls PayloadWriter.write(apkFile, outputFile, channelInfo) (payload_writer/src/main/java/com/meituan/android/walle/PayloadWriter.java)
  3. Stream modified APK back to client as response body (payload_writer/src/main/java/com/meituan/android/walle/PayloadWriter.java)

🔧Why these technologies

  • APK Signature V2 Scheme (Android 7.0+) — Standard Android signing mechanism allows injecting custom metadata in the APK Signing Block without invalidating the signature; enables zero-re-signing channel distribution
  • Gradle Plugin (Groovy/Java hybrid) — Integrates channel generation directly into build pipeline; supports conditional compilation, variant-aware configuration, and seamless IDE integration
  • Java NIO RandomAccessFile for binary I/O — Efficient seeking and in-place modification of large APK files without full memory buffering

⚖️Trade-offs already made

  • Store channel info in APK Signature V2 block instead of AndroidManifest.xml

    • Why: Signature V2 block is immutable after signing; no need to re-sign each channel APK variant
    • Consequence: Requires reverse-engineering APK signature block format; more complex binary parsing but massive efficiency gain (single base APK → N channel APKs instantly)
  • PayloadReader does not verify APK signature validity

    • Why: Prioritizes speed and eliminates dependency on Android Framework signature validation code
    • Consequence: Malformed or tampered APKs may return garbage channel data; responsibility on caller to validate APK integrity separately
  • Gradle plugin approach vs. standalone CLI tool

    • Why: Gradle plugin integrates seamlessly into standard Android build pipeline
    • Consequence: CLI tools (in payload_writer/payload_reader) available for server-side or non-Gradle workflows but requires manual orchestration

🚫Non-goals (don't propose these)

  • Does not modify app code or resources; channel injection is post-build, post-sign
  • Does not re-sign APKs; leverages v2 signing block preservation to avoid re-signing overhead
  • Does not handle APK signature verification; assumes caller validates APK integrity separately
  • Not designed for APK tamper-proofing; channel metadata is readable by any tool that parses APK Signature V2 blocks
  • Does not manage channel distribution or analytics; only stores and retrieves channel identifiers

🪤Traps & gotchas

  1. Signing order: The APK must be signed BEFORE channel info is written to the signature block; if you try to write channels and then re-sign, the signature block changes will be invalidated. The plugin enforces this by hooking post-signing. 2. APK Signature Block format sensitivity: The tool directly mutates binary APK structure; APK files must be in valid V2 Signature Scheme format (no V1-only signing). Using V1 signing only will cause silent failures. 3. Java version compatibility: Project specifies sourceCompatibility JavaVersion.VERSION_1_7, but Gradle 2.2.0+ is required; very new Java versions may have incompatibility issues. 4. Channel file encoding: The channel file (app/channel) must be plain text, one entry per line; malformed JSON in config.json will fail silently during parsing.

🏗️Architecture

💡Concepts to learn

  • APK Signature Block (V2 Scheme) — Walle's entire mechanism relies on understanding the APK Signature Block format introduced in Android 7.0; it embeds channel metadata here after signing without invalidating the signature, which is the core innovation that makes fast multi-channel builds possible
  • Gradle Plugin Architecture & BaseVariant API — The plugin hooks into Android Gradle plugin build tasks using BaseVariant; understanding how variant configuration and task dependencies work is essential to modify or debug the build integration
  • Binary APK format and ZIP structure — APKs are ZIP files with a specific internal structure (META-INF/ for signatures, AndroidManifest.xml, resources.arsc); Walle reads/writes the signature block which is appended after the ZIP central directory, requiring binary-level file manipulation
  • Cryptographic signing and digest verification — The tool must preserve APK cryptographic integrity; understanding why the signature block can be extended without breaking the signature helps prevent security bugs
  • Gradle task graph and dependency resolution — The plugin registers custom tasks (e.g., assembleReleaseChannels) and must respect task ordering; understanding Gradle's task graph is critical for ensuring channels are written after (not before) APK signing
  • JSON configuration parsing and templating — The configFile option uses JSON format with per-channel metadata; the plugin must parse and apply these templates to each generated APK variant, requiring robust config handling
  • Meituan-Dianping/applinker — Complementary Meituan tool for dynamic linking and app plugin systems; works with channel packages generated by Walle
  • protocolbuffers/protobuf — While Walle doesn't use protobuf, understanding binary serialization formats is essential for grokking APK Signature Block manipulation
  • google/android-gradle-dsl — Official Android Gradle plugin; Walle extends this via Gradle plugin pattern and relies on BaseVariant APIs defined here
  • android/ndk — Related to APK signing infrastructure and signature verification; understanding V2 Signature Scheme from the spec level helps debug Walle issues
  • square/gradle-witness — Alternative Gradle plugin approach for APK manipulation; demonstrates similar hook-into-build-process patterns for Android packaging

🪄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 WalleChannelReader.java

The library/src/main/java/com/meituan/android/walle/WalleChannelReader.java appears to be a core component for reading channel information from APKs, but there are no visible test files in the repository structure. Adding comprehensive unit tests would ensure the channel reading logic works correctly across different APK signing scenarios and channel data formats.

  • [ ] Create library/src/test/java/com/meituan/android/walle/ directory structure
  • [ ] Write tests for WalleChannelReader covering: valid channel data parsing, malformed channel blocks, edge cases with different APK Signature V2 block variations
  • [ ] Add test fixtures with sample APKs containing different channel configurations
  • [ ] Ensure tests run on CI pipeline by updating build.gradle test configuration

Add integration tests for payload_reader module CLI tool

The payload_reader module appears to be a standalone tool for reading APK payloads, but there's no visible test suite. Adding integration tests would validate the command-line interface works correctly with real APK files and verify output format consistency.

  • [ ] Create payload_reader/src/test/ directory with integration test class
  • [ ] Write tests that execute the CLI with sample APKs from app/channel/ and app/channel_debug/
  • [ ] Verify output parsing for channel information and signature blocks
  • [ ] Add tests for error handling (invalid APK, missing signature block, etc.)

Add GitHub Actions CI workflow for multi-version Gradle/Android compatibility

The repo uses Gradle 2.2.0 and specific Android SDK versions, but there's no visible CI configuration (no .github/workflows/ directory). Adding a GitHub Actions workflow would automatically test builds across multiple Android/Gradle versions and catch compatibility regressions early.

  • [ ] Create .github/workflows/android-build.yml with jobs for API 21-32 targets
  • [ ] Add matrix testing for Gradle versions (current 2.2.0 plus newer LTS versions)
  • [ ] Include steps: ./gradlew build, ./gradlew test, APK signing and channel package generation
  • [ ] Add status badge to README.md linking to workflow results

🌿Good first issues

  • Add unit tests for WalleChannelReader class to verify channel extraction from APK Signature Block works correctly across different Android versions (currently no test files visible in the manifest for this core functionality)
  • Add documentation and examples in app/ showing how to use the configFile option with custom metadata fields beyond just channel names (the feature exists but is under-documented with only one config.json example)
  • Create an end-to-end integration test that verifies a generated channel APK (via assembleReleaseChannels) can be installed and successfully read channel metadata at runtime on an emulator or device

Top contributors

Click to expand

📝Recent commits

Click to expand
  • f78edcf — Merge pull request #322 from OstAlex/master (achellies)
  • 1f1cbbf — update cli.jar & readme (sailor-deng)
  • 94a841b — clean code (zuochuanqiang)
  • a9f01c4 — Support Application Variants (zuochuanqiang)
  • bd556b9 — 添加Google Maven库 (zuochuanqiang)
  • 5a9e399 — Merge pull request #304 from kc910521/patch-1 (achellies)
  • ace5a99 — amend url path (kc910521)
  • 49676e8 — Merge pull request #285 from liqianjiang/lqj (achellies)
  • c3869bb — fixAPI 'variant.getAssemble()' is obsolete and has been replaced with 'variant.getAssembleProvider()'' (liqianjiang)
  • be6421b — Merge pull request #259 from yrom/fix-signature-scheme-v3 (achellies)

🔒Security observations

The codebase has critical security issues primarily related to hardcoded credentials and exposed keystores in the version control system. The use of outdated build tools (Gradle 2.2.0 from 2016) and debug signing credentials for production significantly increase the attack surface. Immediate action is required to remove sensitive files from the repository, implement secure credential management, and update development tools to recent versions. The security posture is poor and poses substantial risks to application integrity and

  • Critical · Hardcoded Keystore Credentials — app/build.gradle - signingConfigs.sign block. The signing keystore password and key password are hardcoded in the build.gradle file in plain text. The storePassword is '1234567' and keyPassword is '12345678'. This exposes the signing credentials to anyone with access to the source code, enabling APK tampering and unauthorized signing. Fix: Move credentials to a secure configuration file (gradle.properties or local.properties) that is excluded from version control (.gitignore). Use environment variables or a secrets management system for production builds. Use obfuscation or encryption for sensitive configuration data.
  • High · Debug Keystore in Repository — app/keystore/sign-debug.keystore. A debug keystore file (sign-debug.keystore) is committed to the version control repository at app/keystore/sign-debug.keystore. This keystore file can be extracted and used to sign malicious APKs that will be trusted by applications signed with this key. Fix: Remove the keystore file from the repository and add 'app/keystore/' to .gitignore. Store keystores separately in a secure location. Regenerate the keystore if it has been compromised.
  • High · Outdated Gradle Build Tools — app/build.gradle - classpath 'com.android.tools.build:gradle:2.2.0'. The project uses Gradle build tools version 2.2.0 (from 2016) which contains multiple known security vulnerabilities. This version lacks security patches for dependency resolution, signature validation, and other critical areas. Fix: Update to the latest Android Gradle Plugin version (currently 7.x or 8.x). Review and update all dependencies to their latest secure versions. Perform regular dependency audits.
  • Medium · Missing ProGuard Configuration for Release — app/build.gradle - buildTypes.release section. While ProGuard is enabled for release builds, the configuration file 'proguard-rules.pro' is not visible in the provided structure. Without proper ProGuard rules, sensitive code patterns, method names, and logic may remain exposed in the compiled APK. Fix: Review and enhance proguard-rules.pro to ensure all sensitive classes, methods, and packages are properly obfuscated. Enable code shrinking and optimization. Test the release build thoroughly to ensure functionality.
  • Medium · Unversioned Plugin Dependency — app/build.gradle - classpath "com.meituan.android.walle:plugin:latest.integration". The walle plugin dependency uses 'latest.integration' as the version, which can introduce unpredictable behavior and pull arbitrary versions including those with security vulnerabilities. Fix: Pin the plugin to a specific, tested version number (e.g., 'com.meituan.android.walle:plugin:1.x.x'). Implement dependency verification to ensure the correct artifact is downloaded. Regularly review and update to newer stable versions.
  • Medium · Insecure APK Signature Configuration — app/build.gradle - buildTypes section. Debug signing configuration is applied to both debug and release builds. The debug keystore is world-known, and using it for release builds compromises the application's integrity and user trust. Fix: Use separate keystores for debug and release builds. Ensure the release keystore is properly protected and its credentials are managed securely. Never use debug credentials for production releases.
  • Low · Deprecated Java Compilation Target — app/build.gradle - compileOptions section. The project targets Java 1.7 (sourceCompatibility and targetCompatibility), which is deprecated and lacks modern security features and performance improvements. Fix: Update to Java 8 or higher. Java 8 provides lambda expressions, improved security APIs, and better performance. Update minimum SDK version accordingly if needed.

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

🤖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/Meituan-Dianping/walle 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.

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 Meituan-Dianping/walle repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/Meituan-Dianping/walle.

What it runs against: a local clone of Meituan-Dianping/walle — 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 Meituan-Dianping/walle | 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 ≤ 746 days ago | Catches sudden abandonment since generation |

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

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "Meituan-Dianping/walle(\\.git)?\\b" \\
  && ok "origin remote is Meituan-Dianping/walle" \\
  || miss "origin remote is not Meituan-Dianping/walle (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 "payload_writer/src/main/java/com/meituan/android/walle/PayloadWriter.java" \\
  && ok "payload_writer/src/main/java/com/meituan/android/walle/PayloadWriter.java" \\
  || miss "missing critical file: payload_writer/src/main/java/com/meituan/android/walle/PayloadWriter.java"
test -f "payload_reader/src/main/java/com/meituan/android/walle/PayloadReader.java" \\
  && ok "payload_reader/src/main/java/com/meituan/android/walle/PayloadReader.java" \\
  || miss "missing critical file: payload_reader/src/main/java/com/meituan/android/walle/PayloadReader.java"
test -f "plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy" \\
  && ok "plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy" \\
  || miss "missing critical file: plugin/src/main/groovy/com/meituan/android/walle/GradlePlugin.groovy"
test -f "library/src/main/java/com/meituan/android/walle/WalleChannelReader.java" \\
  && ok "library/src/main/java/com/meituan/android/walle/WalleChannelReader.java" \\
  || miss "missing critical file: library/src/main/java/com/meituan/android/walle/WalleChannelReader.java"
test -f "payload_writer/src/main/java/com/meituan/android/walle/ApkSigningBlock.java" \\
  && ok "payload_writer/src/main/java/com/meituan/android/walle/ApkSigningBlock.java" \\
  || miss "missing critical file: payload_writer/src/main/java/com/meituan/android/walle/ApkSigningBlock.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 746 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~716d)"
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/Meituan-Dianping/walle"
  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>

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

Embed this chat in your README →

Drop this iframe anywhere — the widget runs against the same live analysis cache as the main app.

<iframe
  src="https://repopilot.app/embed/meituan-dianping/walle"
  width="100%" height="500"
  style="border:1px solid #d0d7de; border-radius:8px;"
  allow="microphone"
  loading="lazy"
></iframe>