PowerShell/PSReadLine
A bash inspired readline implementation for PowerShell
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 4w ago
- ✓17 active contributors
- ✓BSD-2-Clause licensed
Show 3 more →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 70% of recent commits
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 "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/powershell/psreadline)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/powershell/psreadline on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: PowerShell/PSReadLine
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:
- 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/PowerShell/PSReadLine 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
GO — Healthy across the board
- Last commit 4w ago
- 17 active contributors
- BSD-2-Clause licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 70% of recent commits
<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 PowerShell/PSReadLine
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/PowerShell/PSReadLine.
What it runs against: a local clone of PowerShell/PSReadLine — 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 PowerShell/PSReadLine | Confirms the artifact applies here, not a fork |
| 2 | License is still BSD-2-Clause | 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 ≤ 61 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of PowerShell/PSReadLine. If you don't
# have one yet, run these first:
#
# git clone https://github.com/PowerShell/PSReadLine.git
# cd PSReadLine
#
# 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 PowerShell/PSReadLine and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "PowerShell/PSReadLine(\\.git)?\\b" \\
&& ok "origin remote is PowerShell/PSReadLine" \\
|| miss "origin remote is not PowerShell/PSReadLine (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(BSD-2-Clause)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"BSD-2-Clause\"" package.json 2>/dev/null) \\
&& ok "license is BSD-2-Clause" \\
|| miss "license drift — was BSD-2-Clause 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 "PSReadLine/ReadLine.cs" \\
&& ok "PSReadLine/ReadLine.cs" \\
|| miss "missing critical file: PSReadLine/ReadLine.cs"
test -f "PSReadLine/PublicAPI.cs" \\
&& ok "PSReadLine/PublicAPI.cs" \\
|| miss "missing critical file: PSReadLine/PublicAPI.cs"
test -f "PSReadLine/KeyBindings.cs" \\
&& ok "PSReadLine/KeyBindings.cs" \\
|| miss "missing critical file: PSReadLine/KeyBindings.cs"
test -f "PSReadLine/Render.cs" \\
&& ok "PSReadLine/Render.cs" \\
|| miss "missing critical file: PSReadLine/Render.cs"
test -f "PSReadLine/Completion.cs" \\
&& ok "PSReadLine/Completion.cs" \\
|| miss "missing critical file: PSReadLine/Completion.cs"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 61 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~31d)"
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/PowerShell/PSReadLine"
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
A software project. See architecture tab.
👥Who it's for
Developers.
🌱Maturity & risk
See activity metrics.
Standard open source risks apply.
Active areas of work
Check recent commits.
🚀Get running
Check README for instructions.
🗺️Map of the codebase
PSReadLine/ReadLine.cs— Core entry point and main loop for the readline implementation—handles user input, rendering, and orchestrates all editing operations.PSReadLine/PublicAPI.cs— Exposes all public cmdlets and functions that users and extensions interact with; defines the module's public contract.PSReadLine/KeyBindings.cs— Key binding engine that maps console key chords to editing actions; critical for customization and command dispatch.PSReadLine/Render.cs— Rendering pipeline for syntax coloring and screen updates; responsible for visual output and performance-critical display logic.PSReadLine/Completion.cs— Completion system providing bash-style tab completion and menu-based completion UI; core UX feature.PSReadLine/History.cs— History management including persistence, search (CTRL-R), and cross-session sharing; critical for command recall.PSReadLine/ConsoleLib.cs— Low-level console I/O abstraction wrapping Windows console APIs; foundation for all input/output operations.
🛠️How to make changes
Add a new editing command (e.g., custom deletion or movement)
- Define the action method in BasicEditing.cs, Movement.cs, or a new partial class, following the pattern:
[Export] public static void MyCustomAction(ConsoleKeyInfo? key = null)(PSReadLine/BasicEditing.cs) - Register key bindings in KeyBindings.cs by adding entries to the
_builtInKeyBindingsdictionary, mapping key chords to the action (PSReadLine/KeyBindings.cs) - For Vi mode, add parallel implementations in Movement.vi.cs or other .vi.cs files if the command has mode-specific behavior (
PSReadLine/Movement.vi.cs) - Test the command by creating or updating test cases in test/ directory (e.g., BasicEditingTest.cs) and run via
Invoke-Build Test(test/BasicEditingTest.cs)
Add a new configuration option
- Add a public property to the
PSReadLineOptionsclass in Options.cs with getter/setter and XML documentation (PSReadLine/Options.cs) - Expose the option in the Set-PSReadLineOption and Get-PSReadLineOption cmdlets in PublicAPI.cs by adding parameters (
PSReadLine/PublicAPI.cs) - If rendering or display changes are needed, update Render.cs or relevant rendering code to check the option (
PSReadLine/Render.cs) - Document the option in the cmdlet help (inline XML comments in PublicAPI.cs) (
PSReadLine/PublicAPI.cs)
Add a new Vi command or key binding
- Implement the Vi-specific action in Movement.vi.cs, Replace.vi.cs, or other .vi.cs files, following Vi semantics (motions, operators, text objects) (
PSReadLine/Movement.vi.cs) - Register the key binding in KeyBindings.vi.cs by adding entries to the Vi mode key binding dictionary (
PSReadLine/KeyBindings.vi.cs) - For text object support (e.g., 'iw', 'aw'), implement in TextObjects.Vi.cs (
PSReadLine/TextObjects.Vi.cs) - Add or update tests in test/BasicEditingTest.VI.cs or test/MovementTest.VI.cs (
test/MovementTest.VI.cs)
Add a new completion provider or behavior
- Extend or add logic in Completion.cs to generate completions (e.g., call PowerShell CommandCompletion API or custom logic) (
PSReadLine/Completion.cs) - If menu UI or rendering is needed, update the
ICompletionUIor related classes in Completion.cs or Prediction.Views.cs (PSReadLine/Completion.cs) - Register the completion provider in the key binding to trigger on Tab or via Set-PSReadLineKeyHandler (
PSReadLine/KeyBindings.cs) - Add test cases in test/CompletionTest.cs to verify completion candidates and menu behavior (
test/CompletionTest.cs)
🔧Why these technologies
- C# and .NET Framework/Core — PowerShell is written in C# and hosted on .NET; PSReadLine is a native module that must integrate directly with the PowerShell host.
- Windows Console API (PlatformWindows.cs) — Provides low-level, high-performance access to console input and output, essential for efficient rendering and key capture on Windows.
- MEF (Managed Extensibility Framework) / Export attributes — Dynamically discovers and registers editing commands and key handlers without hardcoded lists; enables modularity.
- PowerShell tokenizer and AST — Syntax coloring and error detection rely on PowerShell's own tokenization and abstract syntax tree parsing for accurate highlighting.
⚖️Trade-offs already made
-
Single-threaded, synchronous input loop in ReadLine.cs
- Why: Console readline is inherently synchronous; maintaining simplicity and avoiding race conditions.
- Consequence: Long-running completion or prediction operations can block UI responsiveness; mitigated by timeouts in completion logic.
-
Separate Vi and Emacs/Cmd mode implementations (multiple .vi.cs files)
- Why: undefined
- Consequence: undefined
🪤Traps & gotchas
Standard debugging applies.
🏗️Architecture
🪄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 comprehensive unit tests for Vi mode editing operations
The repo has extensive Vi mode implementation (Movement.vi.cs, Movement.vi.multiline.cs, Completion.vi.cs, Replace.vi.cs, KeyBindings.vi.cs) but lacks dedicated test coverage. A new contributor could create a test suite validating Vi-specific operations like multiline editing, text objects, and mode transitions. This is critical because Vi mode is a complex feature with many edge cases that could regress.
- [ ] Create PSReadLine.Tests/ViMode.Tests.ps1 for Vi-specific key bindings and movement
- [ ] Add tests in PSReadLine.Tests/ViMode.Completion.Tests.ps1 for Vi completion behavior in Completion.vi.cs
- [ ] Add tests for multiline Vi operations referencing Movement.vi.multiline.cs logic
- [ ] Test Vi text objects and replace operations from TextObjects.Vi.cs and Replace.vi.cs
- [ ] Run tests against MockPSConsole to validate console interaction
Add GitHub Actions workflow for cross-platform testing (Linux/macOS/Windows)
The repo currently uses AppVeyor (deprecated) and has commented-out Azure Pipeline config. PSReadLine is complex and cross-platform support is critical (it targets PowerShell 3+). A new contributor should modernize CI/CD by creating a GitHub Actions workflow that tests on Windows, Ubuntu, and macOS to catch platform-specific readline/console issues early.
- [ ] Create .github/workflows/test.yml with matrix strategy for windows-latest, ubuntu-latest, macos-latest
- [ ] Add build steps: restore dependencies, build PSReadLine.csproj, run pester tests
- [ ] Include validation for both Emacs and Vi key binding modes across platforms
- [ ] Test against multiple PowerShell versions (7.x minimum) using pwsh
- [ ] Remove or replace deprecated AppVeyor badge references in README.md
Add focused Pester tests for Prediction feature
Prediction.cs, Prediction.Entry.cs, and Prediction.Views.cs represent substantial new functionality but lack dedicated test coverage visible in the repo structure. A new contributor could write integration tests validating prediction display, filtering, and interaction with the completion pipeline—this is especially valuable as predictions affect UX across all editing modes.
- [ ] Create PSReadLine.Tests/Prediction.Tests.ps1 testing Prediction.cs entry creation and filtering
- [ ] Add PSReadLine.Tests/Prediction.Views.Tests.ps1 for view rendering from Prediction.Views.cs
- [ ] Test prediction behavior with dynamic help and completion sources
- [ ] Validate prediction interaction with Vi/Emacs modes and multiline editing
- [ ] Mock console I/O using MockPSConsole to test display accuracy
🌿Good first issues
Check the issue tracker.
⭐Top contributors
Click to expand
Top contributors
- @daxian-dbw — 70 commits
- @andyleejordan — 11 commits
- @StevenBucher98 — 3 commits
- @springcomp — 2 commits
- @jazzdelightsme — 2 commits
📝Recent commits
Click to expand
Recent commits
2984546— FixViFindBraceto search for brace the same asvimwhen current char is not a brace (#4862) (sharpchen)caa53f8— Update VSCode tasks for rewritten build script (#5118) (andyleejordan)e266ca6— Fix BackwardKillLine length calculation for multiline input (#5102) (Snowy117)554035e— Ensure CodeQL scan is published to database (#5085) (anamnavi)e563a2f— Migrate PSReadLine to target .NET 8.0 (#5055) (jshigetomi)6fa5711— Merge the v2.4.5 release branch back to master (#4982) (daxian-dbw)98d5610— Prepare for the v2.4.5 release of PSReadLine (daxian-dbw)b6c3e48— Fix a null reference exception when showing parameter help (#4971) (daxian-dbw)4a72454— Add theScreenReaderModeEnabledproperty to formatting (#4970) (daxian-dbw)d642cc6— ReplaceDOTNET_SKIP_FIRST_TIME_EXPERIENCEwithDOTNET_NOLOGO(#4916) (xtqqczze)
🔒Security observations
PSReadLine is a well-structured PowerShell module with reasonable security practices. The main security concerns are related to handling of untrusted user input (clipboard, console input, command history) and potential exposure of sensitive information through history files. No hardcoded secrets were identified in the file structure. The codebase lacks visible evidence of SQL injection or XSS vulnerabilities (not applicable for a PowerShell module). The primary recommendations involve implementing stricter input validation, sanitizing sensitive data from history, and securing history file storage. The project demonstrates good security hygiene with dedicated security policy documentation (.github/SECURITY.md).
- Medium · Potential Unvalidated Input in ConsoleKeyChordConverter —
PSReadLine/ConsoleKeyChordConverter.cs. ConsoleKeyChordConverter.cs may process untrusted console input without proper validation. Key chord conversion from user input could potentially be exploited for injection attacks if the converted chords are used in command execution contexts. Fix: Implement strict input validation and sanitization for all console input processing. Validate key chord values against a whitelist of expected patterns before conversion. - Medium · Clipboard Operations Without Sanitization —
PSReadLine/Clipboard.cs. Clipboard.cs handles clipboard data which may come from untrusted external sources. Without proper validation, malicious clipboard content could be pasted into PowerShell commands, potentially leading to command injection attacks. Fix: Implement validation and sanitization of clipboard content before use. Consider warning users when pasting large amounts of data or content from external sources. Validate against dangerous PowerShell syntax patterns. - Medium · Dynamic Code Evaluation Risk in Prediction and Completion —
PSReadLine/Prediction.cs, PSReadLine/Completion.cs. Prediction.cs and Completion.cs files handle dynamic code suggestion and completion. If predictions or completions are generated based on unvalidated user input or external sources, this could enable code injection or exposure of sensitive information from command history. Fix: Ensure all dynamic code suggestions are generated from safe sources. Implement strict filtering of sensitive data (passwords, tokens) from history and predictions. Validate completion sources thoroughly. - Low · History File Security —
PSReadLine/History.cs, PSReadLine/HistoryQueue.cs. History.cs manages command history which may contain sensitive information like API keys, passwords, or personal data. File permissions and encryption of history files should be reviewed to prevent unauthorized access. Fix: Ensure history files are stored with restricted permissions (readable only by the owner). Implement encryption for sensitive history data. Provide configuration options to exclude sensitive commands from history or mask sensitive values. - Low · Potential Resource Exhaustion in Rendering —
PSReadLine/Render.cs, PSReadLine/DisplayBlockBase.cs. Render.cs and Display-related files handle large text rendering. Very large input or specially crafted input could potentially cause excessive memory consumption or performance degradation. Fix: Implement reasonable limits on input buffer sizes and rendered content. Add resource consumption checks for large operations. Consider implementing timeouts for rendering operations. - Low · Vi Mode Implementation Complexity —
PSReadLine/Movement.vi.cs, PSReadLine/KeyBindings.vi.cs, PSReadLine/Completion.vi.cs, PSReadLine/Replace.vi.cs. Multiple Vi mode implementation files (Movement.vi.cs, KeyBindings.vi.cs, etc.) increase complexity and potential for logic errors. Vi mode specific input handling could have unintended side effects. Fix: Conduct thorough security review of Vi mode implementations. Add comprehensive unit tests for Vi mode key bindings and edge cases. Document security-critical behaviors clearly.
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.