pi-jscpd

A Pi-native, polyglot duplication guardrail powered by jscpd.

Packages

Package details

extensionskill

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

CI npm npm downloads license: MIT GitHub issues

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 /jscpd findings view: one Python duplicate block, both current locations, and advisory review guidance

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 L or 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/a handoff 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:

📄 License

MIT © 2026 Revaz Zakalashvili