@hraness/wordcell 0.21.3 → 0.22.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.
- package/README.md +170 -64
- package/dist/{authority-4sp9d552.js → authority-1pgftmwq.js} +55 -10
- package/dist/benchmark.js +3 -3
- package/dist/capture.js +6 -5
- package/dist/cli.js +37 -31
- package/dist/clip/acquire.js +3 -2
- package/dist/clip/cli.js +6 -5
- package/dist/clip/doctor.js +4 -3
- package/dist/clip/jobs.js +3 -3
- package/dist/clip/refresh.js +1 -1
- package/dist/evaluation-builder.js +18 -17
- package/dist/evaluation-kb.js +14 -13
- package/dist/graph-authority.js +3 -3
- package/dist/graph-percolation.js +5 -5
- package/dist/index-0dqfnrz9.js +1985 -0
- package/dist/{index-0k2x4nn9.js → index-1tm7bgx7.js} +16 -4
- package/dist/{index-vdw5yjfa.js → index-2hf27mws.js} +108 -18
- package/dist/index-3agn8scn.js +306 -0
- package/dist/{index-0rfcqab6.js → index-4ag64rc1.js} +555 -59
- package/dist/index-4knsp9qj.js +34 -0
- package/dist/index-66pshdtx.js +341 -0
- package/dist/index-9rf81m0p.js +368 -0
- package/dist/{index-59ssmqqm.js → index-a6kbv718.js} +1 -1
- package/dist/{index-51bap0mq.js → index-avbce90h.js} +9 -9
- package/dist/{index-9zcpdbjg.js → index-de2w8crk.js} +13 -13
- package/dist/{index-pbr6rv47.js → index-e6p9e926.js} +6 -6
- package/dist/{index-bcfn9xah.js → index-famy7fhs.js} +5 -5
- package/dist/{index-van48n3g.js → index-fc4dr114.js} +4 -2
- package/dist/{index-jzcws0zn.js → index-g5vsqmdy.js} +27 -57
- package/dist/{index-115b07ap.js → index-hcw140eb.js} +5 -5
- package/dist/index-j70m75wd.js +217 -0
- package/dist/{index-3ehtt59c.js → index-qwgsmtsz.js} +1 -1
- package/dist/{index-bgfzwt4h.js → index-t2bs9xdr.js} +4 -4
- package/dist/index.js +285 -93
- package/dist/portfolio.js +14 -13
- package/dist/publish-model.js +36 -0
- package/dist/publish-reader/reader.css +1042 -0
- package/dist/publish-reader/reader.js +1534 -0
- package/dist/publish-reader/theme.js +92 -0
- package/dist/publish-search.js +52 -0
- package/dist/publish.js +36 -0
- package/dist/rerank-typesafe.js +13 -0
- package/dist/rerank.js +14 -0
- package/dist/sdk.js +14 -11
- package/dist/search.js +2 -2
- package/dist/semantic.js +4 -4
- package/dist/{support-vm4mkw0k.js → support-mywv1em0.js} +38 -32
- package/dist/workflows/decision-context.js +13 -12
- package/dist/workflows/index.js +13 -12
- package/package.json +63 -5
- package/skills/wordcell/AGENTS.md +1 -0
- package/skills/wordcell/SKILL.md +2 -1
- package/skills/wordcell/agents/openai.yaml +1 -1
- package/skills/wordcell/references/publish.md +93 -0
- package/skills/wordcell/references/query.md +22 -0
- package/src/cli-program.ts +347 -9
- package/src/index.ts +4 -0
- package/src/oh/authority.ts +14 -5
- package/src/oh/canonical-rust.ts +127 -0
- package/src/oh/projection-rust.ts +63 -0
- package/src/oh-adoption.ts +7 -1
- package/src/publish-graph.ts +0 -0
- package/src/publish-index.ts +195 -0
- package/src/publish-markdown.ts +617 -0
- package/src/publish-model.ts +599 -0
- package/src/publish-nav.ts +204 -0
- package/src/publish-pages.ts +382 -0
- package/src/publish-reader/reader.css +1042 -0
- package/src/publish-reader/reader.ts +1017 -0
- package/src/publish-reader/theme.ts +97 -0
- package/src/publish-search.ts +418 -0
- package/src/publish-select.ts +419 -0
- package/src/publish-theme.ts +106 -0
- package/src/publish.ts +904 -0
- package/src/rerank-credentials.ts +56 -0
- package/src/rerank-typesafe.ts +472 -0
- package/src/rerank.ts +389 -0
- package/src/sdk.ts +157 -6
- package/src/serve.ts +180 -0
- package/src/vault.ts +23 -9
- package/dist/{index-why54q5p.js → index-gm9t95d9.js} +3 -3
|
@@ -3,22 +3,28 @@ import {
|
|
|
3
3
|
backfillSavedUrlMetadata,
|
|
4
4
|
createRustMetadataSearchProvider
|
|
5
5
|
} from "./index-bcknqxrq.js";
|
|
6
|
+
import {
|
|
7
|
+
main as main2
|
|
8
|
+
} from "./index-054mb7d3.js";
|
|
6
9
|
import {
|
|
7
10
|
MAX_AUTHORIZED_VAULTS,
|
|
8
11
|
auditKnowledgePortfolio,
|
|
9
12
|
loadPortfolioRegistry,
|
|
10
13
|
openKnowledgePortfolio,
|
|
11
14
|
snapshotPortfolioRegistry
|
|
12
|
-
} from "./index-
|
|
13
|
-
import {
|
|
14
|
-
main as main2
|
|
15
|
-
} from "./index-054mb7d3.js";
|
|
15
|
+
} from "./index-avbce90h.js";
|
|
16
16
|
import {
|
|
17
17
|
diffCaptureBundle
|
|
18
18
|
} from "./index-j4zgmzjr.js";
|
|
19
|
+
import {
|
|
20
|
+
main
|
|
21
|
+
} from "./index-de2w8crk.js";
|
|
19
22
|
import {
|
|
20
23
|
verifyCaptureBundle
|
|
21
24
|
} from "./index-npg9z1a4.js";
|
|
25
|
+
import {
|
|
26
|
+
redactSensitiveText
|
|
27
|
+
} from "./index-mxxxytys.js";
|
|
22
28
|
import {
|
|
23
29
|
initVault
|
|
24
30
|
} from "./index-23z4zxgg.js";
|
|
@@ -27,18 +33,22 @@ import {
|
|
|
27
33
|
MAX_SOURCE_INBOX_RESULTS,
|
|
28
34
|
sourceInbox
|
|
29
35
|
} from "./index-pj501bh1.js";
|
|
36
|
+
import {
|
|
37
|
+
createTypeSafeReranker
|
|
38
|
+
} from "./index-9rf81m0p.js";
|
|
30
39
|
import {
|
|
31
40
|
knowledgeBaseEvaluationRetrieverIds,
|
|
32
41
|
openKnowledgeBaseEvaluation
|
|
33
|
-
} from "./index-
|
|
42
|
+
} from "./index-e6p9e926.js";
|
|
34
43
|
import {
|
|
35
44
|
DEFAULT_SEARCH_RESULTS,
|
|
36
45
|
MAX_SEARCH_CANDIDATES,
|
|
37
46
|
MAX_SEARCH_NOTE_REFERENCE_BYTES,
|
|
38
47
|
MAX_SEARCH_RELATED_SEEDS,
|
|
39
48
|
MAX_SEARCH_RESULTS,
|
|
40
|
-
openKnowledgeBase
|
|
41
|
-
|
|
49
|
+
openKnowledgeBase,
|
|
50
|
+
searchEvidenceRank
|
|
51
|
+
} from "./index-2hf27mws.js";
|
|
42
52
|
import {
|
|
43
53
|
MAX_SEARCH_RULE_CONFIG_BYTES,
|
|
44
54
|
parseSearchRules
|
|
@@ -49,22 +59,20 @@ import {
|
|
|
49
59
|
recommendedEmbeddingModel,
|
|
50
60
|
recommendedEmbeddingModelSha256,
|
|
51
61
|
sha256EmbeddingModelFile
|
|
52
|
-
} from "./index-
|
|
53
|
-
import {
|
|
54
|
-
percolateWithGraph
|
|
55
|
-
} from "./index-bgfzwt4h.js";
|
|
62
|
+
} from "./index-hcw140eb.js";
|
|
56
63
|
import {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
verifyGraph
|
|
60
|
-
} from "./index-bcfn9xah.js";
|
|
64
|
+
MAX_RERANK_CANDIDATES
|
|
65
|
+
} from "./index-j70m75wd.js";
|
|
61
66
|
import {
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
MAX_EVALUATION_RESULTS_PER_QUERY,
|
|
68
|
+
MAX_EVALUATION_TIMEOUT_MS,
|
|
69
|
+
buildRetrievalEvaluationReport,
|
|
70
|
+
parseRetrievalEvaluationCorpus,
|
|
71
|
+
runRetrievalEvaluation
|
|
72
|
+
} from "./index-b88v3vtm.js";
|
|
64
73
|
import {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
} from "./index-0k2x4nn9.js";
|
|
74
|
+
percolateWithGraph
|
|
75
|
+
} from "./index-t2bs9xdr.js";
|
|
68
76
|
import {
|
|
69
77
|
MAX_PERCOLATION_MENTIONS,
|
|
70
78
|
MAX_PERCOLATION_MENTION_PAIRS,
|
|
@@ -73,26 +81,33 @@ import {
|
|
|
73
81
|
percolateVault
|
|
74
82
|
} from "./index-nd6nynv2.js";
|
|
75
83
|
import {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
runRetrievalEvaluation
|
|
81
|
-
} from "./index-b88v3vtm.js";
|
|
84
|
+
queryGraph,
|
|
85
|
+
rebuildGraph,
|
|
86
|
+
verifyGraph
|
|
87
|
+
} from "./index-famy7fhs.js";
|
|
82
88
|
import {
|
|
83
|
-
|
|
84
|
-
} from "./index-
|
|
89
|
+
validateGraphQueryRequest
|
|
90
|
+
} from "./index-11621h23.js";
|
|
85
91
|
import {
|
|
86
|
-
|
|
87
|
-
} from "./index-
|
|
92
|
+
validateSearchQuery
|
|
93
|
+
} from "./index-gm9t95d9.js";
|
|
88
94
|
import {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
} from "./index-6sw24nvv.js";
|
|
95
|
+
sanitizeTerminalLine,
|
|
96
|
+
sanitizeTerminalText
|
|
97
|
+
} from "./index-1xxnjn0d.js";
|
|
93
98
|
import {
|
|
94
|
-
|
|
95
|
-
|
|
99
|
+
DEFAULT_PUBLISH_LIST_LIMIT,
|
|
100
|
+
MAX_PUBLISH_LIST_LIMIT,
|
|
101
|
+
publishVault,
|
|
102
|
+
renderPublishReportText
|
|
103
|
+
} from "./index-0dqfnrz9.js";
|
|
104
|
+
import {
|
|
105
|
+
refreshVault,
|
|
106
|
+
scanVault
|
|
107
|
+
} from "./index-1tm7bgx7.js";
|
|
108
|
+
import {
|
|
109
|
+
navigateLinks
|
|
110
|
+
} from "./index-d13v9ckt.js";
|
|
96
111
|
import {
|
|
97
112
|
MAX_QUERY_FILTERS,
|
|
98
113
|
MAX_QUERY_TAGS,
|
|
@@ -105,8 +120,11 @@ import {
|
|
|
105
120
|
repositoryMemoryGroupKeys
|
|
106
121
|
} from "./index-06c9ctr6.js";
|
|
107
122
|
import {
|
|
108
|
-
|
|
109
|
-
} from "./index-
|
|
123
|
+
findKbPackageRoot
|
|
124
|
+
} from "./index-4knsp9qj.js";
|
|
125
|
+
import {
|
|
126
|
+
auditAgentGuideRepository
|
|
127
|
+
} from "./index-hya40gb2.js";
|
|
110
128
|
import {
|
|
111
129
|
agentContextGuidePath,
|
|
112
130
|
agentContextMarkerForScope,
|
|
@@ -116,24 +134,19 @@ import {
|
|
|
116
134
|
inspectAgentContextRepository,
|
|
117
135
|
normalizeRepositoryScope
|
|
118
136
|
} from "./index-5vwpzb5a.js";
|
|
137
|
+
import {
|
|
138
|
+
validateMarkdownAttachments
|
|
139
|
+
} from "./index-x3fthpsc.js";
|
|
140
|
+
import {
|
|
141
|
+
addNoteRelation,
|
|
142
|
+
createNote,
|
|
143
|
+
removeNoteRelation
|
|
144
|
+
} from "./index-6sw24nvv.js";
|
|
119
145
|
import {
|
|
120
146
|
lookupNote,
|
|
121
147
|
parseVaultKey,
|
|
122
148
|
renderCatalog
|
|
123
149
|
} from "./index-ekpwvbra.js";
|
|
124
|
-
import {
|
|
125
|
-
main
|
|
126
|
-
} from "./index-9zcpdbjg.js";
|
|
127
|
-
import {
|
|
128
|
-
findKbPackageRoot
|
|
129
|
-
} from "./index-jzcws0zn.js";
|
|
130
|
-
import {
|
|
131
|
-
redactSensitiveText
|
|
132
|
-
} from "./index-mxxxytys.js";
|
|
133
|
-
import {
|
|
134
|
-
sanitizeTerminalLine,
|
|
135
|
-
sanitizeTerminalText
|
|
136
|
-
} from "./index-1xxnjn0d.js";
|
|
137
150
|
|
|
138
151
|
// src/clip/url-metadata-cli.ts
|
|
139
152
|
import { resolve as resolve2 } from "path";
|
|
@@ -800,7 +813,7 @@ function terminalIntro(terminal) {
|
|
|
800
813
|
}
|
|
801
814
|
|
|
802
815
|
// src/cli-program.ts
|
|
803
|
-
import { open } from "fs/promises";
|
|
816
|
+
import { open as open2 } from "fs/promises";
|
|
804
817
|
import { cpus, release, totalmem } from "os";
|
|
805
818
|
import { relative, resolve as resolve3 } from "path";
|
|
806
819
|
import { format } from "util";
|
|
@@ -905,13 +918,197 @@ Snapshot: ${value.revision}
|
|
|
905
918
|
};
|
|
906
919
|
}
|
|
907
920
|
|
|
921
|
+
// src/serve.ts
|
|
922
|
+
import { realpath, stat } from "fs/promises";
|
|
923
|
+
import { join as join2, sep } from "path";
|
|
924
|
+
var MAX_PATH_BYTES = 8 * 1024;
|
|
925
|
+
var CONTENT_TYPES = Object.freeze({
|
|
926
|
+
".avif": "image/avif",
|
|
927
|
+
".css": "text/css; charset=utf-8",
|
|
928
|
+
".gif": "image/gif",
|
|
929
|
+
".html": "text/html; charset=utf-8",
|
|
930
|
+
".ico": "image/x-icon",
|
|
931
|
+
".jpeg": "image/jpeg",
|
|
932
|
+
".jpg": "image/jpeg",
|
|
933
|
+
".js": "text/javascript; charset=utf-8",
|
|
934
|
+
".json": "application/json; charset=utf-8",
|
|
935
|
+
".map": "application/json; charset=utf-8",
|
|
936
|
+
".mp3": "audio/mpeg",
|
|
937
|
+
".mp4": "video/mp4",
|
|
938
|
+
".pdf": "application/pdf",
|
|
939
|
+
".png": "image/png",
|
|
940
|
+
".svg": "image/svg+xml",
|
|
941
|
+
".txt": "text/plain; charset=utf-8",
|
|
942
|
+
".wasm": "application/wasm",
|
|
943
|
+
".wav": "audio/wav",
|
|
944
|
+
".webm": "video/webm",
|
|
945
|
+
".webp": "image/webp",
|
|
946
|
+
".woff": "font/woff",
|
|
947
|
+
".woff2": "font/woff2",
|
|
948
|
+
".xml": "application/xml; charset=utf-8"
|
|
949
|
+
});
|
|
950
|
+
function contentType(path) {
|
|
951
|
+
const extension = path.slice(path.lastIndexOf("."));
|
|
952
|
+
return CONTENT_TYPES[extension] ?? "application/octet-stream";
|
|
953
|
+
}
|
|
954
|
+
async function regularFileUnder(rootReal, candidate) {
|
|
955
|
+
let resolved;
|
|
956
|
+
try {
|
|
957
|
+
resolved = await realpath(candidate);
|
|
958
|
+
} catch {
|
|
959
|
+
return null;
|
|
960
|
+
}
|
|
961
|
+
if (resolved !== rootReal && !resolved.startsWith(`${rootReal}${sep}`))
|
|
962
|
+
return null;
|
|
963
|
+
try {
|
|
964
|
+
return (await stat(resolved)).isFile() ? resolved : null;
|
|
965
|
+
} catch {
|
|
966
|
+
return null;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
async function resolveRequest(rootReal, pathname) {
|
|
970
|
+
let decoded;
|
|
971
|
+
try {
|
|
972
|
+
decoded = decodeURIComponent(pathname);
|
|
973
|
+
} catch {
|
|
974
|
+
return null;
|
|
975
|
+
}
|
|
976
|
+
if (decoded.includes("\x00") || decoded.includes("\\"))
|
|
977
|
+
return null;
|
|
978
|
+
const segments = decoded.split("/").filter((segment) => segment !== "" && segment !== ".");
|
|
979
|
+
if (segments.some((segment) => segment === ".."))
|
|
980
|
+
return null;
|
|
981
|
+
const relative = segments.join("/");
|
|
982
|
+
const candidates = [
|
|
983
|
+
join2(rootReal, relative),
|
|
984
|
+
join2(rootReal, relative, "index.html")
|
|
985
|
+
];
|
|
986
|
+
for (const candidate of candidates) {
|
|
987
|
+
const file = await regularFileUnder(rootReal, candidate);
|
|
988
|
+
if (file !== null)
|
|
989
|
+
return file;
|
|
990
|
+
}
|
|
991
|
+
return null;
|
|
992
|
+
}
|
|
993
|
+
async function createServeHandler(root) {
|
|
994
|
+
const rootReal = await realpath(root);
|
|
995
|
+
return async (request) => {
|
|
996
|
+
const method = request.method.toUpperCase();
|
|
997
|
+
if (method !== "GET" && method !== "HEAD") {
|
|
998
|
+
return new Response("Method not allowed", { status: 405 });
|
|
999
|
+
}
|
|
1000
|
+
let pathname;
|
|
1001
|
+
try {
|
|
1002
|
+
pathname = new URL(request.url).pathname;
|
|
1003
|
+
} catch {
|
|
1004
|
+
return new Response("Bad request", { status: 400 });
|
|
1005
|
+
}
|
|
1006
|
+
if (pathname.length > MAX_PATH_BYTES) {
|
|
1007
|
+
return new Response("URI too long", { status: 414 });
|
|
1008
|
+
}
|
|
1009
|
+
const head = method === "HEAD";
|
|
1010
|
+
const file = await resolveRequest(rootReal, pathname);
|
|
1011
|
+
if (file !== null) {
|
|
1012
|
+
const body = Bun.file(file);
|
|
1013
|
+
return new Response(head ? null : body, {
|
|
1014
|
+
headers: {
|
|
1015
|
+
"Cache-Control": "no-store",
|
|
1016
|
+
"Content-Length": String(body.size),
|
|
1017
|
+
"Content-Type": contentType(file)
|
|
1018
|
+
}
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
const notFound = await regularFileUnder(rootReal, join2(rootReal, "404.html"));
|
|
1022
|
+
if (notFound !== null) {
|
|
1023
|
+
const body = Bun.file(notFound);
|
|
1024
|
+
return new Response(head ? null : body, {
|
|
1025
|
+
status: 404,
|
|
1026
|
+
headers: {
|
|
1027
|
+
"Cache-Control": "no-store",
|
|
1028
|
+
"Content-Length": String(body.size),
|
|
1029
|
+
"Content-Type": "text/html; charset=utf-8"
|
|
1030
|
+
}
|
|
1031
|
+
});
|
|
1032
|
+
}
|
|
1033
|
+
return new Response(head ? null : "Not found", {
|
|
1034
|
+
status: 404,
|
|
1035
|
+
headers: { "Cache-Control": "no-store" }
|
|
1036
|
+
});
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
1039
|
+
async function serveSite(options, io = {}) {
|
|
1040
|
+
const host = options.host ?? "127.0.0.1";
|
|
1041
|
+
const port = options.port ?? 8080;
|
|
1042
|
+
if (!Number.isSafeInteger(port) || port < 0 || port > 65535) {
|
|
1043
|
+
throw new Error("Port must be an integer from 0 through 65535");
|
|
1044
|
+
}
|
|
1045
|
+
const rootReal = await realpath(options.root);
|
|
1046
|
+
if (!(await stat(rootReal)).isDirectory()) {
|
|
1047
|
+
throw new Error(`Site root is not a directory: ${options.root}`);
|
|
1048
|
+
}
|
|
1049
|
+
const listen = io.listen ?? ((init) => Bun.serve(init));
|
|
1050
|
+
const server = listen({
|
|
1051
|
+
hostname: host,
|
|
1052
|
+
port,
|
|
1053
|
+
fetch: await createServeHandler(rootReal)
|
|
1054
|
+
});
|
|
1055
|
+
const boundPort = server.port ?? port;
|
|
1056
|
+
return Object.freeze({
|
|
1057
|
+
root: rootReal,
|
|
1058
|
+
host,
|
|
1059
|
+
port: boundPort,
|
|
1060
|
+
url: `http://${host}:${String(boundPort)}/`,
|
|
1061
|
+
close: () => server.stop()
|
|
1062
|
+
});
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
// src/rerank-credentials.ts
|
|
1066
|
+
import { constants as constants2 } from "fs";
|
|
1067
|
+
import { open } from "fs/promises";
|
|
1068
|
+
import { homedir } from "os";
|
|
1069
|
+
import { isAbsolute as isAbsolute2, join as join3 } from "path";
|
|
1070
|
+
function unavailable(message) {
|
|
1071
|
+
return { id: "typesafe", rerank: async () => ({ status: "unavailable", message }) };
|
|
1072
|
+
}
|
|
1073
|
+
async function createCliTypeSafeReranker(environment = process.env, homeDirectory = homedir()) {
|
|
1074
|
+
if (Object.hasOwn(environment, "TYPESAFE_API_KEY")) {
|
|
1075
|
+
return createTypeSafeReranker({ environment: { TYPESAFE_API_KEY: environment["TYPESAFE_API_KEY"] } });
|
|
1076
|
+
}
|
|
1077
|
+
const explicitFile = environment["TYPESAFE_API_KEY_FILE"];
|
|
1078
|
+
const configDirectory = environment["XDG_CONFIG_HOME"];
|
|
1079
|
+
if (explicitFile !== undefined && !isAbsolute2(explicitFile) || configDirectory !== undefined && configDirectory !== "" && !isAbsolute2(configDirectory)) {
|
|
1080
|
+
return unavailable("TypeSafe credential file configuration requires absolute paths.");
|
|
1081
|
+
}
|
|
1082
|
+
const path = explicitFile ?? join3(configDirectory || join3(homeDirectory, ".config"), "wordcell", "typesafe-api-key");
|
|
1083
|
+
let handle;
|
|
1084
|
+
try {
|
|
1085
|
+
handle = await open(path, constants2.O_RDONLY | constants2.O_NOFOLLOW | constants2.O_NONBLOCK);
|
|
1086
|
+
const metadata = await handle.stat();
|
|
1087
|
+
const uid = process.getuid?.();
|
|
1088
|
+
if (!metadata.isFile() || metadata.nlink !== 1 || metadata.size < 1 || metadata.size > 514 || process.platform !== "win32" && ((metadata.mode & 63) !== 0 || metadata.uid !== uid)) {
|
|
1089
|
+
return unavailable("TypeSafe credential file must be an owner-only regular file containing one API key.");
|
|
1090
|
+
}
|
|
1091
|
+
const bytes = Buffer.alloc(515);
|
|
1092
|
+
const { bytesRead } = await handle.read(bytes, 0, bytes.length, 0);
|
|
1093
|
+
const key = bytes.subarray(0, bytesRead).toString("utf8").replace(/\r?\n$/u, "");
|
|
1094
|
+
if (!/^[\x21-\x7e]{1,512}$/u.test(key)) {
|
|
1095
|
+
return unavailable("TypeSafe credential file must contain one valid API key.");
|
|
1096
|
+
}
|
|
1097
|
+
return createTypeSafeReranker({ environment: { TYPESAFE_API_KEY: key } });
|
|
1098
|
+
} catch {
|
|
1099
|
+
return unavailable("TypeSafe credentials are unavailable; set TYPESAFE_API_KEY or an owner-only TYPESAFE_API_KEY_FILE.");
|
|
1100
|
+
} finally {
|
|
1101
|
+
await handle?.close();
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
908
1105
|
// src/cli-program.ts
|
|
909
1106
|
var defaultOutput2 = {
|
|
910
1107
|
stdout: (value) => process.stdout.write(value),
|
|
911
1108
|
stderr: (value) => process.stderr.write(value)
|
|
912
1109
|
};
|
|
913
1110
|
async function readBoundedUtf8(path, maximumBytes, label) {
|
|
914
|
-
const handle = await
|
|
1111
|
+
const handle = await open2(path, "r");
|
|
915
1112
|
try {
|
|
916
1113
|
const bytes = new Uint8Array(maximumBytes + 1);
|
|
917
1114
|
let offset = 0;
|
|
@@ -943,7 +1140,16 @@ async function loadSearchRulesFile(path) {
|
|
|
943
1140
|
}
|
|
944
1141
|
return parseSearchRules(input);
|
|
945
1142
|
}
|
|
946
|
-
var usage = `wordcell \u2014
|
|
1143
|
+
var usage = `wordcell \u2014 a local knowledge base for coding agents
|
|
1144
|
+
|
|
1145
|
+
Start here (no account or model needed):
|
|
1146
|
+
wordcell init kb
|
|
1147
|
+
wordcell note create notes/decision --title "A decision" --body "Keep retries bounded." --root kb
|
|
1148
|
+
wordcell search "retries" --root kb --mode exact
|
|
1149
|
+
|
|
1150
|
+
Already have Markdown? Search it with --root <your-notes-directory>.
|
|
1151
|
+
Use --mode exact for model-free search; optional hybrid search needs a local index.
|
|
1152
|
+
Quick start and examples: https://wordcell.io/docs
|
|
947
1153
|
|
|
948
1154
|
Usage:
|
|
949
1155
|
wordcell init [directory] [--json]
|
|
@@ -971,12 +1177,14 @@ Usage:
|
|
|
971
1177
|
wordcell percolate [note] [--proofs] [--root <directory>] [--min-support <count>] [--limit <count>] [--json]
|
|
972
1178
|
wordcell list [--root <directory>] [--where <path=value>] [--has <path>] [--tag <tag>] [--scope <repository-path>] [--sort <field>] [--order <asc|desc>] [--limit <count>] [--json]
|
|
973
1179
|
wordcell index [--root <directory>] [--database <path>] [--force] [--json]
|
|
974
|
-
wordcell search <query> [--root <directory>] [--repo <repository>] [--database <path>] [--mode <hybrid|exact|keyword|semantic>] [--rules <file>] [--priority] [--where <path=value>] [--has <path>] [--tag <tag>] [--scope <repository-path>] [--related <note>] [--graph-depth <1|2>] [--no-graph] [--history | --no-history | --require-history] [--limit <count>] [--candidate-limit <count>] [--min-score <score>] [--json]
|
|
1180
|
+
wordcell search <query> [--root <directory>] [--repo <repository>] [--database <path>] [--mode <hybrid|exact|keyword|semantic>] [--rules <file>] [--priority] [--where <path=value>] [--has <path>] [--tag <tag>] [--scope <repository-path>] [--related <note>] [--graph-depth <1|2>] [--no-graph] [--history | --no-history | --require-history] [--limit <count>] [--candidate-limit <count>] [--min-score <score>] [--rerank <typesafe>] [--rerank-limit <2..25>] [--json]
|
|
975
1181
|
wordcell history <note> [--root <directory>] [--repo <repository>] [--limit <count>] [--cochanged-limit <count>] [--json]
|
|
976
1182
|
wordcell history search <query-or-path> [--root <directory>] [--repo <repository>] [--limit <count>] [--commit-limit <count>] [--cochanged-limit <count>] [--json]
|
|
977
1183
|
wordcell evaluate <manifest.json> [--root <directory>] [--repo <repository>] [--database <path>] [--retriever <id>] [--split <development|test|all>] [--limit <count>] [--cutoff <count>] [--timeout <milliseconds>] [--baseline <id>] [--model-file <path>] [--cache-state <cold|mixed|warm>] [--json]
|
|
978
1184
|
wordcell portfolio search <query> --registry <file> --workspace <directory> (--shared | --vault <owner/id>...) [--mode <hybrid|exact|keyword|semantic>] [--rules <file>] [--priority] [--limit <count>] [--require-all] [--json]
|
|
979
1185
|
wordcell portfolio audit --registry <file> --workspace <directory> (--all | --shared | --vault <owner/id>...) [--strict] [--json]
|
|
1186
|
+
wordcell publish --out <directory> [--root <directory>] [--index <path>] [--include <path>]... [--exclude <path>]... [--include-glob <pattern>]... [--exclude-glob <pattern>]... [--where <path=value>]... [--has <path>]... [--tag <tag>]... [--scope <repository-path>]... [--from <note> [--depth <count>] [--direction <in|out|both>]] [--title <title>] [--description <text>] [--base-path <path>] [--base-url <url>] [--noindex] [--no-index-content] [--deterministic] [--dry-run] [--list-limit <0-1000>] [--force] [--json]
|
|
1187
|
+
wordcell serve --root <directory> [--host <host>] [--port <port>] [--json]
|
|
980
1188
|
wordcell inbox [--root <directory>] [--source-prefix <directory>] [--limit <count>] [--json]
|
|
981
1189
|
wordcell context <repository-path> [--root <vault>] [--repo <repository>] [--kind <auto|file|directory>] [--json]
|
|
982
1190
|
wordcell agents identity <repository-scope> [--json]
|
|
@@ -1367,6 +1575,220 @@ function parseListCommand(arguments_) {
|
|
|
1367
1575
|
}
|
|
1368
1576
|
};
|
|
1369
1577
|
}
|
|
1578
|
+
function parsePublishCommand(arguments_) {
|
|
1579
|
+
let root = ".";
|
|
1580
|
+
let out;
|
|
1581
|
+
let index;
|
|
1582
|
+
let title;
|
|
1583
|
+
let description;
|
|
1584
|
+
let basePath;
|
|
1585
|
+
let baseUrl;
|
|
1586
|
+
let noindex = false;
|
|
1587
|
+
let indexContent = true;
|
|
1588
|
+
let deterministic = false;
|
|
1589
|
+
let dryRun = false;
|
|
1590
|
+
let listLimit = DEFAULT_PUBLISH_LIST_LIMIT;
|
|
1591
|
+
let force = false;
|
|
1592
|
+
let json = false;
|
|
1593
|
+
let from;
|
|
1594
|
+
let depth = 1;
|
|
1595
|
+
let direction = "both";
|
|
1596
|
+
const includes = [];
|
|
1597
|
+
const excludes = [];
|
|
1598
|
+
const includeGlobs = [];
|
|
1599
|
+
const excludeGlobs = [];
|
|
1600
|
+
const filters = [];
|
|
1601
|
+
const tags = [];
|
|
1602
|
+
const repositoryScopes = [];
|
|
1603
|
+
for (let cursor = 0;cursor < arguments_.length; cursor += 1) {
|
|
1604
|
+
const argument = arguments_[cursor];
|
|
1605
|
+
if (argument === undefined)
|
|
1606
|
+
continue;
|
|
1607
|
+
if (argument === "--json") {
|
|
1608
|
+
json = true;
|
|
1609
|
+
continue;
|
|
1610
|
+
}
|
|
1611
|
+
if (argument === "--noindex") {
|
|
1612
|
+
noindex = true;
|
|
1613
|
+
continue;
|
|
1614
|
+
}
|
|
1615
|
+
if (argument === "--no-index-content") {
|
|
1616
|
+
indexContent = false;
|
|
1617
|
+
continue;
|
|
1618
|
+
}
|
|
1619
|
+
if (argument === "--deterministic") {
|
|
1620
|
+
deterministic = true;
|
|
1621
|
+
continue;
|
|
1622
|
+
}
|
|
1623
|
+
if (argument === "--dry-run") {
|
|
1624
|
+
dryRun = true;
|
|
1625
|
+
continue;
|
|
1626
|
+
}
|
|
1627
|
+
if (argument === "--force") {
|
|
1628
|
+
force = true;
|
|
1629
|
+
continue;
|
|
1630
|
+
}
|
|
1631
|
+
if (argument === "--root" || argument === "--out" || argument === "--index" || argument === "--title" || argument === "--description" || argument === "--base-path" || argument === "--base-url" || argument === "--include" || argument === "--exclude" || argument === "--include-glob" || argument === "--exclude-glob" || argument === "--list-limit" || argument === "--where" || argument === "--has" || argument === "--tag" || argument === "--scope" || argument === "--repository-scope" || argument === "--from" || argument === "--depth" || argument === "--direction") {
|
|
1632
|
+
const value = readValue(arguments_, cursor);
|
|
1633
|
+
if (value === null)
|
|
1634
|
+
return { ok: false, message: `${argument} requires a value` };
|
|
1635
|
+
if (argument === "--root")
|
|
1636
|
+
root = value;
|
|
1637
|
+
else if (argument === "--out")
|
|
1638
|
+
out = value;
|
|
1639
|
+
else if (argument === "--index")
|
|
1640
|
+
index = value;
|
|
1641
|
+
else if (argument === "--title")
|
|
1642
|
+
title = value;
|
|
1643
|
+
else if (argument === "--description")
|
|
1644
|
+
description = value;
|
|
1645
|
+
else if (argument === "--base-path")
|
|
1646
|
+
basePath = value;
|
|
1647
|
+
else if (argument === "--base-url")
|
|
1648
|
+
baseUrl = value;
|
|
1649
|
+
else if (argument === "--include")
|
|
1650
|
+
includes.push(value);
|
|
1651
|
+
else if (argument === "--exclude")
|
|
1652
|
+
excludes.push(value);
|
|
1653
|
+
else if (argument === "--include-glob")
|
|
1654
|
+
includeGlobs.push(value);
|
|
1655
|
+
else if (argument === "--exclude-glob")
|
|
1656
|
+
excludeGlobs.push(value);
|
|
1657
|
+
else if (argument === "--list-limit") {
|
|
1658
|
+
if (!/^(0|[1-9][0-9]*)$/u.test(value) || Number(value) > MAX_PUBLISH_LIST_LIMIT) {
|
|
1659
|
+
return { ok: false, message: `--list-limit must be an integer from 0 through ${MAX_PUBLISH_LIST_LIMIT}` };
|
|
1660
|
+
}
|
|
1661
|
+
listLimit = Number(value);
|
|
1662
|
+
} else if (argument === "--from")
|
|
1663
|
+
from = value;
|
|
1664
|
+
else if (argument === "--depth") {
|
|
1665
|
+
const parsed = Number(value);
|
|
1666
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > 10) {
|
|
1667
|
+
return { ok: false, message: "--depth must be an integer from 1 through 10" };
|
|
1668
|
+
}
|
|
1669
|
+
depth = parsed;
|
|
1670
|
+
} else if (argument === "--direction") {
|
|
1671
|
+
if (value !== "in" && value !== "out" && value !== "both") {
|
|
1672
|
+
return { ok: false, message: "--direction must be in, out, or both" };
|
|
1673
|
+
}
|
|
1674
|
+
direction = value;
|
|
1675
|
+
} else if (argument === "--tag") {
|
|
1676
|
+
if (tags.length >= MAX_QUERY_TAGS) {
|
|
1677
|
+
return { ok: false, message: `Query tags may contain at most ${MAX_QUERY_TAGS} entries.` };
|
|
1678
|
+
}
|
|
1679
|
+
tags.push(value);
|
|
1680
|
+
} else if (argument === "--scope" || argument === "--repository-scope") {
|
|
1681
|
+
if (repositoryScopes.length >= MAX_REPOSITORY_SCOPES) {
|
|
1682
|
+
return { ok: false, message: `Repository scope filters may contain at most ${MAX_REPOSITORY_SCOPES} entries.` };
|
|
1683
|
+
}
|
|
1684
|
+
repositoryScopes.push(value);
|
|
1685
|
+
} else if (argument === "--has") {
|
|
1686
|
+
if (value.trim() === "")
|
|
1687
|
+
return { ok: false, message: "--has requires a metadata path" };
|
|
1688
|
+
if (filters.length >= MAX_QUERY_FILTERS) {
|
|
1689
|
+
return { ok: false, message: `Query filters may contain at most ${MAX_QUERY_FILTERS} entries.` };
|
|
1690
|
+
}
|
|
1691
|
+
filters.push({ kind: "exists", path: value });
|
|
1692
|
+
} else {
|
|
1693
|
+
const equals = value.indexOf("=");
|
|
1694
|
+
const path = equals === -1 ? "" : value.slice(0, equals).trim();
|
|
1695
|
+
if (path === "")
|
|
1696
|
+
return { ok: false, message: "--where requires path=value" };
|
|
1697
|
+
const scalar = metadataScalar(value.slice(equals + 1));
|
|
1698
|
+
if (!scalar.ok)
|
|
1699
|
+
return scalar;
|
|
1700
|
+
if (filters.length >= MAX_QUERY_FILTERS) {
|
|
1701
|
+
return { ok: false, message: `Query filters may contain at most ${MAX_QUERY_FILTERS} entries.` };
|
|
1702
|
+
}
|
|
1703
|
+
filters.push({ kind: "equals", path, value: scalar.value });
|
|
1704
|
+
}
|
|
1705
|
+
cursor += 1;
|
|
1706
|
+
continue;
|
|
1707
|
+
}
|
|
1708
|
+
return {
|
|
1709
|
+
ok: false,
|
|
1710
|
+
message: argument.startsWith("--") ? "unknown publish option" : "publish does not accept positional arguments"
|
|
1711
|
+
};
|
|
1712
|
+
}
|
|
1713
|
+
if (out === undefined)
|
|
1714
|
+
return { ok: false, message: "publish requires --out <directory>" };
|
|
1715
|
+
try {
|
|
1716
|
+
validateQueryOptions({ filters, tags, repositoryScopes });
|
|
1717
|
+
} catch (error) {
|
|
1718
|
+
return { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
1719
|
+
}
|
|
1720
|
+
const selection = {
|
|
1721
|
+
includes,
|
|
1722
|
+
excludes,
|
|
1723
|
+
includeGlobs,
|
|
1724
|
+
excludeGlobs,
|
|
1725
|
+
filters,
|
|
1726
|
+
tags,
|
|
1727
|
+
repositoryScopes,
|
|
1728
|
+
...from === undefined ? {} : { from: { note: from, depth, direction } }
|
|
1729
|
+
};
|
|
1730
|
+
return {
|
|
1731
|
+
ok: true,
|
|
1732
|
+
value: {
|
|
1733
|
+
kind: "publish",
|
|
1734
|
+
root,
|
|
1735
|
+
out,
|
|
1736
|
+
noindex,
|
|
1737
|
+
indexContent,
|
|
1738
|
+
deterministic,
|
|
1739
|
+
dryRun,
|
|
1740
|
+
listLimit,
|
|
1741
|
+
force,
|
|
1742
|
+
selection,
|
|
1743
|
+
json,
|
|
1744
|
+
...index === undefined ? {} : { index },
|
|
1745
|
+
...title === undefined ? {} : { title },
|
|
1746
|
+
...description === undefined ? {} : { description },
|
|
1747
|
+
...basePath === undefined ? {} : { basePath },
|
|
1748
|
+
...baseUrl === undefined ? {} : { baseUrl }
|
|
1749
|
+
}
|
|
1750
|
+
};
|
|
1751
|
+
}
|
|
1752
|
+
function parseServeCommand(arguments_) {
|
|
1753
|
+
let root;
|
|
1754
|
+
let host = "127.0.0.1";
|
|
1755
|
+
let port = 8080;
|
|
1756
|
+
let json = false;
|
|
1757
|
+
for (let cursor = 0;cursor < arguments_.length; cursor += 1) {
|
|
1758
|
+
const argument = arguments_[cursor];
|
|
1759
|
+
if (argument === undefined)
|
|
1760
|
+
continue;
|
|
1761
|
+
if (argument === "--json") {
|
|
1762
|
+
json = true;
|
|
1763
|
+
continue;
|
|
1764
|
+
}
|
|
1765
|
+
if (argument === "--root" || argument === "--host" || argument === "--port") {
|
|
1766
|
+
const value = readValue(arguments_, cursor);
|
|
1767
|
+
if (value === null)
|
|
1768
|
+
return { ok: false, message: `${argument} requires a value` };
|
|
1769
|
+
if (argument === "--root")
|
|
1770
|
+
root = value;
|
|
1771
|
+
else if (argument === "--host")
|
|
1772
|
+
host = value;
|
|
1773
|
+
else {
|
|
1774
|
+
const parsed = Number(value);
|
|
1775
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0 || parsed > 65535) {
|
|
1776
|
+
return { ok: false, message: "--port must be an integer from 0 through 65535" };
|
|
1777
|
+
}
|
|
1778
|
+
port = parsed;
|
|
1779
|
+
}
|
|
1780
|
+
cursor += 1;
|
|
1781
|
+
continue;
|
|
1782
|
+
}
|
|
1783
|
+
return {
|
|
1784
|
+
ok: false,
|
|
1785
|
+
message: argument.startsWith("--") ? "unknown serve option" : "serve does not accept positional arguments"
|
|
1786
|
+
};
|
|
1787
|
+
}
|
|
1788
|
+
if (root === undefined)
|
|
1789
|
+
return { ok: false, message: "serve requires --root <directory>" };
|
|
1790
|
+
return { ok: true, value: { kind: "serve", root, host, port, json } };
|
|
1791
|
+
}
|
|
1370
1792
|
function parseInboxCommand(arguments_) {
|
|
1371
1793
|
let root = ".";
|
|
1372
1794
|
let index;
|
|
@@ -1439,6 +1861,8 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
1439
1861
|
let limit;
|
|
1440
1862
|
let candidateLimit;
|
|
1441
1863
|
let minScore;
|
|
1864
|
+
let rerank;
|
|
1865
|
+
let rerankLimit;
|
|
1442
1866
|
let graphDepth;
|
|
1443
1867
|
let noGraph = false;
|
|
1444
1868
|
let history = false;
|
|
@@ -1496,7 +1920,7 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
1496
1920
|
cursor += 1;
|
|
1497
1921
|
continue;
|
|
1498
1922
|
}
|
|
1499
|
-
if (command === "search" && (argument === "--mode" || argument === "--limit" || argument === "--candidate-limit" || argument === "--min-score" || argument === "--where" || argument === "--has" || argument === "--tag" || argument === "--scope" || argument === "--repository-scope" || argument === "--related" || argument === "--graph-depth")) {
|
|
1923
|
+
if (command === "search" && (argument === "--mode" || argument === "--limit" || argument === "--candidate-limit" || argument === "--min-score" || argument === "--rerank" || argument === "--rerank-limit" || argument === "--where" || argument === "--has" || argument === "--tag" || argument === "--scope" || argument === "--repository-scope" || argument === "--related" || argument === "--graph-depth")) {
|
|
1500
1924
|
const value = readValue(arguments_, cursor);
|
|
1501
1925
|
if (value === null)
|
|
1502
1926
|
return { ok: false, message: `${argument} requires a value` };
|
|
@@ -1505,6 +1929,17 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
1505
1929
|
return { ok: false, message: "--mode must be hybrid, exact, keyword, or semantic" };
|
|
1506
1930
|
}
|
|
1507
1931
|
mode = value;
|
|
1932
|
+
} else if (argument === "--rerank") {
|
|
1933
|
+
if (value !== "typesafe") {
|
|
1934
|
+
return { ok: false, message: "--rerank must be typesafe" };
|
|
1935
|
+
}
|
|
1936
|
+
rerank = value;
|
|
1937
|
+
} else if (argument === "--rerank-limit") {
|
|
1938
|
+
const parsed = Number(value);
|
|
1939
|
+
if (!Number.isSafeInteger(parsed) || parsed < 2 || parsed > MAX_RERANK_CANDIDATES) {
|
|
1940
|
+
return { ok: false, message: `--rerank-limit must be an integer from 2 through ${MAX_RERANK_CANDIDATES}` };
|
|
1941
|
+
}
|
|
1942
|
+
rerankLimit = parsed;
|
|
1508
1943
|
} else if (argument === "--where") {
|
|
1509
1944
|
const equals = value.indexOf("=");
|
|
1510
1945
|
const path = equals === -1 ? "" : value.slice(0, equals).trim();
|
|
@@ -1637,6 +2072,9 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
1637
2072
|
message: "Search minimum score applies only to hybrid, keyword, or semantic mode."
|
|
1638
2073
|
};
|
|
1639
2074
|
}
|
|
2075
|
+
if (rerankLimit !== undefined && rerank === undefined) {
|
|
2076
|
+
return { ok: false, message: "--rerank-limit requires --rerank typesafe" };
|
|
2077
|
+
}
|
|
1640
2078
|
if (priority && rulesPath === undefined) {
|
|
1641
2079
|
return { ok: false, message: "--priority requires --rules" };
|
|
1642
2080
|
}
|
|
@@ -1674,6 +2112,8 @@ function parseSemanticCommand(command, arguments_) {
|
|
|
1674
2112
|
...limit === undefined ? {} : { limit },
|
|
1675
2113
|
...candidateLimit === undefined ? {} : { candidateLimit },
|
|
1676
2114
|
...minScore === undefined ? {} : { minScore },
|
|
2115
|
+
...rerank === undefined ? {} : { rerank },
|
|
2116
|
+
...rerankLimit === undefined ? {} : { rerankLimit },
|
|
1677
2117
|
query,
|
|
1678
2118
|
json
|
|
1679
2119
|
}
|
|
@@ -2420,6 +2860,10 @@ function parseArguments(arguments_) {
|
|
|
2420
2860
|
return parseRelationCommand(arguments_.slice(1));
|
|
2421
2861
|
if (command === "percolate")
|
|
2422
2862
|
return parsePercolateCommand(arguments_.slice(1));
|
|
2863
|
+
if (command === "publish")
|
|
2864
|
+
return parsePublishCommand(arguments_.slice(1));
|
|
2865
|
+
if (command === "serve")
|
|
2866
|
+
return parseServeCommand(arguments_.slice(1));
|
|
2423
2867
|
return { ok: false, message: "unknown command" };
|
|
2424
2868
|
}
|
|
2425
2869
|
function embeddingCount(result) {
|
|
@@ -2440,11 +2884,23 @@ function renderKnowledgeBaseSearch(result) {
|
|
|
2440
2884
|
const lines = [
|
|
2441
2885
|
`${result.mode[0]?.toLocaleUpperCase("en-US") ?? ""}${result.mode.slice(1)} results for \u201C${safe(result.query)}\u201D (${result.results.length})${result.partial ? " [partial]" : ""}`
|
|
2442
2886
|
];
|
|
2887
|
+
const rerankLane = result.diagnostics.lanes.find(({ lane }) => lane === "rerank");
|
|
2888
|
+
if (rerankLane !== undefined) {
|
|
2889
|
+
lines.push(` Rerank: typesafe over ${rerankLane.results} candidates (${rerankLane.status})` + (rerankLane.message === undefined ? "" : ` \u2014 ${safe(rerankLane.message)}`));
|
|
2890
|
+
const receipt = rerankLane.rerank;
|
|
2891
|
+
if (receipt?.accounting !== undefined) {
|
|
2892
|
+
const { attempted, candidates, completed, elapsedMs, usageComplete } = receipt.accounting;
|
|
2893
|
+
lines.push(` Rerank requests: ${attempted}/${candidates} attempted, ${completed} settled; ${elapsedMs.toFixed(0)} ms` + (usageComplete ? "; usage complete" : "; usage incomplete, additional charges may be unknown"));
|
|
2894
|
+
if (rerankLane.status !== "ready" && receipt.usage !== undefined) {
|
|
2895
|
+
lines.push(` Known rerank usage: ${receipt.usage.inputTokens ?? 0} input tokens, ${receipt.usage.outputTokens ?? 0} output tokens`);
|
|
2896
|
+
}
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2443
2899
|
if (result.results.length === 0)
|
|
2444
2900
|
lines.push(" None.");
|
|
2445
2901
|
for (const hit of result.results) {
|
|
2446
2902
|
const location = `${safe(hit.path)}${hit.line === undefined ? "" : `:${hit.line}`}`;
|
|
2447
|
-
const evidence = hit.evidence.map((item) => `${item.kind}#${item
|
|
2903
|
+
const evidence = hit.evidence.map((item) => `${item.kind}#${searchEvidenceRank(item)}`).join(", ");
|
|
2448
2904
|
lines.push(` ${hit.rank}. ${hit.score.toFixed(3)} ${location} \u2014 ${safe(hit.title)} [${safe(evidence)}]`);
|
|
2449
2905
|
if (hit.snippet !== "")
|
|
2450
2906
|
lines.push(` ${safe(hit.snippet)}`);
|
|
@@ -2476,7 +2932,7 @@ async function runSemantic(command, output, dependencies) {
|
|
|
2476
2932
|
repository: command.repository,
|
|
2477
2933
|
...command.database === undefined ? {} : { database: command.database },
|
|
2478
2934
|
...searchRules === undefined ? {} : { searchRules }
|
|
2479
|
-
});
|
|
2935
|
+
}, ...command.rerank === undefined ? [] : [{ rerankers: dependencies.rerankers ?? [await createCliTypeSafeReranker()] }]);
|
|
2480
2936
|
try {
|
|
2481
2937
|
const result = await kb.search({
|
|
2482
2938
|
query: command.query,
|
|
@@ -2489,7 +2945,13 @@ async function runSemantic(command, output, dependencies) {
|
|
|
2489
2945
|
history: command.history,
|
|
2490
2946
|
...command.limit === undefined ? {} : { limit: command.limit },
|
|
2491
2947
|
...command.candidateLimit === undefined ? {} : { candidateLimit: command.candidateLimit },
|
|
2492
|
-
...command.minScore === undefined ? {} : { minScore: command.minScore }
|
|
2948
|
+
...command.minScore === undefined ? {} : { minScore: command.minScore },
|
|
2949
|
+
...command.rerank === undefined ? {} : {
|
|
2950
|
+
rerank: {
|
|
2951
|
+
engine: command.rerank,
|
|
2952
|
+
...command.rerankLimit === undefined ? {} : { limit: command.rerankLimit }
|
|
2953
|
+
}
|
|
2954
|
+
}
|
|
2493
2955
|
});
|
|
2494
2956
|
output.stdout(command.json ? terminalSafeJson(result) : sanitizeTerminalText(renderKnowledgeBaseSearch(result)));
|
|
2495
2957
|
return 0;
|
|
@@ -3104,6 +3566,36 @@ async function runList(command, output, dependencies) {
|
|
|
3104
3566
|
output.stdout(command.json ? terminalSafeJson({ root: snapshot.root, count: rows.length, notes: rows }) : sanitizeTerminalText(renderList(rows)));
|
|
3105
3567
|
return 0;
|
|
3106
3568
|
}
|
|
3569
|
+
async function runPublish(command, output, dependencies) {
|
|
3570
|
+
const result = await (dependencies.publishVault ?? publishVault)({
|
|
3571
|
+
root: command.root,
|
|
3572
|
+
out: command.out,
|
|
3573
|
+
noindex: command.noindex,
|
|
3574
|
+
indexContent: command.indexContent,
|
|
3575
|
+
deterministic: command.deterministic,
|
|
3576
|
+
dryRun: command.dryRun,
|
|
3577
|
+
listLimit: command.listLimit,
|
|
3578
|
+
force: command.force,
|
|
3579
|
+
selection: command.selection,
|
|
3580
|
+
...command.index === undefined ? {} : { index: command.index },
|
|
3581
|
+
...command.title === undefined ? {} : { title: command.title },
|
|
3582
|
+
...command.description === undefined ? {} : { description: command.description },
|
|
3583
|
+
...command.basePath === undefined ? {} : { basePath: command.basePath },
|
|
3584
|
+
...command.baseUrl === undefined ? {} : { baseUrl: command.baseUrl }
|
|
3585
|
+
});
|
|
3586
|
+
output.stdout(command.json ? terminalSafeJson(result.report) : sanitizeTerminalText(renderPublishReportText(result.report, command.dryRun)));
|
|
3587
|
+
return 0;
|
|
3588
|
+
}
|
|
3589
|
+
async function runServe(command, output, dependencies) {
|
|
3590
|
+
const site = await (dependencies.serveSite ?? serveSite)({
|
|
3591
|
+
root: command.root,
|
|
3592
|
+
host: command.host,
|
|
3593
|
+
port: command.port
|
|
3594
|
+
});
|
|
3595
|
+
output.stdout(command.json ? terminalSafeJson({ root: site.root, host: site.host, port: site.port, url: site.url }) : `Serving ${safe(site.root)} at ${safe(site.url)}
|
|
3596
|
+
`);
|
|
3597
|
+
return 0;
|
|
3598
|
+
}
|
|
3107
3599
|
async function runCatalog(command, output, dependencies) {
|
|
3108
3600
|
const snapshot = await (dependencies.scanVault ?? scanVault)(command.root, command.options);
|
|
3109
3601
|
const relativeIndex = relative(snapshot.root, snapshot.indexPath).split("\\").join("/");
|
|
@@ -3673,6 +4165,10 @@ ${sanitizeTerminalText(usage)}`);
|
|
|
3673
4165
|
return await runPercolate(command, output, dependencies);
|
|
3674
4166
|
if (command.kind === "list")
|
|
3675
4167
|
return await runList(command, output, dependencies);
|
|
4168
|
+
if (command.kind === "publish")
|
|
4169
|
+
return await runPublish(command, output, dependencies);
|
|
4170
|
+
if (command.kind === "serve")
|
|
4171
|
+
return await runServe(command, output, dependencies);
|
|
3676
4172
|
if (command.kind === "inbox")
|
|
3677
4173
|
return await runInbox(command, output, dependencies);
|
|
3678
4174
|
if (command.kind === "catalog")
|