Move the inline Modal dialog for batch folder selection into a reusable
promptForBatchFolder function. Removes Modal import from main.ts.
main.ts now 775 lines.
Change-Id: I7a5c62b7df95635dcbe0ac814007838ff83eded4
Move resolveCardAnchors to src/cards.ts and confirmRegenerateEditedCards
to src/modal.ts to reduce main.ts from 835 to 796 lines (under 800 target).
Change-Id: If38ed4e45c61658b7cc52a6283f8e0e24458761e
Test all parser functions with empty responses, missing fields, null inputs,
legacy format fallbacks, multi-block concatenation, and tool-use rejection
for wrong tool names and missing content arrays.
Change-Id: Ie3c15aa636a6b421ca6bf4315313368c249f2782
Cover the two key paths in requestJsonBodyWithStructuredFallback:
1. 400 with response_format mention → retry without structured output
2. 500 server error → no retry, error propagated
Change-Id: If8d0fc484e49238699444131cbadcf1b18bf992f
Cover the key scenarios for provider switching: model swapped when
matching previous preset, custom model preserved across switches,
empty model triggers swap, and input immutability verified.
Change-Id: I467604d51e8c11e990e54621347094cf914cb6b7
The constructor always receives a validated ResolvedCard from the call
site (which guards with !this.sections[index]). The fallback to an
empty object cast as ResolvedCard was dead code that hid type safety.
Change-Id: I35c9731d9079b9aeea5eb0fda7eda46a740bc964
The regenerate confirmation modal's onClose callback fired after button
click handlers, calling resolve() a second time. While Promise.resolve
is idempotent, this was confusing. Added explicit settlement tracking
so the promise resolves exactly once regardless of how the modal closes.
Change-Id: Ief4cbb78f15fe220a20adaf8343d744ffa8c1653
Verify that when a new entry is added via put() and the cache exceeds
maxCacheEntries, the oldest entry (by timestamp) is pruned and the
pruned state is correctly persisted to disk.
Change-Id: Ia937800a97d7591877e1d2d1fe808b86858735e1
Verify that two concurrent BatchRunState objects don't interfere with
each other (cancelling one doesn't affect the other), and that stats
accumulate correctly when processing is stopped mid-iteration.
Change-Id: Id32b27307beafe49594cfde6fa818b2f22b87c66
Cover pre-aborted signal (aborted before fetch starts) and mid-read
abort (signal aborted while reading response body). Both verify that
abort listeners are properly cleaned up after rejection.
Change-Id: I0760f6ed051de1504e9b7aeead01a10cfd12476e
The previous code checked signal.aborted before adding the listener,
creating a timing window where the signal could abort between the check
and addEventListener. Now the listener is always registered first, then
signal.aborted is checked after, ensuring no abort event is missed.
Change-Id: I1abc3ad21e5bb93559d66922edf7c325a977bc65
normalizeSettings previously modified its input parameter in-place.
While callers already created copies before calling it, the function
signature was misleading. Now it creates a shallow copy internally and
operates on that, with a Readonly<PluginSettings> parameter type to
signal intent. Added a test verifying the original object is unchanged.
Change-Id: I7600ac37930bbcebb02aa7c84d8988cb7aa71196
The CLI path was not forwarding settings.apiMaxTokens, causing the
model to use its own default which is too small for long documents
with many CJK cards. This was the root cause of repeated "LLM 返回
非 JSON" errors — the JSON was being cut off mid-card.
Change-Id: Ia738418e2e6cf7f919752cb3128a82768d95cedf
- Add repairTruncatedCardsJson to recover complete cards when output
is cut off mid-card (e.g. token limit reached)
- Log raw LLM response to console on parse failure for debugging
- Make error panel text selectable and add "copy error" button
Change-Id: I4e76121138888234d42f84f3695cbbfd6beba886
- Fix CI to run all 4 test files (was missing direct-modules.test.js)
- Remove unused ESLint dependencies (eslint, @typescript-eslint/*, eslint-plugin-obsidianmd)
- Enable noImplicitReturns in tsconfig.json for stricter type safety
- Make applyApiProviderPreset return new object instead of mutating input
- Add per-file error handling in batch processing loop with error count in summary
- Narrow all catch clause types to unknown with proper instanceof narrowing
Change-Id: I76975dbd5ebdb5645d18c5858c8a52fd6da3405e
When a note has no cached parallel notes, the empty state now shows a
clickable "Generate" button so users can trigger generation directly
without going through the command palette. Closes#2.
Change-Id: I879897168ef77c44e0ab570e9c094fa9af9f66d4
The catch callback no longer contains any await expressions
after the previous refactor removed await on sync view methods.
Change-Id: I054c50fe209aba0e925bd1838896228bce686841
- Remove unnecessary TFile cast (instanceof already narrows)
- Remove await on non-Promise view methods (loadFor, renderLoading, renderError)
- Remove async from CacheManager.touch() (no await expression)
- Replace this-aliasing with captured locals in batch modal
- Use CSS class instead of inline style for modal input width
- Fix sentence case in settings UI text
Change-Id: I2a222c6429eb7e4d69761cca8369956fef510054
- Remove `parallel-reader-` prefix from command IDs (Obsidian auto-namespaces)
- Remove default hotkeys to avoid conflicts with user keybindings
- Replace `as TFile` casts with `instanceof TFile` checks
- Make onunload sync, remove detachLeavesOfType (preserves leaf positions)
- Use `vault.configDir` instead of hardcoded `.obsidian`
- Replace `window.confirm` with Obsidian Modal dialog
- Fix unhandled promises with `void` or `await`
- Remove unnecessary `async` from methods without `await`
- Use `new Setting().setHeading()` instead of raw HTML headings
- Fix promise-returning callbacks in event listeners
- Fix error type narrowing with `instanceof Error`
- Apply sentence case to UI text labels
Change-Id: I6e850d8a13b458d5cf1ad91227bf1772636b56b9
Register parallel-reader-batch-generate command. It prompts the user for a
folder path via a Modal, finds all .md files in that folder (non-recursive),
skips files whose cache is still valid, and runs runForFile() sequentially
on the rest, showing per-file progress notices. Add i18n keys for the new
UI strings in both zh and en.
https://claude.ai/code/session_016QvEfqw6YZ3RjwBHrJ4w8S
Promote noExplicitAny from warn to error and enable noNonNullAssertion
at warn level. Fix the two resulting errors in src/schema.ts by introducing
a JsonSchema interface to replace the any-typed local variables.
https://claude.ai/code/session_016QvEfqw6YZ3RjwBHrJ4w8S