hyperresearch 0.2.0__tar.gz → 0.4.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.4.0}/.gitignore +3 -0
- hyperresearch-0.4.0/CHANGELOG.md +124 -0
- hyperresearch-0.4.0/PKG-INFO +188 -0
- hyperresearch-0.4.0/README.md +148 -0
- hyperresearch-0.4.0/assets/banner.png +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/pyproject.toml +5 -3
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/__init__.py +1 -1
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/fetch.py +45 -4
- hyperresearch-0.4.0/src/hyperresearch/core/agent_docs.py +579 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/fetcher.py +39 -3
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/hooks.py +16 -7
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/note.py +1 -0
- hyperresearch-0.4.0/src/hyperresearch/skills/research.md +526 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/web/base.py +63 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/web/crawl4ai_provider.py +196 -46
- hyperresearch-0.2.0/CHANGELOG.md +0 -72
- 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/src/hyperresearch/core/agent_docs.py +0 -331
- hyperresearch-0.2.0/src/hyperresearch/skills/research.md +0 -172
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/.github/workflows/ci.yml +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/.github/workflows/publish.yml +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/CONTRIBUTING.md +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/LICENSE +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/__main__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/_output.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/assets.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/batch.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/config_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/dedup.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/export.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/fetch_batch.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/git_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/graph.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/import_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/index.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/install.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/link.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/lint.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/main.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/mcp_cmd.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/note.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/repair.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/research.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/search.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/serve.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/setup.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/sources.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/tag.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/template.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/topic.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/cli/watch.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/config.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/db.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/enrich.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/frontmatter.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/linker.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/migrations.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/patterns.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/similarity.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/sync.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/templates.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/core/vault.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/export/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/graph/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/indexgen/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/indexgen/generator.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/mcp/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/mcp/server.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/models/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/models/graph.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/models/note.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/models/output.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/models/search.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/py.typed +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/search/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/search/filters.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/search/fts.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/serve/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/serve/renderer.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/serve/server.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/skills/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/web/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/src/hyperresearch/web/builtin.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/conftest.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_cli/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_cli/test_commands.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_cli/test_note_ops.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_core/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_core/test_frontmatter.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_core/test_note.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_core/test_sync.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_core/test_vault.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_graph/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_graph/test_links.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_search/__init__.py +0 -0
- {hyperresearch-0.2.0 → hyperresearch-0.4.0}/tests/test_search/test_fts.py +0 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.4.0] - 2026-04-13
|
|
4
|
+
|
|
5
|
+
### New
|
|
6
|
+
|
|
7
|
+
- **Request-type classification (Step 0)** — The research workflow now starts by classifying the user's request into one of 7 types (Canonical Knowledge Retrieval, Market / Landscape Mapping, Engineering / Technical How-To, Interpretive / Humanities Analysis, Comparative Evaluation, Emerging / Cutting-Edge Research, Forecast / Strategy / Recommendation) plus a General fallback. Classification happens before any searching and governs the rest of the workflow.
|
|
8
|
+
- **Type-specific parameter blocks** — Each of the 7 types specifies its own source strategy (count + primary/secondary mix), target length, opening-section shape, H2 heading count, analytical mode, and special rules. A humanities analysis wants 6–10 long thematic sections; a market landscape wants 8–14 vendor-cluster sections with a mandatory comparison matrix; a cutting-edge research request wants primary-heavy preprint reading with a "What we don't know yet" section. One workflow, seven parameterizations.
|
|
9
|
+
- **Primary-heavy vs. secondary-heavy source policy** — New explicit axis: Types 1/4/5/6 are primary-heavy (cite originals, engage deeply, prune irrelevant secondary coverage), Types 2/7 are secondary-heavy (triangulate across many descriptions), Type 3 is balanced. Source count is now a function of request type, not topic complexity.
|
|
10
|
+
- **Conceptual scaffold step (before writing)** — Agent must answer four questions in a scratch file before drafting: the hard question, the naive answer, the structural tension, and a dependency-ordered heading sketch. The final report's opening section must be a framework section, not a definition.
|
|
11
|
+
- **Cross-source comparison step** — Before writing the body, agent finds 3–5 places where sources actually disagree and captures short comparison blocks. Sources earn citations by being compared, not listed. These become the backbone of body sections.
|
|
12
|
+
- **Writing-draft hard constraints** — Target 400–600 words per H2, 12–20 H2s on a 10K-word report, never one-section-per-source, every section ends with an analytical beat, comparison tables not fact tables. Type-specific blocks override these (Type 4 Humanities targets 800–1500 words per section across 6–10 sections).
|
|
13
|
+
- **Frontmatter-first note triage (Step 4.5)** — Six-level protocol for reading notes efficiently. Always start with `note list -j` for summaries, use `note show --meta -j` for frontmatter-only reads, `search --include-body --max-tokens 6000 -j` for token-capped multi-note pulls, and **delegate notes with `word_count > 6000` to a fresh Sonnet subagent** with a pointed extraction prompt (~40× context savings per large note). Rely on the summary field first; read the body only when it earns its place.
|
|
14
|
+
- **Type-aware adversarial audit** — The structure-auditor subagent now checks whether the draft honors its declared type's parameter block: thematic sections for Humanities, mandatory comparison matrix for Comparative, "What we don't know yet" for Emerging, a position on winners for Market. Flags every type violation.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **`fit_markdown` via PruningContentFilter** — crawl4ai provider now uses `DefaultMarkdownGenerator` with `PruningContentFilter` so fetched notes contain just the main content, stripping navigation, footers, and sidebar chrome. Both `AsyncWebCrawler.arun()` and the Playwright visible-browser path use the same generator for consistent output. Applied to single fetch, batch fetch, and visible browser paths.
|
|
19
|
+
- **Skip numeric wiki-links in note parser** — `[[100]]`-style citation markers in bibliographies and academic papers are no longer extracted as note references. Avoids thousands of spurious broken-link warnings on papers that use numbered references.
|
|
20
|
+
- **"Over-collect, then prune" reframed as "over-collect, then engage deeply"** — A report built from 30 sources that disagree and force you to take positions is worth more than a report built from 80 sources that each contribute one bullet of description. Collection is a means to an argument, not the goal.
|
|
21
|
+
- **Scaffold and comparison artifacts are ephemeral, NOT hyperresearch notes** — Both the conceptual scaffold and the cross-source comparison blocks live in `/tmp/scaffold.md` or working memory, explicitly not as notes. Protects the research base from pre-writing scratch work.
|
|
22
|
+
|
|
23
|
+
## [0.3.0] - 2026-04-11
|
|
24
|
+
|
|
25
|
+
### New
|
|
26
|
+
|
|
27
|
+
- **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/`.
|
|
28
|
+
- **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.
|
|
29
|
+
- **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.
|
|
30
|
+
- **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.
|
|
31
|
+
- **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.
|
|
32
|
+
- **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.
|
|
33
|
+
- **Scholarly API guidance** — CLAUDE.md and `/research` skill now encourage use of arXiv, Semantic Scholar, CrossRef, and PubMed APIs for academic research.
|
|
34
|
+
- **Date injection** — today's date injected programmatically into CLAUDE.md at install time.
|
|
35
|
+
- **Multi-round research emphasis** — agent docs stress multiple rounds of search → fetch → follow links, spawning 10-20 fetcher agents per round.
|
|
36
|
+
|
|
37
|
+
### Changed
|
|
38
|
+
|
|
39
|
+
- **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).
|
|
40
|
+
- **Fetcher subagent quality gate** — subagent now checks relevance, content quality, and duplicates. Deprecates bad notes instead of leaving them as drafts.
|
|
41
|
+
- **`_resolve_executable()` prioritizes venv** — checks venv `Scripts/` dir before PATH, preventing system-wide installs from overriding the project's venv.
|
|
42
|
+
- **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.
|
|
43
|
+
- **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.
|
|
44
|
+
- **SSL verification disabled for PDF downloads** — academic sites often have self-signed certs. `httpx.get(verify=False)` for PDF fetches only.
|
|
45
|
+
- **PDF fetch logging** — `_fetch_pdf` failures now logged via `logging.getLogger("hyperresearch.pdf")` instead of silently returning None.
|
|
46
|
+
- **Fetcher subagent continues on failure** — no longer stops on first fetch error, tries all URLs and reports failures individually.
|
|
47
|
+
|
|
48
|
+
### Added dependencies
|
|
49
|
+
|
|
50
|
+
- `pymupdf>=1.24` — PDF text extraction
|
|
51
|
+
- `httpx>=0.27` — direct HTTP downloads for PDFs (bypasses browser)
|
|
52
|
+
|
|
53
|
+
## [0.2.0] - 2026-04-10
|
|
54
|
+
|
|
55
|
+
### New
|
|
56
|
+
|
|
57
|
+
- **`/research` skill** — Scripted deep research workflow as a Claude Code slash command. Clarifies ambiguous requests, searches broadly, fetches aggressively, follows rabbit holes, auto-curates, synthesizes, and presents findings with hub notes
|
|
58
|
+
- **`hyperresearch setup`** — Interactive TUI onboarding: web provider, browser profile selection/creation, agent hooks. Auto-launches on first `install`
|
|
59
|
+
- **`hyperresearch fetch-batch`** — Concurrent multi-URL fetch with batched sync (O(1) syncs instead of O(n))
|
|
60
|
+
- **`hyperresearch link --auto`** — Holistic auto-linking: scans notes for mentions of other notes' titles and appends wiki-links
|
|
61
|
+
- **`hyperresearch assets list/path`** — Browse downloaded screenshots and images
|
|
62
|
+
- **`--save-assets` flag** — Opt-in screenshot + content image download on fetch
|
|
63
|
+
- **`--visible` flag** — Non-headless browser for stubborn auth sites (auto-enabled for LinkedIn, Twitter, Facebook, Instagram, TikTok)
|
|
64
|
+
- **`--max-tokens` on search** — Token budget truncation for context-aware agents
|
|
65
|
+
- **Auto-curation at fetch time** — Notes arrive with auto-generated tags and summaries
|
|
66
|
+
- **MCP write tools** — `fetch_url`, `create_note`, `update_note` (MCP server is now read-write)
|
|
67
|
+
- **MinHash+LSH dedup** — O(n) approximate dedup for large vaults (200+ notes), falls back to brute-force for small vaults
|
|
68
|
+
- **Hub notes auto-surfaced** after research sessions
|
|
69
|
+
- **Synthesis notes** saved as feedback loop (agent Q&A becomes searchable)
|
|
70
|
+
- **`hyperresearch-fetcher` subagent** — Haiku-powered URL fetcher installed to `.claude/agents/`
|
|
71
|
+
- **Login wall detection** — `AUTH_REQUIRED` error instead of saving login page junk
|
|
72
|
+
- **Smart SPA wait** — Polls DOM stability (2s initial + 10s ceiling) instead of fixed delays
|
|
73
|
+
|
|
74
|
+
### Changed
|
|
75
|
+
|
|
76
|
+
- **crawl4ai is the sole browser provider** — Removed firecrawl, tavily, trafilatura
|
|
77
|
+
- **crawl4ai v0.8.x API** — AsyncWebCrawler, BrowserConfig, CrawlerRunConfig, arun/arun_many
|
|
78
|
+
- **Authenticated crawling** via crawl4ai browser profiles (`crwl profiles` or setup TUI)
|
|
79
|
+
- **CLI path baked into CLAUDE.md** — Works without venv activation (forward slashes for Windows bash)
|
|
80
|
+
- **Deep research philosophy** — Agent docs say "over-collect, then prune" and "go down rabbit holes"
|
|
81
|
+
- **Windows encoding fix** — `stream.reconfigure(encoding="utf-8")` at startup, no more charmap crashes
|
|
82
|
+
- **Note slugs capped at 80 chars** — Avoids Windows MAX_PATH issues
|
|
83
|
+
- **Anti-bot stealth always on** when crawl4ai is used (no setup question)
|
|
84
|
+
- **Config commands** now support `web.provider`, `web.profile`, `web.magic`
|
|
85
|
+
|
|
86
|
+
### Removed
|
|
87
|
+
|
|
88
|
+
- Dead fields: `confidence`, `superseded_by`, `llm_compiled`, `llm_model`, `compile_source`
|
|
89
|
+
- Tag plural normalization (use explicit `tag_aliases` instead)
|
|
90
|
+
- `deprecated-no-successor` and `low-confidence` lint rules
|
|
91
|
+
- Firecrawl, Tavily, Trafilatura web providers
|
|
92
|
+
|
|
93
|
+
## [0.1.0] - 2026-04-09
|
|
94
|
+
|
|
95
|
+
Initial release. Forked from [llm-kasten](https://github.com/jordan-gibbs/llm-kasten) and repositioned for agent-driven research workflows.
|
|
96
|
+
|
|
97
|
+
### New
|
|
98
|
+
|
|
99
|
+
- **`hyperresearch install`** — One-step setup: init vault + inject agent docs + install PreToolUse hooks for Claude Code, Codex, Cursor, Gemini CLI
|
|
100
|
+
- **`hyperresearch fetch <url>`** — Fetch a URL, extract content, save as a research note with source tracking
|
|
101
|
+
- **`hyperresearch research <topic>`** — Deep research: web search, fetch results, follow links, save as linked notes, generate synthesis MOC
|
|
102
|
+
- **`hyperresearch sources list/check`** — List and query fetched web sources
|
|
103
|
+
- **Web provider plugin system** — Pluggable backends: builtin (stdlib), crawl4ai (local headless browser)
|
|
104
|
+
- **Agent hook system** — PreToolUse hooks that remind agents to check the research base before web searches
|
|
105
|
+
- **Sources table** — URL deduplication, domain tracking, fetch metadata
|
|
106
|
+
- **Extended frontmatter** — `source_domain`, `fetched_at`, `fetch_provider` fields
|
|
107
|
+
- **MCP server** with 10 tools including `check_source` and `list_sources`
|
|
108
|
+
|
|
109
|
+
### From kasten (the backbone)
|
|
110
|
+
|
|
111
|
+
- SQLite FTS5 full-text search with BM25 ranking
|
|
112
|
+
- Markdown notes with YAML frontmatter as source of truth
|
|
113
|
+
- `[[wiki-link]]` tracking with backlinks
|
|
114
|
+
- `--json` / `-j` structured output on every command
|
|
115
|
+
- Note lifecycle: draft → review → evergreen → stale → deprecated → archive
|
|
116
|
+
- Auto-sync (mtime + SHA-256 change detection)
|
|
117
|
+
- Agent doc injection (CLAUDE.md, AGENTS.md, GEMINI.md, copilot-instructions.md)
|
|
118
|
+
- Web viewer with force-directed knowledge graph
|
|
119
|
+
- 70 tests
|
|
120
|
+
|
|
121
|
+
[0.4.0]: https://github.com/jordan-gibbs/hyperresearch/releases/tag/v0.4.0
|
|
122
|
+
[0.3.0]: https://github.com/jordan-gibbs/hyperresearch/releases/tag/v0.3.0
|
|
123
|
+
[0.2.0]: https://github.com/jordan-gibbs/hyperresearch/releases/tag/v0.2.0
|
|
124
|
+
[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.4.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.4.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:
|