RepoPilotOpen in app →

blinksh/blink

Blink Mobile Shell for iOS (Mosh based)

Mixed

Single-maintainer risk — review before adopting

worst of 4 axes
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; no tests detected

Fork & modifyHealthy

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

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit today
  • 4 active contributors
  • GPL-3.0 licensed
Show 5 more →
  • CI configured
  • Small team — 4 contributors active in recent commits
  • Single-maintainer risk — top contributor 81% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

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

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

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/blinksh/blink?axis=fork)](https://repopilot.app/r/blinksh/blink)

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

Onboarding doc

Onboarding: blinksh/blink

Generated by RepoPilot · 2026-05-10 · 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/blinksh/blink 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 — Single-maintainer risk — review before adopting

  • Last commit today
  • 4 active contributors
  • GPL-3.0 licensed
  • CI configured
  • ⚠ Small team — 4 contributors active in recent commits
  • ⚠ Single-maintainer risk — top contributor 81% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility
  • ⚠ 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 blinksh/blink repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/blinksh/blink.

What it runs against: a local clone of blinksh/blink — 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 blinksh/blink | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch raw exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |

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

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "blinksh/blink(\\.git)?\\b" \\
  && ok "origin remote is blinksh/blink" \\
  || miss "origin remote is not blinksh/blink (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify raw >/dev/null 2>&1 \\
  && ok "default branch raw exists" \\
  || miss "default branch raw no longer exists"

# 4. Critical files exist
test -f "Blink/AppDelegate.h" \\
  && ok "Blink/AppDelegate.h" \\
  || miss "missing critical file: Blink/AppDelegate.h"
test -f "Blink/Commands/ssh/SSHCommand.swift" \\
  && ok "Blink/Commands/ssh/SSHCommand.swift" \\
  || miss "missing critical file: Blink/Commands/ssh/SSHCommand.swift"
test -f "Blink/Commands/mosh/MoshCommand.swift" \\
  && ok "Blink/Commands/mosh/MoshCommand.swift" \\
  || miss "missing critical file: Blink/Commands/mosh/MoshCommand.swift"
test -f "Blink/Complete.swift" \\
  && ok "Blink/Complete.swift" \\
  || miss "missing critical file: Blink/Complete.swift"
test -f "Blink/BrowserController.swift" \\
  && ok "Blink/BrowserController.swift" \\
  || miss "missing critical file: Blink/BrowserController.swift"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
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/blinksh/blink"
  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

Blink is a professional-grade terminal emulator for iOS that combines Mosh (mobile shell) for reliable persistent connections with SSH, delivering desktop-quality terminal experience on iPhone/iPad. It renders using Chromium's HTerm for fast, accurate terminal display and includes a suite of Unix utilities via the ios_system.framework, enabling file management, networking (curl/scp/sftp), compression, and script execution (Python/Lua) directly on iOS. Monolithic iOS app structure: Blink/ contains the main application with AppDelegate and terminal UI controllers (BrowserController.swift); Commands/ houses shell command implementations (browse.swift, code.swift, config.m, device_info.m); BlinkFileProvider and BlinkFileProviderExtension are separate targets for iOS file system integration; AppKitBridge handles macOS compatibility. Swift dominates new code while Objective-C legacy remains in signal handling (TokioSignals.m) and menu systems (BlinkMenu.m).

👥Who it's for

DevOps engineers, system administrators, and developers who need to manage remote servers from iOS devices without losing connections during network transitions. Users who require full keyboard customization (Vim/Emacs mappings), custom themes/fonts, and split-view multitasking alongside terminal work.

🌱Maturity & risk

Production-ready. The codebase is substantial (~2.6M lines across Swift/Objective-C), has multiple xcschemes for testing (BlinkTests, SSHTests, BlinkFilesTests), uses GitHub Actions CI/CD (build.yml), and maintains comprehensive documentation (BUILD.md, Appearance-Style-and-Display.md). The project is actively maintained with organized issue templates and workspace configuration, indicating mature release practices.

Moderate risk. The project depends on external precompiled frameworks (ios_system.framework), which creates a black-box dependency not version-controlled in the repo. The split between Swift (1.9M) and Objective-C (656K) introduces legacy code maintenance burden. No visible dependency lock file (Cartfile.resolved or similar) in the file list; AppKit bridge and file provider extensions add iOS system integration complexity that can break across OS versions.

Active areas of work

Unable to determine from file snapshot alone. The presence of multiple xcschemes (BlinkSnippets.xcscheme suggests a snippets feature), file provider extensions (BlinkFileProviderExtensionUI), and bridge components indicate ongoing features, but specific commit messages and PR activity are not visible in the provided file structure. Review .github/workflows/build.yml for CI activity and GitHub Releases for recent version changes.

🚀Get running

Clone and open the Xcode workspace: git clone https://github.com/blinksh/blink.git && cd blink && open Blink.xcodeproj. Install submodule dependencies via git submodule update --init --recursive (referenced in .gitmodules). Build for iOS 13+ using Xcode 12+ targeting an iPhone/iPad simulator or device.

Daily commands: Open Blink.xcodeproj in Xcode, select Blink scheme, and build for your target device/simulator using Cmd+B. Run tests via Cmd+U targeting BlinkTests or SSHTests schemes. No npm/pip setup required; all dependencies are framework-based or precompiled.

🗺️Map of the codebase

  • Blink/AppDelegate.h — Main application entry point and lifecycle management for the iOS app.
  • Blink/Commands/ssh/SSHCommand.swift — Core SSH command implementation; fundamental to remote connection handling.
  • Blink/Commands/mosh/MoshCommand.swift — Mosh protocol orchestration; critical for stable mobile connections.
  • Blink/Complete.swift — Command completion and shell prompt logic; essential for terminal UX.
  • Blink/BrowserController.swift — Terminal view controller managing UI rendering and input/output.
  • Blink/Commands/ssh/SSHPool.swift — Connection pooling and session management for SSH clients.
  • Blink/Migrator/Migrator.swift — Data migration pipeline for app versioning; prevents data loss across updates.

🛠️How to make changes

Add a new built-in shell command

  1. Create a new .swift or .m file in Blink/Commands/ directory (Blink/Commands/)
  2. Implement the command handler following patterns in Blink/Commands/browse.swift or Blink/Commands/device_info.m (Blink/Commands/browse.swift)
  3. Register the command in the command dispatcher (likely in app initialization or shell execution) (Blink/Complete.swift)
  4. Add completion entries to Blink/CompleteUtils.swift if the command has arguments (Blink/CompleteUtils.swift)
  5. Update help documentation in Blink/Commands/help.m (Blink/Commands/help.m)

Add SSH feature or key management capability

  1. Add logic to Blink/Commands/ssh/SSHCommand.swift for command-line argument handling (Blink/Commands/ssh/SSHCommand.swift)
  2. Implement key agent interactions in Blink/Commands/ssh/SSHDefaultAgent.swift or create new agent file (Blink/Commands/ssh/SSHDefaultAgent.swift)
  3. Update SSH config provider if new config options are needed in Blink/Commands/ssh/SSHConfigProvider.swift (Blink/Commands/ssh/SSHConfigProvider.swift)
  4. Add tests or validation in command initialization flow (Blink/Commands/ssh/Helpers.swift)

Add a new UI view or terminal interaction feature

  1. Create new .swift file in Blink/ root or appropriate subdirectory (following LockView.swift or PipFaceCam.swift pattern) (Blink/LockView.swift)
  2. Add view controller integration points to Blink/BrowserController.swift (Blink/BrowserController.swift)
  3. Register keyboard handling in Blink/KBTracker.swift if input is needed (Blink/KBTracker.swift)
  4. Add menu items or actions to Blink/MenuController.swift if accessible from UI menu (Blink/MenuController.swift)

Handle app migration or version upgrade

  1. Create new migration file in Blink/Migrator/ following naming pattern XYZZ0Migration.swift (e.g., 1900Migration.swift) (Blink/Migrator/1870Migration.swift)
  2. Implement migration logic with data transformation and validation (Blink/Migrator/1870Migration.swift)
  3. Register migration in Blink/Migrator/Migrator.swift in version sequence (Blink/Migrator/Migrator.swift)
  4. Update app version in Blink/Info.plist and Blink.xcodeproj (Blink/Info.plist)

🔧Why these technologies

  • Mosh (Mobile Shell) — Provides stable connections over unstable mobile networks using UDP; allows seamless roaming between WiFi/cellular without disconnection.
  • SSH (OpenSSH) — Industry-standard secure remote access protocol; integrated for key-based authentication and traditional terminal sessions.
  • HTerm (Chromium terminal) — Fast, battle-tested terminal rendering engine with support for encodings and special characters; avoids reinventing wheel.
  • Swift + Objective-C hybrid — Leverages modern Swift for new features while maintaining C/Objective-C integration for system-level and legacy components.
  • iOS platform APIs (UIKit, Entitlements) — Native iOS integration for file provider extension, geolocation, and system permissions.

⚖️Trade-offs already made

  • Mosh over pure SSH
    • Why: SSH connections drop when network changes; Mosh adds complexity but guarantees always-on experience.
    • Consequence: Requires server-side mosh daemon; adds UDP traffic; slightly higher latency for initial setup.

🪤Traps & gotchas

ios_system.framework is precompiled and not in the repo—modifications to built-in commands require rebuilding that external dependency separately. Mosh integration likely requires the mosh server installed on target Unix systems; Blink alone won't function without it. File provider extensions (BlinkFileProvider) require specific entitlements and iOS File Provider APIs that can break across iOS versions. No npm/pod lock file visible; submodules in .gitmodules must be cloned manually or CI will fail. Objective-C legacy code (AppDelegate.m, BlinkMenu.m) interoperates with Swift via Blink-bridge.h—changes to bridging require careful testing.

🏗️Architecture

💡Concepts to learn

  • Mosh (Mobile Shell) — Blink's core differentiator—Mosh maintains persistent connections across network changes (WiFi→cellular), unlike SSH; understanding Mosh's UDP-based state synchronization is essential for debugging connection issues
  • TTY/PTY (Pseudo-Terminal) — Both Mosh and SSH sessions require pseudoterminal allocation for interactive shells; critical for understanding how Blink multiplexes multiple TTY sessions and handles terminal size negotiation
  • iOS File Provider Extension — BlinkFileProvider and related targets implement the NSFileProvider API, exposing remote files via iOS Files app; this is Apple's modern approach to cloud storage integration and involves NSFileProviderExtension lifecycle
  • Swift-Objective-C Bridging — Blink mixes 1.9M Swift lines with 656K Objective-C; the Blink-bridge.h file is the interop layer. Understanding bridging headers and module maps is mandatory for modifying core backend communication
  • UIGestureRecognizer & Swipe Navigation — Blink's swipe-to-switch-sessions and pinch-to-zoom are UIGestureRecognizer implementations in BrowserController; critical for understanding the terminal UI responsiveness and multi-session UX
  • iOS Entitlements & App Sandbox — Blink.entitlements defines what system resources (network, file access, Bluetooth keyboards) the app can use; restrictive iOS sandbox means file provider and SSH key storage require special entitlements
  • Signal Handling & Process Management — TokioSignals.m handles Unix signals (SIGTERM, SIGCHLD, etc.) for graceful command termination in ios_system.framework; mishandled signals cause zombie processes or app crashes
  • mobile-shell/mosh — The upstream Mosh project that Blink packages and integrates; essential for understanding connection stability features
  • OpenSSH/openssh-portable — SSH backend used alongside Mosh in Blink for key-based authentication and traditional connections
  • chromium/hterm — Chromium's terminal emulator used by Blink for fast, accurate terminal rendering with proper encoding support
  • nikitabobko/AnyBar — Related iOS utility showcasing similar deep system integration and custom terminal-like interaction patterns on iOS
  • blinksh/ios_system — The external ios_system.framework source (if open); provides the Unix command utilities (ls, curl, tar, etc.) that Blink shells out to

🪄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 SSH file transfer operations in Blink/Commands/ssh/CopyFiles.swift

The file structure shows CopyFiles.swift exists but there's an SSHTests.xcscheme in the project, indicating a test target exists. SSH file transfer is a critical feature for a mobile terminal, yet no corresponding test file is visible in the repo. Adding comprehensive unit tests for SCP/SFTP operations would improve reliability and catch regressions in this core functionality.

  • [ ] Create Tests/SSH/CopyFilesTests.swift with test cases for local→remote and remote→local file transfers
  • [ ] Add tests for error handling (permission denied, file not found, network interruption simulation)
  • [ ] Add tests for path normalization and special character handling in filenames
  • [ ] Ensure tests are referenced in SSHTests.xcscheme and run in CI via build.yml

Add comprehensive CI workflow for Mosh command validation in .github/workflows/

The repo has a build.yml workflow but Mosh is a critical differentiator for Blink (mentioned prominently in README). The Mosh command structure (MoshCommand.swift, MoshClientParams.swift, MoshServerParams.swift, MoshBootstrap.swift) is complex but lacks visible integration tests. Adding a dedicated GitHub Actions workflow would validate Mosh parameter parsing, server bootstrap logic, and client initialization on every PR.

  • [ ] Create .github/workflows/mosh-integration-tests.yml to run Mosh-specific unit tests
  • [ ] Add tests in Tests/Mosh/ for MoshClientParams.swift and MoshServerParams.swift parameter validation
  • [ ] Add tests for MoshBootstrap.swift to verify server connection initialization logic
  • [ ] Configure workflow to run on PR and push to main branch

Add missing documentation for custom Blink command implementations in BUILD.md

The Commands/ directory shows many custom commands (browse.swift, code.swift, facecam.swift, geo.m, etc.) that appear to be Blink-specific extensions beyond standard SSH/Mosh. However, BUILD.md doesn't explain how contributors can add new commands or the command plugin architecture. This creates friction for potential contributors wanting to extend Blink's functionality.

  • [ ] Expand BUILD.md with a 'Creating Custom Commands' section explaining the command registration pattern
  • [ ] Document the difference between .swift and .m implementations (when to use each) by examining existing commands
  • [ ] Add a minimal example command scaffolding (e.g., 'Creating a Hello World Command') referencing Blink/Commands/help.m
  • [ ] Document how commands are registered in Blink/Commands/ and how they're invoked from the terminal

🌿Good first issues

  • Add unit tests for individual commands in Blink/Commands/ (e.g., BrowseCommandTests.swift, CodeCommandTests.swift). Many .m/.swift files lack corresponding test files in xcschemes like BlinkTests; start with a single command's test suite.
  • Document keyboard shortcut and gesture mappings in Appearance-Style-and-Display.md. The README mentions Caps key customization and swipe/pinch gestures, but there's no centralized reference for all gesture handlers—extract from BrowserController.swift and create a user-facing guide.
  • Create a BlinkSnippets example template or tutorial. The BlinkSnippets.xcscheme exists but no docs explain how users create/manage snippets (Python/Lua scripts mentioned in README). Write a Snippets.md with working examples matching the ios_system.framework capabilities (curl, tar, etc.).

Top contributors

Click to expand

📝Recent commits

Click to expand
  • a90b442 — Created Default style (Carlos Cabanero)
  • ad5fd25 — Snippets control the input when displaying Scratch mode directly. (Carlos Cabanero)
  • ab2822e — TermDevice.SnippetReceiver decides how to send the content (Carlos Cabanero)
  • 6edcaad — Create Snip now with explicit configure for shell (Carlos Cabanero)
  • d1ee516 — Files.app validation restored (Carlos Cabanero)
  • 975499f — Merge branch 'layout-and-payload' into raw (Carlos Cabanero)
  • b12daab — v18.6.0 build 1097 (Carlos Cabanero)
  • ba4dca8 — Merge branch 'appearance-style-and-display' into raw (Carlos Cabanero)
  • 00dad66 — New Settings for Style and Display (Carlos Cabanero)
  • 2c0d46a — SessionRegistry migration clean-up for 18.7.0 (Carlos Cabanero)

🔒Security observations

  • High · Potential Hardcoded Credentials in SSH Configuration — Blink/Commands/ssh/. The codebase contains SSH-related command handlers (Commands/ssh/) that may be processing or storing SSH credentials. Without access to the full implementation, there is a risk that SSH keys, passwords, or authentication tokens could be hardcoded or improperly stored in memory. Fix: Ensure all SSH credentials are loaded from secure storage (Keychain on iOS), never hardcoded. Implement proper credential lifecycle management with secure memory handling and ensure sensitive data is cleared from memory after use.
  • High · Insecure Inter-Process Communication Potential — Blink/AppDelegate.h, AppKitBridge/, Blink/Blink-bridge.h. The codebase includes native code bridges (AppKitBridge, Blink-bridge.h) and multiple command handlers that interface between Swift/Objective-C layers. Without visible input validation, there's a risk of unsafe inter-process communication. Fix: Implement strict input validation and sanitization at all bridging points. Use typed interfaces and avoid passing raw strings between layers. Apply principle of least privilege to bridged functions.
  • High · Mosh and SSH Protocol Implementation Risks — Blink/Commands/mosh/, Blink/Commands/ssh/. The application implements Mosh and SSH clients with custom bootstrap and parameter handling. Custom cryptographic or protocol implementations are high-risk for security vulnerabilities including man-in-the-middle attacks, incorrect certificate validation, or weak cipher usage. Fix: Use well-tested, maintained libraries (libmosh, libssh) rather than custom implementations. Ensure strict certificate validation, proper hostname verification, and use only strong cryptographic algorithms. Conduct security audit of protocol implementations.
  • Medium · Potential Command Injection in Shell Commands — Blink/Commands/. Multiple command handlers exist (browse.swift, code.swift, facecam.swift, help.m, etc.) that may execute shell commands or process user input. Without visible input sanitization, there's a risk of command injection vulnerabilities. Fix: Never pass user input directly to shell execution. Use parameterized APIs, whitelist allowed characters, and avoid shell interpretation. Use ProcessInfo or equivalent safe APIs for command execution.
  • Medium · Missing Dependency Version Pinning — Dependencies/. The Package.resolved file (or equivalent) was not provided. Without explicit dependency pinning, the application may be vulnerable to supply chain attacks through dependency confusion or malicious package updates. Fix: Maintain a comprehensive lock file (Package.resolved) with pinned versions for all dependencies. Regularly audit dependencies for known vulnerabilities using tools like OWASP Dependency-Check or Swift Package Manager security features.
  • Medium · Entitlements Configuration Review Required — Blink/Blink.entitlements. The application has an entitlements file (Blink.entitlements) but its contents are not visible. Over-privileged entitlements could allow unauthorized access to system resources or sensitive user data. Fix: Review entitlements to ensure only necessary capabilities are requested. Follow principle of least privilege. Avoid requesting access to sensitive APIs unless required (Contacts, Calendar, Photos, etc.).
  • Medium · File Provider Extension Security — BlinkFileProvider*, BlinkFilesTests*. The codebase includes BlinkFileProvider and BlinkFileProviderExtension schemes. File providers have broad access to file system operations and must be carefully secured against unauthorized file access or modification. Fix: Implement strict access control in file provider extensions. Validate all file paths, implement proper sandboxing, and log all file access operations. Test for path traversal vulnerabilities.
  • Medium · Native Code Module Risk (OpenSSH Compatibility) — Blink/Commands/openssh/openbsd-compat.h. The codebase includes OpenBSD compatibility headers (openbsd-compat.h), suggesting use of OpenSSH components. Legacy native code may contain unpatched vulnerabilities. Fix: Keep OpenSSH components updated to latest stable versions. Monitor CVE databases for vulnerabilities. Consider using modern SSH libraries instead of legacy code.
  • Low · Lack of Security Testing Documentation — undefined. undefined Fix: undefined

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 · blinksh/blink — RepoPilot