{"id":50323818,"url":"https://github.com/queelius/scholia","last_synced_at":"2026-05-29T04:30:57.943Z","repository":{"id":335784341,"uuid":"1144700558","full_name":"queelius/scholia","owner":"queelius","description":"Agentic-first review tool for LaTeX papers: anchored comments, live PDF preview, and an MCP server for Claude Code.","archived":false,"fork":false,"pushed_at":"2026-05-07T07:56:55.000Z","size":688,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-07T09:39:16.019Z","etag":null,"topics":["academic-writing","agentic-ai","annotations","claude-code","latex","latex-editor","mcp","pdf","review","synctex","tex","writing"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/queelius.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-29T00:29:26.000Z","updated_at":"2026-05-07T07:56:59.000Z","dependencies_parsed_at":"2026-02-01T15:12:04.247Z","dependency_job_id":null,"html_url":"https://github.com/queelius/scholia","commit_stats":null,"previous_names":["queelius/texwatch","queelius/scholia"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/queelius/scholia","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queelius%2Fscholia","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queelius%2Fscholia/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queelius%2Fscholia/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queelius%2Fscholia/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/queelius","download_url":"https://codeload.github.com/queelius/scholia/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/queelius%2Fscholia/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33637485,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-29T02:00:06.066Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["academic-writing","agentic-ai","annotations","claude-code","latex","latex-editor","mcp","pdf","review","synctex","tex","writing"],"created_at":"2026-05-29T04:30:57.798Z","updated_at":"2026-05-29T04:30:57.926Z","avatar_url":"https://github.com/queelius.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# scholia\n\n**Agentic-first PDF review for LaTeX papers, with Claude Code as the author.**\n\nYou read the rendered PDF in your browser. You drop comments on paragraphs, sections, or the paper as a whole. Claude Code reads the queue (via MCP), edits the source, and replies with what changed. The PDF rebuilds in front of you. Repeat until done.\n\n## Why this exists\n\nscholia is deliberately *not* an editor, *not* an IDE, *not* an Overleaf clone. The agent (Claude Code) is already smarter at reading source, parsing LaTeX, grepping citations, and editing files than any tool we could build. So we don't try.\n\nscholia is a **substrate** for the agentic-first writing workflow:\n\n- A **live PDF preview** the human can watch and gesture at.\n- A **comment queue** anchored to PDF regions, sections, source ranges, or the paper as a whole.\n- A **structured-error compile oracle** the agent calls when it wants ground truth.\n\nThat's it. Three responsibilities. Anything that re-implements something the agent does well (file parsing, log analysis, semantic understanding) was deliberately removed.\n\n## Install\n\nRequires Python 3.10+ and `latexmk` (or `pdflatex`/`xelatex`/`lualatex`/`pandoc`) on your `PATH`.\n\n```bash\npip install scholia\npip install scholia[mcp]   # adds MCP server for Claude Code\n```\n\n## Quick start\n\n```bash\ncd my-paper/\nscholia init       # writes .scholia.yaml (configures main file, port)\nscholia            # starts the daemon at http://localhost:8765\n```\n\nIn the browser:\n\n- The PDF appears on the left, the comments sidebar on the right.\n- **Select text in the PDF** to anchor a comment to that region. SyncTeX maps the selection back to a source line range automatically.\n- **Shift-click-drag** to draw a rectangle around any region (figures, equations, whitespace) where text selection doesn't reach. Same `pdf_region` anchor; the agent can render exactly that region with `scholia_image(comment_id=...)`.\n- **Suggest a rewrite** alongside any comment: the compose dialog has an optional `{old, new}` block. When you select text first, \"old\" pre-fills with the selected text, so you only type the replacement. The agent gets a structured edit it can apply directly.\n- **\"+ Note\"** in the top bar for a paper-level comment (\"the abstract is too long\").\n- **Paper tab** lists sections with **\"+ comment\"** buttons for section-level comments.\n- **Reply / Resolve / Dismiss** are inline forms in each comment, not modals.\n- **Keyboard navigation**: `j` / `k` step through comments, `r` opens a reply form, `R` opens resolve, `d` opens dismiss, `Esc` cancels.\n\n## The Claude Code workflow\n\n`scholia` auto-registers an MCP server in `.mcp.json` when it starts, exposing **7 tools**:\n\n| Tool | What it does |\n|---|---|\n| `scholia_paper(include_comments=True)` | Paper state in one call: sections (with line ranges), the comments queue, last-compile cache, main-file paths. |\n| `scholia_compile()` | Recompile and return structured errors with source context. |\n| `scholia_comment(action, ...)` | `add` / `reply` / `resolve` / `dismiss` / `delete`. Optional `suggestion={\"old\", \"new\"}` on add. |\n| `scholia_image(...)` | Render PDF region as PNG. Modes: `page=N`, `page+bbox`, `source=\"file:lstart-lend\"`, `comment_id=\"c-...\"`. |\n| `scholia_section(name)` | Deep-dive: source slice + rendered image + scoped comments for one section in one call. |\n| `scholia_audit(focus=...)` | Workflow primer for agent-initiated review. Returns guidance; the agent then files comments back as `author=\"claude\"`. |\n| `scholia_goto(target)` | Scroll the running viewer to a section / page / line / label. |\n\nWhen a compile finishes, the WebSocket broadcasts `{\"type\": \"compiled\", ..., \"pages_changed\": [3, 7]}` so the agent can verify only the pages that actually shifted, not re-render the whole document.\n\nNotice what's absent: there's no `scholia_labels()`, no `scholia_citations()`, no `scholia_environments()`. Use `Grep`. The agent is better at it than we are.\n\n**Visual review** is the killer mode of `scholia_image`. Claude is multimodal; pure text won't tell it whether a figure caption attaches to the right figure or whether an equation rendered correctly. The `comment_id` mode is the fast path: human draws a rectangle around a figure, files the comment, agent renders that region, sees what the human pointed at, fixes the LaTeX.\n\n**Active review** runs the loop in either direction:\n\n```\nYou:    [drop 8 comments on the PDF; for \"rephrase X\" comments, fill\n         in the suggested rewrite (agent applies it directly)]\n        \"Process the open comments.\"\n\nClaude: scholia_paper()                           # see comments + sections\n        for each: Read/Edit source; if suggestion present, apply it\n        scholia_comment(action=\"resolve\", id=..., summary=\"...\")\n        scholia_compile()                         # verify build\n\nYou:    [PDF rebuilds; reply / dismiss as needed]\n\nYou:    \"Audit my methods section for notation drift.\"\n\nClaude: scholia_audit(focus=\"math\")               # guidance primer\n        Read paper.tex; scholia_image() to inspect rendering\n        scholia_comment(action=\"add\", author=\"claude\",\n                        anchor=..., text=\"...\", suggestion=...)\n        # filed back into the queue, distinct visual treatment\n```\n\n## Comment anchors\n\nFour kinds, with different staleness behavior:\n\n| Anchor | Use when | Staleness handling |\n|---|---|---|\n| `pdf_region` | Reading the PDF and pointing at a paragraph. | SyncTeX resolves to source; a content snippet is captured; if Claude rewrites that region, the snippet match fails and the comment is flagged `STALE`. |\n| `section` | \"Expand the methods section.\" | Resolved by section title or `\\label{...}`. Stale only if the section is removed or renamed. |\n| `source_range` | When the agent already knows the lines (most common from MCP). | Snippet-matched, like `pdf_region`. |\n| `paper` | Global note about the paper. | Never stale. |\n\n## CLI\n\n```\nscholia                 # serve (default)\nscholia init            # scaffold .scholia.yaml\nscholia compile         # one-shot compile, structured errors\nscholia goto \"Methods\"  # tell the running viewer to scroll\nscholia mcp             # run the MCP server (stdio)\n```\n\nThat's the whole CLI. Comment management lives in the browser (for humans) and in the MCP tools (for the agent). There is no `scholia comment add` from the shell because nobody types that.\n\n## What changed in v0.6.0 (active review)\n\nThe framing shifted from \"human reviews; agent dispatches\" to \"review goes both ways\":\n\n- **Suggested rewrites.** Comments now optionally carry a structured `{old, new}` block. The agent applies the rewrite directly instead of parsing prose. Browser pre-fills \"old\" with the selected PDF text so the human only types the replacement.\n- **`scholia_audit(focus=...)`** primes agent-initiated review. The agent reads the paper, files findings back as `author=\"claude\"` comments, and the human steps through them.\n- **Refactor: anchors resolve themselves.** The dispatch that used to live in three switch statements (`server._resolve_anchor`, `imaging.resolve_image_target`, staleness check) is now methods on each anchor type. Adding a new anchor kind is a 30-line addition to one file.\n- **Renamed from `texwatch`.** The old name reflected the v0.3.0 \"TeX watcher\" product; the v0.6.0 product is a corpus of marginal annotations, which is what the Greek *scholia* literally meant.\n\n## What changed in v0.5.x\n\nAggressive simplification with the agentic-first frame:\n\n- **Dropped the CLI comment surface entirely.** The agent and the browser are the only sane places to manage comments.\n- **Dropped `tags`, `reopen`, the `Errors` tab.** Tags were noise, reopen was Github-imitation, the Errors tab duplicated information the topbar already shows.\n- **Dropped `labels` / `citations` / `inputs` from `scholia_paper()`.** Use `Grep`.\n- **Folded `scholia_comments` into `scholia_paper(include_comments=True)`** for one-call orientation.\n- **Inline reply / resolve / dismiss forms** in the viewer, not `prompt()` dialogs.\n- **Compile lock** prevents the watcher and `scholia_compile()` from racing.\n- **Visual review via `scholia_image()`** with four modes (page, page+bbox, source range, comment id). Shift-click-drag selects arbitrary rectangles for figures.\n\n## Configuration\n\n`.scholia.yaml`:\n\n```yaml\nmain: paper.tex\nwatch: [\"*.tex\", \"*.bib\", \"*.md\"]\nignore: [\"*_backup.tex\"]\ncompiler: auto       # auto | latexmk | pdflatex | xelatex | lualatex | pandoc\nport: 8765\n```\n\nComments live in `.scholia/comments.json`. `git add` it to keep your review history with the paper.\n\n## License\n\nMIT. See `LICENSE`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueelius%2Fscholia","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqueelius%2Fscholia","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueelius%2Fscholia/lists"}