Commit graph

309 commits

Author SHA1 Message Date
Kodai Nakamura
059f15622f refactor(settings): group options by user workflow
Why:
- The settings tab mixes unrelated options under broad or service-specific headings.

What:
- Reorder the catalog into six contiguous user-facing groups.
- Lock group membership and display order with a focused test.
2026-07-17 22:30:28 +09:00
Kodai Nakamura
f9d5291e3d fix(candidate-scanner): honor ignored table rows
Why:

AI ambiguity scanning still inspected Markdown table rows when ignoreMarkdownTables was enabled, while replacement skipped those rows through centralized Markdown segmentation. That kept scanner and renderer semantics from fully matching.

What:

Route candidate occurrence scanning through segmentMarkdown protection, move table-row detection into the Markdown segment module, and add regressions for unlinked candidates, existing wikilinks, and AI requests inside ignored table rows.
2026-06-22 04:16:02 +09:00
Kodai Nakamura
9a98513ea8 fix(replace-links): share candidate scan semantics
Why:

The final architecture review found that AI ambiguity scanning and link replacement could diverge on scoped base-directory matching and raw Linear URL protection. The replacement renderer also still carried its own candidate traversal loop, which made that drift possible.

What:

Pass baseDir into ambiguity scanning, share raw URL protection across markdown segmentation and candidate scanning, and route replacement rendering through the scanner's single candidate-at-index matcher. Add regression coverage for baseDir scoped AI requests and Linear URL protection parity.
2026-06-22 04:07:36 +09:00
Kodai Nakamura
cf5562f0cb fix: restore wikilink protection for URL replacement
Why:
Linear URLs were being rewritten inside existing wikilinks, and protected markdown segments were not treating linear:// URLs as URLs. That regressed helper compatibility and selection safety.

What:
- Skip raw URL replacement matches that fall inside wikilinks while keeping the helper direct and linear-aware.
- Extend protected markdown URL segmentation to include linear://.
- Add regression tests for raw replacement, segmentation, and selection formatting.
2026-06-22 03:41:26 +09:00
Kodai Nakamura
3ddcf08538 fix: restore raw URL helper semantics
Why: Task 5 centralized URL formatting but accidentally changed shared Markdown segmentation and the legacy replaceURLs compatibility path.

What: remove angle-bracket autolink protection from shared segmentation, keep angle-bracket and trailing-punctuation handling inside formatURLsInText, and restore replaceURLs to a direct regex replace with linear:// support.
2026-06-22 03:33:12 +09:00
Kodai Nakamura
621b15a7a1 refactor(replace-urls): centralize prose-aware URL formatting
Why:
- URL formatting orchestration was split across formatting-run and the GitHub adapter, which made adapter ordering harder to reason about.
- Task 4 added prose segmentation, and URL formatting needed to use it so protected Markdown stays untouched while still supporting linear:// URLs.

What:
- add a dedicated url-formatting module that applies GitHub, Jira, and Linear adapters in one prose-aware pass
- route formatting-run document/body URL formatting through the central formatter and remove cross-adapter orchestration from github.ts
- extend markdown segmentation and compatibility tests to cover protected angle-bracket autolinks and linear:// matching
2026-06-22 03:22:28 +09:00
Kodai Nakamura
29582da575 fix(markdown): preserve table context after wikilink rewrites
Why: resolved wikilink rewrites can shift segment offsets before the prose pass that decides whether a row is inside a markdown table, which breaks alias escaping in table links. Angle-bracket autolinks also need to stay untouched when URL titles are available.

What: use the rewritten body when checking table context in the second prose-mapping pass, and skip URL-title replacement when a matched URL is wrapped in angle brackets. Add regression tests for both cases.
2026-06-22 03:13:34 +09:00
Kodai Nakamura
db05c2ee1f fix(markdown): protect variable-length fenced code blocks
Why:
Markdown fence handling regressed when the shared segmenter only recognized backticks and exact triple fences. That let link and URL rewriting leak into supported fenced code blocks.

What:
Add fenced-code range collection with opening/closing fence length matching, include tilde-only input in the fast path, and keep fenced blocks out of the generic protected matcher. Add regressions for tilde fences, wider backtick fences, and the URL/link consumers that rely on markdown segmentation.
2026-06-22 03:05:52 +09:00
Kodai Nakamura
9209356ee0 refactor(markdown): centralize protected segment handling
Why:
- Link replacement and URL title code each carried their own Markdown context checks, which made protected text behavior hard to keep consistent.
- A shared Markdown segment module improves locality for prose-only transformations.
- The refactor needed to preserve existing wikilink correction and table behavior without bringing back placeholder collisions.

What:
- Add a pure Markdown segment module with prose mapping and focused tests.
- Route link replacement and URL title flows through shared protected segment handling.
- Preserve existing-link correction, heading/callout/table protection, and add fast paths to keep performance within the existing thresholds.
2026-06-22 02:57:16 +09:00
Kodai Nakamura
f217ee9dad fix(settings): preserve textarea sizing metadata
Why:
Task 3 centralized settings rendering, but the renderer hard-coded textarea dimensions for every multiline control. That enlarged directory lists that previously used Obsidian's default textarea size.

What:
Add optional rows/cols metadata to catalog entries, mark only the three URL textarea settings with explicit 4x50 sizing, and apply textarea dimensions in the renderer only when the catalog requests them. Include a regression test that locks the sizing contract to the URL-related textarea settings only.
2026-06-22 02:43:54 +09:00
Kodai Nakamura
36c6f45128 refactor(settings): centralize settings catalog
Why:
- Adding or changing a setting required parallel edits across defaults, projections, refresh behavior, and UI rendering.
- Task 3 needs one canonical catalog while preserving the existing Task 2 formatting behavior and current settings side effects.

What:
- Add a settings catalog module with defaults, UI metadata, index-refresh flags, and projection helpers.
- Re-export settings info compatibility imports and reuse the catalog projection from formatting-run.
- Render the settings tab from catalog entries while preserving labels, order, validation, and URL-title refresh behavior.
2026-06-22 02:37:49 +09:00
Kodai Nakamura
9098a48053 fix: preserve frontmatter URL formatting
Why:
The Task 2 refactor split frontmatter before URL rewriting, which left GitHub/Jira/Linear URLs in YAML raw even though document formatting previously handled them.

What:
Add a regression test for frontmatter URL formatting with body-only title/link behavior, factor URL rewriting into a shared helper, and apply it to the original frontmatter slice before body-only formatting.
2026-06-22 02:26:52 +09:00
Kodai Nakamura
6585b7393a fix(formatting): restore selection-only link replacement
Why:
- The selection command regressed by inheriting document-level URL formatting from the shared body formatter.
- That changed user-visible output for selected text containing GitHub, Jira, or Linear URLs.

What:
- Added a selection-only formatter that projects link replacement settings and calls `replaceLinks(...)` directly.
- Switched `mofifyLinksSelection()` to the new helper so document formatting stays unchanged.
- Added regression coverage for selection-only behavior and documented the fix in the task report.
2026-06-22 02:20:28 +09:00
Kodai Nakamura
73014eb012 refactor: extract pure formatting run
Why:
- main.ts mixed Obsidian adapter work with pure transformation sequencing, which made formatting behavior require plugin mocks to test.
- A pure formatting run increases locality for URL formatting, URL title replacement, and link replacement order.

What:
- Add a formatting-run module with document and body formatting entry points.
- Route file and selection formatting through the new module.
- Move pure frontmatter URL-title coverage out of main adapter tests.
2026-06-22 02:14:30 +09:00
Kodai Nakamura
a8afe1d847 fix(replace-links): align AI self-link and scanner protection
Why:
- the AI enhancement command normalized the active note path for ambiguity resolution but then passed the raw .md path into replacement, which could still create self-links when preventSelfLinking was enabled
- the scanner merged block-level protected ranges before appending inline-code ranges, which let mixed ordering move scanning backward into protected callout content

What:
- normalize the AI command file path once and reuse it for both resolveAmbiguities() and replaceLinks()
- sort and merge the final protected range list after adding inline-code ranges
- add focused regressions for the AI self-link path handoff and the inline-code-before-callout scanner case
2026-06-22 02:07:14 +09:00
Kodai Nakamura
21fd68c7b9 fix(resolve-ambiguities): pass active file path into AI scan
Why:
AI ambiguity requests were scanned without the current file path, so preventSelfLinking could not filter self-link candidates on the AI path.

What:
- Thread an optional filePath through resolveAmbiguities() and pass it into the shared candidate scanner.
- Pass the active markdown path without .md from the AI command in main.ts.
- Add a regression proving self-link candidates are skipped before AI requests are built when the current file matches.
2026-06-22 01:59:23 +09:00
Kodai Nakamura
325ad7e9f4 fix(replace-links): match Korean particle scanner cursor
Why: The scanner was skipping Korean particle hits by candidate length, which let it jump past overlapping follow-on candidates and diverge from replaceLinks cursor behavior.\n\nWhat: Advance the scanner by one codepoint after a Korean particle skip, add regressions for the isolated and overlapping 문서/서는 cases, and record the verification in the Task 1 report.
2026-06-22 01:54:13 +09:00
Kodai Nakamura
490e0c3277 fix(replace-links): align Korean ambiguity handling
Why:
- Task 1 still had drift between candidate scanning and Korean replacement special cases.
- The scanner could ask AI about Korean particle forms that replacement intentionally skips.
- The Korean suffix replacement path ignored resolved ambiguities and could apply a different target than the AI chose.

What:
- skip Korean particle trie hits in the Task 1 candidate scanner and ambiguity request path
- reuse a shared resolved-ambiguity link-content helper for the standard and Korean suffix replacement branches
- add Task 1 regressions and append the Task 1 fix report with focused and full verification results
2026-06-22 01:49:08 +09:00
Kodai Nakamura
b264541faa fix(candidate-scanner): skip existing wikilinks in inline code
Why:
- Existing wikilinks inside inline code were still being collected as candidate occurrences, which could drive resolveAmbiguities() to prepare AI work for text that replaceLinks() intentionally leaves untouched.

What:
- Added inline-code protected ranges to existing wikilink collection so matches inside backticks are ignored alongside the current block-level exclusions.
- Added regression coverage for scanCandidateOccurrences() and the resolveAmbiguities() request path.
- Appended the focused and full verification results to the task 1 report.
2026-06-22 01:41:26 +09:00
Kodai Nakamura
c3151b3f41 fix(replace-links): align candidate scanner semantics
Why:
- Task 1 scanner drifted from replaceLinks in two places that affect AI ambiguity review.
- Trie-hit namespace handling was filtering candidate sets differently from replacement-time behavior.
- Protected-region scanning was still walking fenced code, callouts, and ignored headings that replaceLinks already shields.

What:
- make trie-hit scanning use the original candidate set and first-candidate scoped checks, matching current replaceLinks behavior
- skip fenced code blocks, callouts, and ignored headings before protected-regex scanning while preserving original occurrence offsets
- add regressions for trie-hit namespace semantics and protected-region skipping, plus AI-side coverage and append the fix report
2026-06-22 01:33:56 +09:00
Kodai Nakamura
953688d96e refactor(replace-links): centralize candidate scanning
Why:
- Candidate detection was duplicated between link replacement and AI ambiguity resolution, which made matching behavior hard to reason about.
- A single scanner improves locality for namespace, protected-span, case, and CJK matching rules.

What:
- Add a shared candidate scanner module for unlinked text and existing wikilinks.
- Route AI ambiguity request construction through the scanner.
- Keep link rendering behavior unchanged and covered by existing replacement tests.
2026-06-22 01:22:38 +09:00
Kodai Nakamura
1490c1d39f feat: add frontmatter opt-out for URL titles
Why:
- Some notes need to keep raw URLs and avoid web title requests even when global URL title replacement is enabled.
- A per-note frontmatter flag gives users local control without disabling other automatic linking behavior.

What:
- Add automatic-linker-disable-url-title frontmatter detection.
- Skip URL title fetching and replacement when the flag is set on a note.
- Document the frontmatter option and add regression coverage for the helper and plugin flow.
- Record this repository's agent version-control instructions in AGENTS.md.
2026-06-21 23:22:35 +09:00
Kodai Nakamura
997e5a8b49 refactor(replace-links): centralize table link escaping
Why:
- Markdown table escaping is link formatting behavior, not plugin orchestration behavior.
- Keeping pipe escaping in main.ts duplicated logic already used by the default link generator and made the Obsidian adapter responsible for markdown rendering details.

What:
- Add a shared escapeLinkForMarkdownTable helper in replace-links.
- Reuse the helper from defaultLinkGenerator and from the Obsidian API link generator path.
- Delegate fallback wikilink rendering in main.ts to defaultLinkGenerator.
- Add direct coverage for table link escaping behavior.
2026-05-30 15:06:07 +09:00
Kodai Nakamura
846ebda9ce fix(replace-links): preserve unclosed fenced code blocks
Why:
- Markdown treats an opening fenced code block without a closing fence as code through the end of the document.
- Automatic linking was still processing that content as normal text, which could turn code block contents into wiki links.

What:
- Extract fenced code blocks before heading, callout, table, and link replacement processing.
- Preserve unmatched fenced blocks through EOF and restore them unchanged after replacement.
- Add regression coverage for unclosed code blocks, including when heading protection is enabled.
2026-05-30 10:32:24 +09:00
Kodai Nakamura
11b0960bc7 feat: add option to ignore markdown tables
Why:
- Some users prefer leaving Markdown table rows untouched to avoid table formatting conflicts during automatic linking.
- Issue #35 requested a skip-tables option as an additional escape hatch alongside pipe escaping.

What:
- Add an ignoreMarkdownTables setting with a default value of false.
- Add a settings toggle for ignoring Markdown table rows during automatic linking.
- Skip both plain-text link insertion and existing-link ambiguity replacement inside Markdown table rows when the option is enabled.
- Cover the table-skip behavior with regression tests.

Refs: #35
2026-05-30 09:46:29 +09:00
Kodai Nakamura
f821e618f6 fix: escape Obsidian alias links in tables
Why:
- Aliased wiki links generated inside Markdown table cells used a raw pipe separator.
- Markdown table formatters interpret that raw pipe as a column delimiter, which mangles table rows after automatic linking.

What:
- Escape pipe characters in links returned by Obsidian's generateMarkdownLink API when the replacement occurs inside a table.
- Add a regression test covering an existing target file with a frontmatter alias inside a Markdown table cell.

Closes: #35
2026-05-30 09:40:36 +09:00
Kodai Nakamura
8748a6c4d2 fix(plugin): resolve obsidian compatibility warnings
Why:
- Obsidian's plugin checks were reporting compatibility and packaging warnings that could break popout-window behavior or leave async failures unhandled.
- The build also depended on a deprecated module listing package and carried inline tests that leaked warning noise into the production bundle.

What:
- add @codemirror/view as a runtime dependency and replace builtin-modules with node:module builtinModules in the esbuild config
- route plugin async startup and save-file hooks through compatibility helpers so delayed work uses window.setTimeout and fire-and-forget promises are explicitly handled
- switch the AI progress notice to activeDocument, await clipboard writes, align extended Obsidian types, rename the settings heading, and remove unused catch bindings
- move trie inline tests into dedicated Vitest files and add coverage for the new compatibility helpers to keep the build warning-free
2026-05-26 21:49:50 +09:00
Kodai Nakamura
76e0da3ac9 fix: resolve lint and formatting errors in AI Link Enhancer implementation 2026-04-06 23:19:38 +09:00
Kodai Nakamura
706bbf91ef feat: add AI Link Enhancer for resolving ambiguous links
- Implemented AI-powered link disambiguation using local LLMs (Gemma 4 / LM Studio).
- Refactored Trie and candidate mapping to support multiple link candidates per word.
- Added 'AI Link Enhancer' command with a progress bar UI in Obsidian.
- Enhanced link replacement logic to verify existing links and resolve ambiguities using context.
- Added comprehensive unit tests for AI disambiguation and candidate mapping.
- Updated settings to include AI configuration (endpoint, model, context length).
2026-04-06 22:59:52 +09:00
Kodai Nakamura
fa4ae53bd6 feat: add sentence case detection for matching capitalized text at sentence start
When ignoreCase is off, text capitalized at the start of a sentence (e.g., "My name")
now matches lowercase candidates (e.g., "my name.md"), producing [[my name|My name]].

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 15:37:15 +08:00
Kodai Nakamura
e591f59df2 chore: rename "Consider Aliases" to "Include Aliases" 2026-02-11 11:31:47 +09:00
Kodai Nakamura
44ae7e7869 chore: add lint:fix 2026-02-11 10:48:16 +09:00
Kodai Nakamura
771bd29ca4 chore: reorganize settings to group integrations together 2026-02-11 10:46:48 +09:00
Kodai Nakamura
240dd06ed8 chore: add ignoreHeadings setting to ReplaceLinksSettings interface 2026-02-09 11:35:58 +09:00
Kodai Nakamura
d6bdf49357 feat: add option to ignore headings when replacing links 2026-02-09 11:17:23 +09:00
Daniel Bauer
65b4eec9a1
fix: remove typo in setting 'Igonre' to 'Ignore' 2026-01-19 11:45:42 +01:00
Kodai Nakamura
07b9fb852e fix: handle missing titles and request errors 2026-01-06 00:01:08 +09:00
Kodai Nakamura
d9154194ef fix: remove frontmatter cache clearing on trie rebuild 2025-12-28 01:47:41 +09:00
Kodai Nakamura
a4e4b77a20 chore: missing change 2025-12-21 18:00:20 +09:00
Kodai Nakamura
8eb47a1d43 chore: stylistic 2025-12-21 17:59:06 +09:00
Kodai Nakamura
8a8a57194d chore: fix incorrect variable name 2025-12-21 17:53:46 +09:00
Kodai Nakamura
b20e2367f9 chore: stylistic 2025-12-21 16:09:27 +09:00
Kodai Nakamura
43ab63bfdf chore 2025-12-21 01:43:07 +09:00
Kodai Nakamura
18d80400ce chore: change default setting to respect "Folder to create new notes in" 2025-12-21 01:03:36 +09:00
Kodai Nakamura
d9277b08f9 chore: refresh trie on settings change 2025-12-21 01:01:07 +09:00
Kodai Nakamura
5d701f949c chore!: rename "namespace resolution" to "proximity-based linking" 2025-12-20 21:55:02 +09:00
Kodai Nakamura
8aae6e45f9 chore: fix test 2025-12-20 21:26:16 +09:00
Kodai Nakamura
99b0531edb chore: improve code formatting and readability in src/main.ts 2025-12-20 21:01:54 +09:00
Kodai Nakamura
0b62af15cd chore: fix stylistic issues in multiple files 2025-12-20 20:57:13 +09:00
Kodai Nakamura
2943d80742 chore: add stylistic eslint plugin and format code 2025-12-20 20:43:05 +09:00