Release 5.1.1
What's new
PLACEHOLDER
Commits details since the last release
- [6feb5f1] by @thiswillbeyourgithub, 32 minutes ago:
bump version 5.1.0 -> 5.1.1
bumpver.toml
docs/source/conf.py
setup.py
wdoc/wdoc.py
- [61c040a] by @thiswillbeyourgithub, 46 minutes ago:
fix: unstrucutred version is now incompatible with python 3.13
Signed-off-by: thiswillbeyourgithub 26625900+thiswillbeyourgithub@users.noreply.github.com
setup.py
- [ed81e2a] by @thiswillbeyourgithub, 7 days ago:
docs: restructure SKILL.md into the wdoc-skill/ skill directory
Split the monolithic root SKILL.md into a Claude Code skill directory
following the write-a-skill conventions: - wdoc-skill/SKILL.md: concise orientation with frontmatter + trigger
description, quick start, the four tasks, and core mechanics (73 lines) - wdoc-skill/REFERENCE.md: full CLI args, env vars, filetypes, loader
options, and the complete Python API tables - wdoc-skill/EXAMPLES.md: copy-pasteable shell and Python recipes
Polished wording, added the skill frontmatter, and removed em-dashes from
the reference content. Updated every reference to the old root SKILL.md
(bump_default_models.sh, README.md, CLAUDE.md, ARCHITECTURE.md) and the
Claude Code install instructions to the new three-file layout.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
ARCHITECTURE.md
CLAUDE.md
README.md
bump_default_models.sh
wdoc-skill/EXAMPLES.md
wdoc-skill/REFERENCE.md
wdoc-skill/SKILL.md
- [af68f46] by @thiswillbeyourgithub, 9 days ago:
docs: note how self-contained adding a new filetype is
Add a compact lead-in to CLAUDE.md's "Adding Support for a New Filetype"
section describing the two routes (standalone loader vs recursive fan-out)
and citing the recent zotero/karakeep types, plus a short note in SKILL.md
after the recursive filetypes table pointing contributors at CLAUDE.md.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
CLAUDE.md
SKILL.md
-
[a5473f4] by @thiswillbeyourgithub, 9 days ago:
fix(summarize): dump LLM output on empty content, fix recursion dedup
Follow-up to the previous empty-summary fix, addressing review feedback. -
Empty message content: instead of retrying (which just reproduces the
same blank when the cause is structural), raise a ValueError that dumps
every attribute of the LLM generations and llm_output. For some
reasoning models litellm leaves the messagecontentempty and puts the
answer inadditional_kwargs['reasoning_content'], so the dump reveals
when we are simply reading the wrong field
(generations[0].text==message.content). -
Recursion dedup bug:
if summary_text not in recursive_summariestested
membership against the dict's integer level keys, so it was always True
and forced recursion to stop after the first pass. Now compares against
recursive_summaries.values(), which also makes the "identical summary"
warning accurate. -
doc_reading_length: default to 0.0 (float) instead of 0 (int) when a
doc has nodoc_reading_time, otherwise wdocSummary construction crashes
under beartype (WDOC_TYPECHECKING=crash).
Tests: the empty-content test now asserts the generation dump is included;
adds a recursion test proving summarization continues past the first pass
(fails as 2 != 3 with the old predicate).
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/test_wdoc.py
wdoc/utils/tasks/summarize.py
- [7eb0a61] by @thiswillbeyourgithub, 9 days ago:
fix(summarize): retry then raise on empty LLM completion
A reasoning model can return an empty completion (all of its budget spent
on reasoning tokens) with finish_reason "stop"._summarizepreviously
turned that into a silently empty summary, which only surfaced much later
as a confusingassert 'monkey' in ''in
test_summary_tim_urban_default_model.
Now each chunk generation retries once while bypassing the cache on an
empty completion, and raises an explicit ValueError if it is still empty.
Token usage from every attempt is accumulated so the cost accounting
stays correct.
Adds a basic regression test that drives _summarize with a fake LLM
returning empty content and asserts the explicit error is raised.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/test_wdoc.py
wdoc/utils/tasks/summarize.py
- [10c3b40] by @thiswillbeyourgithub, 9 days ago:
docs: drop em-dashes introduced in the SKILL.md sync edits
Replace the em-dashes I added (CLAUDE.md SKILL.md bullet, SKILL.md
install comments) with colons, per the project's no-em-dash convention.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
CLAUDE.md
SKILL.md
- [85289a9] by @thiswillbeyourgithub, 9 days ago:
docs(skill): document the citation_url_template argument
It was a real but undocumented CLI/constructor argument (turns page
citations into clickable links in summaries). Add it to the Summary
Arguments table and the Python constructor signature.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
SKILL.md
- [8db96a1] by @thiswillbeyourgithub, 9 days ago:
docs(skill): document youtube subtitle changes and kebab-case flags
Reflect changes since the reference was written: --youtube_language now
auto-detects the original-language (-orig) subtitle track when unset,
--yt_* flags are rewritten to --youtube_*, and CLI flags accept
kebab-case (dashes normalized to underscores).
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
SKILL.md
- [65b619c] by @thiswillbeyourgithub, 9 days ago:
docs(skill): document the zotero and karakeep filetypes
Both were added since the reference was last written. Add them to the
Recursive Filetypes table, document their loader-specific arguments and
--path selector syntax in the DocDict section, and add shell examples.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
SKILL.md
- [f1b2693] by @thiswillbeyourgithub, 9 days ago:
docs(skill): bump reference to v5.1.0 and list modular install extras
The reference was pinned to v5.0.0; the repo is now v5.1.0. Also expand
the Installation section to document the modular extras introduced when
install_requires was split (youtube/audio/anki/office/logseq/zotero/
karakeep/...), since the base package only ships pdf + url loaders.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
SKILL.md
- [36db392] by @thiswillbeyourgithub, 9 days ago:
docs(claude): require keeping SKILL.md in sync with user-facing changes
SKILL.md is a hand-maintained comprehensive reference that drifts unless
updated by hand. Add it to the "Adding New Settings" and "Adding Support
for a New Filetype" checklists and add a dedicated "Keeping SKILL.md in
Sync" section so future changes update it.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
CLAUDE.md
- [43e7e8b] by @thiswillbeyourgithub, 10 days ago:
test(run_all_tests): validate MISTRAL_API_KEY before the suite runs
test_mistral_embeddings hardcoded "mistral/mistral-embed", so the
existing_check_provider_key "mistral/" MISTRAL_API_KEYguard in
run_all_tests.sh never matched anything and the key was never checked
up-front: a missing MISTRAL_API_KEY only surfaced late, mid-suite.
Make the embed model overridable via WDOC_TEST_MISTRAL_EMBED_MODEL
(default mistral/mistral-embed, full id incl. provider) and add it to
_ALL_TEST_MODELS so the guard now matches and crashes early.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/run_all_tests.sh
tests/test_wdoc.py
- [1d4ea7a] by @thiswillbeyourgithub, 10 days ago:
test(karakeep): pad the roundtrip bookmark text past the reading-length guard
A bare marker string is too short and trips wdoc's 'total reading length
is suspiciously low' assertion (> 0.1 min). Repeat a deterministic
sentence around the unique marker so the loaded doc clears the guard
while the assertions still match on the marker.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/test_karakeep.py
-
[14cb323] by @thiswillbeyourgithub, 10 days ago:
Merge branch 'karakeep_source' into dev -
[3ce4a93] by @thiswillbeyourgithub, 11 days ago:
test(karakeep): make the api test self-contained via a bookmark lifecycle
Instead of depending on a pre-existing library and a KARAKEEP_TEST_SELECTOR env
var, the api test now creates its own temporary text bookmark (deterministic,
unlike a link whose html is crawled asynchronously), loads it through wdoc's
loader, asserts the round-trip, then deletes it (mirrors karakeep_python_api's
own create/delete lifecycle tests). It also asserts the live bookmark carries
the structural keys the FakeKarakeep fixtures encode, so the fast basic tests
cannot silently drift from the real schema. Drop the now-unneeded
KARAKEEP_TEST_SELECTOR guard from run_all_tests.sh.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/run_all_tests.sh
tests/test_karakeep.py
- [b3add40] by @thiswillbeyourgithub, 11 days ago:
docs(karakeep): document the karakeep filetype
Add the karakeep filetype, its --path selector syntax and karakeep_* args to
help.md, usage examples to examples.md, and short mentions to README.md and
ARCHITECTURE.md. Built with the help of Claude Code.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
ARCHITECTURE.md
README.md
wdoc/docs/examples.md
wdoc/docs/help.md
- [8ac80fe] by @thiswillbeyourgithub, 11 days ago:
test(karakeep): guard api creds and run karakeep suites in run_all_tests
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/run_all_tests.sh
- [5de76cb] by @thiswillbeyourgithub, 11 days ago:
test(karakeep): cover selector parsing, fan-out, resilience and caching
A fake Karakeep client drives the basic tests (no network): selector parsing,
link/text/asset fan-out, the native-source skip path, the loading_failure=warn
resilience guarantee, and the doc_loaders_cache hit. Adds an api-gated real
instance test driven by KARAKEEP_TEST_SELECTOR.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/test_karakeep.py
- [02df505] by @thiswillbeyourgithub, 11 days ago:
feat(karakeep): add parse_karakeep recursive fan-out type
Resolves a Karakeep selector to bookmarks, materializes each bookmark's stored
artifact to a temp file via the cached resolver, and emits one local_html/txt/pdf
DocDict per bookmark (loading_failure=warn so one bad bookmark does not abort the
selection). Registered in recursive_types_func_mapping.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
wdoc/utils/load_recursive.py
- [fa6ecbc] by @thiswillbeyourgithub, 11 days ago:
feat(karakeep): add Karakeep API helper module
Client construction (with private-mode guard), selector parsing, bookmark
resolution across lists/tags/search/ids/library with cursor pagination, a
metadata header builder, and a doc_loaders_cache-backed per-bookmark content
resolver that prefers Karakeep's stored artifacts (html/text/pdf asset) and
never re-fetches the live URL.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
wdoc/utils/loaders/karakeep.py
- [08b015a] by @thiswillbeyourgithub, 11 days ago:
feat(karakeep): add karakeep extra and loader arg types
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
setup.py
wdoc/utils/misc.py
-
[d03299d] by @thiswillbeyourgithub, 11 days ago:
Merge branch 'zotero_source' into dev -
[3df03dc] by @thiswillbeyourgithub, 12 days ago:
test(zotero): drive the api test from ZOTERO_COLLECTION_NAME
Replace the bespoke ZOTERO_TEST_SELECTOR env var with ZOTERO_COLLECTION_NAME,
which sits alongside the standard pyzotero ZOTERO_* credentials, so the api
test setup is consistent with the other env-driven tests. The test now
parametrizes over both attachment-text routes (fulltext and wdoc) against the
named collection, and a new basic test asserts the fan-out marks every
sub-document loading_failure='warn'. run_all_tests.sh guards on
ZOTERO_COLLECTION_NAME accordingly.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/run_all_tests.sh
tests/test_zotero.py
- [6515753] by @thiswillbeyourgithub, 12 days ago:
fix(zotero): make the fan-out resilient to per-item load failures
A selection that spans a whole library inevitably contains items that fail
wdoc's loaders: a sparse bibliographic entry whose metadata document is too
short for the minimum reading-length check, a corrupt or DRM'd attachment, an
unsupported attachment type, etc. Inherited from parse_doc, every emitted
sub-document carried loading_failure='crash', so a single bad item aborted the
entire selection.
Emit each zotero sub-document with loading_failure='warn' so a failure is
logged and skipped while the rest load; the batch still raises only if every
sub-document fails. Found while parsing a real 17-item collection where one
abstract-less book entry crashed the whole run.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
wdoc/utils/load_recursive.py
- [1b1c113] by @thiswillbeyourgithub, 12 days ago:
docs(zotero): trim the supported-types and README mentions
Drop the parenthetical after zotero in ARCHITECTURE.md's supported-types
line and shorten the README recursive-filetype entry to match the house
style, deferring the selector syntax and options to help.md.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
ARCHITECTURE.md
README.md
- [cd4e5bd] by @thiswillbeyourgithub, 12 days ago:
test(zotero): exercise both attachment routes against a real library
The api test now parametrizes over the fulltext and wdoc attachment-text
routes so both the Zotero indexed-fulltext path and the download-then-parse
path are covered, and asserts every emitted document carries a title.
run_all_tests.sh now actually runs test_zotero.py (basic + api) and crashes
early, mirroring the whisper key guard, when ZOTERO_API_KEY or
ZOTERO_TEST_SELECTOR are missing.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/run_all_tests.sh
tests/test_zotero.py
- [c711ada] by @thiswillbeyourgithub, 12 days ago:
fix(loaders): make title a first-class load_one_doc arg
Passing a title via a DocDict crashed any loader that does not declare a
title parameter (txt, pdf, ...) with MissingDocdictArguments, because title
was validated as a loader argument. Only load_url accepts title, so every
other filetype was affected. The zotero fan-out hit this whenever it labelled
its emitted txt/pdf sub-documents.
title is now an explicit parameter of load_one_doc: it is consumed for
document metadata and still forwarded to loaders that declare it (url), but no
longer rejected by loaders that do not. Adds a basic regression test that
parses a txt file with a title kwarg.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/test_parsing.py
wdoc/utils/loaders/init.py
- [f8c5575] by @thiswillbeyourgithub, 2 weeks ago:
fix(zotero): pin pyzotero to a real version floor
1.5.18 was not a real release; pin to >= 1.6.0 (well past local-API support;
current pyzotero is 1.13.1).
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
setup.py
- [f056008] by @thiswillbeyourgithub, 2 weeks ago:
docs(zotero): document the zotero filetype
Document the new zotero recursive filetype and its --path selector + zotero_*
arguments in help.md, add CLI examples (collection/library/tag, fulltext
backend, notes) to examples.md, and list it in the README filetypes and
ARCHITECTURE.md. Implemented with Claude Code.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
ARCHITECTURE.md
README.md
wdoc/docs/examples.md
wdoc/docs/help.md
- [34ebdfa] by @thiswillbeyourgithub, 2 weeks ago:
test(zotero): cover selector parsing and fan-out with a fake client
Add tests/test_zotero.py: basic tests for the --path selector parser, the
recursive registration, DocDict acceptance of zotero_*/title keys, and the
fan-out behaviour for each backend (wdoc pdf, fulltext, notes on/off, metadata
off, tag selector) using a fake pyzotero client (no network). Plus an api-marked
test gated on ZOTERO_TEST_SELECTOR for a real library.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
tests/test_zotero.py
- [dee47a5] by @thiswillbeyourgithub, 2 weeks ago:
feat(zotero): add parse_zotero recursive fan-out type
Register azoterorecursive filetype that expands a Zotero selector (passed via
--path: collection path, tag:, items:, search:, or library) into one DocDict per
loadable sub-document: each attachment becomes a pdf/auto/url doc handed to
wdoc's existing loaders (or a txt doc with Zotero's indexed fulltext when
zotero_attachment_text requests it), plus an always-on per-item metadata/abstract
doc and optional note docs. This reuses wdoc's loaders/caching with no
duplicated extraction.
Also allow title as a DocDict key so per-document titles set by recursive
loaders reach load_one_doc's metadata enrichment (it already reads
kwargs["title"]).
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
wdoc/utils/load_recursive.py
wdoc/utils/misc.py
- [8a74e36] by @thiswillbeyourgithub, 2 weeks ago:
feat(zotero): add Zotero API helper module
New wdoc/utils/loaders/zotero.py with the Zotero-facing helpers used by the
upcoming parse_zotero recursive type: client connection (local API first, web
API fallback, private-mode guard), selector parsing (collection path / tag /
item keys / saved search / whole library), collection-tree resolution,
attachment materialisation (download or linked file/url), indexed fulltext
fetch, and bibliographic header / metadata-document formatting.
Attachments are handed to wdoc's own pdf/auto loaders rather than re-extracting
text, so no PDF parsing logic is duplicated.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
wdoc/utils/loaders/zotero.py
- [38bb00f] by @thiswillbeyourgithub, 2 weeks ago:
feat(zotero): add zotero extra and loader arg types
Add thezoterooptional dependency (pyzotero) to setup.py and include it
in thefullaggregate. Register the zotero_* loader arguments in
filetype_arg_types so they flow into extra_args_types and DocDict.allowed_keys.
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
setup.py
wdoc/utils/misc.py
- [d66fbd8] by @thiswillbeyourgithub, 3 weeks ago:
fix: typo
Signed-off-by: thiswillbeyourgithub 26625900+thiswillbeyourgithub@users.noreply.github.com
README.md