@hraness/wordcell 0.21.3 → 0.22.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 +170 -64
- package/dist/authoring.js +5 -3
- package/dist/{authority-4sp9d552.js → authority-06eqhqam.js} +57 -12
- package/dist/benchmark.js +4 -4
- package/dist/capture.js +6 -5
- package/dist/cli.js +39 -33
- 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 +20 -19
- package/dist/evaluation-kb.js +16 -15
- package/dist/graph-authority.js +5 -5
- package/dist/graph-percolation.js +7 -7
- package/dist/graph.js +1 -1
- package/dist/{index-pbr6rv47.js → index-1k595z6v.js} +6 -6
- package/dist/{index-0k2x4nn9.js → index-233z9wmn.js} +17 -5
- package/dist/index-3agn8scn.js +306 -0
- package/dist/index-4knsp9qj.js +34 -0
- package/dist/index-66pshdtx.js +341 -0
- package/dist/{index-59ssmqqm.js → index-76dbn6pe.js} +1 -1
- package/dist/{index-0rfcqab6.js → index-810nfzdj.js} +617 -66
- package/dist/index-9rf81m0p.js +368 -0
- package/dist/{index-51bap0mq.js → index-bqtqeak3.js} +10 -10
- package/dist/{index-9zcpdbjg.js → index-de2w8crk.js} +13 -13
- package/dist/{index-bgfzwt4h.js → index-djrcc1yf.js} +6 -6
- package/dist/{index-6sw24nvv.js → index-ecqpgr5y.js} +53 -2
- package/dist/{index-van48n3g.js → index-fc4dr114.js} +4 -2
- package/dist/{index-jzcws0zn.js → index-g5vsqmdy.js} +27 -57
- package/dist/index-hmw17zaa.js +1985 -0
- package/dist/index-j70m75wd.js +217 -0
- package/dist/{index-nd6nynv2.js → index-jk1sgx36.js} +1 -1
- package/dist/{index-3ehtt59c.js → index-n386evxj.js} +1 -1
- package/dist/{index-vdw5yjfa.js → index-q7tbg07z.js} +110 -20
- package/dist/{index-ekpwvbra.js → index-qbssx940.js} +1 -2
- package/dist/{index-115b07ap.js → index-rr9kzq4n.js} +5 -5
- package/dist/{index-11621h23.js → index-tf4wzjew.js} +1 -1
- package/dist/{index-why54q5p.js → index-vnybgywh.js} +4 -4
- package/dist/{index-bcfn9xah.js → index-xv80vzfp.js} +7 -7
- package/dist/index.js +289 -95
- package/dist/percolate.js +2 -2
- package/dist/portfolio.js +16 -15
- 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 +16 -13
- package/dist/search.js +3 -3
- package/dist/semantic.js +5 -5
- package/dist/{support-vm4mkw0k.js → support-1rh2d7mt.js} +38 -32
- package/dist/workflows/decision-context.js +15 -14
- package/dist/workflows/index.js +15 -14
- package/package.json +65 -6
- 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 +127 -0
- package/skills/wordcell/references/query.md +22 -0
- package/skills/wordcell/references/refresh.md +14 -0
- package/src/authoring-model.ts +29 -0
- package/src/authoring-program.ts +38 -3
- package/src/authoring.ts +17 -3
- package/src/cli-program.ts +441 -12
- package/src/graph.ts +1 -1
- 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/src/cli-program.ts
CHANGED
|
@@ -96,6 +96,14 @@ import {
|
|
|
96
96
|
openKnowledgePortfolio,
|
|
97
97
|
type PortfolioSearchResult,
|
|
98
98
|
} from "./portfolio.js";
|
|
99
|
+
import {
|
|
100
|
+
DEFAULT_PUBLISH_LIST_LIMIT,
|
|
101
|
+
MAX_PUBLISH_LIST_LIMIT,
|
|
102
|
+
publishVault,
|
|
103
|
+
renderPublishReportText,
|
|
104
|
+
type PublishSelectionInput,
|
|
105
|
+
} from "./publish.js";
|
|
106
|
+
import { serveSite } from "./serve.js";
|
|
99
107
|
import {
|
|
100
108
|
MAX_AUTHORIZED_VAULTS,
|
|
101
109
|
loadPortfolioRegistry,
|
|
@@ -114,10 +122,14 @@ import {
|
|
|
114
122
|
type QuerySort,
|
|
115
123
|
} from "./query.js";
|
|
116
124
|
import {
|
|
125
|
+
auditRepositoryMemoryScopes,
|
|
117
126
|
buildRepositoryMemoryContext,
|
|
127
|
+
MAX_REPOSITORY_MEMORY_DETAIL_LIMIT,
|
|
118
128
|
MAX_REPOSITORY_SCOPES,
|
|
119
129
|
repositoryMemoryGroupKeys,
|
|
120
130
|
type RepositoryMemoryContext,
|
|
131
|
+
type RepositoryMemoryScopeAudit,
|
|
132
|
+
type RepositoryMemoryScopeAuditError,
|
|
121
133
|
} from "./repository-memory.js";
|
|
122
134
|
import { validateSearchQuery } from "./search.js";
|
|
123
135
|
import {
|
|
@@ -140,11 +152,14 @@ import {
|
|
|
140
152
|
MAX_SEARCH_RELATED_SEEDS,
|
|
141
153
|
MAX_SEARCH_RESULTS,
|
|
142
154
|
openKnowledgeBase,
|
|
155
|
+
searchEvidenceRank,
|
|
143
156
|
type KnowledgeBaseGraphOptions,
|
|
144
157
|
type KnowledgeBaseSearchMode,
|
|
145
158
|
type KnowledgeBaseSearchOrdering,
|
|
146
159
|
type KnowledgeBaseSearchResult,
|
|
147
160
|
} from "./sdk.js";
|
|
161
|
+
import { MAX_RERANK_CANDIDATES, type SearchReranker } from "./rerank.js";
|
|
162
|
+
import { createCliTypeSafeReranker } from "./rerank-credentials.js";
|
|
148
163
|
import {
|
|
149
164
|
refreshVault,
|
|
150
165
|
scanVault,
|
|
@@ -215,7 +230,16 @@ async function loadSearchRulesFile(path: string): Promise<SearchRulesV1> {
|
|
|
215
230
|
return parseSearchRules(input);
|
|
216
231
|
}
|
|
217
232
|
|
|
218
|
-
export const usage = `wordcell —
|
|
233
|
+
export const usage = `wordcell — a local knowledge base for coding agents
|
|
234
|
+
|
|
235
|
+
Start here (no account or model needed):
|
|
236
|
+
wordcell init kb
|
|
237
|
+
wordcell note create notes/decision --title "A decision" --body "Keep retries bounded." --root kb
|
|
238
|
+
wordcell search "retries" --root kb --mode exact
|
|
239
|
+
|
|
240
|
+
Already have Markdown? Search it with --root <your-notes-directory>.
|
|
241
|
+
Use --mode exact for model-free search; optional hybrid search needs a local index.
|
|
242
|
+
Quick start and examples: https://wordcell.io/docs
|
|
219
243
|
|
|
220
244
|
Usage:
|
|
221
245
|
wordcell init [directory] [--json]
|
|
@@ -228,7 +252,7 @@ Usage:
|
|
|
228
252
|
wordcell inspect <url> [capture options]
|
|
229
253
|
wordcell pdf <file-or-url> [PDF options]
|
|
230
254
|
wordcell refresh [--root <directory>] [--index <path>] [--json]
|
|
231
|
-
wordcell check [--root <directory>] [--index <path>] [--no-catalog] [--json]
|
|
255
|
+
wordcell check [--root <directory>] [--index <path>] [--no-catalog] [--repo <repository>] [--json]
|
|
232
256
|
wordcell catalog [--root <directory>] [--index <path>] [--json]
|
|
233
257
|
wordcell graph [--root <directory>] [--index <path>] [--json]
|
|
234
258
|
wordcell graph rebuild [--fresh] [--root <directory>] [--index <path>] [--json]
|
|
@@ -243,12 +267,14 @@ Usage:
|
|
|
243
267
|
wordcell percolate [note] [--proofs] [--root <directory>] [--min-support <count>] [--limit <count>] [--json]
|
|
244
268
|
wordcell list [--root <directory>] [--where <path=value>] [--has <path>] [--tag <tag>] [--scope <repository-path>] [--sort <field>] [--order <asc|desc>] [--limit <count>] [--json]
|
|
245
269
|
wordcell index [--root <directory>] [--database <path>] [--force] [--json]
|
|
246
|
-
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]
|
|
270
|
+
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]
|
|
247
271
|
wordcell history <note> [--root <directory>] [--repo <repository>] [--limit <count>] [--cochanged-limit <count>] [--json]
|
|
248
272
|
wordcell history search <query-or-path> [--root <directory>] [--repo <repository>] [--limit <count>] [--commit-limit <count>] [--cochanged-limit <count>] [--json]
|
|
249
273
|
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]
|
|
250
274
|
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]
|
|
251
275
|
wordcell portfolio audit --registry <file> --workspace <directory> (--all | --shared | --vault <owner/id>...) [--strict] [--json]
|
|
276
|
+
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]
|
|
277
|
+
wordcell serve --root <directory> [--host <host>] [--port <port>] [--json]
|
|
252
278
|
wordcell inbox [--root <directory>] [--source-prefix <directory>] [--limit <count>] [--json]
|
|
253
279
|
wordcell context <repository-path> [--root <vault>] [--repo <repository>] [--kind <auto|file|directory>] [--json]
|
|
254
280
|
wordcell agents identity <repository-scope> [--json]
|
|
@@ -359,6 +385,8 @@ type ParsedCommand =
|
|
|
359
385
|
readonly limit?: number;
|
|
360
386
|
readonly candidateLimit?: number;
|
|
361
387
|
readonly minScore?: number;
|
|
388
|
+
readonly rerank?: "typesafe";
|
|
389
|
+
readonly rerankLimit?: number;
|
|
362
390
|
readonly query: string;
|
|
363
391
|
readonly json: boolean;
|
|
364
392
|
}
|
|
@@ -419,6 +447,8 @@ type ParsedCommand =
|
|
|
419
447
|
readonly depth?: number;
|
|
420
448
|
readonly limit?: number;
|
|
421
449
|
readonly noCatalog?: boolean;
|
|
450
|
+
/** `check --repo` only: repository working tree for the advisory scope lane. */
|
|
451
|
+
readonly repository?: string;
|
|
422
452
|
}
|
|
423
453
|
| {
|
|
424
454
|
readonly kind: "note-create";
|
|
@@ -446,6 +476,31 @@ type ParsedCommand =
|
|
|
446
476
|
readonly minSupport: number;
|
|
447
477
|
readonly limit: number;
|
|
448
478
|
readonly json: boolean;
|
|
479
|
+
}
|
|
480
|
+
| {
|
|
481
|
+
readonly kind: "publish";
|
|
482
|
+
readonly root: string;
|
|
483
|
+
readonly out: string;
|
|
484
|
+
readonly index?: string;
|
|
485
|
+
readonly title?: string;
|
|
486
|
+
readonly description?: string;
|
|
487
|
+
readonly basePath?: string;
|
|
488
|
+
readonly baseUrl?: string;
|
|
489
|
+
readonly noindex: boolean;
|
|
490
|
+
readonly indexContent: boolean;
|
|
491
|
+
readonly deterministic: boolean;
|
|
492
|
+
readonly dryRun: boolean;
|
|
493
|
+
readonly listLimit: number;
|
|
494
|
+
readonly force: boolean;
|
|
495
|
+
readonly selection: PublishSelectionInput;
|
|
496
|
+
readonly json: boolean;
|
|
497
|
+
}
|
|
498
|
+
| {
|
|
499
|
+
readonly kind: "serve";
|
|
500
|
+
readonly root: string;
|
|
501
|
+
readonly host: string;
|
|
502
|
+
readonly port: number;
|
|
503
|
+
readonly json: boolean;
|
|
449
504
|
};
|
|
450
505
|
|
|
451
506
|
type ParseResult =
|
|
@@ -468,6 +523,8 @@ type CliDependencies = GraphCliDependencies & {
|
|
|
468
523
|
readonly indexSemanticVault?: typeof indexSemanticVault;
|
|
469
524
|
readonly openKnowledgeBase?: typeof openKnowledgeBase;
|
|
470
525
|
readonly openKnowledgeBaseEvaluation?: typeof openKnowledgeBaseEvaluation;
|
|
526
|
+
/** Test seam; production wiring builds the TypeSafe reranker lazily per flag. */
|
|
527
|
+
readonly rerankers?: readonly SearchReranker[];
|
|
471
528
|
readonly digestEvaluationModel?: (path: string) => Promise<string>;
|
|
472
529
|
readonly evaluationNow?: () => Date;
|
|
473
530
|
readonly createNote?: typeof createNote;
|
|
@@ -477,8 +534,11 @@ type CliDependencies = GraphCliDependencies & {
|
|
|
477
534
|
readonly percolateWithGraph?: typeof percolateWithGraph;
|
|
478
535
|
readonly inspectAgentContextRepository?: typeof inspectAgentContextRepository;
|
|
479
536
|
readonly buildRepositoryMemoryContext?: typeof buildRepositoryMemoryContext;
|
|
537
|
+
readonly auditRepositoryMemoryScopes?: typeof auditRepositoryMemoryScopes;
|
|
480
538
|
readonly auditAgentGuideRepository?: typeof auditAgentGuideRepository;
|
|
481
539
|
readonly validateMarkdownAttachments?: typeof validateMarkdownAttachments;
|
|
540
|
+
readonly publishVault?: typeof publishVault;
|
|
541
|
+
readonly serveSite?: typeof serveSite;
|
|
482
542
|
};
|
|
483
543
|
|
|
484
544
|
function safe(value: string): string {
|
|
@@ -570,6 +630,7 @@ function parseVaultCommand(command: VaultCommand, arguments_: readonly string[])
|
|
|
570
630
|
let depth = 1;
|
|
571
631
|
let limit: number | undefined;
|
|
572
632
|
let noCatalog = false;
|
|
633
|
+
let repository: string | undefined;
|
|
573
634
|
const positional: string[] = [];
|
|
574
635
|
|
|
575
636
|
for (let cursor = 0; cursor < arguments_.length; cursor += 1) {
|
|
@@ -583,6 +644,13 @@ function parseVaultCommand(command: VaultCommand, arguments_: readonly string[])
|
|
|
583
644
|
noCatalog = true;
|
|
584
645
|
continue;
|
|
585
646
|
}
|
|
647
|
+
if (argument === "--repo" && command === "check") {
|
|
648
|
+
const value = readValue(arguments_, cursor);
|
|
649
|
+
if (value === null) return { ok: false, message: "--repo requires a value" };
|
|
650
|
+
repository = value;
|
|
651
|
+
cursor += 1;
|
|
652
|
+
continue;
|
|
653
|
+
}
|
|
586
654
|
if (argument === "--root" || argument === "--index") {
|
|
587
655
|
const value = readValue(arguments_, cursor);
|
|
588
656
|
if (value === null) return { ok: false, message: `${argument} requires a value` };
|
|
@@ -647,6 +715,7 @@ function parseVaultCommand(command: VaultCommand, arguments_: readonly string[])
|
|
|
647
715
|
options: index === undefined ? {} : { index },
|
|
648
716
|
json,
|
|
649
717
|
...(command === "check" && noCatalog ? { noCatalog: true } : {}),
|
|
718
|
+
...(command === "check" && repository !== undefined ? { repository } : {}),
|
|
650
719
|
},
|
|
651
720
|
};
|
|
652
721
|
}
|
|
@@ -866,6 +935,195 @@ function parseListCommand(arguments_: readonly string[]): ParseResult {
|
|
|
866
935
|
};
|
|
867
936
|
}
|
|
868
937
|
|
|
938
|
+
function parsePublishCommand(arguments_: readonly string[]): ParseResult {
|
|
939
|
+
let root = ".";
|
|
940
|
+
let out: string | undefined;
|
|
941
|
+
let index: string | undefined;
|
|
942
|
+
let title: string | undefined;
|
|
943
|
+
let description: string | undefined;
|
|
944
|
+
let basePath: string | undefined;
|
|
945
|
+
let baseUrl: string | undefined;
|
|
946
|
+
let noindex = false;
|
|
947
|
+
let indexContent = true;
|
|
948
|
+
let deterministic = false;
|
|
949
|
+
let dryRun = false;
|
|
950
|
+
let listLimit = DEFAULT_PUBLISH_LIST_LIMIT;
|
|
951
|
+
let force = false;
|
|
952
|
+
let json = false;
|
|
953
|
+
let from: string | undefined;
|
|
954
|
+
let depth = 1;
|
|
955
|
+
let direction: LinkDirection = "both";
|
|
956
|
+
const includes: string[] = [];
|
|
957
|
+
const excludes: string[] = [];
|
|
958
|
+
const includeGlobs: string[] = [];
|
|
959
|
+
const excludeGlobs: string[] = [];
|
|
960
|
+
const filters: MetadataFilter[] = [];
|
|
961
|
+
const tags: string[] = [];
|
|
962
|
+
const repositoryScopes: string[] = [];
|
|
963
|
+
|
|
964
|
+
for (let cursor = 0; cursor < arguments_.length; cursor += 1) {
|
|
965
|
+
const argument = arguments_[cursor];
|
|
966
|
+
if (argument === undefined) continue;
|
|
967
|
+
if (argument === "--json") { json = true; continue; }
|
|
968
|
+
if (argument === "--noindex") { noindex = true; continue; }
|
|
969
|
+
if (argument === "--no-index-content") { indexContent = false; continue; }
|
|
970
|
+
if (argument === "--deterministic") { deterministic = true; continue; }
|
|
971
|
+
if (argument === "--dry-run") { dryRun = true; continue; }
|
|
972
|
+
if (argument === "--force") { force = true; continue; }
|
|
973
|
+
if (
|
|
974
|
+
argument === "--root" || argument === "--out" || argument === "--index"
|
|
975
|
+
|| argument === "--title" || argument === "--description"
|
|
976
|
+
|| argument === "--base-path" || argument === "--base-url"
|
|
977
|
+
|| argument === "--include" || argument === "--exclude"
|
|
978
|
+
|| argument === "--include-glob" || argument === "--exclude-glob"
|
|
979
|
+
|| argument === "--list-limit"
|
|
980
|
+
|| argument === "--where" || argument === "--has" || argument === "--tag"
|
|
981
|
+
|| argument === "--scope" || argument === "--repository-scope"
|
|
982
|
+
|| argument === "--from" || argument === "--depth" || argument === "--direction"
|
|
983
|
+
) {
|
|
984
|
+
const value = readValue(arguments_, cursor);
|
|
985
|
+
if (value === null) return { ok: false, message: `${argument} requires a value` };
|
|
986
|
+
if (argument === "--root") root = value;
|
|
987
|
+
else if (argument === "--out") out = value;
|
|
988
|
+
else if (argument === "--index") index = value;
|
|
989
|
+
else if (argument === "--title") title = value;
|
|
990
|
+
else if (argument === "--description") description = value;
|
|
991
|
+
else if (argument === "--base-path") basePath = value;
|
|
992
|
+
else if (argument === "--base-url") baseUrl = value;
|
|
993
|
+
else if (argument === "--include") includes.push(value);
|
|
994
|
+
else if (argument === "--exclude") excludes.push(value);
|
|
995
|
+
else if (argument === "--include-glob") includeGlobs.push(value);
|
|
996
|
+
else if (argument === "--exclude-glob") excludeGlobs.push(value);
|
|
997
|
+
else if (argument === "--list-limit") {
|
|
998
|
+
if (!/^(0|[1-9][0-9]*)$/u.test(value) || Number(value) > MAX_PUBLISH_LIST_LIMIT) {
|
|
999
|
+
return { ok: false, message: `--list-limit must be an integer from 0 through ${MAX_PUBLISH_LIST_LIMIT}` };
|
|
1000
|
+
}
|
|
1001
|
+
listLimit = Number(value);
|
|
1002
|
+
}
|
|
1003
|
+
else if (argument === "--from") from = value;
|
|
1004
|
+
else if (argument === "--depth") {
|
|
1005
|
+
const parsed = Number(value);
|
|
1006
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1 || parsed > 10) {
|
|
1007
|
+
return { ok: false, message: "--depth must be an integer from 1 through 10" };
|
|
1008
|
+
}
|
|
1009
|
+
depth = parsed;
|
|
1010
|
+
} else if (argument === "--direction") {
|
|
1011
|
+
if (value !== "in" && value !== "out" && value !== "both") {
|
|
1012
|
+
return { ok: false, message: "--direction must be in, out, or both" };
|
|
1013
|
+
}
|
|
1014
|
+
direction = value;
|
|
1015
|
+
} else if (argument === "--tag") {
|
|
1016
|
+
if (tags.length >= MAX_QUERY_TAGS) {
|
|
1017
|
+
return { ok: false, message: `Query tags may contain at most ${MAX_QUERY_TAGS} entries.` };
|
|
1018
|
+
}
|
|
1019
|
+
tags.push(value);
|
|
1020
|
+
} else if (argument === "--scope" || argument === "--repository-scope") {
|
|
1021
|
+
if (repositoryScopes.length >= MAX_REPOSITORY_SCOPES) {
|
|
1022
|
+
return { ok: false, message: `Repository scope filters may contain at most ${MAX_REPOSITORY_SCOPES} entries.` };
|
|
1023
|
+
}
|
|
1024
|
+
repositoryScopes.push(value);
|
|
1025
|
+
} else if (argument === "--has") {
|
|
1026
|
+
if (value.trim() === "") return { ok: false, message: "--has requires a metadata path" };
|
|
1027
|
+
if (filters.length >= MAX_QUERY_FILTERS) {
|
|
1028
|
+
return { ok: false, message: `Query filters may contain at most ${MAX_QUERY_FILTERS} entries.` };
|
|
1029
|
+
}
|
|
1030
|
+
filters.push({ kind: "exists", path: value });
|
|
1031
|
+
} else {
|
|
1032
|
+
const equals = value.indexOf("=");
|
|
1033
|
+
const path = equals === -1 ? "" : value.slice(0, equals).trim();
|
|
1034
|
+
if (path === "") return { ok: false, message: "--where requires path=value" };
|
|
1035
|
+
const scalar = metadataScalar(value.slice(equals + 1));
|
|
1036
|
+
if (!scalar.ok) return scalar;
|
|
1037
|
+
if (filters.length >= MAX_QUERY_FILTERS) {
|
|
1038
|
+
return { ok: false, message: `Query filters may contain at most ${MAX_QUERY_FILTERS} entries.` };
|
|
1039
|
+
}
|
|
1040
|
+
filters.push({ kind: "equals", path, value: scalar.value });
|
|
1041
|
+
}
|
|
1042
|
+
cursor += 1;
|
|
1043
|
+
continue;
|
|
1044
|
+
}
|
|
1045
|
+
return {
|
|
1046
|
+
ok: false,
|
|
1047
|
+
message: argument.startsWith("--")
|
|
1048
|
+
? "unknown publish option"
|
|
1049
|
+
: "publish does not accept positional arguments",
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
if (out === undefined) return { ok: false, message: "publish requires --out <directory>" };
|
|
1054
|
+
try {
|
|
1055
|
+
validateQueryOptions({ filters, tags, repositoryScopes });
|
|
1056
|
+
} catch (error: unknown) {
|
|
1057
|
+
return { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
1058
|
+
}
|
|
1059
|
+
const selection: PublishSelectionInput = {
|
|
1060
|
+
includes,
|
|
1061
|
+
excludes,
|
|
1062
|
+
includeGlobs,
|
|
1063
|
+
excludeGlobs,
|
|
1064
|
+
filters,
|
|
1065
|
+
tags,
|
|
1066
|
+
repositoryScopes,
|
|
1067
|
+
...(from === undefined ? {} : { from: { note: from, depth, direction } }),
|
|
1068
|
+
};
|
|
1069
|
+
return {
|
|
1070
|
+
ok: true,
|
|
1071
|
+
value: {
|
|
1072
|
+
kind: "publish",
|
|
1073
|
+
root,
|
|
1074
|
+
out,
|
|
1075
|
+
noindex,
|
|
1076
|
+
indexContent,
|
|
1077
|
+
deterministic,
|
|
1078
|
+
dryRun,
|
|
1079
|
+
listLimit,
|
|
1080
|
+
force,
|
|
1081
|
+
selection,
|
|
1082
|
+
json,
|
|
1083
|
+
...(index === undefined ? {} : { index }),
|
|
1084
|
+
...(title === undefined ? {} : { title }),
|
|
1085
|
+
...(description === undefined ? {} : { description }),
|
|
1086
|
+
...(basePath === undefined ? {} : { basePath }),
|
|
1087
|
+
...(baseUrl === undefined ? {} : { baseUrl }),
|
|
1088
|
+
},
|
|
1089
|
+
};
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
function parseServeCommand(arguments_: readonly string[]): ParseResult {
|
|
1093
|
+
let root: string | undefined;
|
|
1094
|
+
let host = "127.0.0.1";
|
|
1095
|
+
let port = 8080;
|
|
1096
|
+
let json = false;
|
|
1097
|
+
for (let cursor = 0; cursor < arguments_.length; cursor += 1) {
|
|
1098
|
+
const argument = arguments_[cursor];
|
|
1099
|
+
if (argument === undefined) continue;
|
|
1100
|
+
if (argument === "--json") { json = true; continue; }
|
|
1101
|
+
if (argument === "--root" || argument === "--host" || argument === "--port") {
|
|
1102
|
+
const value = readValue(arguments_, cursor);
|
|
1103
|
+
if (value === null) return { ok: false, message: `${argument} requires a value` };
|
|
1104
|
+
if (argument === "--root") root = value;
|
|
1105
|
+
else if (argument === "--host") host = value;
|
|
1106
|
+
else {
|
|
1107
|
+
const parsed = Number(value);
|
|
1108
|
+
if (!Number.isSafeInteger(parsed) || parsed < 0 || parsed > 65_535) {
|
|
1109
|
+
return { ok: false, message: "--port must be an integer from 0 through 65535" };
|
|
1110
|
+
}
|
|
1111
|
+
port = parsed;
|
|
1112
|
+
}
|
|
1113
|
+
cursor += 1;
|
|
1114
|
+
continue;
|
|
1115
|
+
}
|
|
1116
|
+
return {
|
|
1117
|
+
ok: false,
|
|
1118
|
+
message: argument.startsWith("--")
|
|
1119
|
+
? "unknown serve option"
|
|
1120
|
+
: "serve does not accept positional arguments",
|
|
1121
|
+
};
|
|
1122
|
+
}
|
|
1123
|
+
if (root === undefined) return { ok: false, message: "serve requires --root <directory>" };
|
|
1124
|
+
return { ok: true, value: { kind: "serve", root, host, port, json } };
|
|
1125
|
+
}
|
|
1126
|
+
|
|
869
1127
|
function parseInboxCommand(arguments_: readonly string[]): ParseResult {
|
|
870
1128
|
let root = ".";
|
|
871
1129
|
let index: string | undefined;
|
|
@@ -942,6 +1200,8 @@ function parseSemanticCommand(command: "index" | "search", arguments_: readonly
|
|
|
942
1200
|
let limit: number | undefined;
|
|
943
1201
|
let candidateLimit: number | undefined;
|
|
944
1202
|
let minScore: number | undefined;
|
|
1203
|
+
let rerank: "typesafe" | undefined;
|
|
1204
|
+
let rerankLimit: number | undefined;
|
|
945
1205
|
let graphDepth: number | undefined;
|
|
946
1206
|
let noGraph = false;
|
|
947
1207
|
let history = false;
|
|
@@ -1003,6 +1263,8 @@ function parseSemanticCommand(command: "index" | "search", arguments_: readonly
|
|
|
1003
1263
|
|| argument === "--limit"
|
|
1004
1264
|
|| argument === "--candidate-limit"
|
|
1005
1265
|
|| argument === "--min-score"
|
|
1266
|
+
|| argument === "--rerank"
|
|
1267
|
+
|| argument === "--rerank-limit"
|
|
1006
1268
|
|| argument === "--where"
|
|
1007
1269
|
|| argument === "--has"
|
|
1008
1270
|
|| argument === "--tag"
|
|
@@ -1018,6 +1280,17 @@ function parseSemanticCommand(command: "index" | "search", arguments_: readonly
|
|
|
1018
1280
|
return { ok: false, message: "--mode must be hybrid, exact, keyword, or semantic" };
|
|
1019
1281
|
}
|
|
1020
1282
|
mode = value;
|
|
1283
|
+
} else if (argument === "--rerank") {
|
|
1284
|
+
if (value !== "typesafe") {
|
|
1285
|
+
return { ok: false, message: "--rerank must be typesafe" };
|
|
1286
|
+
}
|
|
1287
|
+
rerank = value;
|
|
1288
|
+
} else if (argument === "--rerank-limit") {
|
|
1289
|
+
const parsed = Number(value);
|
|
1290
|
+
if (!Number.isSafeInteger(parsed) || parsed < 2 || parsed > MAX_RERANK_CANDIDATES) {
|
|
1291
|
+
return { ok: false, message: `--rerank-limit must be an integer from 2 through ${MAX_RERANK_CANDIDATES}` };
|
|
1292
|
+
}
|
|
1293
|
+
rerankLimit = parsed;
|
|
1021
1294
|
} else if (argument === "--where") {
|
|
1022
1295
|
const equals = value.indexOf("=");
|
|
1023
1296
|
const path = equals === -1 ? "" : value.slice(0, equals).trim();
|
|
@@ -1147,6 +1420,9 @@ function parseSemanticCommand(command: "index" | "search", arguments_: readonly
|
|
|
1147
1420
|
message: "Search minimum score applies only to hybrid, keyword, or semantic mode.",
|
|
1148
1421
|
};
|
|
1149
1422
|
}
|
|
1423
|
+
if (rerankLimit !== undefined && rerank === undefined) {
|
|
1424
|
+
return { ok: false, message: "--rerank-limit requires --rerank typesafe" };
|
|
1425
|
+
}
|
|
1150
1426
|
if (priority && rulesPath === undefined) {
|
|
1151
1427
|
return { ok: false, message: "--priority requires --rules" };
|
|
1152
1428
|
}
|
|
@@ -1185,6 +1461,8 @@ function parseSemanticCommand(command: "index" | "search", arguments_: readonly
|
|
|
1185
1461
|
...(limit === undefined ? {} : { limit }),
|
|
1186
1462
|
...(candidateLimit === undefined ? {} : { candidateLimit }),
|
|
1187
1463
|
...(minScore === undefined ? {} : { minScore }),
|
|
1464
|
+
...(rerank === undefined ? {} : { rerank }),
|
|
1465
|
+
...(rerankLimit === undefined ? {} : { rerankLimit }),
|
|
1188
1466
|
query,
|
|
1189
1467
|
json,
|
|
1190
1468
|
},
|
|
@@ -1938,6 +2216,8 @@ export function parseArguments(arguments_: readonly string[]): ParseResult {
|
|
|
1938
2216
|
if (command === "note") return parseNoteCommand(arguments_.slice(1));
|
|
1939
2217
|
if (command === "relation") return parseRelationCommand(arguments_.slice(1));
|
|
1940
2218
|
if (command === "percolate") return parsePercolateCommand(arguments_.slice(1));
|
|
2219
|
+
if (command === "publish") return parsePublishCommand(arguments_.slice(1));
|
|
2220
|
+
if (command === "serve") return parseServeCommand(arguments_.slice(1));
|
|
1941
2221
|
return { ok: false, message: "unknown command" };
|
|
1942
2222
|
}
|
|
1943
2223
|
|
|
@@ -1960,10 +2240,28 @@ function renderKnowledgeBaseSearch(result: KnowledgeBaseSearchResult): string {
|
|
|
1960
2240
|
const lines = [
|
|
1961
2241
|
`${result.mode[0]?.toLocaleUpperCase("en-US") ?? ""}${result.mode.slice(1)} results for “${safe(result.query)}” (${result.results.length})${result.partial ? " [partial]" : ""}`,
|
|
1962
2242
|
];
|
|
2243
|
+
const rerankLane = result.diagnostics.lanes.find(({ lane }) => lane === "rerank");
|
|
2244
|
+
if (rerankLane !== undefined) {
|
|
2245
|
+
lines.push(
|
|
2246
|
+
` Rerank: typesafe over ${rerankLane.results} candidates (${rerankLane.status})`
|
|
2247
|
+
+ (rerankLane.message === undefined ? "" : ` — ${safe(rerankLane.message)}`),
|
|
2248
|
+
);
|
|
2249
|
+
const receipt = rerankLane.rerank;
|
|
2250
|
+
if (receipt?.accounting !== undefined) {
|
|
2251
|
+
const { attempted, candidates, completed, elapsedMs, usageComplete } = receipt.accounting;
|
|
2252
|
+
lines.push(` Rerank requests: ${attempted}/${candidates} attempted, ${completed} settled; ${elapsedMs.toFixed(0)} ms`
|
|
2253
|
+
+ (usageComplete ? "; usage complete" : "; usage incomplete, additional charges may be unknown"));
|
|
2254
|
+
if (rerankLane.status !== "ready" && receipt.usage !== undefined) {
|
|
2255
|
+
lines.push(` Known rerank usage: ${receipt.usage.inputTokens ?? 0} input tokens, ${receipt.usage.outputTokens ?? 0} output tokens`);
|
|
2256
|
+
}
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
1963
2259
|
if (result.results.length === 0) lines.push(" None.");
|
|
1964
2260
|
for (const hit of result.results) {
|
|
1965
2261
|
const location = `${safe(hit.path)}${hit.line === undefined ? "" : `:${hit.line}`}`;
|
|
1966
|
-
const evidence = hit.evidence
|
|
2262
|
+
const evidence = hit.evidence
|
|
2263
|
+
.map((item) => `${item.kind}#${searchEvidenceRank(item)}`)
|
|
2264
|
+
.join(", ");
|
|
1967
2265
|
lines.push(` ${hit.rank}. ${hit.score.toFixed(3)} ${location} — ${safe(hit.title)} [${safe(evidence)}]`);
|
|
1968
2266
|
if (hit.snippet !== "") lines.push(` ${safe(hit.snippet)}`);
|
|
1969
2267
|
}
|
|
@@ -1999,12 +2297,17 @@ async function runSemantic(
|
|
|
1999
2297
|
const searchRules = command.rulesPath === undefined
|
|
2000
2298
|
? undefined
|
|
2001
2299
|
: await loadSearchRulesFile(command.rulesPath);
|
|
2002
|
-
const kb = await (dependencies.openKnowledgeBase ?? openKnowledgeBase)(
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2300
|
+
const kb = await (dependencies.openKnowledgeBase ?? openKnowledgeBase)(
|
|
2301
|
+
{
|
|
2302
|
+
root: command.root,
|
|
2303
|
+
repository: command.repository,
|
|
2304
|
+
...(command.database === undefined ? {} : { database: command.database }),
|
|
2305
|
+
...(searchRules === undefined ? {} : { searchRules }),
|
|
2306
|
+
},
|
|
2307
|
+
...(command.rerank === undefined
|
|
2308
|
+
? []
|
|
2309
|
+
: [{ rerankers: dependencies.rerankers ?? [await createCliTypeSafeReranker()] }]),
|
|
2310
|
+
);
|
|
2008
2311
|
try {
|
|
2009
2312
|
const result = await kb.search({
|
|
2010
2313
|
query: command.query,
|
|
@@ -2020,6 +2323,12 @@ async function runSemantic(
|
|
|
2020
2323
|
? {}
|
|
2021
2324
|
: { candidateLimit: command.candidateLimit }),
|
|
2022
2325
|
...(command.minScore === undefined ? {} : { minScore: command.minScore }),
|
|
2326
|
+
...(command.rerank === undefined ? {} : {
|
|
2327
|
+
rerank: {
|
|
2328
|
+
engine: command.rerank,
|
|
2329
|
+
...(command.rerankLimit === undefined ? {} : { limit: command.rerankLimit }),
|
|
2330
|
+
},
|
|
2331
|
+
}),
|
|
2023
2332
|
});
|
|
2024
2333
|
output.stdout(command.json
|
|
2025
2334
|
? terminalSafeJson(result)
|
|
@@ -2344,6 +2653,7 @@ function summary(
|
|
|
2344
2653
|
options: {
|
|
2345
2654
|
readonly noCatalog?: boolean;
|
|
2346
2655
|
readonly attachments?: AttachmentValidationReport;
|
|
2656
|
+
readonly repositoryScopes?: RepositoryMemoryScopeAudit;
|
|
2347
2657
|
} = {},
|
|
2348
2658
|
): Record<string, unknown> {
|
|
2349
2659
|
return {
|
|
@@ -2369,6 +2679,9 @@ function summary(
|
|
|
2369
2679
|
issues: options.attachments.issues,
|
|
2370
2680
|
},
|
|
2371
2681
|
}),
|
|
2682
|
+
...(options.repositoryScopes === undefined
|
|
2683
|
+
? {}
|
|
2684
|
+
: { repositoryScopes: options.repositoryScopes }),
|
|
2372
2685
|
};
|
|
2373
2686
|
}
|
|
2374
2687
|
|
|
@@ -2404,6 +2717,60 @@ function renderAdvisories(analysis: VaultAnalysis): string[] {
|
|
|
2404
2717
|
return lines;
|
|
2405
2718
|
}
|
|
2406
2719
|
|
|
2720
|
+
function renderRepositoryScopeAuditError(error: RepositoryMemoryScopeAuditError): string {
|
|
2721
|
+
if (error.kind === "invalid-record") {
|
|
2722
|
+
return `${safe(error.path)}: ${error.issues.map(safe).join(" ")}`;
|
|
2723
|
+
}
|
|
2724
|
+
const declared = error.recordPaths.map(safe).join(", ")
|
|
2725
|
+
+ (error.recordPathsTruncated ? ", …" : "");
|
|
2726
|
+
return `${safe(error.scope)}: ${safe(error.state.reason)} at ${safe(error.state.path)}`
|
|
2727
|
+
+ ` (declared by ${declared})`;
|
|
2728
|
+
}
|
|
2729
|
+
|
|
2730
|
+
/**
|
|
2731
|
+
* Advisory repository-state lane for `check --repo`.
|
|
2732
|
+
*
|
|
2733
|
+
* Every line derives from authored `repository_scopes` declarations and the
|
|
2734
|
+
* working tree they name. Nothing here changes the exit code: a current note
|
|
2735
|
+
* that names a path the repository no longer has is reported for a reader to
|
|
2736
|
+
* judge, never treated as a vault correctness failure.
|
|
2737
|
+
*/
|
|
2738
|
+
function renderRepositoryScopeAudit(audit: RepositoryMemoryScopeAudit): string[] {
|
|
2739
|
+
const { counts } = audit;
|
|
2740
|
+
const lines = [
|
|
2741
|
+
`Repository scopes: ${counts.authoredRecords} declaring note${counts.authoredRecords === 1 ? "" : "s"}; `
|
|
2742
|
+
+ `${counts.distinctScopes} distinct scope${counts.distinctScopes === 1 ? "" : "s"} `
|
|
2743
|
+
+ `(${counts.presentScopes} present, ${counts.absentScopes} absent, ${counts.invalidScopes} unusable).`,
|
|
2744
|
+
];
|
|
2745
|
+
if (audit.advisories.total > 0) {
|
|
2746
|
+
lines.push(audit.advisories.total === 1
|
|
2747
|
+
? "Advisory: 1 current note declares a repository path that no longer exists."
|
|
2748
|
+
: `Advisory: ${audit.advisories.total} current notes declare repository paths that no longer exist.`);
|
|
2749
|
+
for (const advisory of audit.advisories.details) {
|
|
2750
|
+
lines.push(` ${safe(advisory.path)} declares absent scope ${safe(advisory.scope)}`);
|
|
2751
|
+
}
|
|
2752
|
+
if (audit.advisories.truncated) {
|
|
2753
|
+
lines.push(
|
|
2754
|
+
` … ${audit.advisories.total - audit.advisories.returned} more; rerun with --json for the complete audit.`,
|
|
2755
|
+
);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
if (audit.errors.total > 0) {
|
|
2759
|
+
lines.push(
|
|
2760
|
+
`Advisory: ${audit.errors.total} repository scope declaration problem${audit.errors.total === 1 ? "" : "s"}.`,
|
|
2761
|
+
);
|
|
2762
|
+
for (const error of audit.errors.details) {
|
|
2763
|
+
lines.push(` ${renderRepositoryScopeAuditError(error)}`);
|
|
2764
|
+
}
|
|
2765
|
+
if (audit.errors.truncated) {
|
|
2766
|
+
lines.push(
|
|
2767
|
+
` … ${audit.errors.total - audit.errors.returned} more; rerun with --json for the complete audit.`,
|
|
2768
|
+
);
|
|
2769
|
+
}
|
|
2770
|
+
}
|
|
2771
|
+
return lines;
|
|
2772
|
+
}
|
|
2773
|
+
|
|
2407
2774
|
function checkExitCode(
|
|
2408
2775
|
snapshot: VaultSnapshot,
|
|
2409
2776
|
noCatalog = false,
|
|
@@ -2430,6 +2797,7 @@ function renderSnapshot(
|
|
|
2430
2797
|
snapshot: VaultSnapshot,
|
|
2431
2798
|
noCatalog = false,
|
|
2432
2799
|
attachments?: AttachmentValidationReport,
|
|
2800
|
+
repositoryScopes?: RepositoryMemoryScopeAudit,
|
|
2433
2801
|
): string {
|
|
2434
2802
|
const lines = [
|
|
2435
2803
|
`${command === "refresh" ? "Refreshed" : "Checked"} ${safe(snapshot.root)}`,
|
|
@@ -2449,6 +2817,7 @@ function renderSnapshot(
|
|
|
2449
2817
|
lines.push("error: attachment validation was truncated by a resource limit");
|
|
2450
2818
|
}
|
|
2451
2819
|
lines.push(...renderAdvisories(snapshot.analysis));
|
|
2820
|
+
if (repositoryScopes !== undefined) lines.push(...renderRepositoryScopeAudit(repositoryScopes));
|
|
2452
2821
|
return `${lines.join("\n")}\n`;
|
|
2453
2822
|
}
|
|
2454
2823
|
|
|
@@ -2834,6 +3203,49 @@ async function runList(
|
|
|
2834
3203
|
return 0;
|
|
2835
3204
|
}
|
|
2836
3205
|
|
|
3206
|
+
async function runPublish(
|
|
3207
|
+
command: Extract<ParsedCommand, { readonly kind: "publish" }>,
|
|
3208
|
+
output: Output,
|
|
3209
|
+
dependencies: CliDependencies,
|
|
3210
|
+
): Promise<number> {
|
|
3211
|
+
const result = await (dependencies.publishVault ?? publishVault)({
|
|
3212
|
+
root: command.root,
|
|
3213
|
+
out: command.out,
|
|
3214
|
+
noindex: command.noindex,
|
|
3215
|
+
indexContent: command.indexContent,
|
|
3216
|
+
deterministic: command.deterministic,
|
|
3217
|
+
dryRun: command.dryRun,
|
|
3218
|
+
listLimit: command.listLimit,
|
|
3219
|
+
force: command.force,
|
|
3220
|
+
selection: command.selection,
|
|
3221
|
+
...(command.index === undefined ? {} : { index: command.index }),
|
|
3222
|
+
...(command.title === undefined ? {} : { title: command.title }),
|
|
3223
|
+
...(command.description === undefined ? {} : { description: command.description }),
|
|
3224
|
+
...(command.basePath === undefined ? {} : { basePath: command.basePath }),
|
|
3225
|
+
...(command.baseUrl === undefined ? {} : { baseUrl: command.baseUrl }),
|
|
3226
|
+
});
|
|
3227
|
+
output.stdout(command.json
|
|
3228
|
+
? terminalSafeJson(result.report)
|
|
3229
|
+
: sanitizeTerminalText(renderPublishReportText(result.report, command.dryRun)));
|
|
3230
|
+
return 0;
|
|
3231
|
+
}
|
|
3232
|
+
|
|
3233
|
+
async function runServe(
|
|
3234
|
+
command: Extract<ParsedCommand, { readonly kind: "serve" }>,
|
|
3235
|
+
output: Output,
|
|
3236
|
+
dependencies: CliDependencies,
|
|
3237
|
+
): Promise<number> {
|
|
3238
|
+
const site = await (dependencies.serveSite ?? serveSite)({
|
|
3239
|
+
root: command.root,
|
|
3240
|
+
host: command.host,
|
|
3241
|
+
port: command.port,
|
|
3242
|
+
});
|
|
3243
|
+
output.stdout(command.json
|
|
3244
|
+
? terminalSafeJson({ root: site.root, host: site.host, port: site.port, url: site.url })
|
|
3245
|
+
: `Serving ${safe(site.root)} at ${safe(site.url)}\n`);
|
|
3246
|
+
return 0;
|
|
3247
|
+
}
|
|
3248
|
+
|
|
2837
3249
|
async function runCatalog(
|
|
2838
3250
|
command: Extract<ParsedCommand, { readonly kind: "catalog" }>,
|
|
2839
3251
|
output: Output,
|
|
@@ -3470,9 +3882,24 @@ async function runVault(
|
|
|
3470
3882
|
documents: snapshot.notes.map(({ path, content }) => ({ path, content })),
|
|
3471
3883
|
})
|
|
3472
3884
|
: undefined;
|
|
3885
|
+
const repositoryScopes = command.kind === "check" && command.repository !== undefined
|
|
3886
|
+
? await (dependencies.auditRepositoryMemoryScopes ?? auditRepositoryMemoryScopes)(
|
|
3887
|
+
snapshot.notes,
|
|
3888
|
+
{
|
|
3889
|
+
repositoryRoot: command.repository,
|
|
3890
|
+
detailLimit: MAX_REPOSITORY_MEMORY_DETAIL_LIMIT,
|
|
3891
|
+
},
|
|
3892
|
+
)
|
|
3893
|
+
: undefined;
|
|
3473
3894
|
output.stdout(command.json
|
|
3474
|
-
? terminalSafeJson(summary(snapshot, {
|
|
3475
|
-
|
|
3895
|
+
? terminalSafeJson(summary(snapshot, {
|
|
3896
|
+
noCatalog,
|
|
3897
|
+
...(attachments === undefined ? {} : { attachments }),
|
|
3898
|
+
...(repositoryScopes === undefined ? {} : { repositoryScopes }),
|
|
3899
|
+
}))
|
|
3900
|
+
: sanitizeTerminalText(
|
|
3901
|
+
renderSnapshot(command.kind, snapshot, noCatalog, attachments, repositoryScopes),
|
|
3902
|
+
));
|
|
3476
3903
|
return checkExitCode(snapshot, noCatalog, attachments);
|
|
3477
3904
|
}
|
|
3478
3905
|
if (command.kind === "graph") {
|
|
@@ -3580,6 +4007,8 @@ export async function main(
|
|
|
3580
4007
|
}
|
|
3581
4008
|
if (command.kind === "percolate") return await runPercolate(command, output, dependencies);
|
|
3582
4009
|
if (command.kind === "list") return await runList(command, output, dependencies);
|
|
4010
|
+
if (command.kind === "publish") return await runPublish(command, output, dependencies);
|
|
4011
|
+
if (command.kind === "serve") return await runServe(command, output, dependencies);
|
|
3583
4012
|
if (command.kind === "inbox") return await runInbox(command, output, dependencies);
|
|
3584
4013
|
if (command.kind === "catalog") return await runCatalog(command, output, dependencies);
|
|
3585
4014
|
return await runVault(command, output, dependencies);
|