feat: competitive companion HTTP listener #255

Closed
opened 2026-02-27 00:19:59 +00:00 by barrettruth · 1 comment
barrettruth commented 2026-02-27 00:19:59 +00:00

Problem

cp.nvim's custom Python scrapers cover only 4 platforms (AtCoder, CodeChef, Codeforces, CSES). The Competitive Companion browser extension supports 116+ judges (LeetCode, USACO, HackerRank, Kattis, Toph, etc.) and is the industry-standard protocol for getting test cases into any CP tool. Every other Neovim CP plugin (competitest.nvim, cphelper.nvim, assistant.nvim) integrates with it. cp.nvim has no listener at all.

Proposed solution

Implement a local HTTP server (listening on port 10042, Competitive Companion's default) using vim.uv TCP primitives — no external dependencies required. Accept POST / requests and decode the Competitive Companion JSON payload:

{
  "name": "G. Castle Defense",
  "group": "Codeforces - Educational Round 40",
  "url": "https://codeforces.com/...",
  "interactive": false,
  "memoryLimit": 256,
  "timeLimit": 1500,
  "tests": [{"input": "...\n", "output": "...\n"}],
  "testType": "single",
  "batch": {"id": "uuid", "size": 3}
}

The payload maps cleanly onto existing types: timeLimittimeout_ms, memoryLimitmemory_mb, tests[].input/outputTestCase[]. Batch mode (where size > 1) allows receiving entire contests at once.

Expose via config: companion = { enabled = true, port = 10042 }. A :CP companion toggle command could start/stop the listener.

Alternatives considered

Continuing to maintain platform-specific Python scrapers. This is viable but limits coverage to platforms we choose to support and requires ongoing maintenance as site structures change.

## Problem cp.nvim's custom Python scrapers cover only 4 platforms (AtCoder, CodeChef, Codeforces, CSES). The [Competitive Companion](https://github.com/jmerle/competitive-companion) browser extension supports 116+ judges (LeetCode, USACO, HackerRank, Kattis, Toph, etc.) and is the industry-standard protocol for getting test cases into any CP tool. Every other Neovim CP plugin (competitest.nvim, cphelper.nvim, assistant.nvim) integrates with it. cp.nvim has no listener at all. ## Proposed solution Implement a local HTTP server (listening on port 10042, Competitive Companion's default) using `vim.uv` TCP primitives — no external dependencies required. Accept `POST /` requests and decode the Competitive Companion JSON payload: ```json { "name": "G. Castle Defense", "group": "Codeforces - Educational Round 40", "url": "https://codeforces.com/...", "interactive": false, "memoryLimit": 256, "timeLimit": 1500, "tests": [{"input": "...\n", "output": "...\n"}], "testType": "single", "batch": {"id": "uuid", "size": 3} } ``` The payload maps cleanly onto existing types: `timeLimit` → `timeout_ms`, `memoryLimit` → `memory_mb`, `tests[].input/output` → `TestCase[]`. Batch mode (where size > 1) allows receiving entire contests at once. Expose via config: `companion = { enabled = true, port = 10042 }`. A `:CP companion` toggle command could start/stop the listener. ## Alternatives considered Continuing to maintain platform-specific Python scrapers. This is viable but limits coverage to platforms we choose to support and requires ongoing maintenance as site structures change.
barrettruth commented 2026-03-03 18:32:23 +00:00

Closing — cp.nvim's core value is self-contained scrapers without browser extension dependencies.

Closing — cp.nvim's core value is self-contained scrapers without browser extension dependencies.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
barrettruth/cp.nvim#255
No description provided.