@hraness/wordcell 0.24.0 → 0.25.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.
Files changed (49) hide show
  1. package/README.md +14 -12
  2. package/dist/authoring.js +2 -1
  3. package/dist/capture.js +2 -2
  4. package/dist/cli.js +12 -11
  5. package/dist/clip/cli.js +2 -2
  6. package/dist/clip/defuddle-worker.js +87 -2
  7. package/dist/clip/jobs.js +5 -1
  8. package/dist/evaluation-builder.js +5 -4
  9. package/dist/evaluation-kb.js +5 -4
  10. package/dist/graph-authority.js +2 -1
  11. package/dist/graph-percolation.js +3 -2
  12. package/dist/{index-44kw9tr8.js → index-1wccy765.js} +18 -12
  13. package/dist/{index-1er88ckw.js → index-3gc2yk4k.js} +10 -5
  14. package/dist/{index-0eacgvpv.js → index-47893rgw.js} +22 -8
  15. package/dist/{index-mvs6f7ne.js → index-59bcxqee.js} +1 -1
  16. package/dist/{index-1w0sp1q7.js → index-7drercgk.js} +1 -1
  17. package/dist/{index-tcaq1c7f.js → index-e26mdwxz.js} +1 -1
  18. package/dist/{index-6jcz0m1c.js → index-hxyjer3x.js} +52 -1
  19. package/dist/{index-f184qyh1.js → index-hz2wyggk.js} +1 -1
  20. package/dist/{index-5d1rd5v9.js → index-mcpppwbq.js} +2 -2
  21. package/dist/index-qkesh4c6.js +7 -0
  22. package/dist/{index-b0khj0h5.js → index-qt2zwza8.js} +6 -1
  23. package/dist/{index-2fmnttca.js → index-t3abkwk4.js} +1 -1
  24. package/dist/index.js +6 -5
  25. package/dist/portfolio.js +5 -4
  26. package/dist/sdk.js +4 -3
  27. package/dist/{support-1yhv6vm6.js → support-adj7bbge.js} +11 -10
  28. package/dist/url-intelligence.js +3 -2
  29. package/dist/workflows/decision-context.js +5 -4
  30. package/dist/workflows/index.js +5 -4
  31. package/package.json +13 -8
  32. package/skills/wordcell/SKILL.md +1 -1
  33. package/skills/wordcell/references/publish.md +2 -1
  34. package/src/authoring-platform.ts +3 -0
  35. package/src/cli-program.ts +3 -3
  36. package/src/clip/jobs.ts +2 -1
  37. package/src/clip/metadata-search-tool/Cargo.lock +12 -0
  38. package/src/clip/metadata-search-tool/Cargo.toml +3 -0
  39. package/src/clip/metadata-search-tool/runner.ts +4 -1
  40. package/src/clip/metadata-search-tool/src/bing.rs +539 -0
  41. package/src/clip/metadata-search-tool/src/duckduckgo.rs +562 -0
  42. package/src/clip/metadata-search-tool/src/main.rs +263 -24
  43. package/src/clip/metadata-search-tool/src/openalex.rs +557 -0
  44. package/src/clip/metadata-search.ts +22 -4
  45. package/src/clip/url-intelligence.ts +54 -1
  46. package/src/clip/url-metadata.ts +2 -1
  47. package/src/directory-sync.ts +9 -0
  48. package/src/graph-authority.ts +5 -2
  49. package/src/url-intelligence.ts +2 -0
package/README.md CHANGED
@@ -3,9 +3,11 @@
3
3
 
4
4
  [![Agent Skill](https://raw.githubusercontent.com/hraness/wordcell/main/assets/agent-skill.svg)](https://github.com/hraness/wordcell/tree/main/skills/wordcell)
5
5
 
6
- Wordcell keeps decisions, plans, and sources as Markdown files beside your
7
- code. Coding agents find them by exact words, by meaning with an optional
8
- local model, or from the file they are about to change.
6
+ Wordcell is a Markdown knowledge base and local MCP memory server for coding
7
+ agents such as Claude Code, Codex, and Cursor. It keeps decisions, plans, and
8
+ sources as Markdown files beside your code, and agents find them by exact
9
+ words, by meaning with an optional local model, or from the file they are
10
+ about to change.
9
11
 
10
12
  A new coding-agent session can read your code, but not the decisions that
11
13
  stayed in the last session's chat. Wordcell keeps those decisions as Markdown
@@ -20,7 +22,7 @@ Web capture, optional hosted reranking, and your agent's provider reach other
20
22
  services; [Privacy and boundaries](#privacy-and-boundaries) says what each one
21
23
  sends.
22
24
 
23
- [Documentation](https://wordcell.io/docs) · [Comparisons](https://github.com/hraness/wordcell/blob/main/docs/comparisons.md) · [Measured evidence](https://github.com/hraness/wordcell/blob/main/docs/evidence.md) · [Changelog](https://github.com/hraness/wordcell/blob/main/CHANGELOG.md)
25
+ [Documentation](https://wordcell.io/docs) · [Comparisons](https://wordcell.io/docs/comparisons) · [Measured evidence](https://wordcell.io/docs/evidence) · [Changelog](https://github.com/hraness/wordcell/blob/main/CHANGELOG.md)
24
26
 
25
27
  ## Why Wordcell
26
28
 
@@ -42,7 +44,7 @@ sends.
42
44
  Plain Markdown may be enough for a small set of notes. QMD is a good fit for
43
45
  local document retrieval and also supplies Wordcell's optional semantic search.
44
46
  Wordcell adds a connected workflow for repository context, authored relationships,
45
- Git evidence, and selective publishing. [Compare the tradeoffs](https://github.com/hraness/wordcell/blob/main/docs/comparisons.md).
47
+ Git evidence, and selective publishing. [Compare the tradeoffs](https://wordcell.io/docs/comparisons).
46
48
 
47
49
  Wordcell keeps the record in Markdown files you own, rebuilds every index from those files, and lets the next session start from the notes for the file it is changing: the design every Hraness project shares. [The thread through hraness](https://hraness.com/writing/the-thread-through-hraness) follows that design across the projects, and the [ALGAL vision](https://algal.computer/docs/vision/) states the bet behind it.
48
50
 
@@ -52,14 +54,14 @@ Wordcell keeps the record in Markdown files you own, rebuilds every index from t
52
54
  The CLI and TypeScript SDK run with Bun. Install the versioned GitHub archive:
53
55
 
54
56
  ```sh
55
- bun add --global --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.24.0/hraness-wordcell-0.24.0.tgz
57
+ bun add --global --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.25.0/hraness-wordcell-0.25.0.tgz
56
58
  wordcell --help
57
59
  ```
58
60
 
59
61
  Prefer npm? The same release is [mirrored there](https://www.npmjs.com/package/@hraness/wordcell):
60
62
 
61
63
  ```sh
62
- npm install --global --ignore-scripts @hraness/wordcell@0.24.0
64
+ npm install --global --ignore-scripts @hraness/wordcell@0.25.0
63
65
  wordcell --help
64
66
  ```
65
67
 
@@ -101,7 +103,7 @@ After trying the CLI, install the public Agent Skill into a compatible agent,
101
103
  such as Claude Code, Codex, Cursor, or GitHub Copilot:
102
104
 
103
105
  ```sh
104
- bunx skills add hraness/wordcell#v0.24.0 --skill wordcell
106
+ bunx skills add hraness/wordcell#v0.25.0 --skill wordcell
105
107
  ```
106
108
 
107
109
  Then ask:
@@ -270,9 +272,9 @@ Wordcell's benefit is selecting relevant context and keeping its sources
270
272
  inspectable. Local ownership is also available in other tools, and Wordcell
271
273
  does not claim to beat QMD's retrieval quality or every Markdown workflow.
272
274
 
273
- [Measured evidence](https://github.com/hraness/wordcell/blob/main/docs/evidence.md)
275
+ [Measured evidence](https://wordcell.io/docs/evidence)
274
276
  shows a reproducible public-vault example, with the inputs, output sizes, and
275
- limits beside each result. [The comparison guide](https://github.com/hraness/wordcell/blob/main/docs/comparisons.md)
277
+ limits beside each result. [The comparison guide](https://wordcell.io/docs/comparisons)
276
278
  covers Markdown alone, QMD, Basic Memory, Obsidian, static publishing tools,
277
279
  Supermemory, Mem0, and Zep using their own documentation. Choose the smallest
278
280
  workflow that meets your needs.
@@ -332,7 +334,7 @@ exist. [Graph queries and proof limits](https://github.com/hraness/wordcell/blob
332
334
  Add the same immutable release to a Bun project:
333
335
 
334
336
  ```sh
335
- bun add --exact --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.24.0/hraness-wordcell-0.24.0.tgz
337
+ bun add --exact --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.25.0/hraness-wordcell-0.25.0.tgz
336
338
  ```
337
339
 
338
340
  The SDK provides read-only vault sessions, metadata queries, search, graph
@@ -369,7 +371,7 @@ the design. Browse it on the [documentation index](https://wordcell.io/docs).
369
371
  | [Web capture](https://github.com/hraness/wordcell/blob/main/docs/capture.md) and [PDF capture](https://github.com/hraness/wordcell/blob/main/docs/pdf.md) | Save sources with provenance, assets, and explicit completeness limits. |
370
372
  | [Publish selected notes](https://github.com/hraness/wordcell/blob/main/docs/publish.md) | Preview a slice, build a static site, and choose how to host it. |
371
373
  | [Graph guide](https://github.com/hraness/wordcell/blob/main/docs/graph-authority.md) | Named queries, proofs, revisions, resource limits, and cache recovery. |
372
- | [Portfolio federation](https://github.com/hraness/wordcell/blob/main/docs/portfolio.md) | Search only selected, authorized vaults. |
374
+ | [Search several vaults together](https://github.com/hraness/wordcell/blob/main/docs/portfolio.md) | Search only selected, authorized vaults. |
373
375
  | [Sync with Git](https://github.com/hraness/wordcell/blob/main/docs/sync.md) | Keep one vault current on several machines with a private repository. |
374
376
  | [Migrate from Supermemory](https://github.com/hraness/wordcell/blob/main/docs/migration-from-supermemory.md) | Export documents and memory entries, import them as notes, and replace connectors. |
375
377
  | [Design](https://github.com/hraness/wordcell/blob/main/docs/design.md) and [memory rationale](https://github.com/hraness/wordcell/blob/main/docs/agent-memory.md) | File contracts, design choices, and evaluation context. |
package/dist/authoring.js CHANGED
@@ -14,8 +14,9 @@ import {
14
14
  noteRevision,
15
15
  removeNoteRelation,
16
16
  updateNoteBody
17
- } from "./index-b0khj0h5.js";
17
+ } from "./index-qt2zwza8.js";
18
18
  import"./index-3rm7cz6h.js";
19
+ import"./index-qkesh4c6.js";
19
20
  import"./index-jvb7w0gg.js";
20
21
  import"./index-z1w83f81.js";
21
22
  export {
package/dist/capture.js CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  captureSummary,
6
6
  main,
7
7
  runCapture
8
- } from "./index-2fmnttca.js";
9
- import"./index-6jcz0m1c.js";
8
+ } from "./index-t3abkwk4.js";
9
+ import"./index-hxyjer3x.js";
10
10
  import"./index-k86wepd8.js";
11
11
  import {
12
12
  adapterCapabilities,
package/dist/cli.js CHANGED
@@ -6,13 +6,13 @@ import {
6
6
  parseArguments,
7
7
  runExecutable,
8
8
  usage
9
- } from "./index-44kw9tr8.js";
10
- import"./index-0eacgvpv.js";
9
+ } from "./index-1wccy765.js";
10
+ import"./index-47893rgw.js";
11
11
  import"./index-qfqjfxaa.js";
12
- import"./index-f184qyh1.js";
12
+ import"./index-hz2wyggk.js";
13
13
  import"./index-j4zgmzjr.js";
14
- import"./index-2fmnttca.js";
15
- import"./index-6jcz0m1c.js";
14
+ import"./index-t3abkwk4.js";
15
+ import"./index-hxyjer3x.js";
16
16
  import"./index-k86wepd8.js";
17
17
  import"./index-nwrehke7.js";
18
18
  import"./index-5n05se68.js";
@@ -28,16 +28,16 @@ import"./index-mxxxytys.js";
28
28
  import"./index-23z4zxgg.js";
29
29
  import"./index-pj501bh1.js";
30
30
  import"./index-9rf81m0p.js";
31
- import"./index-mvs6f7ne.js";
32
- import"./index-5d1rd5v9.js";
31
+ import"./index-59bcxqee.js";
32
+ import"./index-mcpppwbq.js";
33
33
  import"./index-adx6khj5.js";
34
34
  import"./index-fp732bgg.js";
35
35
  import"./index-4j3tt0c3.js";
36
36
  import"./index-j70m75wd.js";
37
37
  import"./index-b88v3vtm.js";
38
- import"./index-tcaq1c7f.js";
38
+ import"./index-e26mdwxz.js";
39
39
  import"./index-bdwcjvr4.js";
40
- import"./index-1er88ckw.js";
40
+ import"./index-3gc2yk4k.js";
41
41
  import"./index-pgtm2nhf.js";
42
42
  import"./index-1gwbassd.js";
43
43
  import"./index-ahyhryb8.js";
@@ -53,8 +53,9 @@ import"./index-23m6bbjt.js";
53
53
  import"./index-hya40gb2.js";
54
54
  import"./index-5vwpzb5a.js";
55
55
  import"./index-x3fthpsc.js";
56
- import"./index-b0khj0h5.js";
56
+ import"./index-qt2zwza8.js";
57
57
  import"./index-3rm7cz6h.js";
58
+ import"./index-qkesh4c6.js";
58
59
  import"./index-jvb7w0gg.js";
59
60
  import {
60
61
  __require
@@ -62,7 +63,7 @@ import {
62
63
 
63
64
  // src/cli.ts
64
65
  if (import.meta.main) {
65
- const { standaloneSupportEnvironment, isUsefulSupportResult, runProductSupportCommand, showProductSupportInvitation } = await import("./support-1yhv6vm6.js");
66
+ const { standaloneSupportEnvironment, isUsefulSupportResult, runProductSupportCommand, showProductSupportInvitation } = await import("./support-adj7bbge.js");
66
67
  const env = standaloneSupportEnvironment();
67
68
  const args = process.argv.slice(2);
68
69
  if (args[0] === "support") {
package/dist/clip/cli.js CHANGED
@@ -5,8 +5,8 @@ import {
5
5
  captureSucceeded,
6
6
  captureSummary,
7
7
  main
8
- } from "../index-2fmnttca.js";
9
- import"../index-6jcz0m1c.js";
8
+ } from "../index-t3abkwk4.js";
9
+ import"../index-hxyjer3x.js";
10
10
  import"../index-k86wepd8.js";
11
11
  import"../index-nwrehke7.js";
12
12
  import"../index-5n05se68.js";
@@ -1,6 +1,90 @@
1
1
  // @bun
2
+ import"../index-z1w83f81.js";
3
+
2
4
  // src/clip/defuddle-worker.ts
3
5
  import { Defuddle } from "defuddle/node";
6
+
7
+ // src/clip/embedded-article.ts
8
+ var EMBEDDED_ARTICLE_LIMITS = Object.freeze({ htmlBytes: 8 * 1024 * 1024, scripts: 64, jsonBytes: 256 * 1024, bodyBytes: 192 * 1024, depth: 8 });
9
+ function shallowJson(value) {
10
+ let depth = 0, quoted = false, escaped = false;
11
+ for (const char of value) {
12
+ if (quoted) {
13
+ if (escaped)
14
+ escaped = false;
15
+ else if (char === "\\")
16
+ escaped = true;
17
+ else if (char === '"')
18
+ quoted = false;
19
+ } else if (char === '"')
20
+ quoted = true;
21
+ else if (char === "{" || char === "[") {
22
+ if (++depth > EMBEDDED_ARTICLE_LIMITS.depth)
23
+ return false;
24
+ } else if (char === "}" || char === "]")
25
+ depth--;
26
+ }
27
+ return !quoted && depth === 0;
28
+ }
29
+ var escapeText = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
30
+ async function embeddedArticleHtml(html, sourceUrl) {
31
+ if (Buffer.byteLength(html) > EMBEDDED_ARTICLE_LIMITS.htmlBytes)
32
+ return null;
33
+ let source;
34
+ try {
35
+ source = new URL(sourceUrl);
36
+ } catch {
37
+ return null;
38
+ }
39
+ if (!/^https?:$/.test(source.protocol) || source.username || source.password)
40
+ return null;
41
+ source.hash = "";
42
+ let scripts = 0, candidates = 0, active = false, invalid = false, payload = "";
43
+ const rewriter = new HTMLRewriter().on("script", {
44
+ element(element) {
45
+ if (++scripts > EMBEDDED_ARTICLE_LIMITS.scripts)
46
+ invalid = true;
47
+ active = element.getAttribute("id") === "jsonArticle";
48
+ if (!active)
49
+ return;
50
+ candidates++;
51
+ if (element.getAttribute("type")?.toLowerCase() !== "application/json" || element.hasAttribute("src"))
52
+ invalid = true;
53
+ },
54
+ text(chunk) {
55
+ if (!active || invalid)
56
+ return;
57
+ payload += chunk.text;
58
+ if (Buffer.byteLength(payload) > EMBEDDED_ARTICLE_LIMITS.jsonBytes)
59
+ invalid = true;
60
+ }
61
+ });
62
+ await rewriter.transform(new Response(html)).text();
63
+ if (invalid || candidates !== 1 || !shallowJson(payload))
64
+ return null;
65
+ let value;
66
+ try {
67
+ value = JSON.parse(payload);
68
+ } catch {
69
+ return null;
70
+ }
71
+ if (typeof value !== "object" || value === null || Array.isArray(value))
72
+ return null;
73
+ const row = value;
74
+ if (Object.keys(row).length > 128 || row.dataType !== "Article" || !Number.isSafeInteger(row.dataId) || row.dataId <= 0 || typeof row.urlArticle !== "string" || row.urlArticle.length > 8192 || typeof row.title !== "string" || !row.title.trim() || Buffer.byteLength(row.title) > 4096 || typeof row.body !== "string" || !row.body.trim() || Buffer.byteLength(row.body) > EMBEDDED_ARTICLE_LIMITS.bodyBytes)
75
+ return null;
76
+ let article;
77
+ try {
78
+ article = new URL(row.urlArticle, source);
79
+ } catch {
80
+ return null;
81
+ }
82
+ if (article.username || article.password || article.hash || article.href !== source.href || article.pathname.split("/").filter(Boolean).at(-1) !== String(row.dataId))
83
+ return null;
84
+ return `<!doctype html><html><head><title>${escapeText(row.title)}</title></head><body><article><h1>${escapeText(row.title)}</h1>${row.body}</article></body></html>`;
85
+ }
86
+
87
+ // src/clip/defuddle-worker.ts
4
88
  var workerGlobal = globalThis;
5
89
  function asciiCaseEqualAt(value, offset, expected, end = value.length) {
6
90
  if (offset < 0 || offset + expected.length > end)
@@ -68,8 +152,9 @@ workerGlobal.onmessage = async (event) => {
68
152
  return;
69
153
  }
70
154
  try {
71
- const videoPosters = collectVideoPosters(request.html);
72
- const value = await Defuddle(request.html, request.url, {
155
+ const extractionHtml = request.includeReplies === false ? await embeddedArticleHtml(request.html, request.url) ?? request.html : request.html;
156
+ const videoPosters = collectVideoPosters(extractionHtml);
157
+ const value = await Defuddle(extractionHtml, request.url, {
73
158
  markdown: false,
74
159
  separateMarkdown: true,
75
160
  includeReplies: request.includeReplies,
package/dist/clip/jobs.js CHANGED
@@ -9,6 +9,9 @@ import {
9
9
  import {
10
10
  acquireFileLease
11
11
  } from "../index-3rm7cz6h.js";
12
+ import {
13
+ syncsDirectories
14
+ } from "../index-qkesh4c6.js";
12
15
  import"../index-z1w83f81.js";
13
16
 
14
17
  // src/clip/jobs.ts
@@ -360,7 +363,8 @@ async function fsyncStore(store) {
360
363
  if (!stat.isDirectory() || !sameIdentity(stat, expected)) {
361
364
  throw new CaptureJobSafetyError("Capture job store changed before synchronization.");
362
365
  }
363
- await handle.sync();
366
+ if (syncsDirectories())
367
+ await handle.sync();
364
368
  } finally {
365
369
  await handle.close();
366
370
  }
@@ -4,8 +4,8 @@ import {
4
4
  knowledgeBaseEvaluationRetrieverIds,
5
5
  openKnowledgeBaseEvaluation,
6
6
  verifyFrozenEvaluationSnapshot
7
- } from "./index-mvs6f7ne.js";
8
- import"./index-5d1rd5v9.js";
7
+ } from "./index-59bcxqee.js";
8
+ import"./index-mcpppwbq.js";
9
9
  import"./index-adx6khj5.js";
10
10
  import {
11
11
  indexSemanticVault,
@@ -19,9 +19,9 @@ import {
19
19
  MAX_EVALUATION_EVIDENCE_BYTES,
20
20
  MAX_EVALUATION_RESULTS_PER_QUERY
21
21
  } from "./index-b88v3vtm.js";
22
- import"./index-tcaq1c7f.js";
22
+ import"./index-e26mdwxz.js";
23
23
  import"./index-bdwcjvr4.js";
24
- import"./index-1er88ckw.js";
24
+ import"./index-3gc2yk4k.js";
25
25
  import"./index-pgtm2nhf.js";
26
26
  import {
27
27
  runGitCommand
@@ -36,6 +36,7 @@ import"./index-48pz4jpc.js";
36
36
  import"./index-06c9ctr6.js";
37
37
  import"./index-5vwpzb5a.js";
38
38
  import"./index-3rm7cz6h.js";
39
+ import"./index-qkesh4c6.js";
39
40
  import"./index-jvb7w0gg.js";
40
41
  import"./index-z1w83f81.js";
41
42
 
@@ -4,16 +4,16 @@ import {
4
4
  knowledgeBaseEvaluationRetrieverIds,
5
5
  openKnowledgeBaseEvaluation,
6
6
  verifyFrozenEvaluationSnapshot
7
- } from "./index-mvs6f7ne.js";
8
- import"./index-5d1rd5v9.js";
7
+ } from "./index-59bcxqee.js";
8
+ import"./index-mcpppwbq.js";
9
9
  import"./index-adx6khj5.js";
10
10
  import"./index-fp732bgg.js";
11
11
  import"./index-4j3tt0c3.js";
12
12
  import"./index-j70m75wd.js";
13
13
  import"./index-b88v3vtm.js";
14
- import"./index-tcaq1c7f.js";
14
+ import"./index-e26mdwxz.js";
15
15
  import"./index-bdwcjvr4.js";
16
- import"./index-1er88ckw.js";
16
+ import"./index-3gc2yk4k.js";
17
17
  import"./index-pgtm2nhf.js";
18
18
  import"./index-1gwbassd.js";
19
19
  import"./index-ahyhryb8.js";
@@ -24,6 +24,7 @@ import"./index-48pz4jpc.js";
24
24
  import"./index-06c9ctr6.js";
25
25
  import"./index-5vwpzb5a.js";
26
26
  import"./index-3rm7cz6h.js";
27
+ import"./index-qkesh4c6.js";
27
28
  import"./index-jvb7w0gg.js";
28
29
  import"./index-z1w83f81.js";
29
30
  export {
@@ -5,7 +5,7 @@ import {
5
5
  queryGraph,
6
6
  rebuildGraph,
7
7
  verifyGraph
8
- } from "./index-1er88ckw.js";
8
+ } from "./index-3gc2yk4k.js";
9
9
  import {
10
10
  GRAPH_LIMITS,
11
11
  GraphAuthorityError,
@@ -15,6 +15,7 @@ import"./index-1s8mc4hz.js";
15
15
  import"./index-06c9ctr6.js";
16
16
  import"./index-5vwpzb5a.js";
17
17
  import"./index-3rm7cz6h.js";
18
+ import"./index-qkesh4c6.js";
18
19
  import"./index-jvb7w0gg.js";
19
20
  import"./index-z1w83f81.js";
20
21
  export {
@@ -1,14 +1,15 @@
1
1
  // @bun
2
2
  import {
3
3
  percolateWithGraph
4
- } from "./index-tcaq1c7f.js";
4
+ } from "./index-e26mdwxz.js";
5
5
  import"./index-bdwcjvr4.js";
6
- import"./index-1er88ckw.js";
6
+ import"./index-3gc2yk4k.js";
7
7
  import"./index-pgtm2nhf.js";
8
8
  import"./index-1s8mc4hz.js";
9
9
  import"./index-06c9ctr6.js";
10
10
  import"./index-5vwpzb5a.js";
11
11
  import"./index-3rm7cz6h.js";
12
+ import"./index-qkesh4c6.js";
12
13
  import"./index-jvb7w0gg.js";
13
14
  import"./index-z1w83f81.js";
14
15
  export {
@@ -3,7 +3,7 @@ import {
3
3
  backfillSavedUrlMetadata,
4
4
  createRustMetadataSearchProvider,
5
5
  savedSourceProblem
6
- } from "./index-0eacgvpv.js";
6
+ } from "./index-47893rgw.js";
7
7
  import {
8
8
  main as main2
9
9
  } from "./index-qfqjfxaa.js";
@@ -13,13 +13,13 @@ import {
13
13
  loadPortfolioRegistry,
14
14
  openKnowledgePortfolio,
15
15
  snapshotPortfolioRegistry
16
- } from "./index-f184qyh1.js";
16
+ } from "./index-hz2wyggk.js";
17
17
  import {
18
18
  diffCaptureBundle
19
19
  } from "./index-j4zgmzjr.js";
20
20
  import {
21
21
  main
22
- } from "./index-2fmnttca.js";
22
+ } from "./index-t3abkwk4.js";
23
23
  import {
24
24
  detectAudience,
25
25
  renderFailure,
@@ -51,7 +51,7 @@ import {
51
51
  import {
52
52
  knowledgeBaseEvaluationRetrieverIds,
53
53
  openKnowledgeBaseEvaluation
54
- } from "./index-mvs6f7ne.js";
54
+ } from "./index-59bcxqee.js";
55
55
  import {
56
56
  DEFAULT_SEARCH_RESULTS,
57
57
  MAX_SEARCH_CANDIDATES,
@@ -60,7 +60,7 @@ import {
60
60
  MAX_SEARCH_RESULTS,
61
61
  openKnowledgeBase,
62
62
  searchEvidenceRank
63
- } from "./index-5d1rd5v9.js";
63
+ } from "./index-mcpppwbq.js";
64
64
  import {
65
65
  MAX_SEARCH_RULE_CONFIG_BYTES,
66
66
  parseSearchRules
@@ -85,7 +85,7 @@ import {
85
85
  } from "./index-b88v3vtm.js";
86
86
  import {
87
87
  percolateWithGraph
88
- } from "./index-tcaq1c7f.js";
88
+ } from "./index-e26mdwxz.js";
89
89
  import {
90
90
  MAX_PERCOLATION_MENTIONS,
91
91
  MAX_PERCOLATION_MENTION_PAIRS,
@@ -97,7 +97,7 @@ import {
97
97
  queryGraph,
98
98
  rebuildGraph,
99
99
  verifyGraph
100
- } from "./index-1er88ckw.js";
100
+ } from "./index-3gc2yk4k.js";
101
101
  import {
102
102
  validateGraphQueryRequest
103
103
  } from "./index-pgtm2nhf.js";
@@ -184,7 +184,10 @@ import {
184
184
  sha256,
185
185
  updateNoteBody,
186
186
  updateNoteBodyProgram
187
- } from "./index-b0khj0h5.js";
187
+ } from "./index-qt2zwza8.js";
188
+ import {
189
+ syncsDirectories
190
+ } from "./index-qkesh4c6.js";
188
191
  import {
189
192
  isMetadataNumber,
190
193
  lookupNote,
@@ -440,7 +443,10 @@ function installMetadataSearchExecutable(input) {
440
443
  const backupName = `.${executableName}.${process.pid}.${randomUUID()}.backup`;
441
444
  const stagingPath = join(toolDirectory, stagingName);
442
445
  const backupPath = join(toolDirectory, backupName);
443
- const syncDirectory = input.syncDirectory ?? ((descriptor) => fsyncSync(descriptor));
446
+ const syncDirectory = input.syncDirectory ?? ((descriptor) => {
447
+ if (syncsDirectories())
448
+ fsyncSync(descriptor);
449
+ });
444
450
  const toolBinding = openBoundDirectory(toolDirectory, "metadata-search tool directory");
445
451
  let targetBinding = null;
446
452
  let releaseBinding = null;
@@ -7873,7 +7879,7 @@ async function main4(rawArguments = process.argv.slice(2), output = defaultOutpu
7873
7879
  }
7874
7880
  try {
7875
7881
  if (command.kind === "clip") {
7876
- return await (dependencies.runClipCommand ?? main)(command.arguments, process.env, output);
7882
+ return await (dependencies.runClipCommand ?? main)(command.arguments, terminal.env, output);
7877
7883
  }
7878
7884
  if (command.kind === "capture-bundle")
7879
7885
  return await runCaptureBundle(command, output, dependencies);
@@ -7884,10 +7890,10 @@ async function main4(rawArguments = process.argv.slice(2), output = defaultOutpu
7884
7890
  if (command.kind === "portfolio-audit")
7885
7891
  return await runPortfolioAudit(command, output, dependencies);
7886
7892
  if (command.kind === "url-metadata") {
7887
- return await (dependencies.runUrlMetadataCommand ?? main3)(command.arguments, process.env, output);
7893
+ return await (dependencies.runUrlMetadataCommand ?? main3)(command.arguments, terminal.env, output);
7888
7894
  }
7889
7895
  if (command.kind === "pdf") {
7890
- return await (dependencies.runPdfCommand ?? main2)(command.arguments, process.env, output);
7896
+ return await (dependencies.runPdfCommand ?? main2)(command.arguments, terminal.env, output);
7891
7897
  }
7892
7898
  if (command.kind === "init") {
7893
7899
  return await runInit(command, output, dependencies.initVault ?? initVault, dependencies.terminal ?? processTerminal());
@@ -13,6 +13,9 @@ import {
13
13
  import {
14
14
  acquireFileLease
15
15
  } from "./index-3rm7cz6h.js";
16
+ import {
17
+ syncsDirectories
18
+ } from "./index-qkesh4c6.js";
16
19
  import {
17
20
  VaultAnalysisBudgetError,
18
21
  analyzeVault,
@@ -443,11 +446,13 @@ async function rebuildGraph(rootInput, options = {}) {
443
446
  await handle.close();
444
447
  }
445
448
  await rename(stagedPath, path);
446
- const directory = await graphCacheFileSystem.open(cache, constants.O_RDONLY);
447
- try {
448
- await directory.sync();
449
- } finally {
450
- await directory.close();
449
+ if (syncsDirectories()) {
450
+ const directory = await graphCacheFileSystem.open(cache, constants.O_RDONLY);
451
+ try {
452
+ await directory.sync();
453
+ } finally {
454
+ await directory.close();
455
+ }
451
456
  }
452
457
  return result;
453
458
  } finally {
@@ -5,7 +5,7 @@ import {
5
5
  parseArchiveTodayMementoUrl,
6
6
  parseMetadataSearchResponse,
7
7
  rankMetadataSearchResults
8
- } from "./index-6jcz0m1c.js";
8
+ } from "./index-hxyjer3x.js";
9
9
  import {
10
10
  assertSafeNetworkUrl,
11
11
  isPrivateHostname,
@@ -14,6 +14,9 @@ import {
14
14
  import {
15
15
  sanitizeArtifactUrl
16
16
  } from "./index-mxxxytys.js";
17
+ import {
18
+ syncsDirectories
19
+ } from "./index-qkesh4c6.js";
17
20
 
18
21
  // src/clip/metadata-search.ts
19
22
  import { spawn } from "child_process";
@@ -311,16 +314,17 @@ function deterministicResponse(response, maximumResults) {
311
314
  results: Object.freeze(results),
312
315
  enginesQueried,
313
316
  enginesFailed: Object.freeze([...response.enginesFailed].sort()),
314
- engineStatus: response.engineStatus
317
+ engineStatus: response.engineStatus,
318
+ ...response.engineFailures === undefined ? {} : { engineFailures: Object.freeze([...response.engineFailures].sort((a, b) => compareText(a.engine, b.engine))) }
315
319
  });
316
320
  }
317
- async function resolveEngineHosts(resolver, timeoutMs) {
318
- const resolved = await Promise.all(METADATA_SEARCH_ENGINE_HOSTS.map(async (hostname) => {
321
+ async function resolveEngineHosts(resolver, timeoutMs, enableBingRss, enableOpenAlexDiscovery) {
322
+ const resolved = await Promise.all([...METADATA_SEARCH_ENGINE_HOSTS, ...enableBingRss ? ["www.bing.com"] : [], ...enableOpenAlexDiscovery ? ["api.openalex.org"] : []].map(async (hostname) => {
319
323
  const addresses = await resolver(new URL(`https://${hostname}/`), {
320
324
  allowPrivateNetwork: false,
321
325
  timeoutMs
322
326
  });
323
- if (addresses.length === 0 || addresses.length > MAX_ENGINE_ADDRESSES) {
327
+ if (addresses.length === 0) {
324
328
  throw new Error("metadata search engine DNS answer count is invalid");
325
329
  }
326
330
  const unique = new Map;
@@ -333,7 +337,7 @@ async function resolveEngineHosts(resolver, timeoutMs) {
333
337
  throw new Error("metadata search engine DNS answer is duplicated");
334
338
  return Object.freeze({
335
339
  hostname,
336
- addresses: Object.freeze([...unique.values()].sort((left, right) => left.family - right.family || (left.address < right.address ? -1 : left.address > right.address ? 1 : 0)))
340
+ addresses: Object.freeze([...unique.values()].sort((left, right) => left.family - right.family || (left.address < right.address ? -1 : left.address > right.address ? 1 : 0)).slice(0, MAX_ENGINE_ADDRESSES))
337
341
  });
338
342
  }));
339
343
  return Object.freeze(resolved);
@@ -361,6 +365,12 @@ function createExactUrlSearchQuery(value) {
361
365
  return `"${exactUrl}"`;
362
366
  }
363
367
  function createRustMetadataSearchProvider(options) {
368
+ if (options.enableBingRss !== undefined && typeof options.enableBingRss !== "boolean")
369
+ throw new TypeError("enableBingRss must be boolean.");
370
+ const enableBingRss = options.enableBingRss === true;
371
+ if (options.enableOpenAlexDiscovery !== undefined && typeof options.enableOpenAlexDiscovery !== "boolean")
372
+ throw new TypeError("enableOpenAlexDiscovery must be boolean.");
373
+ const enableOpenAlexDiscovery = options.enableOpenAlexDiscovery === true;
364
374
  if (!isAbsolute(options.binaryPath)) {
365
375
  throw new TypeError("The metadata search binary path must be absolute.");
366
376
  }
@@ -386,7 +396,7 @@ function createRustMetadataSearchProvider(options) {
386
396
  return failure("aborted", "Metadata search was aborted.");
387
397
  let engineHosts;
388
398
  try {
389
- engineHosts = await resolveEngineHosts(resolveNetworkTarget, validated.timeoutMs);
399
+ engineHosts = await resolveEngineHosts(resolveNetworkTarget, validated.timeoutMs, enableBingRss, enableOpenAlexDiscovery);
390
400
  } catch {
391
401
  return failure("unavailable", "Metadata search network targets are unavailable.");
392
402
  }
@@ -410,6 +420,9 @@ function createRustMetadataSearchProvider(options) {
410
420
  try {
411
421
  const input = JSON.stringify({
412
422
  schema_version: REQUEST_SCHEMA_VERSION,
423
+ diagnostics: true,
424
+ ...enableBingRss ? { bing_rss: true } : {},
425
+ ...enableOpenAlexDiscovery ? { openalex_discovery: true } : {},
413
426
  query: validated.query,
414
427
  max_results: validated.maxResults,
415
428
  timeout_ms: validated.timeoutMs,
@@ -1524,7 +1537,8 @@ function writeUrlMetadataDocument(saved, document) {
1524
1537
  throw new Error(`URL metadata sidecar failed post-install verification: ${saved.sidecarPath}`);
1525
1538
  }
1526
1539
  assertHeldUrlMetadataWriteLockCurrent(heldLock);
1527
- fsyncSync2(directoryDescriptor);
1540
+ if (syncsDirectories())
1541
+ fsyncSync2(directoryDescriptor);
1528
1542
  return { changed: true, path: saved.sidecarPath };
1529
1543
  } catch (error) {
1530
1544
  operationError = error;
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  MAX_SEARCH_RESULTS,
4
4
  openKnowledgeBase
5
- } from "./index-5d1rd5v9.js";
5
+ } from "./index-mcpppwbq.js";
6
6
  import {
7
7
  MAX_EVALUATION_EVIDENCE_BYTES,
8
8
  redactEvaluationMachinePaths
@@ -4,7 +4,7 @@ import {
4
4
  } from "./index-h170byqw.js";
5
5
  import {
6
6
  packUntrustedSearchContext
7
- } from "./index-5d1rd5v9.js";
7
+ } from "./index-mcpppwbq.js";
8
8
 
9
9
  // src/workflows/decision-context.ts
10
10
  var decisionContextWorkflow = defineWorkflow({
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  createGraphSnapshot,
7
7
  openGraphAuthority
8
- } from "./index-1er88ckw.js";
8
+ } from "./index-3gc2yk4k.js";
9
9
  import {
10
10
  GraphAuthorityError,
11
11
  validateGraphPercolationOptions