pi-jscpd
A Pi-native, polyglot duplication guardrail powered by jscpd.
Package details
Install pi-jscpd from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-jscpd- Package
pi-jscpd- Version
0.2.2- Published
- Sep 17, 2026
- Downloads
- 612/mo · 62/wk
- Author
- revazi
- License
- MIT
- Types
- extension, skill
- Size
- 607.1 KB
- Dependencies
- 2 dependencies · 4 peers
Pi manifest JSON
{
"skills": [
"./skills/jscpd/SKILL.md"
],
"extensions": [
"./src/index.ts"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-jscpd
A quiet, read-only duplication guardrail for the Pi coding agent, powered by jscpd.
pi-jscpd detects duplicate blocks introduced during a Pi session, shows both
locations, and helps you inspect, refactor, test, and verify the result. jscpd
remains the source of truth for tokenization, clone detection, supported
languages, and statistics.
| 🤫 Quiet | 🧭 Advisory | 🌍 Polyglot | 🛟 Fail open |
|---|---|---|---|
| Clean checks stay out of the model | Never blocks a write or edits source | Uses jscpd’s languages, not a JS-only parser | A missing analyzer never breaks Pi |
Install · Usage · pi-jscpd benchmarks · Overview · Safety
📦 Install
pi install npm:pi-jscpd
pi-jscpd includes jscpd and its on-demand agent skill, so there is no
separate analyzer setup or runtime download. It prefers a compatible project or
PATH installation and otherwise uses its bundled analyzer.
Start (or restart) Pi in your project, check readiness, then scan a directory that exists in your project:
/jscpd status
/jscpd scan src
No extension configuration is required. A scoped scan finds matches only within
its targets; use /jscpd scan to include the whole project. If no compatible
binary is available, the extension stays dormant and Pi continues normally;
status explains how to recover.
In TUI sessions, the extension performs one best-effort, metadata-only npm check
and shows a warning only when a newer pi-jscpd release is available. The check
is bounded to 1.5 seconds, never sends project data, and never downloads or
installs package content. Set PI_JSCPD_DISABLE_UPDATE_NOTICE=1 (or run Pi
offline) to disable it.
⌨️ Usage
Run /jscpd to open the interactive overview. Opening it shows status only; it
never starts an implicit scan.
| Command | Purpose | |
|---|---|---|
| 🖥️ | /jscpd |
Open the responsive overview |
| 🆕 | /jscpd changed |
Show unacknowledged duplication introduced this session |
| 🔍 | /jscpd scan |
Scan the whole project |
| 📂 | /jscpd scan src tests |
Scan specific in-project files or directories |
| 📋 | /jscpd status |
Show binary, configuration, mode, and last-check status |
| ⏸️ | /jscpd off |
Disable scans for the current session |
| ▶️ | /jscpd on |
Re-enable scans for the current session |
| ❓ | /jscpd help |
Show command help |
Pi can use the same operations through the jscpd_run tool:
{
"command": "scan",
"args": ["src"]
}
Supported tool commands are scan, changed, status, off, on, and
help. In TUI mode, tool calls use a compact native transcript view for clean,
findings, unavailable, timeout, cancellation, status, and session-control
results. Expanding a result shows only its bounded public terminal presentation;
it never reveals analyzer output, temporary paths, source fragments, or the
overlay-only finding cache.
In TUI mode, /jscpd provides subcommand autocomplete with labels and
descriptions; selecting scan leaves the editor ready for an optional target.
The package also exposes /skill:jscpd. Pi advertises only the skill's concise
description at startup and loads its full workflow guidance on demand when a
duplication task matches or the user invokes the skill command. The extension
and jscpd_run tool remain usable when skills are disabled.
For short walkthroughs, see clean scans, new session duplication, and intentional duplication. A finding is a reason to inspect, not permission to refactor.
📊 pi-jscpd benchmarks
These are pi-jscpd benchmarks, not a raw jscpd CLI. Each cell is an isolated
Pi 0.85.1 /jscpd scan through this extension (packaged jscpd 5.1.2 still
detects). Full-tree snapshots, not session findings and not a quality ranking.
Median of three fresh host processes on macOS arm64 / Node 24.12.0, 2026-09-17.
| Project | Version | Blocks | Dup. lines | /jscpd scan |
|
|---|---|---|---|---|---|
| ⚡ | Vite | v8.3.0 | 524 | 5.91% | 498 ms |
| ⏱️ | React | v19.3.0 | 10,812 | 17.38% | 3.11 s |
| ⚡ | Vue | v3.5.43 | 805 | 6.71% | 451 ms |
| ⏱️ | Svelte | svelte@5.57.0 | 1,102 | 8.27% | 1.25 s |
| ⚡ | Express | v5.2.1 | 274 | 11.19% | 142 ms |
| ⏱️ | Prettier | 3.9.8 | 976 | 4.88% | 1.16 s |
⚡ under 1 s · ⏱️ 1 s or more. Totals are jscpd’s; the session lists a bounded subset. Version links open the exact scanned commit. Method and sample times: pi-jscpd benchmark method. Scheduled refresh: #111.
🔄 How session checks work
At session start, the extension captures one bounded, in-memory project baseline.
It then tracks successful writes and edits made through Pi's built-in write
and edit tools.
After Pi settles, one coalesced background check compares the current project with the baseline:
- 🤫 clean checks stay out of model context;
- ⚠️ failures remain advisory and available through
/jscpd status; - 📍 new duplicate blocks are reported with both locations;
- 🗂️ existing repository duplication is omitted from changed-only results; and
- 🚫 actionable automatic findings never trigger a surprise model turn.
Displayed findings are acknowledged for the active conversation branch so the same unchanged block is not repeatedly reported. Baselines, source bytes, verification checkpoints, and reports are never persisted.
Manual edits, shell commands, custom mutation tools, deletes, and renames are not
attributed because Pi does not provide a stable structured file list for them.
Use /jscpd scan when changes happened outside built-in write or edit.
🖥️ Interactive overview

Real Pi TUI, disposable synthetic project, explicit project scan and Enter to expand. Monochrome terminal-cell capture cropped to the overlay; no mock results. This is current duplication, not a session-delta example. Capture details and text alternative.
Bare /jscpd opens a status-first, Fallow-style bounded TUI with:
- 📋 a framed overview of mode, binary, configuration, last check, and explicit changed/project scan actions;
- 🔎 a searchable, scrollable findings navigator that retains up to 100 findings,
initially shows 10, and reveals the next 10 with
Lor by navigating past the last shown row—without rescanning or changing configuration; - 📍 both duplicate locations, size, format, session relationship, inline detail, verification, and omission/ambiguity context;
- ⌨️
j/k, arrows, Home/End, paging, expand/collapse, search, and multi-selection controls consistent with Pi Fallow's navigator; and - ✉️ a bounded
e/ahandoff that closes the overlay and loads selected findings into Pi's editor for user review.
The extra overlay cache is in-memory and TUI-only. maxFindings still caps
model/tool and explicit-command output, and cached findings are not added to
persisted session state or acknowledgement records. The editor handoff never
submits a prompt. The overview never edits source, writes jscpd configuration,
runs project tests, or refactors automatically. In RPC, JSON, and print modes,
explicit subcommands remain available and the bare command uses a bounded
non-interactive fallback.
⚙️ Configuration
Project configuration is optional:
.pi/jscpd-guardrail.json
Use .pi/jscpd-guardrail.local.json for an ignored local override. Configuration
is read only after Pi trusts the project.
{
"enabled": true,
"timeoutMs": 30000,
"maxFindings": 10,
"fallowCoexistence": "auto"
}
| Setting | Default | Allowed values |
|---|---|---|
enabled |
true |
Boolean |
timeoutMs |
30000 |
Integer from 100 to 300000 |
maxFindings |
10 |
Integer from 1 to 100 |
fallowCoexistence |
auto |
auto, on-demand, or allow |
Clone thresholds, formats, ignore rules, and other detection policy belong in
jscpd's normal configuration, such as .jscpd.json or package-level jscpd
settings. The extension does not maintain a parallel clone policy.
🤝 Fallow coexistence
| Choose | When it fits | |
|---|---|---|
| 🧬 | pi-jscpd |
Focused polyglot duplicate-block review, session deltas, or reuse of existing jscpd detection/CI policy |
| 🌿 | Pi Fallow | Broader JavaScript/TypeScript codebase analysis, including duplication, dead code, complexity, and related checks |
| 🤝 | Both | Fallow's broader checks plus scoped jscpd analysis where its formats or existing policy add value; avoid checking the same duplication scope twice without a reason |
Neither replaces the other's full workflow or your repository's tests and CI
policy. Pi Fallow can also detect duplication. With the default auto policy,
pi-jscpd conservatively detects supported signs of active Fallow duplication
analysis and moves automatic jscpd checks to on-demand mode to avoid duplicate
warnings.
Explicit /jscpd changed, project scans, and scoped scans remain available. Set
fallowCoexistence to allow when both automatic analyzers are intentional, or
on-demand to disable automatic jscpd checks explicitly.
See Fallow coexistence for the supported signals and limitations.
🔒 Safety and privacy
- 🧭 Advisory and read-only by default.
- 📦 Never downloads packages at runtime or mutates source.
- 🧱 Invokes binaries with argument arrays, never a shell command string.
- 🧹 Keeps reports in restrictive temporary directories and removes them after success, failure, timeout, cancellation, or shutdown.
- ⏱️ Bounds process time, output, report size, findings, paths, and persisted state.
- 🙈 Omits source fragments, raw child output, temporary paths, and internal fingerprints from results.
- 🔐 Reads extension configuration only for trusted projects.
- 🛟 Fails open so analyzer problems do not break the Pi session.
✅ Requirements
| Component | Supported |
|---|---|
| Node.js | >=22.19.0 <23 or >=24 <25 |
| Pi packages | >=0.84.4 <0.85.0 or >=0.85.1 <0.86.0 (tested with 0.85.1) |
| TypeBox | >=1.3.7 <2 |
| Effect | Exact reviewed 3.22.1 runtime foundation |
| jscpd | Bundled 5.1.2; compatible project-local or PATH v5 installations are preferred |
See the compatibility policy for the exact tested fixtures and certification matrix.
💬 Share feedback
Tried a scan or the onboarding examples? Use the optional validation and adoption feedback form. It asks for version information and coarse size, latency, and finding-review buckets; “Unknown” and “Not tested” are welcome. No new scan is required.
Submissions are public and manual—no telemetry or automatic submission is added. Do not include credentials, private paths, source fragments, raw reports, raw child output, terminal captures, or account/repository identifiers. For a reproducible defect, prefer the bug report; report vulnerabilities privately.
🧩 More Pi packages by Revaz
| Package | Purpose |
|---|---|
pi-fallow |
Fallow codebase intelligence for Pi |
pi-reads |
Source capture, cited reading, Obsidian, EPUB, PDF, and Kindle workflows |
pi-career |
Deterministic resume and career workflows |
pi-tmux-orchestrator |
Multi-agent coordination in tmux |
@tasklight/pi-tasklight |
Tasklight notifications for Pi |
🛠️ Development
npm ci --ignore-scripts
npm run format
npm run docs:check
npm run repo:hygiene
npm run check
npm run pack:certify
npm run check includes the Effect runtime-boundary architecture gate.
npm run release:check runs the complete documentation, hygiene, compatibility,
architecture, test, and packed-artifact release gate. Tests are network-free and
use deterministic fake jscpd executables and Effect layers.
The repository-owned .jscpd.json excludes dependency/build
artifacts, caches, source maps, snapshots, archives, and common package-manager
lockfiles while continuing to analyze src, test, scripts, documentation, and
workflow files.
Useful documentation:
- 📊 pi-jscpd benchmarks
- ✨ First scans and safe finding review
- 🧬 Effect architecture and conformance
- ⏱️ Automatic checkpoint lifecycle
- 🖥️
/jscpdoverlay contract - 🤝 Fallow coexistence
- ✅ Compatibility and packed-artifact certification
- 📋 Real-project validation evidence
- 🏷️ Release preparation and publication policy
- 👋 Contributing
- 🔐 Security policy
- 📝 Changelog
📄 License
MIT © 2026 Revaz Zakalashvili