Node.js util.styleText does not accept 'grey' as a format name.
While util.inspect.colors defines 'grey' as a non-enumerable alias
for 'gray', styleText validates against Object.keys(inspect.colors)
which only includes enumerable properties — so 'grey' has never
been a valid styleText format and throws ERR_INVALID_ARG_VALUE.
micromorph() returns Promise<void> because its internal patch() function
is async and uses Promise.all for recursive child patching. Without
await, the DOM morph may still be in progress when the nav event fires
and downstream handlers attempt to rebuild dynamic content.
Fixes#2322
* Fix language parameter of the citation plugin for non en-US settings
Per default the rehype-citation project only supports en-US, as
explained here: https://github.com/timlrx/rehype-citation/issues/12
For other languages one can provide a locale-file either by passing
its path or providing an URL. The following repository contains locale
files for multiple languages. So, these are used, in case a non en-US
language is used in quarzt. But this optimistically assumes there is
indeed an according locale file.
In summary this solves the problem only partially, since there are
still some languages which will not work properly.
* Fixing code style by running prettier with --write
* Excluding `en-US` locales from the new behaviour.
* Removing unnecessary `null` und `undefined` check.
* Update quartz/plugins/transformers/citations.ts
* Update quartz/plugins/transformers/citations.ts
* Update quartz/plugins/transformers/citations.ts
---------
Co-authored-by: Jacky Zhao <j.zhao2k19@gmail.com>
This makes it so that the events are not fired until the file have stabilized.
This also changes the order of the fired events.
A move / rename now results in `delete` then `add` rather than the other way around.
From `chokidar` README - https://github.com/paulmillr/chokidar?tab=readme-ov-file#performance:
```
awaitWriteFinish.stabilityThreshold (default: 2000). Amount of time in milliseconds for a file size to remain constant before emitting its event.
```
Fixes#2232
* feat: improve search tokenization for CJK languages
Enhance the encoder function to properly tokenize CJK (Chinese, Japanese,
Korean) characters while maintaining English word tokenization. This fixes
search issues where CJK text was not searchable due to whitespace-only
splitting.
Changes:
- Tokenize CJK characters (Hiragana, Katakana, Kanji, Hangul) individually
- Preserve whitespace-based tokenization for non-CJK text
- Support mixed CJK/English content in search queries
This addresses the CJK search issues reported in #2109 where Japanese text
like "て以来" was not searchable because the encoder only split on whitespace.
Tested with Japanese, Chinese, and Korean content to verify character-level
tokenization works correctly while maintaining English search functionality.
* perf: optimize CJK search encoder with manual buffer tracking
Replace regex-based tokenization with index-based buffer management.
This improves performance by ~2.93x according to benchmark results.
- Use explicit buffer start/end indices instead of string concatenation
- Replace split(/\s+/) with direct whitespace code point checks
- Remove redundant filter() operations
- Add CJK Extension A support (U+20000-U+2A6DF)
Performance: ~878ms → ~300ms (100 iterations, mixed CJK/English text)
* test: add comprehensive unit tests for CJK search encoder
Add 21 unit tests covering:
- English word tokenization
- CJK character-level tokenization (Japanese, Korean, Chinese)
- Mixed CJK/English content
- Edge cases
All tests pass, confirming the encoder correctly handles CJK text.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
* Initial plan
* Initial analysis and plan for decoupling completion
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* docs: add @plugin annotations to transformers missing documentation
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* docs: mark decoupling phases and success criteria as complete
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* fix: move @plugin annotation in roam.ts to correct location
Move the @plugin documentation block to immediately precede the
RoamFlavoredMarkdown export, consistent with other transformer files
(gfm.ts, syntax.ts, linebreaks.ts). Previously it was placed before
the regex constant declarations.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Changes before error encountered
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* refactor: move documentation files from docs/ to project root
Move IMPLEMENTATION_SUMMARY.md, PLUGIN_MIGRATION.md, and SECURITY_SUMMARY.md
from docs/ directory to project root to keep them separate from user-facing
documentation.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* config: add implementation docs to ignore patterns
Add IMPLEMENTATION_SUMMARY.md, PLUGIN_MIGRATION.md, and SECURITY_SUMMARY.md
to ignorePatterns in quartz.config.ts to exclude them from the documentation
build. These files are implementation documentation for the project itself,
not user-facing documentation.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* chore: remove build output directories from git tracking
Remove public-current and public-v4 directories that were accidentally
committed during build testing. These directories are already covered by
.gitignore and should not be tracked in the repository.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Initial plan
* refactor: remove BuildCtx mutation from FrontMatter plugin
- Remove temporary cast to mutable allSlugs array
- Move alias collection to build orchestration layer
- Update ctx.allSlugs immutably after parsing
- Apply same pattern to incremental rebuild
- Verified alias functionality works correctly
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* fix: ensure alias collection happens before filtering in rebuild flow
Move alias collection before filterContent() in rebuild flow to match
initial build flow. This ensures consistent behavior where aliases from
all markdown files (including those that will be filtered out) are
included in ctx.allSlugs in both build scenarios.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* refactor: simplify collectAliases using functional array methods
Replace imperative for-loop with declarative filter/flatMap chain for
better readability and conciseness. Functionally equivalent but more
idiomatic TypeScript.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* docs: update roadmap with completion status for decoupling phases
Mark phases 1-5 as completed with detailed status notes:
- Phase 1 (Foundation): vfile-schema, plugin-context, test-helpers
- Phase 2 (Utility Abstraction): ctx.utils migration complete
- Phase 3 (Component Decoupling): component registry created
- Phase 4 (Immutability): BuildCtx readonly, alias collection refactored
- Phase 5 (Full Migration): all plugins migrated to new pattern
Add implementation status summary showing all objectives achieved.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Initial plan
* Extend PluginUtilities with missing path and escape utilities
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Migrate transformers to use ctx.utils instead of direct imports
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Migrate emitters to use ctx.utils - part 1 (helpers, aliases, assets, contentIndex, contentPage, tagPage, static, favicon)
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Complete emitter migration to ctx.utils - all emitters decoupled
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Add comment explaining double-unescaping in test helper mock
This mirrors the production implementation in util/escape.ts which has the same pattern. The CodeQL alert is a known limitation of simple HTML unescaping that exists in the production code as well.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Fix type safety: change join() return type to string and simplify casts
- Changed PluginUtilities.path.join() return type from FilePath to string to allow proper single-cast at call sites
- Removed unsafe double-casts (as unknown as FullSlug) in favor of single casts (as FullSlug)
- Fixed ogImage.tsx to use consistent destructuring pattern (ctx.cfg.configuration instead of cfg.configuration)
- Updated implementation in plugin-context.ts and test-helpers.ts
This addresses all code review feedback about type safety issues.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Fix test mock implementations to match production code behavior
- Fixed getAllSegmentPrefixes to return cumulative prefixes (e.g., ["a", "a/b", "a/b/c"])
- Fixed isRelativeURL to include all three validation conditions
- Fixed stripSlashes to use substring(1) instead of replace(/^\/+/)
- Fixed slugTag to properly handle hierarchical tags with sluggify logic
- Fixed split to handle PDF files and anchor normalization
- Fixed HTML entity ' to ' for consistency
- Changed QUARTZ imports to use utils.path.QUARTZ for consistency
- Fixed favicon.ts to pass full ctx instead of reconstructing partial object
All mocks now accurately reflect production code behavior for reliable testing.
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Initial plan
* docs: format design document for decoupling strategy
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* feat: implement Phase 1-4 of plugin decoupling strategy
- Created centralized vfile-schema.ts with all VFile data type definitions
- Created plugin-context.ts with PluginUtilities abstraction layer
- Created test-helpers.ts for plugin testing utilities
- Made BuildCtx readonly to prevent plugin mutations
- Added MutableBuildCtx for build orchestration layer
- Updated components to not mutate ctx.trie
- Updated FrontMatter plugin with temporary cast for backward compatibility
- Updated TransformOptions to accept ReadonlyArray
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* feat: add plugin utilities to BuildCtx and document plugin decoupling
- Added utils property to BuildCtx with createPluginUtilities()
- Documented plugin data dependencies with JSDoc comments on transformers and filters
- Created comprehensive plugin migration guide in docs/PLUGIN_MIGRATION.md
- Updated plugin types.ts with guidance on using PluginContext
- All plugins now have access to ctx.utils for path, resource, and escape utilities
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* docs: add implementation and security summaries
- Created IMPLEMENTATION_SUMMARY.md documenting all phases completed
- Created SECURITY_SUMMARY.md with CodeQL scan results
- All security checks passed with 0 vulnerabilities
- Complete documentation of changes, decisions, and impact
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* docs: add guidance for custom plugins extending vfile data
- Added section "Adding Custom VFile Fields" to PLUGIN_MIGRATION.md
- Demonstrates TypeScript module augmentation for custom fields
- Shows best practices for extending vfile data in third-party plugins
- Clarifies that centralized schema doesn't prevent custom extensions
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* refactor: address code review feedback
- Remove `any` type annotations from component map callbacks (Breadcrumbs, FolderContent)
- Fix test-helpers: change `config` to `cfg` to match BuildCtx interface
- Add `trie: undefined` to mock context for completeness
- Add missing vfile fields to schema: text, blocks, htmlAst, hasMermaidDiagram
- Make Argv properties truly readonly with ReadonlyArgv type
- Add documentation explaining module augmentation pattern is intentional
- Document FrontMatter mutation as known technical debt with timeline
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Initial plan
* Add comprehensive plugin decoupling design document
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Address code review feedback: fix incomplete types and missing files
- Add missing transformer files to Appendix A (gfm, linebreaks, oxhugofm, roam)
- Complete emit/partialEmit return types in QuartzEmitterPluginInstance
- Export TocEntry interface in vfile-schema to fix reference issue
- Add missing externalResources method to QuartzTransformerPluginInstance
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Address code review: add imports, fix component example, clarify interfaces, update file count
- Add missing import statements to all code examples (vfile-schema, plugin-context, registry, emitter types, test helpers)
- Fix component example to properly use QuartzComponentConstructor pattern
- Remove redundant externalResources from init() return type to avoid ambiguity
- Add placeholder implementations for helper functions in test example
- Update total file count from ~65 to ~71 to match breakdown (3+13+2+14+30+5+4)
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Address code review: fix type references, add missing properties, improve examples
- Fix JSResourceOptions/CSSResourceOptions to use actual JSResource/CSSResource types
- Add missing externalResources property to QuartzEmitterPluginInstance
- Clarify that requiredComponents is only for emitters, not transformers
- Fix TOC slug comment to indicate no "#" prefix (e.g., "some-heading")
- Expand frontmatter interface to include all fields from actual implementation
- Improve migration guide with complete example showing type import pattern
- Add skeleton implementations for test helper mock functions with realistic return types
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
* Address code review: fix imports, add required fields, simplify types
- Fix QuartzVFileData import from "./vfile-schema" instead of "./plugin-context"
- Add all missing import statements for types used in test helpers
- Add required config fields (enableSPA, enablePopovers, analytics, ignorePatterns, defaultDateType, theme)
- Import TocEntry type alongside QuartzVFileData in migration guide
- Simplify resource creation to separate createExternalJS/createInlineJS functions
- Remove circular import of ChangeEvent from "./types" (already defined in that file)
- Fix enableToc type to boolean | string for consistency with other frontmatter fields
- Update mock utilities to match new resource creation pattern
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: saberzero1 <8161064+saberzero1@users.noreply.github.com>
In 'processors/parse.ts' the 'remarkRehype' plugin is used with
'allowDangerousHtml' enabled, but that needs to be combined with (e.g.)
'rehypeRaw' to have any effect on the output.