@hraness/wordcell 0.22.3 → 0.22.5

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.
Files changed (53) hide show
  1. package/README.md +20 -17
  2. package/dist/authoring.js +2 -2
  3. package/dist/{authority-06eqhqam.js → authority-3ga47syb.js} +2 -2
  4. package/dist/benchmark.js +3 -3
  5. package/dist/cli.js +16 -16
  6. package/dist/evaluation-builder.js +10 -10
  7. package/dist/evaluation-kb.js +10 -10
  8. package/dist/graph-authority.js +4 -4
  9. package/dist/graph-percolation.js +6 -6
  10. package/dist/graph.js +3 -1
  11. package/dist/{index-1k595z6v.js → index-1r5rnkfr.js} +2 -2
  12. package/dist/{index-3agn8scn.js → index-23m6bbjt.js} +47 -11
  13. package/dist/{index-q7tbg07z.js → index-42tb8qqp.js} +7 -7
  14. package/dist/{index-yx6p1vzc.js → index-8bgnhjgq.js} +17 -16
  15. package/dist/{index-233z9wmn.js → index-8v6k9h4r.js} +13 -5
  16. package/dist/{index-vnybgywh.js → index-aer0jdrq.js} +1 -1
  17. package/dist/{index-xv80vzfp.js → index-f75zmmdr.js} +4 -4
  18. package/dist/{index-ecqpgr5y.js → index-f7fnww7a.js} +1 -1
  19. package/dist/{index-djrcc1yf.js → index-gtwqye5a.js} +4 -4
  20. package/dist/{index-bqtqeak3.js → index-h2qn3y3f.js} +4 -4
  21. package/dist/{index-rr9kzq4n.js → index-n57tewfr.js} +2 -2
  22. package/dist/{index-76dbn6pe.js → index-n9kwenpt.js} +1 -1
  23. package/dist/{index-n386evxj.js → index-p96kb6t2.js} +1 -1
  24. package/dist/{index-tf4wzjew.js → index-pz2b2x0y.js} +1 -1
  25. package/dist/{index-jk1sgx36.js → index-qdb8f8va.js} +1 -1
  26. package/dist/{index-a3j61wz9.js → index-xzvcw9ga.js} +201 -131
  27. package/dist/{index-qbssx940.js → index-zy7an84p.js} +223 -8
  28. package/dist/index.js +21 -15
  29. package/dist/percolate.js +2 -2
  30. package/dist/portfolio.js +10 -10
  31. package/dist/publish-reader/reader.js +48 -12
  32. package/dist/publish-search.js +1 -1
  33. package/dist/publish.js +4 -4
  34. package/dist/sdk.js +9 -9
  35. package/dist/search.js +2 -2
  36. package/dist/semantic.js +4 -4
  37. package/dist/{support-vm8fw4yc.js → support-jf9v10j7.js} +15 -15
  38. package/dist/workflows/decision-context.js +10 -10
  39. package/dist/workflows/index.js +10 -10
  40. package/package.json +5 -4
  41. package/skills/wordcell/SKILL.md +1 -1
  42. package/skills/wordcell/references/plan-structure.md +1 -1
  43. package/skills/wordcell/references/url-platforms.md +1 -1
  44. package/src/cli-program.ts +4 -2
  45. package/src/graph.ts +79 -9
  46. package/src/mention-index.ts +194 -0
  47. package/src/publish-index.ts +3 -2
  48. package/src/publish-markdown.ts +55 -0
  49. package/src/publish-model.ts +2 -2
  50. package/src/publish-reader/reader.ts +3 -1
  51. package/src/publish-search.ts +44 -13
  52. package/src/publish.ts +4 -1
  53. package/src/vault.ts +26 -2
@@ -113,6 +113,175 @@ function portfolioDocumentIdentity(vault, path, metadata) {
113
113
  });
114
114
  }
115
115
 
116
+ // src/mention-index.ts
117
+ var MENTION_INDEX_LIMITS = {
118
+ maxNodes: 262144,
119
+ maxWork: 64 * 1024 * 1024,
120
+ maxMatches: 1e6,
121
+ maxInputCodeUnits: 256 * 1024 * 1024
122
+ };
123
+
124
+ class MentionIndexBudgetError extends RangeError {
125
+ kind;
126
+ limit;
127
+ constructor(kind, limit) {
128
+ super(`Vault analysis exceeds the ${limit} ${kind} limit.`);
129
+ this.kind = kind;
130
+ this.limit = limit;
131
+ }
132
+ }
133
+ function checkedLimits(options) {
134
+ const limits = { ...MENTION_INDEX_LIMITS };
135
+ for (const name of Object.keys(MENTION_INDEX_LIMITS)) {
136
+ const value = options[name] ?? MENTION_INDEX_LIMITS[name];
137
+ if (!Number.isSafeInteger(value) || value < 0 || value > MENTION_INDEX_LIMITS[name]) {
138
+ throw new RangeError(`${name} must be a safe integer from 0 through ${MENTION_INDEX_LIMITS[name]}.`);
139
+ }
140
+ limits[name] = value;
141
+ }
142
+ return limits;
143
+ }
144
+ function preflightMentionInput(inputs, options) {
145
+ const limits = checkedLimits(options);
146
+ let rawInputCodeUnits = 0, work = 0;
147
+ for (const input of inputs) {
148
+ rawInputCodeUnits += input.length;
149
+ if (rawInputCodeUnits > limits.maxInputCodeUnits)
150
+ throw new MentionIndexBudgetError("mention-input-code-units", limits.maxInputCodeUnits);
151
+ work += input.length + 1;
152
+ if (work > limits.maxWork)
153
+ throw new MentionIndexBudgetError("mention-index-work", limits.maxWork);
154
+ }
155
+ return { rawInputCodeUnits, work };
156
+ }
157
+ function cleanMentionBoundary(text, phrase, offset) {
158
+ const word = (value) => /[A-Za-z0-9]/.test(value);
159
+ return (!word(phrase[0] ?? "") || !word(text[offset - 1] ?? "")) && (!word(phrase.at(-1) ?? "") || !word(text[offset + phrase.length] ?? ""));
160
+ }
161
+
162
+ class MentionMatcher {
163
+ limits;
164
+ nodes = [];
165
+ work = 0;
166
+ matches = 0;
167
+ input = 0;
168
+ constructor(patterns, options = {}, rawInputCodeUnits = 0, preflightWork = 0) {
169
+ this.limits = checkedLimits(options);
170
+ if (!Number.isSafeInteger(preflightWork) || preflightWork < 0)
171
+ throw new RangeError("Invalid mention preflight work.");
172
+ if (preflightWork > this.limits.maxWork)
173
+ this.fail("mention-index-work", this.limits.maxWork);
174
+ this.work = preflightWork;
175
+ if (!Number.isSafeInteger(rawInputCodeUnits) || rawInputCodeUnits < 0)
176
+ throw new RangeError("Invalid mention input length.");
177
+ if (rawInputCodeUnits > this.limits.maxInputCodeUnits)
178
+ this.fail("mention-input-code-units", this.limits.maxInputCodeUnits);
179
+ this.node();
180
+ for (const pattern of patterns) {
181
+ this.inputUnits(pattern.lowerPhrase.length);
182
+ let state = 0;
183
+ for (let index = 0;index < pattern.lowerPhrase.length; index += 1) {
184
+ this.step();
185
+ const character = pattern.lowerPhrase.charCodeAt(index);
186
+ let next = this.nodes[state].next.get(character);
187
+ if (next === undefined) {
188
+ next = this.node();
189
+ this.nodes[state].next.set(character, next);
190
+ }
191
+ state = next;
192
+ }
193
+ if (pattern.lowerPhrase.length === 0 || this.nodes[state].pattern !== undefined) {
194
+ throw new TypeError("Mention index requires nonempty, uniquely owned normalized phrases.");
195
+ }
196
+ this.nodes[state].pattern = pattern;
197
+ }
198
+ const queue = [...this.nodes[0].next.values()];
199
+ for (let cursor = 0;cursor < queue.length; cursor += 1) {
200
+ const state = queue[cursor];
201
+ for (const [character, child] of this.nodes[state].next) {
202
+ this.step();
203
+ let fallback = this.nodes[state].failure;
204
+ while (fallback !== 0 && !this.nodes[fallback].next.has(character)) {
205
+ this.step();
206
+ fallback = this.nodes[fallback].failure;
207
+ }
208
+ const failure = this.nodes[fallback].next.get(character) ?? 0;
209
+ this.nodes[child].failure = failure;
210
+ this.nodes[child].output = this.nodes[failure].pattern === undefined ? this.nodes[failure].output : failure;
211
+ queue.push(child);
212
+ }
213
+ }
214
+ }
215
+ fail(kind, limit) {
216
+ throw new MentionIndexBudgetError(kind, limit);
217
+ }
218
+ step() {
219
+ if (this.work >= this.limits.maxWork)
220
+ this.fail("mention-index-work", this.limits.maxWork);
221
+ this.work += 1;
222
+ }
223
+ node() {
224
+ if (this.nodes.length >= this.limits.maxNodes)
225
+ this.fail("mention-index-nodes", this.limits.maxNodes);
226
+ this.nodes.push({ next: new Map, failure: 0, output: -1, pattern: undefined });
227
+ return this.nodes.length - 1;
228
+ }
229
+ inputUnits(count) {
230
+ this.input += count;
231
+ if (this.input > this.limits.maxInputCodeUnits)
232
+ this.fail("mention-input-code-units", this.limits.maxInputCodeUnits);
233
+ }
234
+ newlineOffsets(originalText) {
235
+ const offsets = [];
236
+ for (let index = 0;index < originalText.length; index += 1) {
237
+ this.step();
238
+ if (originalText.charCodeAt(index) === 10)
239
+ offsets.push(index);
240
+ }
241
+ return offsets;
242
+ }
243
+ lineAt(offsets, offset) {
244
+ let low = 0, high = offsets.length;
245
+ while (low < high) {
246
+ this.step();
247
+ const middle = low + Math.floor((high - low) / 2);
248
+ if (offsets[middle] < offset)
249
+ low = middle + 1;
250
+ else
251
+ high = middle;
252
+ }
253
+ return low + 1;
254
+ }
255
+ scan(lowerText) {
256
+ this.inputUnits(lowerText.length);
257
+ const result = new Map;
258
+ let state = 0;
259
+ for (let index = 0;index < lowerText.length; index += 1) {
260
+ this.step();
261
+ const character = lowerText.charCodeAt(index);
262
+ while (state !== 0 && !this.nodes[state].next.has(character)) {
263
+ this.step();
264
+ state = this.nodes[state].failure;
265
+ }
266
+ state = this.nodes[state].next.get(character) ?? 0;
267
+ let output = this.nodes[state].pattern === undefined ? this.nodes[state].output : state;
268
+ while (output !== -1) {
269
+ if (this.matches >= this.limits.maxMatches)
270
+ this.fail("mention-matches", this.limits.maxMatches);
271
+ this.matches += 1;
272
+ const pattern = this.nodes[output].pattern;
273
+ const offset = index + 1 - pattern.lowerPhrase.length;
274
+ const existing = result.get(pattern.targetId);
275
+ if (cleanMentionBoundary(lowerText, pattern.lowerPhrase, offset) && (existing === undefined || pattern.rank < existing.pattern.rank)) {
276
+ result.set(pattern.targetId, { pattern, offset });
277
+ }
278
+ output = this.nodes[output].output;
279
+ }
280
+ }
281
+ return result;
282
+ }
283
+ }
284
+
116
285
  // src/graph.ts
117
286
  var catalogStart = "<!-- kb:catalog:start -->";
118
287
  var catalogEnd = "<!-- kb:catalog:end -->";
@@ -722,16 +891,10 @@ function compareRelationIssues(left, right) {
722
891
  const targetComparison = (left.target ?? "").localeCompare(right.target ?? "");
723
892
  return left.source.localeCompare(right.source) || left.line - right.line || left.kind.localeCompare(right.kind) || predicateComparison || targetComparison;
724
893
  }
725
- var wordCharacter = (value) => /[A-Za-z0-9]/.test(value);
726
894
  function phraseOffset(lowerHaystack, lowerPhrase) {
727
895
  let offset = lowerHaystack.indexOf(lowerPhrase);
728
896
  while (offset !== -1) {
729
- const before = offset === 0 ? "" : lowerHaystack[offset - 1] ?? "";
730
- const afterIndex = offset + lowerPhrase.length;
731
- const after = afterIndex >= lowerHaystack.length ? "" : lowerHaystack[afterIndex] ?? "";
732
- const startsClean = !wordCharacter(lowerPhrase[0] ?? "") || !wordCharacter(before);
733
- const endsClean = !wordCharacter(lowerPhrase.at(-1) ?? "") || !wordCharacter(after);
734
- if (startsClean && endsClean)
897
+ if (cleanMentionBoundary(lowerHaystack, lowerPhrase, offset))
735
898
  return offset;
736
899
  offset = lowerHaystack.indexOf(lowerPhrase, offset + 1);
737
900
  }
@@ -777,6 +940,19 @@ function checkedAnalysisLimit(value, hardMaximum, option) {
777
940
  return limit;
778
941
  }
779
942
  function analyzeVault(notes, options = {}) {
943
+ return analyzeVaultInternal(notes, options);
944
+ }
945
+ function analyzeVaultComplete(notes, options = {}) {
946
+ try {
947
+ return analyzeVaultInternal(notes, options, options.mentionIndexLimits ?? {});
948
+ } catch (error) {
949
+ if (error instanceof MentionIndexBudgetError) {
950
+ throw new VaultAnalysisBudgetError(error.kind, error.limit, error.message);
951
+ }
952
+ throw error;
953
+ }
954
+ }
955
+ function analyzeVaultInternal(notes, options, mentionIndexLimits) {
780
956
  const maxNotes = checkedAnalysisLimit(options.maxNotes, MAX_ANALYZED_NOTES, "maxNotes");
781
957
  const maxMentionPairs = checkedAnalysisLimit(options.maxMentionPairs, MAX_MENTION_PAIRS, "maxMentionPairs");
782
958
  const maxMentions = checkedAnalysisLimit(options.maxMentions, MAX_MENTIONS, "maxMentions");
@@ -784,6 +960,13 @@ function analyzeVault(notes, options = {}) {
784
960
  if (notes.length > maxNotes) {
785
961
  throw new VaultAnalysisBudgetError("notes", maxNotes, `Vault analysis exceeds the ${maxNotes} note limit.`);
786
962
  }
963
+ const mentionInput = mentionIndexLimits === undefined ? undefined : preflightMentionInput(function* () {
964
+ for (const note of notes) {
965
+ yield note.searchableText;
966
+ yield note.title;
967
+ yield* note.aliases;
968
+ }
969
+ }(), mentionIndexLimits);
787
970
  const catalogNoteId = withoutMarkdownExtension(normalizeVaultPath(options.catalogNoteId ?? "index"));
788
971
  const byId = new Map(notes.map((note) => [note.id, note]));
789
972
  const byBasename = new Map;
@@ -953,7 +1136,39 @@ function analyzeVault(notes, options = {}) {
953
1136
  const phrasesByTarget = scopedMentionNotes.length === 0 ? new Map : uniquePhrasesByTarget(suggestionNotes);
954
1137
  const mentions = [];
955
1138
  let mentionPairs = 0;
1139
+ const matcher = mentionIndexLimits === undefined ? undefined : new MentionMatcher([...phrasesByTarget].flatMap(([targetId, phrases]) => phrases.map((phrase, rank) => ({ ...phrase, targetId, rank }))), mentionIndexLimits, mentionInput.rawInputCodeUnits, mentionInput.work);
1140
+ const targetsById = new Map;
1141
+ if (matcher !== undefined)
1142
+ suggestionNotes.forEach((note, order) => {
1143
+ const targets = targetsById.get(note.id) ?? [];
1144
+ targets.push({ note, order });
1145
+ targetsById.set(note.id, targets);
1146
+ });
956
1147
  for (const source of suggestionNotes) {
1148
+ if (matcher !== undefined) {
1149
+ if (scopedMentionNotes.length === 0)
1150
+ continue;
1151
+ const found = matcher.scan(source.searchableText.toLocaleLowerCase("en-US"));
1152
+ const targets2 = [...found].flatMap(([id, match]) => (targetsById.get(id) ?? []).map((target) => ({ ...target, match }))).filter(({ note }) => source.id !== note.id && (options.mentionScope === undefined || scopedMentionIds.has(source.id) || scopedMentionIds.has(note.id))).sort((left, right) => left.order - right.order);
1153
+ let newlineOffsets;
1154
+ for (const { note: target, match } of targets2) {
1155
+ if (mentionPairs >= maxMentionPairs)
1156
+ throw new VaultAnalysisBudgetError("mention-pairs", maxMentionPairs, `Vault analysis exceeds the ${maxMentionPairs} mention-pair limit.`);
1157
+ mentionPairs += 1;
1158
+ if (linkedPairs.has(pairKey(source.id, target.id)))
1159
+ continue;
1160
+ if (mentions.length >= maxMentions)
1161
+ throw new VaultAnalysisBudgetError("mentions", maxMentions, `Vault analysis exceeds the ${maxMentions} mention limit.`);
1162
+ newlineOffsets ??= matcher.newlineOffsets(source.searchableText);
1163
+ mentions.push({
1164
+ source: source.path,
1165
+ target: target.path,
1166
+ phrase: match.pattern.phrase,
1167
+ line: matcher.lineAt(newlineOffsets, match.offset)
1168
+ });
1169
+ }
1170
+ continue;
1171
+ }
957
1172
  const targets = options.mentionScope === undefined || scopedMentionIds.has(source.id) ? suggestionNotes : scopedMentionNotes;
958
1173
  let lowerSearchableText;
959
1174
  for (const target of targets) {
@@ -1066,4 +1281,4 @@ function replaceCatalog(indexContent, catalog) {
1066
1281
  return indexContent.slice(0, start) + catalog + indexContent.slice(end + catalogEnd.length);
1067
1282
  }
1068
1283
 
1069
- export { MAX_PORTFOLIO_NAME_BYTES, MAX_DOCUMENT_ID_BYTES, portfolioVaultIdentity, parseVaultKey, parseDocumentId, documentIdState, formatQualifiedDocumentUri, parseQualifiedDocumentUri, portfolioDocumentIdentity, catalogStart, catalogEnd, MAX_ANALYZED_NOTES, MAX_CONNECTION_OBSERVATIONS, MAX_MENTION_PAIRS, MAX_MENTIONS, VaultAnalysisBudgetError, metadataValueFromUnknown, isCanonicalRelationPredicate, isCanonicalNoteId, normalizeVaultPath, searchableMarkdown, wikiLinks, parseNote, lookupNote, analyzeVault, renderCatalog, replaceCatalog };
1284
+ export { MAX_PORTFOLIO_NAME_BYTES, MAX_DOCUMENT_ID_BYTES, portfolioVaultIdentity, parseVaultKey, parseDocumentId, documentIdState, formatQualifiedDocumentUri, parseQualifiedDocumentUri, portfolioDocumentIdentity, catalogStart, catalogEnd, MAX_ANALYZED_NOTES, MAX_CONNECTION_OBSERVATIONS, MAX_MENTION_PAIRS, MAX_MENTIONS, VaultAnalysisBudgetError, metadataValueFromUnknown, isCanonicalRelationPredicate, isCanonicalNoteId, normalizeVaultPath, searchableMarkdown, wikiLinks, parseNote, lookupNote, analyzeVault, analyzeVaultComplete, renderCatalog, replaceCatalog };
package/dist/index.js CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  createSyntheticRankFusionFixture,
16
16
  evaluateRanking,
17
17
  evaluateRetrievalBenchmark
18
- } from "./index-n386evxj.js";
18
+ } from "./index-p96kb6t2.js";
19
19
  import {
20
20
  initVault
21
21
  } from "./index-23z4zxgg.js";
@@ -37,7 +37,7 @@ import {
37
37
  knowledgeBaseEvaluationRetrieverIds,
38
38
  openKnowledgeBaseEvaluation,
39
39
  verifyFrozenEvaluationSnapshot
40
- } from "./index-1k595z6v.js";
40
+ } from "./index-1r5rnkfr.js";
41
41
  import {
42
42
  DEFAULT_SEARCH_RESULTS,
43
43
  MAX_SEARCH_CANDIDATES,
@@ -50,7 +50,7 @@ import {
50
50
  packUntrustedSearchContext,
51
51
  searchEvidenceRank,
52
52
  validateKnowledgeBaseSearchHistory
53
- } from "./index-q7tbg07z.js";
53
+ } from "./index-42tb8qqp.js";
54
54
  import"./index-adx6khj5.js";
55
55
  import {
56
56
  MAX_EMBEDDING_MODEL_BYTES,
@@ -67,7 +67,7 @@ import {
67
67
  searchSemanticVault,
68
68
  semanticDatabasePath,
69
69
  sha256EmbeddingModelFile
70
- } from "./index-rr9kzq4n.js";
70
+ } from "./index-n57tewfr.js";
71
71
  import"./index-4j3tt0c3.js";
72
72
  import {
73
73
  MAX_RERANK_CANDIDATES,
@@ -94,7 +94,7 @@ import {
94
94
  } from "./index-b88v3vtm.js";
95
95
  import {
96
96
  percolateWithGraph
97
- } from "./index-djrcc1yf.js";
97
+ } from "./index-gtwqye5a.js";
98
98
  import {
99
99
  DEFAULT_PERCOLATION_LIMIT,
100
100
  DEFAULT_PERCOLATION_MIN_SUPPORT,
@@ -115,19 +115,19 @@ import {
115
115
  parsePercolationResultV1,
116
116
  parsePercolationResultV2,
117
117
  percolateVault
118
- } from "./index-jk1sgx36.js";
118
+ } from "./index-qdb8f8va.js";
119
119
  import {
120
120
  createGraphSnapshot,
121
121
  openGraphAuthority,
122
122
  queryGraph,
123
123
  rebuildGraph,
124
124
  verifyGraph
125
- } from "./index-xv80vzfp.js";
125
+ } from "./index-f75zmmdr.js";
126
126
  import {
127
127
  GRAPH_LIMITS,
128
128
  GraphAuthorityError,
129
129
  validateGraphQueryRequest
130
- } from "./index-tf4wzjew.js";
130
+ } from "./index-pz2b2x0y.js";
131
131
  import {
132
132
  GitHistoryError,
133
133
  MAX_GIT_HISTORY_COMMITS,
@@ -154,7 +154,7 @@ import {
154
154
  fuseRankedCandidates,
155
155
  searchExactVault,
156
156
  validateSearchQuery
157
- } from "./index-vnybgywh.js";
157
+ } from "./index-aer0jdrq.js";
158
158
  import"./index-1xxnjn0d.js";
159
159
  import {
160
160
  DEFAULT_PUBLISH_LIST_LIMIT,
@@ -167,7 +167,7 @@ import {
167
167
  publishVault,
168
168
  renderPublishReportText,
169
169
  serializeSiteFile
170
- } from "./index-a3j61wz9.js";
170
+ } from "./index-xzvcw9ga.js";
171
171
  import {
172
172
  MAX_NOTE_UTF8_BYTES,
173
173
  MAX_SCANNED_NOTES,
@@ -177,8 +177,10 @@ import {
177
177
  markdownFiles,
178
178
  readVaultNotes,
179
179
  refreshVault,
180
- scanVault
181
- } from "./index-233z9wmn.js";
180
+ refreshVaultComplete,
181
+ scanVault,
182
+ scanVaultComplete
183
+ } from "./index-8v6k9h4r.js";
182
184
  import {
183
185
  MAX_NAVIGATION_INDEXED_CONNECTIONS,
184
186
  MAX_NAVIGATION_RETURNED_CONNECTIONS,
@@ -245,7 +247,7 @@ import {
245
247
  parseSitePostingsV1,
246
248
  parseSiteTermsV1
247
249
  } from "./index-66pshdtx.js";
248
- import"./index-3agn8scn.js";
250
+ import"./index-23m6bbjt.js";
249
251
  import {
250
252
  auditAgentGuideRepository,
251
253
  auditAgentGuideSource,
@@ -295,7 +297,7 @@ import {
295
297
  noteRevision,
296
298
  removeNoteRelation,
297
299
  updateNoteBody
298
- } from "./index-ecqpgr5y.js";
300
+ } from "./index-f7fnww7a.js";
299
301
  import"./index-3rm7cz6h.js";
300
302
  import {
301
303
  MAX_ANALYZED_NOTES,
@@ -304,6 +306,7 @@ import {
304
306
  MAX_MENTION_PAIRS,
305
307
  VaultAnalysisBudgetError,
306
308
  analyzeVault,
309
+ analyzeVaultComplete,
307
310
  catalogEnd,
308
311
  catalogStart,
309
312
  isCanonicalNoteId,
@@ -316,7 +319,7 @@ import {
316
319
  replaceCatalog,
317
320
  searchableMarkdown,
318
321
  wikiLinks
319
- } from "./index-qbssx940.js";
322
+ } from "./index-zy7an84p.js";
320
323
  import"./index-z1w83f81.js";
321
324
  // src/oh-adoption.ts
322
325
  import { createHash } from "crypto";
@@ -768,6 +771,7 @@ export {
768
771
  searchGitHistory,
769
772
  searchExactVault,
770
773
  searchEvidenceRank,
774
+ scanVaultComplete,
771
775
  scanVault,
772
776
  runWorkflow,
773
777
  runRetrievalEvaluation,
@@ -779,6 +783,7 @@ export {
779
783
  renderPublishReportText,
780
784
  renderCatalog,
781
785
  removeNoteRelation,
786
+ refreshVaultComplete,
782
787
  refreshVault,
783
788
  recommendedEmbeddingModelSha256,
784
789
  recommendedEmbeddingModel,
@@ -875,6 +880,7 @@ export {
875
880
  auditAgentGuideRepository,
876
881
  attestSemanticWarmCache,
877
882
  applyRerank,
883
+ analyzeVaultComplete,
878
884
  analyzeVault,
879
885
  analyzeAuthoredRepositoryScopes,
880
886
  analyzeAgentContexts,
package/dist/percolate.js CHANGED
@@ -19,8 +19,8 @@ import {
19
19
  parsePercolationResultV1,
20
20
  parsePercolationResultV2,
21
21
  percolateVault
22
- } from "./index-jk1sgx36.js";
23
- import"./index-qbssx940.js";
22
+ } from "./index-qdb8f8va.js";
23
+ import"./index-zy7an84p.js";
24
24
  import"./index-z1w83f81.js";
25
25
  export {
26
26
  percolateVault,
package/dist/portfolio.js CHANGED
@@ -20,20 +20,20 @@ import {
20
20
  selectAuthorizedVaults,
21
21
  snapshotPortfolioRegistry,
22
22
  validateResolvedPortfolioVaults
23
- } from "./index-bqtqeak3.js";
24
- import"./index-q7tbg07z.js";
23
+ } from "./index-h2qn3y3f.js";
24
+ import"./index-42tb8qqp.js";
25
25
  import"./index-adx6khj5.js";
26
- import"./index-rr9kzq4n.js";
26
+ import"./index-n57tewfr.js";
27
27
  import"./index-4j3tt0c3.js";
28
28
  import"./index-j70m75wd.js";
29
- import"./index-djrcc1yf.js";
30
- import"./index-jk1sgx36.js";
31
- import"./index-xv80vzfp.js";
32
- import"./index-tf4wzjew.js";
29
+ import"./index-gtwqye5a.js";
30
+ import"./index-qdb8f8va.js";
31
+ import"./index-f75zmmdr.js";
32
+ import"./index-pz2b2x0y.js";
33
33
  import"./index-1gwbassd.js";
34
- import"./index-vnybgywh.js";
34
+ import"./index-aer0jdrq.js";
35
35
  import"./index-1xxnjn0d.js";
36
- import"./index-233z9wmn.js";
36
+ import"./index-8v6k9h4r.js";
37
37
  import"./index-d13v9ckt.js";
38
38
  import"./index-48pz4jpc.js";
39
39
  import"./index-06c9ctr6.js";
@@ -50,7 +50,7 @@ import {
50
50
  parseVaultKey,
51
51
  portfolioDocumentIdentity,
52
52
  portfolioVaultIdentity
53
- } from "./index-qbssx940.js";
53
+ } from "./index-zy7an84p.js";
54
54
  import"./index-z1w83f81.js";
55
55
  export {
56
56
  validateResolvedPortfolioVaults,
@@ -757,22 +757,58 @@ function comparePublishScores(left, right) {
757
757
  return Number(right.identity) - Number(left.identity) || right.score - left.score || left.i - right.i;
758
758
  }
759
759
  function publishSnippet(text, query, fallback, windowBytes = 160) {
760
- const normalized = publishNormalize(text);
761
- let offset = query.normalized === "" ? -1 : normalized.indexOf(query.normalized);
762
- if (offset < 0) {
760
+ if (!Number.isSafeInteger(windowBytes) || windowBytes < 0)
761
+ throw new RangeError("Snippet window must be a nonnegative safe byte count.");
762
+ const display = text.normalize("NFC");
763
+ const normalized = publishNormalize(display);
764
+ let match = query.normalized === "" ? -1 : normalized.indexOf(query.normalized);
765
+ if (match < 0) {
763
766
  for (const term of query.terms) {
764
- offset = normalized.indexOf(term);
765
- if (offset >= 0)
767
+ match = normalized.indexOf(term);
768
+ if (match >= 0)
766
769
  break;
767
770
  }
768
771
  }
769
- if (offset < 0)
772
+ if (match < 0)
770
773
  return fallback;
771
- const half = Math.floor(windowBytes / 2);
772
- const start = Math.max(0, offset - half);
773
- const end = Math.min(text.length, offset + half);
774
- const snippet = text.slice(start, end).replace(/\s+/gu, " ").trim();
775
- return `${start > 0 ? "…" : ""}${snippet}${end < text.length ? "…" : ""}`;
774
+ let offset = 0, normalizedOffset = 0;
775
+ for (const character of display) {
776
+ const width = character.toLocaleLowerCase("en-US").length;
777
+ if (normalizedOffset + width > match)
778
+ break;
779
+ normalizedOffset += width;
780
+ offset += character.length;
781
+ }
782
+ const edge = windowBytes >= 6 ? "…" : "";
783
+ const budget = windowBytes - 2 * publishUtf8Bytes(edge);
784
+ const previous = (end2) => {
785
+ const last = display.charCodeAt(end2 - 1);
786
+ return end2 > 1 && last >= 56320 && last <= 57343 && display.charCodeAt(end2 - 2) >= 55296 && display.charCodeAt(end2 - 2) <= 56319 ? end2 - 2 : end2 - 1;
787
+ };
788
+ let start = offset, end = offset, used = 0;
789
+ while (start > 0) {
790
+ const before = previous(start), bytes = publishUtf8Bytes(display.slice(before, start));
791
+ if (used + bytes > Math.floor(budget / 2))
792
+ break;
793
+ start = before;
794
+ used += bytes;
795
+ }
796
+ while (end < display.length) {
797
+ const character = String.fromCodePoint(display.codePointAt(end) ?? 0), bytes = publishUtf8Bytes(character);
798
+ if (used + bytes > budget)
799
+ break;
800
+ end += character.length;
801
+ used += bytes;
802
+ }
803
+ while (start > 0) {
804
+ const before = previous(start), bytes = publishUtf8Bytes(display.slice(before, start));
805
+ if (used + bytes > budget)
806
+ break;
807
+ start = before;
808
+ used += bytes;
809
+ }
810
+ const snippet = display.slice(start, end).replace(/\s+/gu, " ").trim();
811
+ return `${start > 0 ? edge : ""}${snippet}${end < display.length ? edge : ""}`;
776
812
  }
777
813
 
778
814
  // src/publish-theme.ts
@@ -924,7 +960,7 @@ function resultHref(base, slug) {
924
960
  }
925
961
  function snippetFor(index, doc, query) {
926
962
  const hydrated = index.notes.get(doc.s);
927
- const text = hydrated?.text ?? doc.x;
963
+ const text = hydrated?.text;
928
964
  return text === undefined ? doc.p : publishSnippet(text, query, doc.p);
929
965
  }
930
966
  function appendMarked(parent, text, terms) {
@@ -23,7 +23,7 @@ import {
23
23
  publishSnippet,
24
24
  publishUtf8Bytes,
25
25
  scorePublishDocument
26
- } from "./index-3agn8scn.js";
26
+ } from "./index-23m6bbjt.js";
27
27
  import"./index-z1w83f81.js";
28
28
  export {
29
29
  scorePublishDocument,
package/dist/publish.js CHANGED
@@ -10,17 +10,17 @@ import {
10
10
  publishVault,
11
11
  renderPublishReportText,
12
12
  serializeSiteFile
13
- } from "./index-a3j61wz9.js";
14
- import"./index-233z9wmn.js";
13
+ } from "./index-xzvcw9ga.js";
14
+ import"./index-8v6k9h4r.js";
15
15
  import"./index-d13v9ckt.js";
16
16
  import"./index-48pz4jpc.js";
17
17
  import"./index-06c9ctr6.js";
18
18
  import"./index-4knsp9qj.js";
19
19
  import"./index-66pshdtx.js";
20
- import"./index-3agn8scn.js";
20
+ import"./index-23m6bbjt.js";
21
21
  import"./index-5vwpzb5a.js";
22
22
  import"./index-x3fthpsc.js";
23
- import"./index-qbssx940.js";
23
+ import"./index-zy7an84p.js";
24
24
  import"./index-z1w83f81.js";
25
25
  export {
26
26
  serializeSiteFile,
package/dist/sdk.js CHANGED
@@ -11,25 +11,25 @@ import {
11
11
  packUntrustedSearchContext,
12
12
  searchEvidenceRank,
13
13
  validateKnowledgeBaseSearchHistory
14
- } from "./index-q7tbg07z.js";
14
+ } from "./index-42tb8qqp.js";
15
15
  import"./index-adx6khj5.js";
16
- import"./index-rr9kzq4n.js";
16
+ import"./index-n57tewfr.js";
17
17
  import"./index-4j3tt0c3.js";
18
18
  import"./index-j70m75wd.js";
19
- import"./index-djrcc1yf.js";
20
- import"./index-jk1sgx36.js";
21
- import"./index-xv80vzfp.js";
22
- import"./index-tf4wzjew.js";
19
+ import"./index-gtwqye5a.js";
20
+ import"./index-qdb8f8va.js";
21
+ import"./index-f75zmmdr.js";
22
+ import"./index-pz2b2x0y.js";
23
23
  import"./index-1gwbassd.js";
24
- import"./index-vnybgywh.js";
24
+ import"./index-aer0jdrq.js";
25
25
  import"./index-1xxnjn0d.js";
26
- import"./index-233z9wmn.js";
26
+ import"./index-8v6k9h4r.js";
27
27
  import"./index-d13v9ckt.js";
28
28
  import"./index-48pz4jpc.js";
29
29
  import"./index-06c9ctr6.js";
30
30
  import"./index-5vwpzb5a.js";
31
31
  import"./index-3rm7cz6h.js";
32
- import"./index-qbssx940.js";
32
+ import"./index-zy7an84p.js";
33
33
  import"./index-z1w83f81.js";
34
34
  export {
35
35
  validateKnowledgeBaseSearchHistory,
package/dist/search.js CHANGED
@@ -6,12 +6,12 @@ import {
6
6
  fuseRankedCandidates,
7
7
  searchExactVault,
8
8
  validateSearchQuery
9
- } from "./index-vnybgywh.js";
9
+ } from "./index-aer0jdrq.js";
10
10
  import"./index-d13v9ckt.js";
11
11
  import"./index-48pz4jpc.js";
12
12
  import"./index-06c9ctr6.js";
13
13
  import"./index-5vwpzb5a.js";
14
- import"./index-qbssx940.js";
14
+ import"./index-zy7an84p.js";
15
15
  import"./index-z1w83f81.js";
16
16
  export {
17
17
  validateSearchQuery,
package/dist/semantic.js CHANGED
@@ -14,14 +14,14 @@ import {
14
14
  searchSemanticVault,
15
15
  semanticDatabasePath,
16
16
  sha256EmbeddingModelFile
17
- } from "./index-rr9kzq4n.js";
18
- import"./index-vnybgywh.js";
19
- import"./index-233z9wmn.js";
17
+ } from "./index-n57tewfr.js";
18
+ import"./index-aer0jdrq.js";
19
+ import"./index-8v6k9h4r.js";
20
20
  import"./index-d13v9ckt.js";
21
21
  import"./index-48pz4jpc.js";
22
22
  import"./index-06c9ctr6.js";
23
23
  import"./index-5vwpzb5a.js";
24
- import"./index-qbssx940.js";
24
+ import"./index-zy7an84p.js";
25
25
  import"./index-z1w83f81.js";
26
26
  export {
27
27
  sha256EmbeddingModelFile,