@hraness/wordcell 0.23.0 → 0.24.1
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.
- package/README.md +29 -16
- package/dist/authoring.js +2 -1
- package/dist/cli.js +10 -9
- package/dist/clip/jobs.js +5 -1
- package/dist/evaluation-builder.js +5 -4
- package/dist/evaluation-kb.js +5 -4
- package/dist/graph-authority.js +2 -1
- package/dist/graph-percolation.js +3 -2
- package/dist/{index-1er88ckw.js → index-3gc2yk4k.js} +10 -5
- package/dist/{index-mnq2wy34.js → index-59bcxqee.js} +1 -1
- package/dist/{index-p70t8j13.js → index-7drercgk.js} +1 -1
- package/dist/{index-tcaq1c7f.js → index-e26mdwxz.js} +1 -1
- package/dist/{index-r4qs6vq4.js → index-hz2wyggk.js} +1 -1
- package/dist/{index-vtwbapjr.js → index-jqkkb4fr.js} +72 -12
- package/dist/{index-tvd2sqrx.js → index-mcpppwbq.js} +439 -4
- package/dist/index-qkesh4c6.js +7 -0
- package/dist/{index-b0khj0h5.js → index-qt2zwza8.js} +6 -1
- package/dist/{index-0eacgvpv.js → index-t0fh8a1q.js} +7 -3
- package/dist/index.js +6 -5
- package/dist/portfolio.js +5 -4
- package/dist/sdk.js +4 -3
- package/dist/{support-c8hy7qfa.js → support-07jpt1z4.js} +9 -8
- package/dist/url-intelligence.js +2 -1
- package/dist/workflows/decision-context.js +5 -4
- package/dist/workflows/index.js +5 -4
- package/package.json +12 -8
- package/skills/wordcell/SKILL.md +1 -1
- package/skills/wordcell/references/publish.md +2 -1
- package/skills/wordcell/references/query.md +17 -3
- package/src/authoring-platform.ts +3 -0
- package/src/cli-help.ts +1 -0
- package/src/cli-program.ts +41 -3
- package/src/clip/jobs.ts +2 -1
- package/src/clip/metadata-search-tool/Cargo.lock +2 -0
- package/src/clip/metadata-search-tool/Cargo.toml +2 -0
- package/src/clip/metadata-search-tool/runner.ts +4 -1
- package/src/clip/metadata-search-tool/src/duckduckgo.rs +534 -0
- package/src/clip/metadata-search-tool/src/main.rs +31 -18
- package/src/clip/metadata-search.ts +4 -2
- package/src/clip/url-metadata.ts +2 -1
- package/src/directory-sync.ts +9 -0
- package/src/graph-authority.ts +5 -2
- package/src/mcp-tools.ts +17 -1
- package/src/sdk.ts +149 -1
- package/src/selected-passage.ts +409 -0
package/README.md
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
|
|
4
4
|
[](https://github.com/hraness/wordcell/tree/main/skills/wordcell)
|
|
5
5
|
|
|
6
|
-
Wordcell
|
|
7
|
-
|
|
8
|
-
|
|
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://
|
|
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://
|
|
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.
|
|
57
|
+
bun add --global --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.24.1/hraness-wordcell-0.24.1.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.
|
|
64
|
+
npm install --global --ignore-scripts @hraness/wordcell@0.24.1
|
|
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.
|
|
106
|
+
bunx skills add hraness/wordcell#v0.24.1 --skill wordcell
|
|
105
107
|
```
|
|
106
108
|
|
|
107
109
|
Then ask:
|
|
@@ -247,6 +249,14 @@ keeps one vault current on several machines.
|
|
|
247
249
|
|
|
248
250
|
## Evidence and comparisons
|
|
249
251
|
|
|
252
|
+
On eight questions sealed before the passage selector was finished,
|
|
253
|
+
`wordcell search --selected-passage` returned an excerpt holding the labeled
|
|
254
|
+
answer for **6 of 8**, versus **1 of 8** for the older search snippets, at the
|
|
255
|
+
same 512-byte limit and from the same retrieved notes. It runs locally with no
|
|
256
|
+
model. The corpus is small and consists of Wordcell's own notes; containing the
|
|
257
|
+
answer is not the same as an agent answering correctly.
|
|
258
|
+
[Method, raw results, and reproduction](https://github.com/hraness/wordcell/blob/main/docs/evidence.md#measure-whether-excerpts-contain-the-answer).
|
|
259
|
+
|
|
250
260
|
In a four-query example over a seven-note public vault, packed search snippets
|
|
251
261
|
used **80% fewer UTF-8 bytes** than passing the same matching notes in full:
|
|
252
262
|
12,126 versus 60,584 bytes. This measures context payload size, not tokenizer
|
|
@@ -262,17 +272,20 @@ Wordcell's benefit is selecting relevant context and keeping its sources
|
|
|
262
272
|
inspectable. Local ownership is also available in other tools, and Wordcell
|
|
263
273
|
does not claim to beat QMD's retrieval quality or every Markdown workflow.
|
|
264
274
|
|
|
265
|
-
[Measured evidence](https://
|
|
275
|
+
[Measured evidence](https://wordcell.io/docs/evidence)
|
|
266
276
|
shows a reproducible public-vault example, with the inputs, output sizes, and
|
|
267
|
-
limits beside each result. [The comparison guide](https://
|
|
277
|
+
limits beside each result. [The comparison guide](https://wordcell.io/docs/comparisons)
|
|
268
278
|
covers Markdown alone, QMD, Basic Memory, Obsidian, static publishing tools,
|
|
269
279
|
Supermemory, Mem0, and Zep using their own documentation. Choose the smallest
|
|
270
280
|
workflow that meets your needs.
|
|
271
281
|
|
|
272
|
-
The [benchmarks page](https://wordcell.io/benchmarks) shows the payload
|
|
273
|
-
SciFact results beside the published results of Oh, the embedded memory
|
|
274
|
-
framework, each with its source data and limits.
|
|
275
|
-
|
|
282
|
+
The [benchmarks page](https://wordcell.io/benchmarks) shows the excerpt, payload,
|
|
283
|
+
and SciFact results beside the published results of Oh, the embedded memory
|
|
284
|
+
framework, each with its source data and limits. On all 500 LongMemEval-S
|
|
285
|
+
questions, Oh semantic retrieval scored 88.87% and BM25 86.13% with the same
|
|
286
|
+
reader and budget; on the measure Oh named before the run, its interval does
|
|
287
|
+
not rule out a tie. Oh's scores measure its own memory-retrieval path, not a
|
|
288
|
+
Wordcell vault.
|
|
276
289
|
|
|
277
290
|
## How the files fit together
|
|
278
291
|
|
|
@@ -321,7 +334,7 @@ exist. [Graph queries and proof limits](https://github.com/hraness/wordcell/blob
|
|
|
321
334
|
Add the same immutable release to a Bun project:
|
|
322
335
|
|
|
323
336
|
```sh
|
|
324
|
-
bun add --exact --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.
|
|
337
|
+
bun add --exact --ignore-scripts https://github.com/hraness/wordcell/releases/download/v0.24.1/hraness-wordcell-0.24.1.tgz
|
|
325
338
|
```
|
|
326
339
|
|
|
327
340
|
The SDK provides read-only vault sessions, metadata queries, search, graph
|
|
@@ -358,7 +371,7 @@ the design. Browse it on the [documentation index](https://wordcell.io/docs).
|
|
|
358
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. |
|
|
359
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. |
|
|
360
373
|
| [Graph guide](https://github.com/hraness/wordcell/blob/main/docs/graph-authority.md) | Named queries, proofs, revisions, resource limits, and cache recovery. |
|
|
361
|
-
| [
|
|
374
|
+
| [Search several vaults together](https://github.com/hraness/wordcell/blob/main/docs/portfolio.md) | Search only selected, authorized vaults. |
|
|
362
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. |
|
|
363
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. |
|
|
364
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-
|
|
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/cli.js
CHANGED
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
parseArguments,
|
|
7
7
|
runExecutable,
|
|
8
8
|
usage
|
|
9
|
-
} from "./index-
|
|
10
|
-
import"./index-
|
|
9
|
+
} from "./index-jqkkb4fr.js";
|
|
10
|
+
import"./index-t0fh8a1q.js";
|
|
11
11
|
import"./index-qfqjfxaa.js";
|
|
12
|
-
import"./index-
|
|
12
|
+
import"./index-hz2wyggk.js";
|
|
13
13
|
import"./index-j4zgmzjr.js";
|
|
14
14
|
import"./index-2fmnttca.js";
|
|
15
15
|
import"./index-6jcz0m1c.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-
|
|
32
|
-
import"./index-
|
|
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-
|
|
38
|
+
import"./index-e26mdwxz.js";
|
|
39
39
|
import"./index-bdwcjvr4.js";
|
|
40
|
-
import"./index-
|
|
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-
|
|
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-
|
|
66
|
+
const { standaloneSupportEnvironment, isUsefulSupportResult, runProductSupportCommand, showProductSupportInvitation } = await import("./support-07jpt1z4.js");
|
|
66
67
|
const env = standaloneSupportEnvironment();
|
|
67
68
|
const args = process.argv.slice(2);
|
|
68
69
|
if (args[0] === "support") {
|
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
|
-
|
|
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-
|
|
8
|
-
import"./index-
|
|
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-
|
|
22
|
+
import"./index-e26mdwxz.js";
|
|
23
23
|
import"./index-bdwcjvr4.js";
|
|
24
|
-
import"./index-
|
|
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
|
|
package/dist/evaluation-kb.js
CHANGED
|
@@ -4,16 +4,16 @@ import {
|
|
|
4
4
|
knowledgeBaseEvaluationRetrieverIds,
|
|
5
5
|
openKnowledgeBaseEvaluation,
|
|
6
6
|
verifyFrozenEvaluationSnapshot
|
|
7
|
-
} from "./index-
|
|
8
|
-
import"./index-
|
|
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-
|
|
14
|
+
import"./index-e26mdwxz.js";
|
|
15
15
|
import"./index-bdwcjvr4.js";
|
|
16
|
-
import"./index-
|
|
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 {
|
package/dist/graph-authority.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
queryGraph,
|
|
6
6
|
rebuildGraph,
|
|
7
7
|
verifyGraph
|
|
8
|
-
} from "./index-
|
|
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-
|
|
4
|
+
} from "./index-e26mdwxz.js";
|
|
5
5
|
import"./index-bdwcjvr4.js";
|
|
6
|
-
import"./index-
|
|
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 {
|
|
@@ -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
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
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 {
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
backfillSavedUrlMetadata,
|
|
4
4
|
createRustMetadataSearchProvider,
|
|
5
5
|
savedSourceProblem
|
|
6
|
-
} from "./index-
|
|
6
|
+
} from "./index-t0fh8a1q.js";
|
|
7
7
|
import {
|
|
8
8
|
main as main2
|
|
9
9
|
} from "./index-qfqjfxaa.js";
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
loadPortfolioRegistry,
|
|
14
14
|
openKnowledgePortfolio,
|
|
15
15
|
snapshotPortfolioRegistry
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-hz2wyggk.js";
|
|
17
17
|
import {
|
|
18
18
|
diffCaptureBundle
|
|
19
19
|
} from "./index-j4zgmzjr.js";
|
|
@@ -51,7 +51,7 @@ import {
|
|
|
51
51
|
import {
|
|
52
52
|
knowledgeBaseEvaluationRetrieverIds,
|
|
53
53
|
openKnowledgeBaseEvaluation
|
|
54
|
-
} from "./index-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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) =>
|
|
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;
|
|
@@ -932,6 +938,7 @@ var commandHelp = [
|
|
|
932
938
|
["--min-score <score>", "Drop results scoring below this (0 to 1)"],
|
|
933
939
|
["--rerank <typesafe>", "Rerank results with the hosted TypeSafe service"],
|
|
934
940
|
["--rerank-limit <2..25>", "How many results the reranker sees"],
|
|
941
|
+
["--selected-passage", "Add a local source excerpt to each result"],
|
|
935
942
|
JSON_OPTION
|
|
936
943
|
],
|
|
937
944
|
examples: ['wordcell search "retries" --root kb --mode exact', 'wordcell search "retry policy" --root kb --limit 5']
|
|
@@ -3624,6 +3631,15 @@ function requiredText(arguments_, key, maxBytes) {
|
|
|
3624
3631
|
function optionalText(arguments_, key, maxBytes) {
|
|
3625
3632
|
return has(arguments_, key) ? checkedText(arguments_[key], key, maxBytes) : undefined;
|
|
3626
3633
|
}
|
|
3634
|
+
function optionalBoolean(arguments_, key) {
|
|
3635
|
+
if (!has(arguments_, key))
|
|
3636
|
+
return;
|
|
3637
|
+
const value = arguments_[key];
|
|
3638
|
+
if (typeof value !== "boolean") {
|
|
3639
|
+
throw new ToolArgumentError(`Invalid argument "${key}": expected a boolean.`);
|
|
3640
|
+
}
|
|
3641
|
+
return value;
|
|
3642
|
+
}
|
|
3627
3643
|
function optionalInteger(arguments_, key, minimum, maximum) {
|
|
3628
3644
|
if (!has(arguments_, key))
|
|
3629
3645
|
return;
|
|
@@ -3923,6 +3939,11 @@ function readTools(root, sessions) {
|
|
|
3923
3939
|
properties: {
|
|
3924
3940
|
query: { type: "string", minLength: 1, maxLength: MAX_QUERY_TEXT_UTF8_BYTES },
|
|
3925
3941
|
mode: { type: "string", enum: SEARCH_MODES, default: "hybrid" },
|
|
3942
|
+
selectedPassage: {
|
|
3943
|
+
type: "boolean",
|
|
3944
|
+
default: false,
|
|
3945
|
+
description: "Include a local source excerpt with line references and section headings. Ranking is unchanged."
|
|
3946
|
+
},
|
|
3926
3947
|
limit: { type: "integer", minimum: 1, maximum: MAX_SEARCH_RESULTS, default: DEFAULT_SEARCH_RESULTS },
|
|
3927
3948
|
...filterProperties
|
|
3928
3949
|
}
|
|
@@ -3930,10 +3951,11 @@ function readTools(root, sessions) {
|
|
|
3930
3951
|
annotations: { title: "Search notes", ...READ_ONLY }
|
|
3931
3952
|
},
|
|
3932
3953
|
handler: async (arguments_) => {
|
|
3933
|
-
allowOnly(arguments_, ["query", "mode", "limit", "tags", "where", "has", "scope"]);
|
|
3954
|
+
allowOnly(arguments_, ["query", "mode", "limit", "tags", "where", "has", "scope", "selectedPassage"]);
|
|
3934
3955
|
const query = requiredText(arguments_, "query", MAX_QUERY_TEXT_UTF8_BYTES);
|
|
3935
3956
|
const mode = optionalChoice(arguments_, "mode", SEARCH_MODES) ?? "hybrid";
|
|
3936
3957
|
const limit = optionalInteger(arguments_, "limit", 1, MAX_SEARCH_RESULTS) ?? DEFAULT_SEARCH_RESULTS;
|
|
3958
|
+
const selectedPassage = optionalBoolean(arguments_, "selectedPassage");
|
|
3937
3959
|
const filters = metadataFilters(arguments_);
|
|
3938
3960
|
const tags = optionalTextList(arguments_, "tags", MAX_QUERY_TAGS, MAX_QUERY_TEXT_UTF8_BYTES);
|
|
3939
3961
|
const scopes = optionalTextList(arguments_, "scope", MAX_REPOSITORY_SCOPES, MAX_QUERY_TEXT_UTF8_BYTES);
|
|
@@ -3942,6 +3964,7 @@ function readTools(root, sessions) {
|
|
|
3942
3964
|
query,
|
|
3943
3965
|
mode,
|
|
3944
3966
|
limit,
|
|
3967
|
+
...selectedPassage === undefined ? {} : { selectedPassage },
|
|
3945
3968
|
...filters.length === 0 ? {} : { filters },
|
|
3946
3969
|
...tags === undefined ? {} : { tags },
|
|
3947
3970
|
...scopes === undefined ? {} : { repositoryScopes: scopes }
|
|
@@ -5151,6 +5174,7 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
5151
5174
|
let minScore;
|
|
5152
5175
|
let rerank;
|
|
5153
5176
|
let rerankLimit;
|
|
5177
|
+
let selectedPassage = false;
|
|
5154
5178
|
let graphDepth;
|
|
5155
5179
|
let noGraph = false;
|
|
5156
5180
|
let history = false;
|
|
@@ -5177,6 +5201,10 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
5177
5201
|
noGraph = true;
|
|
5178
5202
|
continue;
|
|
5179
5203
|
}
|
|
5204
|
+
if (argument === "--selected-passage" && command === "search") {
|
|
5205
|
+
selectedPassage = true;
|
|
5206
|
+
continue;
|
|
5207
|
+
}
|
|
5180
5208
|
if (argument === "--no-history" && command === "search") {
|
|
5181
5209
|
noHistory = true;
|
|
5182
5210
|
continue;
|
|
@@ -5402,6 +5430,7 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
5402
5430
|
...minScore === undefined ? {} : { minScore },
|
|
5403
5431
|
...rerank === undefined ? {} : { rerank },
|
|
5404
5432
|
...rerankLimit === undefined ? {} : { rerankLimit },
|
|
5433
|
+
...selectedPassage ? { selectedPassage: true } : {},
|
|
5405
5434
|
query,
|
|
5406
5435
|
json
|
|
5407
5436
|
}
|
|
@@ -6293,6 +6322,22 @@ function renderSemanticIndex(result) {
|
|
|
6293
6322
|
].join(`
|
|
6294
6323
|
`);
|
|
6295
6324
|
}
|
|
6325
|
+
function searchForDisplay(result) {
|
|
6326
|
+
return {
|
|
6327
|
+
...result,
|
|
6328
|
+
results: result.results.map((hit) => {
|
|
6329
|
+
const passage = hit.selectedPassage;
|
|
6330
|
+
if (passage?.status !== "selected")
|
|
6331
|
+
return hit;
|
|
6332
|
+
const texts = [passage.text, ...passage.headings.map(({ text }) => text)];
|
|
6333
|
+
if (texts.every((text) => sanitizeTerminalText(redactSensitiveText(text)) === text.replaceAll(`\r
|
|
6334
|
+
`, `
|
|
6335
|
+
`).replaceAll("\t", " ")))
|
|
6336
|
+
return hit;
|
|
6337
|
+
return { ...hit, selectedPassage: { status: "unavailable", reason: "display-sanitized" } };
|
|
6338
|
+
})
|
|
6339
|
+
};
|
|
6340
|
+
}
|
|
6296
6341
|
function renderKnowledgeBaseSearch(result) {
|
|
6297
6342
|
const lines = [
|
|
6298
6343
|
`${result.mode[0]?.toLocaleUpperCase("en-US") ?? ""}${result.mode.slice(1)} results for \u201C${safe(result.query)}\u201D (${result.results.length})${result.partial ? " [partial]" : ""}`
|
|
@@ -6315,8 +6360,21 @@ function renderKnowledgeBaseSearch(result) {
|
|
|
6315
6360
|
const location = `${safe(hit.path)}${hit.line === undefined ? "" : `:${hit.line}`}`;
|
|
6316
6361
|
const evidence = hit.evidence.map((item) => `${item.kind}#${searchEvidenceRank(item)}`).join(", ");
|
|
6317
6362
|
lines.push(` ${hit.rank}. ${hit.score.toFixed(3)} ${location} \u2014 ${safe(hit.title)} [${safe(evidence)}]`);
|
|
6318
|
-
|
|
6319
|
-
|
|
6363
|
+
const passage = hit.selectedPassage;
|
|
6364
|
+
if (passage?.status === "selected") {
|
|
6365
|
+
lines.push(` Selected passage: ${safe(hit.path)}:${passage.startLine}-${passage.endLine}` + (passage.clippedStart || passage.clippedEnd ? " (clipped excerpt)" : ""));
|
|
6366
|
+
for (const heading of passage.headings) {
|
|
6367
|
+
lines.push(` Section: ${safe(heading.text)}${heading.truncated ? " (clipped)" : ""}`);
|
|
6368
|
+
}
|
|
6369
|
+
for (const line of passage.text.split(/\r?\n/u))
|
|
6370
|
+
lines.push(` ${safe(line)}`);
|
|
6371
|
+
} else {
|
|
6372
|
+
if (hit.snippet !== "")
|
|
6373
|
+
lines.push(` ${safe(hit.snippet)}`);
|
|
6374
|
+
if (passage !== undefined) {
|
|
6375
|
+
lines.push(` Selected passage: ${passage.status} (${safe(passage.reason)}); showing the search snippet.`);
|
|
6376
|
+
}
|
|
6377
|
+
}
|
|
6320
6378
|
}
|
|
6321
6379
|
if ((result.graph?.related.length ?? 0) > 0) {
|
|
6322
6380
|
lines.push(` Related graph context: ${result.graph?.related.length ?? 0}`);
|
|
@@ -6369,6 +6427,7 @@ async function runSemantic(command, output, dependencies) {
|
|
|
6369
6427
|
...command.limit === undefined ? {} : { limit: command.limit },
|
|
6370
6428
|
...command.candidateLimit === undefined ? {} : { candidateLimit: command.candidateLimit },
|
|
6371
6429
|
...command.minScore === undefined ? {} : { minScore: command.minScore },
|
|
6430
|
+
...command.selectedPassage === undefined ? {} : { selectedPassage: command.selectedPassage },
|
|
6372
6431
|
...command.rerank === undefined ? {} : {
|
|
6373
6432
|
rerank: {
|
|
6374
6433
|
engine: command.rerank,
|
|
@@ -6376,7 +6435,8 @@ async function runSemantic(command, output, dependencies) {
|
|
|
6376
6435
|
}
|
|
6377
6436
|
}
|
|
6378
6437
|
});
|
|
6379
|
-
|
|
6438
|
+
const display = searchForDisplay(result);
|
|
6439
|
+
output.stdout(command.json ? terminalSafeJson(display) : sanitizeTerminalText(renderKnowledgeBaseSearch(display)));
|
|
6380
6440
|
if (withoutIndex && person) {
|
|
6381
6441
|
output.stderr("Searched without an index, so only exact words matched. " + `For meaning-based search, run wordcell index --root ${safe(shellWord(command.root))} ` + `(downloads about 300 MB once).
|
|
6382
6442
|
`);
|