hyperresearch 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/.gitignore +2 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/CHANGELOG.md +31 -0
- hyperresearch-0.3.0/PKG-INFO +188 -0
- hyperresearch-0.3.0/README.md +148 -0
- hyperresearch-0.3.0/assets/banner.png +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/pyproject.toml +5 -3
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/fetch.py +45 -4
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/agent_docs.py +107 -16
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/fetcher.py +39 -3
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/hooks.py +16 -7
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/skills/research.md +86 -6
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/web/base.py +63 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/web/crawl4ai_provider.py +178 -39
- hyperresearch-0.2.0/PKG-INFO +0 -172
- hyperresearch-0.2.0/PLAN.md +0 -330
- hyperresearch-0.2.0/README.md +0 -132
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/.github/workflows/ci.yml +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/.github/workflows/publish.yml +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/CONTRIBUTING.md +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/LICENSE +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/__main__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/_output.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/assets.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/batch.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/config_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/dedup.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/export.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/fetch_batch.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/git_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/graph.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/import_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/index.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/install.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/link.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/lint.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/main.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/mcp_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/note.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/repair.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/research.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/search.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/serve.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/setup.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/sources.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/tag.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/template.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/topic.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/cli/watch.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/config.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/db.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/enrich.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/frontmatter.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/linker.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/migrations.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/note.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/patterns.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/similarity.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/sync.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/templates.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/core/vault.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/export/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/graph/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/indexgen/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/indexgen/generator.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/mcp/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/mcp/server.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/models/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/models/graph.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/models/note.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/models/output.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/models/search.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/py.typed +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/search/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/search/filters.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/search/fts.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/serve/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/serve/renderer.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/serve/server.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/skills/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/web/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/src/hyperresearch/web/builtin.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/conftest.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_cli/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_cli/test_commands.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_cli/test_note_ops.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_core/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_core/test_frontmatter.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_core/test_note.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_core/test_sync.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_core/test_vault.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_graph/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_graph/test_links.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_search/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.3.0}/tests/test_search/test_fts.py +0 -0
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.3.0] - 2026-04-11
|
|
4
|
+
|
|
5
|
+
### New
|
|
6
|
+
|
|
7
|
+
- **Native PDF extraction** — PDFs detected by URL pattern, downloaded directly with httpx, text extracted with pymupdf. No browser needed. arXiv `/abs/` links auto-convert to `/pdf/`.
|
|
8
|
+
- **Raw file storage** — PDF bytes saved to `research/raw/<note-id>.pdf`, linked from note frontmatter via `raw_file:` field. Agent can read the raw PDF directly.
|
|
9
|
+
- **Junk page detection** — `WebResult.looks_like_junk()` catches Cloudflare captchas, error pages, cookie walls, binary garbage, reCAPTCHA, and empty content before saving. Returns `JUNK_CONTENT` error instead of creating useless notes.
|
|
10
|
+
- **Gap analysis step** — after drafting the report, agent re-reads the original query word by word, identifies gaps, and does another full round of research to fill them.
|
|
11
|
+
- **Adversarial audit** — two subagents (comprehensiveness auditor + logic/structure auditor) review the draft in parallel. Runs up to 2 loops. Agent uses wait time productively to improve summaries and tags.
|
|
12
|
+
- **Source checkpoint** — agent must review collected sources before writing any draft. Checks coverage breadth, missing angles, uncited references. Expects 50-100+ sources on complex topics.
|
|
13
|
+
- **Scholarly API guidance** — CLAUDE.md and `/research` skill now encourage use of arXiv, Semantic Scholar, CrossRef, and PubMed APIs for academic research.
|
|
14
|
+
- **Date injection** — today's date injected programmatically into CLAUDE.md at install time.
|
|
15
|
+
- **Multi-round research emphasis** — agent docs stress multiple rounds of search → fetch → follow links, spawning 10-20 fetcher agents per round.
|
|
16
|
+
|
|
17
|
+
### Changed
|
|
18
|
+
|
|
19
|
+
- **Agent-driven curation replaces auto-enrich** — removed the keyword-matching `enrich_note_file()` from the fetch pipeline. Fetcher subagents now read content, write real summaries, add meaningful tags, and quality-check each source (deprecating junk/off-topic notes).
|
|
20
|
+
- **Fetcher subagent quality gate** — subagent now checks relevance, content quality, and duplicates. Deprecates bad notes instead of leaving them as drafts.
|
|
21
|
+
- **`_resolve_executable()` prioritizes venv** — checks venv `Scripts/` dir before PATH, preventing system-wide installs from overriding the project's venv.
|
|
22
|
+
- **PDF binary detection improved** — checks for `endstream`, `endobj`, `/FlateDecode`, `%PDF-` markers and non-printable character ratios. Catches binary garbage in both single-fetch and batch-fetch paths.
|
|
23
|
+
- **Junk detection thresholds raised** — empty content threshold: 100→300 chars, cookie page threshold: 500→1500 chars. Added `recaptcha`, `checking your browser`, `verify you are human` to bot detection signals.
|
|
24
|
+
- **SSL verification disabled for PDF downloads** — academic sites often have self-signed certs. `httpx.get(verify=False)` for PDF fetches only.
|
|
25
|
+
- **PDF fetch logging** — `_fetch_pdf` failures now logged via `logging.getLogger("hyperresearch.pdf")` instead of silently returning None.
|
|
26
|
+
- **Fetcher subagent continues on failure** — no longer stops on first fetch error, tries all URLs and reports failures individually.
|
|
27
|
+
|
|
28
|
+
### Added dependencies
|
|
29
|
+
|
|
30
|
+
- `pymupdf>=1.24` — PDF text extraction
|
|
31
|
+
- `httpx>=0.27` — direct HTTP downloads for PDFs (bypasses browser)
|
|
32
|
+
|
|
3
33
|
## [0.2.0] - 2026-04-10
|
|
4
34
|
|
|
5
35
|
### New
|
|
@@ -68,5 +98,6 @@ Initial release. Forked from [llm-kasten](https://github.com/jordan-gibbs/llm-ka
|
|
|
68
98
|
- Web viewer with force-directed knowledge graph
|
|
69
99
|
- 70 tests
|
|
70
100
|
|
|
101
|
+
[0.3.0]: https://github.com/jordan-gibbs/hyperresearch/releases/tag/v0.3.0
|
|
71
102
|
[0.2.0]: https://github.com/jordan-gibbs/hyperresearch/releases/tag/v0.2.0
|
|
72
103
|
[0.1.0]: https://github.com/jordan-gibbs/hyperresearch/releases/tag/v0.1.0
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hyperresearch
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Agent-driven research knowledge base. Browse, collect, and synthesize web sources into a searchable wiki.
|
|
5
|
+
Project-URL: Homepage, https://github.com/jordan-gibbs/hyperresearch
|
|
6
|
+
Project-URL: Repository, https://github.com/jordan-gibbs/hyperresearch
|
|
7
|
+
Project-URL: Issues, https://github.com/jordan-gibbs/hyperresearch/issues
|
|
8
|
+
Author-email: Jordan Gibbs <jordan@jordangibbs.xyz>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: agent,cli,knowledge-base,llm,markdown,research,wiki,zettelkasten
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Text Processing :: Markup :: Markdown
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: crawl4ai>=0.4
|
|
22
|
+
Requires-Dist: httpx>=0.27
|
|
23
|
+
Requires-Dist: jinja2>=3.1
|
|
24
|
+
Requires-Dist: platformdirs>=4.0
|
|
25
|
+
Requires-Dist: pydantic>=2.0
|
|
26
|
+
Requires-Dist: pymupdf>=1.24
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Requires-Dist: rich>=13.0
|
|
29
|
+
Requires-Dist: typer>=0.9.0
|
|
30
|
+
Provides-Extra: all
|
|
31
|
+
Requires-Dist: mcp>=1.6; extra == 'all'
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: mypy>=1.8; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=4.1; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=7.4; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.3; extra == 'dev'
|
|
37
|
+
Provides-Extra: mcp
|
|
38
|
+
Requires-Dist: mcp>=1.6; extra == 'mcp'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
<p align="center">
|
|
42
|
+
<img src="assets/banner.png" alt="HYPERRESEARCH" width="700">
|
|
43
|
+
</p>
|
|
44
|
+
|
|
45
|
+
<h3 align="center">Ultra deep, persistent web research for AI coding agents</h3>
|
|
46
|
+
|
|
47
|
+
<p align="center">
|
|
48
|
+
<a href="https://pypi.org/project/hyperresearch/"><img src="https://img.shields.io/pypi/v/hyperresearch" alt="PyPI version"></a>
|
|
49
|
+
<a href="https://pypi.org/project/hyperresearch/"><img src="https://img.shields.io/pypi/pyversions/hyperresearch" alt="Python 3.11+"></a>
|
|
50
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/jordan-gibbs/hyperresearch" alt="License: MIT"></a>
|
|
51
|
+
<a href="https://github.com/jordan-gibbs/hyperresearch"><img src="https://img.shields.io/github/stars/jordan-gibbs/hyperresearch?style=social" alt="GitHub stars"></a>
|
|
52
|
+
</p>
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
Your AI agent searches the web, finds great sources, synthesizes an answer — then the session ends and everything is gone. Next time, it starts from zero.
|
|
57
|
+
|
|
58
|
+
**Hyperresearch makes research persist.** Every source your agent finds is fetched with a real headless browser, saved as searchable markdown, and indexed into a knowledge base that compounds across sessions. Hyperresearch can follow maps of links to digest paths of information that current agent web searching isn't capable of.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install hyperresearch
|
|
62
|
+
hyperresearch install
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## What people use it for
|
|
66
|
+
|
|
67
|
+
- **In-depth topic research** — "Research the latest advances in state space models" → agent fetches 20+ papers, docs, and blog posts, follows citations to primary sources, builds a linked knowledge graph
|
|
68
|
+
- **News tracking over time** — run research sessions weekly on a topic, each session builds on what's already collected, nothing gets re-fetched
|
|
69
|
+
- **State-of-the-art surveys** — "What's the current SOTA for speech recognition?" → agent goes down rabbit holes, collects benchmarks, papers, and implementations
|
|
70
|
+
- **Competitive analysis** — scrape company pages, LinkedIn profiles, product docs, news articles into a persistent, searchable corpus
|
|
71
|
+
- **Due diligence** — aggregate everything about a person, company, or technology from across the web with authenticated crawling (LinkedIn, Twitter, paywalled sites)
|
|
72
|
+
|
|
73
|
+
## How it works
|
|
74
|
+
|
|
75
|
+
1. **You ask your agent to research something**
|
|
76
|
+
2. **Agent searches the web** — multiple queries, different angles
|
|
77
|
+
3. **Fetches every source** with a real headless browser (crawl4ai) — JS rendering, bot detection bypass, login-gated content
|
|
78
|
+
4. **Saves each page** as a searchable markdown note with tags, summary, and source tracking
|
|
79
|
+
5. **Follows links** to primary sources — the paper, not the blog post about the paper
|
|
80
|
+
6. **Auto-links related notes** with `[[wiki-links]]` across the knowledge graph
|
|
81
|
+
7. **Synthesizes findings** into a summary note linking all sources
|
|
82
|
+
8. **Next session** — agent checks the KB before searching the web. Knowledge compounds.
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
your-repo/
|
|
86
|
+
.hyperresearch/ # Config + SQLite FTS5 index (rebuildable)
|
|
87
|
+
research/
|
|
88
|
+
notes/ # Markdown notes — the source of truth
|
|
89
|
+
index/ # Auto-generated wiki pages
|
|
90
|
+
CLAUDE.md # Agent docs (auto-injected)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Works with every major agent
|
|
94
|
+
|
|
95
|
+
`hyperresearch install` hooks into your agent in one step:
|
|
96
|
+
|
|
97
|
+
| Platform | Hook | Trigger |
|
|
98
|
+
|----------|------|---------|
|
|
99
|
+
| **Claude Code** | `.claude/settings.json` + `/research` skill | Before WebSearch, WebFetch |
|
|
100
|
+
| **Codex** | `.codex/hooks.json` | Before Bash |
|
|
101
|
+
| **Cursor** | `.cursor/rules/hyperresearch.mdc` | Always-apply rule |
|
|
102
|
+
| **Gemini CLI** | `.gemini/settings.json` | Before tool calls |
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
hyperresearch install --platform all # Hook every platform at once
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Key features
|
|
109
|
+
|
|
110
|
+
- **Real headless browser** — crawl4ai runs local Chromium. Handles JavaScript, bypasses bot detection, renders SPAs. Not a simple HTTP fetch.
|
|
111
|
+
- **Native PDF extraction** — fetches PDFs directly, extracts full text with pymupdf, saves raw files to `research/raw/`. Academic papers, whitepapers, reports — all first-class citizens.
|
|
112
|
+
- **Authenticated crawling** — log into LinkedIn, Twitter, paywalled news. Your sessions persist across fetches.
|
|
113
|
+
- **Agent-driven curation** — fetcher subagents read each source, write real summaries, add meaningful tags, and flag junk. No keyword-matching shortcuts.
|
|
114
|
+
- **Junk detection** — Cloudflare captchas, error pages, cookie walls, binary garbage, login redirects all caught and rejected before saving.
|
|
115
|
+
- **Multi-round deep research** — the agent does multiple rounds of search → fetch → follow links, with a source checkpoint that forces breadth before synthesis.
|
|
116
|
+
- **Gap analysis + adversarial audit** — after drafting, the agent re-reads the original query to find gaps, then spawns two auditor subagents (comprehensiveness + logic) to tear the draft apart. Runs twice.
|
|
117
|
+
- **Cheap parallel fetching** — ships a Haiku-powered subagent that fetches, summarizes, and quality-checks URLs in parallel for pennies. Spawn 10-20 per round.
|
|
118
|
+
- **Scholarly API guidance** — agent docs encourage use of arXiv, Semantic Scholar, CrossRef, and PubMed APIs for academic topics.
|
|
119
|
+
- **`/research` skill** — scripted deep research workflow. Clarifies ambiguous requests, searches broadly, fetches aggressively, follows rabbit holes, audits, synthesizes.
|
|
120
|
+
- **Smart SPA wait** — polls DOM stability instead of fixed delays. Fast pages finish instantly, SPAs get up to 10 seconds.
|
|
121
|
+
- **FTS5 search** — instant full-text search across thousands of notes with BM25 ranking
|
|
122
|
+
- **Knowledge graph** — `[[wiki-links]]`, backlinks, hub detection, auto-linking
|
|
123
|
+
- **MCP server** — 13 tools (read + write) for Claude Desktop, Cursor, or any MCP client
|
|
124
|
+
- **Note lifecycle** — draft → review → evergreen → stale → deprecated → archive
|
|
125
|
+
|
|
126
|
+
## Commands
|
|
127
|
+
|
|
128
|
+
```bash
|
|
129
|
+
# Research
|
|
130
|
+
hyperresearch fetch <url> --tag t -j # Fetch a URL into the KB
|
|
131
|
+
hyperresearch fetch-batch <urls...> -j # Fetch many URLs at once
|
|
132
|
+
hyperresearch research "topic" --max 5 -j # Full pipeline: search → fetch → link → synthesize
|
|
133
|
+
|
|
134
|
+
# Search
|
|
135
|
+
hyperresearch search "query" -j # Full-text search
|
|
136
|
+
hyperresearch search "query" --max-tokens 8000 # Stay within context budget
|
|
137
|
+
hyperresearch note show <id> -j # Read a note
|
|
138
|
+
|
|
139
|
+
# Knowledge graph
|
|
140
|
+
hyperresearch link --auto -j # Auto-link related notes
|
|
141
|
+
hyperresearch graph hubs -j # Most-connected notes
|
|
142
|
+
hyperresearch graph backlinks <id> -j # What links to this note
|
|
143
|
+
|
|
144
|
+
# Manage
|
|
145
|
+
hyperresearch sources list -j # Every URL ever fetched
|
|
146
|
+
hyperresearch lint -j # Health check
|
|
147
|
+
hyperresearch repair -j # Fix links, rebuild indexes
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Every command returns `{"ok": true, "data": {...}}` with `-j`.
|
|
151
|
+
|
|
152
|
+
## Authenticated crawling
|
|
153
|
+
|
|
154
|
+
Fetch from LinkedIn, Twitter, paywalled sites — anything you can log into:
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
hyperresearch setup # Browser opens. Log into your sites. Done.
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
```toml
|
|
161
|
+
# .hyperresearch/config.toml
|
|
162
|
+
[web]
|
|
163
|
+
provider = "crawl4ai"
|
|
164
|
+
profile = "research"
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
LinkedIn, Twitter, Facebook, Instagram, and TikTok automatically use a visible browser to avoid session kills.
|
|
168
|
+
|
|
169
|
+
## Philosophy
|
|
170
|
+
|
|
171
|
+
- **No LLM calls.** Hyperresearch stores, indexes, and searches. Your agent is the LLM.
|
|
172
|
+
- **Markdown is truth.** Notes are plain files. SQLite is a rebuildable cache.
|
|
173
|
+
- **Over-collect, then prune.** Fetch aggressively. Deprecate what you don't need.
|
|
174
|
+
- **Check before you fetch.** Hooks kill redundant searches across sessions.
|
|
175
|
+
- **Raw content is king.** Save the original with formatting, not a rewritten summary.
|
|
176
|
+
|
|
177
|
+
## Requirements
|
|
178
|
+
|
|
179
|
+
- Python 3.11+
|
|
180
|
+
- Windows, macOS, Linux
|
|
181
|
+
|
|
182
|
+
## License
|
|
183
|
+
|
|
184
|
+
[MIT](LICENSE)
|
|
185
|
+
|
|
186
|
+
## Star History
|
|
187
|
+
|
|
188
|
+
[](https://star-history.com/#jordan-gibbs/hyperresearch&Date)
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/banner.png" alt="HYPERRESEARCH" width="700">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h3 align="center">Ultra deep, persistent web research for AI coding agents</h3>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="https://pypi.org/project/hyperresearch/"><img src="https://img.shields.io/pypi/v/hyperresearch" alt="PyPI version"></a>
|
|
9
|
+
<a href="https://pypi.org/project/hyperresearch/"><img src="https://img.shields.io/pypi/pyversions/hyperresearch" alt="Python 3.11+"></a>
|
|
10
|
+
<a href="LICENSE"><img src="https://img.shields.io/github/license/jordan-gibbs/hyperresearch" alt="License: MIT"></a>
|
|
11
|
+
<a href="https://github.com/jordan-gibbs/hyperresearch"><img src="https://img.shields.io/github/stars/jordan-gibbs/hyperresearch?style=social" alt="GitHub stars"></a>
|
|
12
|
+
</p>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Your AI agent searches the web, finds great sources, synthesizes an answer — then the session ends and everything is gone. Next time, it starts from zero.
|
|
17
|
+
|
|
18
|
+
**Hyperresearch makes research persist.** Every source your agent finds is fetched with a real headless browser, saved as searchable markdown, and indexed into a knowledge base that compounds across sessions. Hyperresearch can follow maps of links to digest paths of information that current agent web searching isn't capable of.
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install hyperresearch
|
|
22
|
+
hyperresearch install
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## What people use it for
|
|
26
|
+
|
|
27
|
+
- **In-depth topic research** — "Research the latest advances in state space models" → agent fetches 20+ papers, docs, and blog posts, follows citations to primary sources, builds a linked knowledge graph
|
|
28
|
+
- **News tracking over time** — run research sessions weekly on a topic, each session builds on what's already collected, nothing gets re-fetched
|
|
29
|
+
- **State-of-the-art surveys** — "What's the current SOTA for speech recognition?" → agent goes down rabbit holes, collects benchmarks, papers, and implementations
|
|
30
|
+
- **Competitive analysis** — scrape company pages, LinkedIn profiles, product docs, news articles into a persistent, searchable corpus
|
|
31
|
+
- **Due diligence** — aggregate everything about a person, company, or technology from across the web with authenticated crawling (LinkedIn, Twitter, paywalled sites)
|
|
32
|
+
|
|
33
|
+
## How it works
|
|
34
|
+
|
|
35
|
+
1. **You ask your agent to research something**
|
|
36
|
+
2. **Agent searches the web** — multiple queries, different angles
|
|
37
|
+
3. **Fetches every source** with a real headless browser (crawl4ai) — JS rendering, bot detection bypass, login-gated content
|
|
38
|
+
4. **Saves each page** as a searchable markdown note with tags, summary, and source tracking
|
|
39
|
+
5. **Follows links** to primary sources — the paper, not the blog post about the paper
|
|
40
|
+
6. **Auto-links related notes** with `[[wiki-links]]` across the knowledge graph
|
|
41
|
+
7. **Synthesizes findings** into a summary note linking all sources
|
|
42
|
+
8. **Next session** — agent checks the KB before searching the web. Knowledge compounds.
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
your-repo/
|
|
46
|
+
.hyperresearch/ # Config + SQLite FTS5 index (rebuildable)
|
|
47
|
+
research/
|
|
48
|
+
notes/ # Markdown notes — the source of truth
|
|
49
|
+
index/ # Auto-generated wiki pages
|
|
50
|
+
CLAUDE.md # Agent docs (auto-injected)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Works with every major agent
|
|
54
|
+
|
|
55
|
+
`hyperresearch install` hooks into your agent in one step:
|
|
56
|
+
|
|
57
|
+
| Platform | Hook | Trigger |
|
|
58
|
+
|----------|------|---------|
|
|
59
|
+
| **Claude Code** | `.claude/settings.json` + `/research` skill | Before WebSearch, WebFetch |
|
|
60
|
+
| **Codex** | `.codex/hooks.json` | Before Bash |
|
|
61
|
+
| **Cursor** | `.cursor/rules/hyperresearch.mdc` | Always-apply rule |
|
|
62
|
+
| **Gemini CLI** | `.gemini/settings.json` | Before tool calls |
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
hyperresearch install --platform all # Hook every platform at once
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Key features
|
|
69
|
+
|
|
70
|
+
- **Real headless browser** — crawl4ai runs local Chromium. Handles JavaScript, bypasses bot detection, renders SPAs. Not a simple HTTP fetch.
|
|
71
|
+
- **Native PDF extraction** — fetches PDFs directly, extracts full text with pymupdf, saves raw files to `research/raw/`. Academic papers, whitepapers, reports — all first-class citizens.
|
|
72
|
+
- **Authenticated crawling** — log into LinkedIn, Twitter, paywalled news. Your sessions persist across fetches.
|
|
73
|
+
- **Agent-driven curation** — fetcher subagents read each source, write real summaries, add meaningful tags, and flag junk. No keyword-matching shortcuts.
|
|
74
|
+
- **Junk detection** — Cloudflare captchas, error pages, cookie walls, binary garbage, login redirects all caught and rejected before saving.
|
|
75
|
+
- **Multi-round deep research** — the agent does multiple rounds of search → fetch → follow links, with a source checkpoint that forces breadth before synthesis.
|
|
76
|
+
- **Gap analysis + adversarial audit** — after drafting, the agent re-reads the original query to find gaps, then spawns two auditor subagents (comprehensiveness + logic) to tear the draft apart. Runs twice.
|
|
77
|
+
- **Cheap parallel fetching** — ships a Haiku-powered subagent that fetches, summarizes, and quality-checks URLs in parallel for pennies. Spawn 10-20 per round.
|
|
78
|
+
- **Scholarly API guidance** — agent docs encourage use of arXiv, Semantic Scholar, CrossRef, and PubMed APIs for academic topics.
|
|
79
|
+
- **`/research` skill** — scripted deep research workflow. Clarifies ambiguous requests, searches broadly, fetches aggressively, follows rabbit holes, audits, synthesizes.
|
|
80
|
+
- **Smart SPA wait** — polls DOM stability instead of fixed delays. Fast pages finish instantly, SPAs get up to 10 seconds.
|
|
81
|
+
- **FTS5 search** — instant full-text search across thousands of notes with BM25 ranking
|
|
82
|
+
- **Knowledge graph** — `[[wiki-links]]`, backlinks, hub detection, auto-linking
|
|
83
|
+
- **MCP server** — 13 tools (read + write) for Claude Desktop, Cursor, or any MCP client
|
|
84
|
+
- **Note lifecycle** — draft → review → evergreen → stale → deprecated → archive
|
|
85
|
+
|
|
86
|
+
## Commands
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Research
|
|
90
|
+
hyperresearch fetch <url> --tag t -j # Fetch a URL into the KB
|
|
91
|
+
hyperresearch fetch-batch <urls...> -j # Fetch many URLs at once
|
|
92
|
+
hyperresearch research "topic" --max 5 -j # Full pipeline: search → fetch → link → synthesize
|
|
93
|
+
|
|
94
|
+
# Search
|
|
95
|
+
hyperresearch search "query" -j # Full-text search
|
|
96
|
+
hyperresearch search "query" --max-tokens 8000 # Stay within context budget
|
|
97
|
+
hyperresearch note show <id> -j # Read a note
|
|
98
|
+
|
|
99
|
+
# Knowledge graph
|
|
100
|
+
hyperresearch link --auto -j # Auto-link related notes
|
|
101
|
+
hyperresearch graph hubs -j # Most-connected notes
|
|
102
|
+
hyperresearch graph backlinks <id> -j # What links to this note
|
|
103
|
+
|
|
104
|
+
# Manage
|
|
105
|
+
hyperresearch sources list -j # Every URL ever fetched
|
|
106
|
+
hyperresearch lint -j # Health check
|
|
107
|
+
hyperresearch repair -j # Fix links, rebuild indexes
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Every command returns `{"ok": true, "data": {...}}` with `-j`.
|
|
111
|
+
|
|
112
|
+
## Authenticated crawling
|
|
113
|
+
|
|
114
|
+
Fetch from LinkedIn, Twitter, paywalled sites — anything you can log into:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
hyperresearch setup # Browser opens. Log into your sites. Done.
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
```toml
|
|
121
|
+
# .hyperresearch/config.toml
|
|
122
|
+
[web]
|
|
123
|
+
provider = "crawl4ai"
|
|
124
|
+
profile = "research"
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
LinkedIn, Twitter, Facebook, Instagram, and TikTok automatically use a visible browser to avoid session kills.
|
|
128
|
+
|
|
129
|
+
## Philosophy
|
|
130
|
+
|
|
131
|
+
- **No LLM calls.** Hyperresearch stores, indexes, and searches. Your agent is the LLM.
|
|
132
|
+
- **Markdown is truth.** Notes are plain files. SQLite is a rebuildable cache.
|
|
133
|
+
- **Over-collect, then prune.** Fetch aggressively. Deprecate what you don't need.
|
|
134
|
+
- **Check before you fetch.** Hooks kill redundant searches across sessions.
|
|
135
|
+
- **Raw content is king.** Save the original with formatting, not a rewritten summary.
|
|
136
|
+
|
|
137
|
+
## Requirements
|
|
138
|
+
|
|
139
|
+
- Python 3.11+
|
|
140
|
+
- Windows, macOS, Linux
|
|
141
|
+
|
|
142
|
+
## License
|
|
143
|
+
|
|
144
|
+
[MIT](LICENSE)
|
|
145
|
+
|
|
146
|
+
## Star History
|
|
147
|
+
|
|
148
|
+
[](https://star-history.com/#jordan-gibbs/hyperresearch&Date)
|
|
Binary file
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "hyperresearch"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Agent-driven research knowledge base. Browse, collect, and synthesize web sources into a searchable wiki."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -28,12 +28,14 @@ dependencies = [
|
|
|
28
28
|
"pydantic>=2.0",
|
|
29
29
|
"jinja2>=3.1",
|
|
30
30
|
"platformdirs>=4.0",
|
|
31
|
+
"Crawl4AI>=0.4",
|
|
32
|
+
"pymupdf>=1.24",
|
|
33
|
+
"httpx>=0.27",
|
|
31
34
|
]
|
|
32
35
|
|
|
33
36
|
[project.optional-dependencies]
|
|
34
|
-
crawl4ai = ["Crawl4AI>=0.4"]
|
|
35
37
|
mcp = ["mcp>=1.6"]
|
|
36
|
-
all = ["hyperresearch[
|
|
38
|
+
all = ["hyperresearch[mcp]"]
|
|
37
39
|
dev = [
|
|
38
40
|
"pytest>=7.4",
|
|
39
41
|
"pytest-cov>=4.1",
|
|
@@ -116,6 +116,16 @@ def fetch(
|
|
|
116
116
|
console.print(f"[red]Auth required:[/] {msg}")
|
|
117
117
|
raise typer.Exit(1)
|
|
118
118
|
|
|
119
|
+
# Detect junk pages — captcha, error pages, binary garbage, empty content
|
|
120
|
+
junk_reason = result.looks_like_junk()
|
|
121
|
+
if junk_reason:
|
|
122
|
+
msg = f"Skipped junk content from {url}: {junk_reason}"
|
|
123
|
+
if json_output:
|
|
124
|
+
output(error(msg, "JUNK_CONTENT"), json_mode=True)
|
|
125
|
+
else:
|
|
126
|
+
console.print(f"[yellow]Skipped:[/] {msg}")
|
|
127
|
+
raise typer.Exit(1)
|
|
128
|
+
|
|
119
129
|
# Write note
|
|
120
130
|
note_title = title or result.title or urlparse(url).path.split("/")[-1] or "Untitled"
|
|
121
131
|
domain = result.domain
|
|
@@ -140,10 +150,40 @@ def fetch(
|
|
|
140
150
|
extra_frontmatter=extra_meta,
|
|
141
151
|
)
|
|
142
152
|
|
|
143
|
-
#
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
153
|
+
# Save raw file (PDF, etc.) if present
|
|
154
|
+
raw_file_path = None
|
|
155
|
+
if result.raw_bytes and result.raw_content_type:
|
|
156
|
+
ext_map = {
|
|
157
|
+
"application/pdf": ".pdf",
|
|
158
|
+
"image/png": ".png",
|
|
159
|
+
"image/jpeg": ".jpg",
|
|
160
|
+
"image/gif": ".gif",
|
|
161
|
+
"image/webp": ".webp",
|
|
162
|
+
}
|
|
163
|
+
ext = ext_map.get(result.raw_content_type, "")
|
|
164
|
+
if ext:
|
|
165
|
+
raw_dir = vault.root / "research" / "raw"
|
|
166
|
+
raw_dir.mkdir(parents=True, exist_ok=True)
|
|
167
|
+
raw_filename = note_path.stem + ext
|
|
168
|
+
raw_file = raw_dir / raw_filename
|
|
169
|
+
raw_file.write_bytes(result.raw_bytes)
|
|
170
|
+
raw_file_path = f"raw/{raw_filename}"
|
|
171
|
+
|
|
172
|
+
# Note: tagging and summarization is the agent's job, not an automatic process.
|
|
173
|
+
# The agent reads the fetched content and writes meaningful summaries and tags.
|
|
174
|
+
|
|
175
|
+
# Add raw_file reference to frontmatter AFTER enrich (enrich rewrites frontmatter)
|
|
176
|
+
if raw_file_path:
|
|
177
|
+
note_text = note_path.read_text(encoding="utf-8")
|
|
178
|
+
if note_text.startswith("---") and "raw_file:" not in note_text:
|
|
179
|
+
end_idx = note_text.find("---", 3)
|
|
180
|
+
if end_idx != -1:
|
|
181
|
+
note_text = (
|
|
182
|
+
note_text[:end_idx]
|
|
183
|
+
+ f"raw_file: {raw_file_path}\n"
|
|
184
|
+
+ note_text[end_idx:]
|
|
185
|
+
)
|
|
186
|
+
note_path.write_text(note_text, encoding="utf-8")
|
|
147
187
|
|
|
148
188
|
# Sync first so the note exists in the notes table (needed for FK on sources/assets)
|
|
149
189
|
note_id = note_path.stem
|
|
@@ -175,6 +215,7 @@ def fetch(
|
|
|
175
215
|
"path": str(note_path.relative_to(vault.root)),
|
|
176
216
|
"word_count": len(result.content.split()),
|
|
177
217
|
"assets": saved_assets,
|
|
218
|
+
"raw_file": raw_file_path,
|
|
178
219
|
}
|
|
179
220
|
|
|
180
221
|
if json_output:
|