jekyll-client-search 0.3.4 → 0.4.0
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +109 -1
- data/LICENSE +654 -15
- data/README.developer.md +37 -15
- data/README.md +195 -30
- data/assets/includes/related-articles.html +4 -2
- data/assets/query-embedders/ollama-api.js +1 -1
- data/lib/jekyll/client_search/configuration.rb +11 -10
- data/lib/jekyll/client_search/configuration_accessors.rb +13 -0
- data/lib/jekyll/client_search/dropdown_tag.rb +24 -41
- data/lib/jekyll/client_search/embedding_configuration.rb +51 -15
- data/lib/jekyll/client_search/generator.rb +66 -19
- data/lib/jekyll/client_search/index_cache.rb +3 -2
- data/lib/jekyll/client_search/ollama_embedding_adapter.rb +47 -1
- data/lib/jekyll/client_search/query_embedder_configuration.rb +3 -0
- data/lib/jekyll/client_search/related_analyzer.rb +4 -1
- data/lib/jekyll/client_search/related_configuration.rb +15 -0
- data/lib/jekyll/client_search/related_tag.rb +23 -17
- data/lib/jekyll/client_search/script_tags.rb +41 -0
- data/lib/jekyll/client_search/search_tag.rb +20 -34
- data/lib/jekyll/client_search/semantic_configuration.rb +46 -0
- data/lib/jekyll/client_search/version.rb +1 -1
- data/lib/jekyll/client_search.rb +2 -0
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 749a1708fe34bce1624db0eb4d91ea58a569f2663f8d78b8200365188faf7ae4
|
|
4
|
+
data.tar.gz: 833b1c87a57b2f78a05f42103efef6f9aa2ec09ee0726cad734e0f28f268fc50
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 169936c38c680b2f4ec657243909aaad0a902b6bbbc52e9c586d3d986651e1529fdfb2d2a9dcde69f997075b8c901c5178b7148d86f064242ee018a228b2e457
|
|
7
|
+
data.tar.gz: 3e75798e1b41dac7982ca34e83e61e8b28b03b347f6ca60b6e527570a72d4a69a9f5ddf6293197410c6935a699b54a7001b601145c57c7e09302e4f1edf4d426
|
data/CHANGELOG.md
CHANGED
|
@@ -1,13 +1,109 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 0.4.0 — 2026-10-24
|
|
4
|
+
|
|
5
|
+
- Dev-tooling bump: `jsdom` 30.1.3 (patch).
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- `benchmarks/embedding_model_benchmark.rb`,
|
|
10
|
+
`benchmarks/related_model_benchmark.rb`, and
|
|
11
|
+
`benchmarks/related_quality_judge.rb` — measure Ollama embedding
|
|
12
|
+
latency per model on a real site, compare `related` output across
|
|
13
|
+
models, and score judged relevance with a blind LLM judge
|
|
14
|
+
(10 local embedding models benchmarked on a 152-document site).
|
|
15
|
+
- `embeddinggemma-2` document/query prefixes (same prompt format as
|
|
16
|
+
`embeddinggemma`), `voyage-4-nano` prefixes (open-weight Voyage
|
|
17
|
+
model via community GGUF), and `qwen3-embedding` prefixes (official
|
|
18
|
+
instruct-format query prefix; empty document prefix).
|
|
19
|
+
- README model-selection guidance: measured per-document latency table,
|
|
20
|
+
LLM-judged quality ratings, quality-per-cost value index, amortized
|
|
21
|
+
yearly cost, `qwen3-embedding` build-time-only notes, and the
|
|
22
|
+
`localhost` → `127.0.0.1` loopback gotcha.
|
|
23
|
+
- Split index/related embedding models: `semantic.index_model` selects
|
|
24
|
+
the Ollama model whose vectors go into `search-index.json` (must match
|
|
25
|
+
the browser query embedder); `related.index_model` selects the model
|
|
26
|
+
used for related-article analysis. Both default to `embedding.model`;
|
|
27
|
+
equal models share one embedding pass, divergent models embed each
|
|
28
|
+
document twice into separate cached vector fields.
|
|
29
|
+
`semantic.document_prefix` / `semantic.query_prefix` override the
|
|
30
|
+
index model's prefixes. Related-model vectors are cached separately
|
|
31
|
+
in `.jekyll-client-search-related-cache.json` and never written to
|
|
32
|
+
the index.
|
|
33
|
+
- `embeddinggemma-2` (`:270m`, `:570m`, untagged) maps to
|
|
34
|
+
`onnx-community/embeddinggemma-2-ONNX` for the transformers.js query
|
|
35
|
+
embedder. `test/onnx-parity.test.js` is an opt-in check
|
|
36
|
+
(`ONNX_PARITY=1`, requires `@huggingface/transformers` and a running
|
|
37
|
+
Ollama) that compares ONNX and Ollama vectors and rankings;
|
|
38
|
+
`embeddinggemma:300m` remains the verified mapping.
|
|
39
|
+
|
|
40
|
+
### Changed
|
|
41
|
+
|
|
42
|
+
- Default `embedding.model` is now `embeddinggemma-2:570m` (was
|
|
43
|
+
`embeddinggemma:300m`) — the judged-quality leader among license-free
|
|
44
|
+
local models (111 vs 96) at ~2.5× the per-document latency; its text
|
|
45
|
+
vectors are byte-identical to `embeddinggemma-2:270m`. The
|
|
46
|
+
transformers.js query embedder maps it to
|
|
47
|
+
`onnx-community/embeddinggemma-2-ONNX`; sites that prefer the verified
|
|
48
|
+
browser mapping can set `semantic.index_model: embeddinggemma:300m`
|
|
49
|
+
while related analysis stays on the default model.
|
|
50
|
+
- CI: Semgrep moved from an inline `pip3 install semgrep==1.176.0` pin to hashed `.github/requirements-ci.txt` (compiled from `requirements-ci.in`, Python 3.12), installed with `--require-hashes`. Bumped Semgrep to 1.180.0; the version is now Dependabot-visible via a new `pip` ecosystem entry for `/.github`.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- A `localhost` `embedding.base_url` (the default) is resolved once to
|
|
55
|
+
the loopback literal that accepts a TCP connection — `127.0.0.1` or
|
|
56
|
+
`[::1]` — because `ollama-ruby`/Excon does not fall back across
|
|
57
|
+
address families and Ollama commonly listens on IPv4 loopback only.
|
|
58
|
+
Embedding calls that died with `Excon::Error::Socket "Broken pipe"`
|
|
59
|
+
when `localhost` resolved to `::1` first now connect on both
|
|
60
|
+
IPv4-only and IPv6-only servers.
|
|
61
|
+
|
|
62
|
+
## 0.3.5 — 2026-10-06
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- `LICENSE` now contains the verbatim AGPL-3.0 text (was a 22-line
|
|
67
|
+
stub that license scanners could not detect); README keeps the
|
|
68
|
+
copyright attribution.
|
|
69
|
+
|
|
70
|
+
### Added
|
|
71
|
+
|
|
72
|
+
- Codecov coverage reporting: CI uploads Cobertura XML (via `simplecov-cobertura`) from the Ruby 3.4 / Node 24 matrix job, with `codecov.yml` status checks (85% project/patch targets) and a README badge
|
|
73
|
+
- `rake version:check_consistency` — two-axis drift check: doc floor
|
|
74
|
+
literals (`Ruby >= X.Y`, `TargetRubyVersion`) against the gemspec,
|
|
75
|
+
full `X.Y.Z` pins against `.ruby-version`. `rake version:pre_release`
|
|
76
|
+
runs it with `check_changelog`.
|
|
77
|
+
|
|
78
|
+
### Changed
|
|
79
|
+
|
|
80
|
+
- `release.yml` no longer hardcodes the Ruby pin — `setup-ruby` reads
|
|
81
|
+
`.ruby-version` (single source for dev/release; the 3.2 floor stays a
|
|
82
|
+
deliberate gemspec literal proven by the CI matrix).
|
|
83
|
+
- `rbenv` instructions in README/README.developer.md now derive from
|
|
84
|
+
`.ruby-version` instead of restating the pin.
|
|
85
|
+
- Git hooks moved to tracked `bin/hooks/` enabled via `core.hooksPath`
|
|
86
|
+
— `bin/install-hooks.sh` no longer generates copies into `.git/hooks`.
|
|
87
|
+
- `spec/spec_helper.rb` autoloads `spec/support/**/*.rb`.
|
|
88
|
+
- Removed stale literal counts from docs (test examples, Semgrep rule
|
|
89
|
+
counts) — numbers that change on their own aren't restated.
|
|
90
|
+
|
|
91
|
+
### Security
|
|
92
|
+
|
|
93
|
+
- Dev-tooling audit gate: `scripts/npm-audit.mjs` + `.audit-allow.json`
|
|
94
|
+
replace the bare `npm audit` CI step — patchable transitive deps are
|
|
95
|
+
forced to fixed versions via `overrides` (smol-toml, katex), and only
|
|
96
|
+
explicitly allowlisted unpatched advisories are tolerated (braces,
|
|
97
|
+
dev-only, no patched release).
|
|
4
98
|
|
|
5
99
|
## 0.3.4 — 2026-09-11
|
|
6
100
|
|
|
7
101
|
### Added
|
|
102
|
+
|
|
8
103
|
- SonarQube Cloud badge in README.md (project key: `gundestrup_jekyll-client-search`)
|
|
9
104
|
|
|
10
105
|
### Fixed
|
|
106
|
+
|
|
11
107
|
- Verify `event.origin` in transformers-worker.js `message` listener to prevent cross-origin message injection (SonarQube: `javascript:S2819`, CRITICAL)
|
|
12
108
|
- Add `--ignore-scripts` to `npm ci` in CI to prevent lifecycle script execution during dependency installation (SonarQube: `githubactions:S6505`)
|
|
13
109
|
- Pin Semgrep to `1.176.0` with `--only-binary :all:` in CI to prevent setup script execution and lock resolved versions (SonarQube: `githubactions:S8541`, `githubactions:S8544`)
|
|
@@ -18,11 +114,13 @@
|
|
|
18
114
|
## 0.3.3 — 2026-09-11
|
|
19
115
|
|
|
20
116
|
### Refactored
|
|
117
|
+
|
|
21
118
|
- Extract duplicated `normalize` function from `client-search-base.js` and `client-search-dropdown.js` into new shared module `assets/client-search-shared.js` (exposes `window.ClientSearchShared.normalize` and `window.ClientSearchShared.coreFields`) — eliminates CodeFactor duplicate-code finding and ensures consistent normalization across both runtimes
|
|
22
119
|
|
|
23
120
|
## 0.3.2 — 2026-09-10
|
|
24
121
|
|
|
25
122
|
### Added
|
|
123
|
+
|
|
26
124
|
- Semgrep security scan in CI (`semgrep ci` job in `.github/workflows/ci.yml`) — runs on every push and pull request using the `SEMGREP_APP_TOKEN` secret and the Semgrep Pro engine with the organization's full policy (2,900+ rules)
|
|
27
125
|
- `.semgrep.yml` with custom Ruby ReDoS detection rules and usage documentation
|
|
28
126
|
- Semgrep step in pre-commit hook (`bin/install-hooks.sh`)
|
|
@@ -32,20 +130,24 @@
|
|
|
32
130
|
- Semgrep usage guide in README.developer.md (local commands, nosemgrep annotations, SHA pinning)
|
|
33
131
|
|
|
34
132
|
### Fixed
|
|
133
|
+
|
|
35
134
|
- Pin all GitHub Actions to full 40-character commit SHAs with version comments to prevent supply-chain attacks via mutable tag repointing (Semgrep: `github-actions-mutable-action-tag`)
|
|
36
135
|
- Replace `Object.assign({}, entry, ...)` in benchmark with explicit field construction to avoid mass-assignment taint (Semgrep: `insecure-object-assign`)
|
|
37
136
|
- Replace manual arXiv query string with `URI.encode_www_form` for correct URL encoding (Semgrep: `avoid-tainted-http-request`)
|
|
38
137
|
|
|
39
138
|
### Changed
|
|
139
|
+
|
|
40
140
|
- Add `nosemgrep` annotations with justifications for false positives (static ERB template, array-form `Open3.capture2`, fixed-host arXiv request) and acceptable risks (local loopback Ollama HTTP in tests and benchmarks)
|
|
41
141
|
|
|
42
142
|
## 0.3.1 — 2026-09-09
|
|
43
143
|
|
|
44
144
|
### Fixed
|
|
145
|
+
|
|
45
146
|
- Fix CodeQL `rb/bad-tag-filter` (high) in `DocumentBuilder#clean` — closing tag regex `</script\s*>` only matched whitespace before `>`, missing browser-accepted tags like `</script\t\n bar>`; changed to `</script[^>]*>` and `</style[^>]*>` to match any non-`>` content
|
|
46
147
|
- Fix CodeQL `rb/polynomial-redos` (high) in `RelatedTag` — `\s*` patterns between optional groups in SYNTAX regex caused O(n²) backtracking on input with many spaces; replaced single regex with token-split parser that validates each token individually
|
|
47
148
|
|
|
48
149
|
### Changed
|
|
150
|
+
|
|
49
151
|
- Update `simplecov` 1.1.1 → 1.2.0
|
|
50
152
|
- Update `google-protobuf` 4.36.0 → 4.36.1 (transitive)
|
|
51
153
|
- Update `sass-embedded` 1.103.1 → 1.104.0 (transitive)
|
|
@@ -55,6 +157,7 @@
|
|
|
55
157
|
## 0.3.0 — 2026-09-02
|
|
56
158
|
|
|
57
159
|
### Added
|
|
160
|
+
|
|
58
161
|
- `{% search_dropdown %}` Liquid tag — compact live-search dropdown for navbars and headers with keyboard navigation (Arrow/Enter/Escape), lazy index loading, icon support, and framework-agnostic semantic HTML (no Bulma/Bootstrap/Tailwind classes)
|
|
59
162
|
- `DropdownConfiguration` class with `enabled`, `max_items`, `min_chars`, `debounce_ms`, `redirect_url` options
|
|
60
163
|
- `assets/client-search-dropdown.js` runtime (434 lines) — two-stage search (AND first, fuzzy OR fallback), shared index cache with the base runtime, multi-instance support via `[data-client-search-dropdown]` attributes, icon rendering from `icon_field`
|
|
@@ -69,6 +172,7 @@
|
|
|
69
172
|
- System test assertions for embeddings/retrieval content matching and non-ASCII query robustness
|
|
70
173
|
|
|
71
174
|
### Changed
|
|
175
|
+
|
|
72
176
|
- `related.max_items` default changed from `nil` (unlimited) to `5`
|
|
73
177
|
- `Configuration#initialize` refactored — extracted `normalize_configured` helper for cleaner config validation
|
|
74
178
|
- Runtime config page now merges `dropdown` config alongside `liveSearch`
|
|
@@ -80,6 +184,7 @@
|
|
|
80
184
|
- README.md updated with dropdown section, related `max:N` docs, and CSS styling examples for dropdown
|
|
81
185
|
|
|
82
186
|
### Fixed
|
|
187
|
+
|
|
83
188
|
- `SearchTag#render` no longer raises on nil site (now returns empty string)
|
|
84
189
|
- `RelatedTag#render` no longer raises on nil site or `client_search: false` config
|
|
85
190
|
- Meta test race condition — `forEach` callback couldn't `await settle()`, causing flaky cross-engine comparisons; fixed by switching to `for` loops
|
|
@@ -87,6 +192,7 @@
|
|
|
87
192
|
## 0.2.0 — 2026-08-27
|
|
88
193
|
|
|
89
194
|
### Added
|
|
195
|
+
|
|
90
196
|
- Generic `passthrough_fields` config option: external plugins declare which document `data` fields to forward into the search index (e.g. `file_type`, `icon_url`, `icon_set` from jekyll-documents)
|
|
91
197
|
- Field renaming in `passthrough_fields`: entries can be strings (same name) or hashes (`{source => target}`) for integration with other search conventions
|
|
92
198
|
- `icon_field` config option (default: `"icon_url"`): tells the browser runtime which field to render as an `<img>` icon before the result title; set to `null` to disable
|
|
@@ -94,10 +200,12 @@
|
|
|
94
200
|
- Result `<article>` elements carry `data-source`, `data-categories`, `data-tags`, plus `data-*` for all passthrough fields (snake_case → data-kebab-case) for CSS-based result customization
|
|
95
201
|
|
|
96
202
|
### Fixed
|
|
203
|
+
|
|
97
204
|
- Allow whitespace in script/style end tags in `DocumentBuilder#clean` (`</script\s*>` instead of `</script>`) — CodeQL: bad HTML filtering regexp
|
|
98
205
|
- Fix polynomial ReDoS in `SearchTag` and `RelatedTag` syntax regexes — strip markup before matching, remove leading/trailing `\s*` patterns that caused O(n²) backtracking (CodeQL: polynomial regex on uncontrolled data)
|
|
99
206
|
|
|
100
207
|
### Changed
|
|
208
|
+
|
|
101
209
|
- Simplified release workflow to tag-push trigger (`push: tags: v*`) — no manual `gh release create` needed
|
|
102
210
|
- Switched to RubyGems trusted publishing (`rubygems/release-gem@v1` with OIDC)
|
|
103
211
|
- Centralized version in `version.rb` as single source of truth — removed `version` field from `package.json`
|