| Version | Supported |
|---|---|
| 0.2.x | ✅ |
| 0.1.x | ✅ |
If you discover a security vulnerability, please report it responsibly:
- Do NOT open a public GitHub issue.
- Prefer GitHub's private reporting flow from the Security tab or the repository's advisory form: https://github.com/jackbatzner/copilot-insights/security/advisories/new.
- If the advisory form is unavailable, contact the maintainer privately before sharing any details.
- Include a description of the vulnerability, steps to reproduce, and potential impact.
We will acknowledge receipt within 48 hours and aim to release a patch within 7 days for critical issues.
Copilot Insights is a local-only development tool:
- The server binds to
127.0.0.1(localhost only) — it is not accessible from the network. - CORS is restricted to
localhostorigins. - The app reads your local Copilot session database (
~/.copilot/session-store.db) in read-only mode. - Goal data is stored locally at
~/.copilot/insights-goals.json. - No data is transmitted to external services.
- No authentication is required because the server is only accessible to the local user.
- The
POST /api/practice/analyzeendpoint enforces a 10,000 character input limit and validates that the body contains a string. - The
GET /api/practice/libraryendpoint validates tag query parameters against a whitelist of known tags — unrecognized tags are silently dropped. - The
GET /api/practice/challengeandGET /api/practice/weaknessesendpoints validate timeframe parameters with a strict pattern (\d{1,4}[dwmy]orall). - The Express JSON body parser is limited to 50 KB.
- All regex patterns used for prompt analysis are designed to avoid catastrophic backtracking (ReDoS). Greedy quantifiers like
.*are bounded (e.g.,.{0,200}?) and nested quantifiers use explicit upper bounds.
- JSON body parser limit: 50 KB (
express.json({ limit: "50kb" }))
| Parameter | Used by | Validation |
|---|---|---|
timeframe |
Most endpoints | Validated with strict pattern (/^\d{1,4}[dwmy]$/ or all). Returns 400 for invalid values. |
repo |
Most endpoints | Validated as a non-empty string. Passed as a SQL LIKE parameter with % wrapping in parameterized queries only. Returns 400 for non-string values. |
since |
/api/live/feed |
Validated as a parseable date via new Date(). Returns 400 if invalid. Normalized to ISO 8601 before SQL use. |
text |
POST /api/practice/analyze |
Must be a string, max 10,000 characters. Returns 400 if missing or invalid. |
tag |
GET /api/practice/library |
Validated against a whitelist of known tags. Invalid tags silently dropped. |
:id |
/api/sessions/:id/* |
Path parameter used as a session ID lookup key. Passed to parameterized SQL queries. Returns 404 if not found. |
:id |
POST/DELETE /api/sessions/:id/hide |
Validated as a UUID v4 format (/^[0-9a-f]{8}-…$/i). Returns 400 if invalid. Returns 429 if hidden set cap (5,000) reached. Hidden IDs stored in-memory only — reset on server restart. |
On startup, src/db.mjs validates the session-store schema before executing queries. Required tables (sessions, turns, session_files) must be present or the server exits with a descriptive error. Optional tables (session_refs, checkpoints) degrade gracefully — features that depend on them return empty results and a console warning is logged. This prevents confusing SQLite errors when the database is from an incompatible Copilot CLI version.
All database queries use parameterized statements via better-sqlite3's .prepare().all() / .get() API. No user input is interpolated into SQL strings.
All 130+ regex patterns (in src/patterns.mjs and other analysis modules) have been audited for ReDoS. None use nested quantifiers, unbounded .+/.* in dangerous positions, or overlapping alternations.
All endpoints are read-only (GET) except where noted. The server exposes:
| Endpoint | Description |
|---|---|
GET /api/summary |
Aggregate redirection stats |
GET /api/sessions |
List sessions with scores |
GET /api/sessions/:id |
Single session detail |
GET /api/sessions/:id/sprawl |
Session scope-creep analysis |
GET /api/sessions/:id/efficiency |
Session efficiency metrics |
GET /api/sessions/:id/replay |
Annotated turn-by-turn replay |
GET /api/sessions/:id/complexity |
Session complexity scoring |
GET /api/patterns |
Top correction patterns |
GET /api/trends |
Trend data for charts |
GET /api/pillar-trends |
Pillar score trends |
GET /api/insights |
Combined insights |
GET /api/suggestions |
Prompt rewrite suggestions |
GET /api/clarity |
First-turn clarity analysis |
GET /api/efficiency |
Efficiency batch analysis |
GET /api/delegation |
Delegation analysis |
GET /api/judgment |
Judgment quality analysis |
GET /api/instruction-gaps |
Missing instruction detection |
GET /api/instruction-failures |
Rule failure analysis |
GET /api/dev-plan |
Personalized dev plan |
GET /api/progress-check |
Daily check-in |
GET /api/retro |
Session retrospective |
GET /api/work-style |
Work style analysis |
GET /api/live/feed |
Real-time turn feed with pattern annotations |
POST /api/practice/analyze |
Instant prompt scoring (10,000 char limit) |
GET /api/practice/challenge |
Random low-scoring prompt from user sessions |
GET /api/practice/library |
Curated challenge library with tag filtering |
GET /api/practice/weaknesses |
Personalized category recommendations |
GET /api/analytics/hourly |
Hourly productivity |
GET /api/analytics/prompt-length |
Prompt length analysis |
GET /api/analytics/repos |
Repository health |
GET /api/analytics/hot-files |
Most-edited files |
GET /api/analytics/depth |
Session depth metrics |
GET /api/analytics/tools |
Tool usage statistics |
GET /api/analytics/create-edit-ratio |
Create vs. edit ratio |
GET /api/analytics/file-types |
File type diversity |
GET /api/hidden-sessions |
List hidden session IDs (in-memory) |
POST /api/sessions/:id/hide |
Hide a session from analysis |
DELETE /api/sessions/:id/hide |
Unhide a session |