librian 0.1.0 → 0.1.2
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/CHANGELOG.md +47 -1
- package/README.md +35 -10
- package/dist/cli.js +429 -271
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -2985,7 +2985,7 @@ var require_compile = __commonJS({
|
|
|
2985
2985
|
const schOrFunc = root.refs[ref];
|
|
2986
2986
|
if (schOrFunc)
|
|
2987
2987
|
return schOrFunc;
|
|
2988
|
-
let _sch =
|
|
2988
|
+
let _sch = resolve6.call(this, root, ref);
|
|
2989
2989
|
if (_sch === void 0) {
|
|
2990
2990
|
const schema = (_a3 = root.localRefs) === null || _a3 === void 0 ? void 0 : _a3[ref];
|
|
2991
2991
|
const { schemaId } = this.opts;
|
|
@@ -3012,7 +3012,7 @@ var require_compile = __commonJS({
|
|
|
3012
3012
|
function sameSchemaEnv(s1, s2) {
|
|
3013
3013
|
return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
|
|
3014
3014
|
}
|
|
3015
|
-
function
|
|
3015
|
+
function resolve6(root, ref) {
|
|
3016
3016
|
let sch;
|
|
3017
3017
|
while (typeof (sch = this.refs[ref]) == "string")
|
|
3018
3018
|
ref = sch;
|
|
@@ -3872,11 +3872,11 @@ var require_fast_uri = __commonJS({
|
|
|
3872
3872
|
normalizeString(uri, options);
|
|
3873
3873
|
} else if (typeof uri === "object") {
|
|
3874
3874
|
uri = /** @type {T} */
|
|
3875
|
-
|
|
3875
|
+
parse4(serialize(uri, options), options);
|
|
3876
3876
|
}
|
|
3877
3877
|
return uri;
|
|
3878
3878
|
}
|
|
3879
|
-
function
|
|
3879
|
+
function resolve6(baseURI, relativeURI, options) {
|
|
3880
3880
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3881
3881
|
const {
|
|
3882
3882
|
parsed: baseParsed,
|
|
@@ -3915,8 +3915,8 @@ var require_fast_uri = __commonJS({
|
|
|
3915
3915
|
function resolveComponent(base, relative3, options, skipNormalization) {
|
|
3916
3916
|
const target = {};
|
|
3917
3917
|
if (!skipNormalization) {
|
|
3918
|
-
base =
|
|
3919
|
-
relative3 =
|
|
3918
|
+
base = parse4(serialize(base, options), options);
|
|
3919
|
+
relative3 = parse4(serialize(relative3, options), options);
|
|
3920
3920
|
}
|
|
3921
3921
|
options = options || {};
|
|
3922
3922
|
if (!options.tolerant && relative3.scheme) {
|
|
@@ -4234,7 +4234,7 @@ var require_fast_uri = __commonJS({
|
|
|
4234
4234
|
}
|
|
4235
4235
|
return { parsed, malformedAuthorityOrPort, malformedPercentEncoding, malformedSchemeSpecific, malformedHost, malformedScheme };
|
|
4236
4236
|
}
|
|
4237
|
-
function
|
|
4237
|
+
function parse4(uri, opts) {
|
|
4238
4238
|
return parseWithStatus(uri, opts).parsed;
|
|
4239
4239
|
}
|
|
4240
4240
|
function normalizeString(uri, opts) {
|
|
@@ -4267,11 +4267,11 @@ var require_fast_uri = __commonJS({
|
|
|
4267
4267
|
var fastUri = {
|
|
4268
4268
|
SCHEMES,
|
|
4269
4269
|
normalize: normalize2,
|
|
4270
|
-
resolve:
|
|
4270
|
+
resolve: resolve6,
|
|
4271
4271
|
resolveComponent,
|
|
4272
4272
|
equal,
|
|
4273
4273
|
serialize,
|
|
4274
|
-
parse:
|
|
4274
|
+
parse: parse4
|
|
4275
4275
|
};
|
|
4276
4276
|
module.exports = fastUri;
|
|
4277
4277
|
module.exports.default = fastUri;
|
|
@@ -7258,12 +7258,12 @@ var require_dist = __commonJS({
|
|
|
7258
7258
|
|
|
7259
7259
|
// src/cli.ts
|
|
7260
7260
|
import { statSync as statSync5 } from "node:fs";
|
|
7261
|
-
import { resolve as
|
|
7261
|
+
import { resolve as resolve5 } from "node:path";
|
|
7262
7262
|
|
|
7263
7263
|
// package.json
|
|
7264
7264
|
var package_default = {
|
|
7265
7265
|
name: "librian",
|
|
7266
|
-
version: "0.1.
|
|
7266
|
+
version: "0.1.2",
|
|
7267
7267
|
description: "Find and read sections of a markdown docs folder over MCP, with outlines and line ranges that stay current as the docs change",
|
|
7268
7268
|
repository: {
|
|
7269
7269
|
type: "git",
|
|
@@ -7331,6 +7331,8 @@ var TITLE_MAX_CHARS = 80;
|
|
|
7331
7331
|
var EXCERPT_BYTES = 160;
|
|
7332
7332
|
var SEARCH_LIMIT_DEFAULT = 20;
|
|
7333
7333
|
var SEARCH_LIMIT_MAX = 50;
|
|
7334
|
+
var COUNT_MAX_FILES = 5e3;
|
|
7335
|
+
var COUNT_MAX_MS = 2e3;
|
|
7334
7336
|
|
|
7335
7337
|
// src/modules/catalog/catalog.ts
|
|
7336
7338
|
var CATALOG_FILE_NAME = "catalog.json";
|
|
@@ -7456,9 +7458,10 @@ function defaultEntryName(root, taken) {
|
|
|
7456
7458
|
}
|
|
7457
7459
|
}
|
|
7458
7460
|
|
|
7459
|
-
// src/modules/
|
|
7460
|
-
import {
|
|
7461
|
-
import {
|
|
7461
|
+
// src/modules/cli/folder-check.ts
|
|
7462
|
+
import { statSync as statSync2 } from "node:fs";
|
|
7463
|
+
import { homedir as homedir2 } from "node:os";
|
|
7464
|
+
import { join as join3, parse, resolve as resolve2 } from "node:path";
|
|
7462
7465
|
|
|
7463
7466
|
// src/_libs/compare-text.ts
|
|
7464
7467
|
function compareText(left, right) {
|
|
@@ -7491,6 +7494,10 @@ function compareText(left, right) {
|
|
|
7491
7494
|
return 0;
|
|
7492
7495
|
}
|
|
7493
7496
|
|
|
7497
|
+
// src/modules/docs/library.ts
|
|
7498
|
+
import { readFileSync as readFileSync2, readdirSync, realpathSync, statSync } from "node:fs";
|
|
7499
|
+
import { basename, join as join2, resolve } from "node:path";
|
|
7500
|
+
|
|
7494
7501
|
// src/_libs/is-inside.ts
|
|
7495
7502
|
import { isAbsolute, relative, sep } from "node:path";
|
|
7496
7503
|
function isInside(root, target) {
|
|
@@ -7682,18 +7689,10 @@ var ALWAYS_EXCLUDED_DIRECTORY = "node_modules";
|
|
|
7682
7689
|
function normalizeExclude(entry) {
|
|
7683
7690
|
return entry.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+$/, "");
|
|
7684
7691
|
}
|
|
7685
|
-
function
|
|
7686
|
-
const root = realpathSync.native(resolve(options.root));
|
|
7687
|
-
if (statSync(root).isDirectory() == false) {
|
|
7688
|
-
throw new Error("root is not a folder: " + root);
|
|
7689
|
-
}
|
|
7690
|
-
let name = basename(root);
|
|
7691
|
-
if (name == "") {
|
|
7692
|
-
name = root;
|
|
7693
|
-
}
|
|
7692
|
+
function listMarkdownPaths(root, exclude, limits) {
|
|
7694
7693
|
const excludedNames = /* @__PURE__ */ new Set();
|
|
7695
7694
|
const excludedPaths = /* @__PURE__ */ new Set();
|
|
7696
|
-
for (const entry of
|
|
7695
|
+
for (const entry of exclude) {
|
|
7697
7696
|
const normalized = normalizeExclude(entry);
|
|
7698
7697
|
if (normalized == "") {
|
|
7699
7698
|
continue;
|
|
@@ -7704,43 +7703,65 @@ function openLibrary(options) {
|
|
|
7704
7703
|
excludedNames.add(normalized);
|
|
7705
7704
|
}
|
|
7706
7705
|
}
|
|
7707
|
-
const
|
|
7708
|
-
|
|
7709
|
-
|
|
7710
|
-
|
|
7711
|
-
|
|
7712
|
-
|
|
7713
|
-
|
|
7714
|
-
|
|
7706
|
+
const deadline = Date.now() + (limits?.maxMs ?? Number.POSITIVE_INFINITY);
|
|
7707
|
+
const found = [];
|
|
7708
|
+
let truncated = false;
|
|
7709
|
+
const isOverLimit = () => limits != null && (found.length >= limits.maxFiles || Date.now() > deadline);
|
|
7710
|
+
const walk = (absoluteDirectory, relativePrefix) => {
|
|
7711
|
+
if (isOverLimit() == true) {
|
|
7712
|
+
truncated = true;
|
|
7713
|
+
return;
|
|
7714
|
+
}
|
|
7715
|
+
let entries;
|
|
7716
|
+
try {
|
|
7717
|
+
entries = readdirSync(absoluteDirectory, { withFileTypes: true });
|
|
7718
|
+
} catch {
|
|
7719
|
+
return;
|
|
7720
|
+
}
|
|
7721
|
+
for (const entry of entries) {
|
|
7722
|
+
if (truncated == true) {
|
|
7715
7723
|
return;
|
|
7716
7724
|
}
|
|
7717
|
-
|
|
7718
|
-
|
|
7719
|
-
|
|
7720
|
-
|
|
7721
|
-
|
|
7722
|
-
|
|
7723
|
-
|
|
7724
|
-
|
|
7725
|
-
if (entry.
|
|
7726
|
-
if (entry.name.startsWith(".") == true || entry.name == ALWAYS_EXCLUDED_DIRECTORY) {
|
|
7727
|
-
continue;
|
|
7728
|
-
}
|
|
7729
|
-
walk(join2(absoluteDirectory, entry.name), relativePath + "/");
|
|
7725
|
+
if (entry.isSymbolicLink() == true) {
|
|
7726
|
+
continue;
|
|
7727
|
+
}
|
|
7728
|
+
const relativePath = relativePrefix + entry.name;
|
|
7729
|
+
if (excludedNames.has(entry.name) == true || excludedPaths.has(relativePath) == true) {
|
|
7730
|
+
continue;
|
|
7731
|
+
}
|
|
7732
|
+
if (entry.isDirectory() == true) {
|
|
7733
|
+
if (entry.name.startsWith(".") == true || entry.name == ALWAYS_EXCLUDED_DIRECTORY) {
|
|
7730
7734
|
continue;
|
|
7731
7735
|
}
|
|
7732
|
-
|
|
7733
|
-
|
|
7736
|
+
walk(join2(absoluteDirectory, entry.name), relativePath + "/");
|
|
7737
|
+
continue;
|
|
7738
|
+
}
|
|
7739
|
+
if (entry.isFile() == true && /\.md$/i.test(entry.name) == true) {
|
|
7740
|
+
found.push(relativePath);
|
|
7741
|
+
if (isOverLimit() == true) {
|
|
7742
|
+
truncated = true;
|
|
7743
|
+
return;
|
|
7734
7744
|
}
|
|
7735
7745
|
}
|
|
7736
|
-
}
|
|
7737
|
-
|
|
7738
|
-
|
|
7746
|
+
}
|
|
7747
|
+
};
|
|
7748
|
+
walk(root, "");
|
|
7749
|
+
return { paths: found, truncated };
|
|
7750
|
+
}
|
|
7751
|
+
function openLibrary(options) {
|
|
7752
|
+
const root = realpathSync.native(resolve(options.root));
|
|
7753
|
+
if (statSync(root).isDirectory() == false) {
|
|
7754
|
+
throw new Error("root is not a folder: " + root);
|
|
7739
7755
|
}
|
|
7756
|
+
let name = basename(root);
|
|
7757
|
+
if (name == "") {
|
|
7758
|
+
name = root;
|
|
7759
|
+
}
|
|
7760
|
+
const cache = /* @__PURE__ */ new Map();
|
|
7740
7761
|
function refresh() {
|
|
7741
7762
|
const documents = [];
|
|
7742
7763
|
const seen = /* @__PURE__ */ new Set();
|
|
7743
|
-
for (const path of listMarkdownPaths().sort(compareText)) {
|
|
7764
|
+
for (const path of listMarkdownPaths(root, options.exclude).paths.sort(compareText)) {
|
|
7744
7765
|
const absolutePath = join2(root, path);
|
|
7745
7766
|
let modifiedMs;
|
|
7746
7767
|
let size;
|
|
@@ -7885,6 +7906,113 @@ function cutPage(document, start, end, budgetBytes) {
|
|
|
7885
7906
|
return { text: joinLines2(lastLine), lastLine };
|
|
7886
7907
|
}
|
|
7887
7908
|
|
|
7909
|
+
// src/modules/cli/folder-check.ts
|
|
7910
|
+
var LARGEST_FILE_COUNT = 3;
|
|
7911
|
+
var COUNT_LIMITS = { maxFiles: COUNT_MAX_FILES, maxMs: COUNT_MAX_MS };
|
|
7912
|
+
function isFolder(path) {
|
|
7913
|
+
try {
|
|
7914
|
+
return statSync2(path).isDirectory();
|
|
7915
|
+
} catch {
|
|
7916
|
+
return false;
|
|
7917
|
+
}
|
|
7918
|
+
}
|
|
7919
|
+
function comparable(path) {
|
|
7920
|
+
const resolved = resolve2(path);
|
|
7921
|
+
if (process.platform == "win32") {
|
|
7922
|
+
return resolved.toLowerCase();
|
|
7923
|
+
}
|
|
7924
|
+
return resolved;
|
|
7925
|
+
}
|
|
7926
|
+
function isSameFolder(left, right) {
|
|
7927
|
+
return comparable(left) == comparable(right);
|
|
7928
|
+
}
|
|
7929
|
+
function isHomeOrDriveRoot(path) {
|
|
7930
|
+
const resolved = resolve2(path);
|
|
7931
|
+
return isSameFolder(resolved, homedir2()) || isSameFolder(resolved, parse(resolved).root);
|
|
7932
|
+
}
|
|
7933
|
+
function normalizeFolderInput(input2, base = process.cwd()) {
|
|
7934
|
+
let folder = input2.trim();
|
|
7935
|
+
const quoted = /^(["'])(.*)\1$/.exec(folder);
|
|
7936
|
+
if (quoted != null) {
|
|
7937
|
+
folder = quoted[2].trim();
|
|
7938
|
+
}
|
|
7939
|
+
if (folder == "") {
|
|
7940
|
+
return "";
|
|
7941
|
+
}
|
|
7942
|
+
if (folder == "~" || folder.startsWith("~/") || folder.startsWith("~\\")) {
|
|
7943
|
+
folder = homedir2() + folder.slice(1);
|
|
7944
|
+
}
|
|
7945
|
+
return resolve2(base, folder);
|
|
7946
|
+
}
|
|
7947
|
+
function formatFileCount(files, truncated) {
|
|
7948
|
+
let suffix = "";
|
|
7949
|
+
if (truncated == true) {
|
|
7950
|
+
suffix = "+";
|
|
7951
|
+
}
|
|
7952
|
+
if (files == 1 && truncated == false) {
|
|
7953
|
+
return "1 file";
|
|
7954
|
+
}
|
|
7955
|
+
return `${files}${suffix} files`;
|
|
7956
|
+
}
|
|
7957
|
+
function countMarkdownFiles(root, exclude) {
|
|
7958
|
+
if (isFolder(root) == false) {
|
|
7959
|
+
return null;
|
|
7960
|
+
}
|
|
7961
|
+
const scan = listMarkdownPaths(root, exclude, COUNT_LIMITS);
|
|
7962
|
+
return { files: scan.paths.length, truncated: scan.truncated };
|
|
7963
|
+
}
|
|
7964
|
+
function checkFolder(root, exclude) {
|
|
7965
|
+
if (isFolder(root) == false) {
|
|
7966
|
+
return { ok: false, message: `The docs folder does not exist or is not a folder: ${root}` };
|
|
7967
|
+
}
|
|
7968
|
+
const scan = listMarkdownPaths(root, exclude, COUNT_LIMITS);
|
|
7969
|
+
const sized = scan.paths.map((path) => {
|
|
7970
|
+
let bytes = 0;
|
|
7971
|
+
try {
|
|
7972
|
+
bytes = statSync2(join3(root, path)).size;
|
|
7973
|
+
} catch {
|
|
7974
|
+
bytes = 0;
|
|
7975
|
+
}
|
|
7976
|
+
return { path, bytes };
|
|
7977
|
+
});
|
|
7978
|
+
sized.sort((left, right) => right.bytes - left.bytes || compareText(left.path, right.path));
|
|
7979
|
+
return {
|
|
7980
|
+
ok: true,
|
|
7981
|
+
files: sized.length,
|
|
7982
|
+
truncated: scan.truncated,
|
|
7983
|
+
totalBytes: sized.reduce((sum, file2) => sum + file2.bytes, 0),
|
|
7984
|
+
largest: sized.slice(0, LARGEST_FILE_COUNT)
|
|
7985
|
+
};
|
|
7986
|
+
}
|
|
7987
|
+
function summarizeCheck(check2) {
|
|
7988
|
+
if (check2.ok == false) {
|
|
7989
|
+
return "folder not found";
|
|
7990
|
+
}
|
|
7991
|
+
if (check2.truncated == true) {
|
|
7992
|
+
return formatFileCount(check2.files, true);
|
|
7993
|
+
}
|
|
7994
|
+
return `${formatFileCount(check2.files, false)} \xB7 ${formatSize(check2.totalBytes)}`;
|
|
7995
|
+
}
|
|
7996
|
+
function describeCheck(check2) {
|
|
7997
|
+
if (check2.ok == false) {
|
|
7998
|
+
return [check2.message];
|
|
7999
|
+
}
|
|
8000
|
+
const lines = [summarizeCheck(check2)];
|
|
8001
|
+
if (check2.truncated == true) {
|
|
8002
|
+
lines.push(`Stopped counting after ${COUNT_MAX_FILES} files or ${COUNT_MAX_MS / 1e3} seconds. Is this the docs folder?`);
|
|
8003
|
+
return lines;
|
|
8004
|
+
}
|
|
8005
|
+
if (check2.files == 0) {
|
|
8006
|
+
lines.push("No .md files found. Check the folder and the Exclude list.");
|
|
8007
|
+
return lines;
|
|
8008
|
+
}
|
|
8009
|
+
lines.push("Largest:");
|
|
8010
|
+
for (const file2 of check2.largest) {
|
|
8011
|
+
lines.push(` ${file2.path} ${formatSize(file2.bytes)}`);
|
|
8012
|
+
}
|
|
8013
|
+
return lines;
|
|
8014
|
+
}
|
|
8015
|
+
|
|
7888
8016
|
// src/modules/cli/display.ts
|
|
7889
8017
|
var STYLE_CODES = {
|
|
7890
8018
|
dim: "\x1B[2m",
|
|
@@ -8022,67 +8150,6 @@ function renderParts(parts, maxWidth, color) {
|
|
|
8022
8150
|
return line;
|
|
8023
8151
|
}
|
|
8024
8152
|
|
|
8025
|
-
// src/modules/cli/folder-check.ts
|
|
8026
|
-
import { statSync as statSync2 } from "node:fs";
|
|
8027
|
-
import { homedir as homedir2 } from "node:os";
|
|
8028
|
-
import { resolve as resolve2 } from "node:path";
|
|
8029
|
-
var LARGEST_FILE_COUNT = 3;
|
|
8030
|
-
function isFolder(path) {
|
|
8031
|
-
try {
|
|
8032
|
-
return statSync2(path).isDirectory();
|
|
8033
|
-
} catch {
|
|
8034
|
-
return false;
|
|
8035
|
-
}
|
|
8036
|
-
}
|
|
8037
|
-
function normalizeFolderInput(input2) {
|
|
8038
|
-
let folder = input2.trim();
|
|
8039
|
-
const quoted = /^(["'])(.*)\1$/.exec(folder);
|
|
8040
|
-
if (quoted != null) {
|
|
8041
|
-
folder = quoted[2].trim();
|
|
8042
|
-
}
|
|
8043
|
-
if (folder == "") {
|
|
8044
|
-
return "";
|
|
8045
|
-
}
|
|
8046
|
-
if (folder == "~" || folder.startsWith("~/") || folder.startsWith("~\\")) {
|
|
8047
|
-
folder = homedir2() + folder.slice(1);
|
|
8048
|
-
}
|
|
8049
|
-
return resolve2(folder);
|
|
8050
|
-
}
|
|
8051
|
-
function checkFolder(root, exclude) {
|
|
8052
|
-
if (isFolder(root) == false) {
|
|
8053
|
-
return { ok: false, message: `The docs folder does not exist or is not a folder: ${root}` };
|
|
8054
|
-
}
|
|
8055
|
-
const documents = openLibrary({ root, exclude }).refresh();
|
|
8056
|
-
const bySize = [...documents].sort((left, right) => right.totalBytes - left.totalBytes || compareText(left.path, right.path));
|
|
8057
|
-
return {
|
|
8058
|
-
ok: true,
|
|
8059
|
-
files: documents.length,
|
|
8060
|
-
totalBytes: documents.reduce((sum, document) => sum + document.totalBytes, 0),
|
|
8061
|
-
largest: bySize.slice(0, LARGEST_FILE_COUNT).map((document) => ({ path: document.path, bytes: document.totalBytes }))
|
|
8062
|
-
};
|
|
8063
|
-
}
|
|
8064
|
-
function summarizeCheck(check2) {
|
|
8065
|
-
if (check2.ok == false) {
|
|
8066
|
-
return "folder not found";
|
|
8067
|
-
}
|
|
8068
|
-
return `${pluralize(check2.files, "file")} \xB7 ${formatSize(check2.totalBytes)}`;
|
|
8069
|
-
}
|
|
8070
|
-
function describeCheck(check2) {
|
|
8071
|
-
if (check2.ok == false) {
|
|
8072
|
-
return [check2.message];
|
|
8073
|
-
}
|
|
8074
|
-
const lines = [summarizeCheck(check2)];
|
|
8075
|
-
if (check2.files == 0) {
|
|
8076
|
-
lines.push("No .md files found. Check the folder and the Exclude list.");
|
|
8077
|
-
return lines;
|
|
8078
|
-
}
|
|
8079
|
-
lines.push("Largest:");
|
|
8080
|
-
for (const file2 of check2.largest) {
|
|
8081
|
-
lines.push(` ${file2.path} ${formatSize(file2.bytes)}`);
|
|
8082
|
-
}
|
|
8083
|
-
return lines;
|
|
8084
|
-
}
|
|
8085
|
-
|
|
8086
8153
|
// src/modules/cli/input-owner.ts
|
|
8087
8154
|
var InputOwner = class {
|
|
8088
8155
|
constructor(input2) {
|
|
@@ -8138,8 +8205,8 @@ var InputOwner = class {
|
|
|
8138
8205
|
this.pendingText = "";
|
|
8139
8206
|
return rest;
|
|
8140
8207
|
}
|
|
8141
|
-
await new Promise((
|
|
8142
|
-
this.lineWaiter =
|
|
8208
|
+
await new Promise((resolve6) => {
|
|
8209
|
+
this.lineWaiter = resolve6;
|
|
8143
8210
|
this.input.resume();
|
|
8144
8211
|
});
|
|
8145
8212
|
this.lineWaiter = null;
|
|
@@ -8304,6 +8371,9 @@ function writeLine(text2 = "") {
|
|
|
8304
8371
|
function styled(text2, style) {
|
|
8305
8372
|
return styleText(text2, style, getTerminal().color);
|
|
8306
8373
|
}
|
|
8374
|
+
function tickMark() {
|
|
8375
|
+
return styleText(symbolsOf(getTerminal()).tick, "green", getTerminal().color);
|
|
8376
|
+
}
|
|
8307
8377
|
function columnsOf(terminal) {
|
|
8308
8378
|
return terminal.output.columns ?? DEFAULT_COLUMNS;
|
|
8309
8379
|
}
|
|
@@ -8366,7 +8436,7 @@ async function withRawMode(terminal, hideCursor, frame, body) {
|
|
|
8366
8436
|
}
|
|
8367
8437
|
}
|
|
8368
8438
|
function readKeys(terminal, onKey) {
|
|
8369
|
-
return new Promise((
|
|
8439
|
+
return new Promise((resolve6, reject) => {
|
|
8370
8440
|
let finished = false;
|
|
8371
8441
|
const stop = terminal.owner.beginKeys(
|
|
8372
8442
|
(chunk) => {
|
|
@@ -8379,7 +8449,7 @@ function readKeys(terminal, onKey) {
|
|
|
8379
8449
|
if (outcome != void 0) {
|
|
8380
8450
|
finished = true;
|
|
8381
8451
|
stop();
|
|
8382
|
-
|
|
8452
|
+
resolve6(outcome.result);
|
|
8383
8453
|
return;
|
|
8384
8454
|
}
|
|
8385
8455
|
} catch (error62) {
|
|
@@ -8847,6 +8917,122 @@ async function confirm(question, defaultYes, options = {}) {
|
|
|
8847
8917
|
return confirmWithLines(terminal, question, defaultYes);
|
|
8848
8918
|
}
|
|
8849
8919
|
|
|
8920
|
+
// src/modules/cli/quick-add.ts
|
|
8921
|
+
function initialFolderFor(currentFolder) {
|
|
8922
|
+
if (isHomeOrDriveRoot(currentFolder) == true) {
|
|
8923
|
+
return "";
|
|
8924
|
+
}
|
|
8925
|
+
return currentFolder;
|
|
8926
|
+
}
|
|
8927
|
+
async function addFolderAsEntry(home, root) {
|
|
8928
|
+
const catalog = readCatalog(home);
|
|
8929
|
+
const existing = catalog.entries.find((entry) => isSameFolder(entry.root, root));
|
|
8930
|
+
if (existing != null) {
|
|
8931
|
+
writeLine(`Already added as "${existing.name}".`);
|
|
8932
|
+
return { kind: "exists", name: existing.name };
|
|
8933
|
+
}
|
|
8934
|
+
const check2 = checkFolder(root, []);
|
|
8935
|
+
if (check2.ok == false) {
|
|
8936
|
+
writeLine(styled(check2.message, "red"));
|
|
8937
|
+
return { kind: "declined" };
|
|
8938
|
+
}
|
|
8939
|
+
let summary = formatFileCount(check2.files, check2.truncated).replace(/ files?$/, (unit) => ` markdown${unit}`);
|
|
8940
|
+
if (check2.truncated == false) {
|
|
8941
|
+
summary += ` \xB7 ${formatSize(check2.totalBytes)}`;
|
|
8942
|
+
}
|
|
8943
|
+
writeLine(` ${summary}`);
|
|
8944
|
+
if (check2.files == 0) {
|
|
8945
|
+
writeLine(styled("No markdown files were found in this folder.", "yellow"));
|
|
8946
|
+
}
|
|
8947
|
+
const name = defaultEntryName(root, catalog.entries.map((entry) => entry.name));
|
|
8948
|
+
const accepted = await confirm(`Add it as "${name}"?`, check2.files > 0, { transient: true });
|
|
8949
|
+
if (accepted == false) {
|
|
8950
|
+
return { kind: "declined" };
|
|
8951
|
+
}
|
|
8952
|
+
const latest = readCatalog(home);
|
|
8953
|
+
const finalName = defaultEntryName(root, latest.entries.map((entry) => entry.name));
|
|
8954
|
+
latest.entries.push({ name: finalName, root, exclude: [], maxBytes: DEFAULT_MAX_BYTES });
|
|
8955
|
+
writeCatalog(home, latest);
|
|
8956
|
+
writeLine(`${tickMark()} Added ${finalName}. Open a new session to use ${finalName}__read and the other tools.`);
|
|
8957
|
+
return { kind: "added", name: finalName };
|
|
8958
|
+
}
|
|
8959
|
+
async function quickAddFromMenu(home, initialFolder, base) {
|
|
8960
|
+
let candidate = initialFolder;
|
|
8961
|
+
for (; ; ) {
|
|
8962
|
+
let typed;
|
|
8963
|
+
try {
|
|
8964
|
+
typed = await text("Docs folder", { initial: candidate, hint: "the folder that holds your .md files", transient: true });
|
|
8965
|
+
} catch (error62) {
|
|
8966
|
+
if (error62 instanceof PromptBackError) {
|
|
8967
|
+
return { kind: "declined" };
|
|
8968
|
+
}
|
|
8969
|
+
throw error62;
|
|
8970
|
+
}
|
|
8971
|
+
const root = normalizeFolderInput(typed, base);
|
|
8972
|
+
if (root == "") {
|
|
8973
|
+
writeLine(styled("Enter the path of a docs folder.", "red"));
|
|
8974
|
+
candidate = typed;
|
|
8975
|
+
continue;
|
|
8976
|
+
}
|
|
8977
|
+
if (isFolder(root) == false) {
|
|
8978
|
+
writeLine(styled(`The folder does not exist or is not a folder: ${root}`, "red"));
|
|
8979
|
+
candidate = typed;
|
|
8980
|
+
continue;
|
|
8981
|
+
}
|
|
8982
|
+
writeLine(`${tickMark()} Docs folder \xB7 ${root}`);
|
|
8983
|
+
try {
|
|
8984
|
+
return await addFolderAsEntry(home, root);
|
|
8985
|
+
} catch (error62) {
|
|
8986
|
+
if (error62 instanceof PromptBackError) {
|
|
8987
|
+
return { kind: "declined" };
|
|
8988
|
+
}
|
|
8989
|
+
throw error62;
|
|
8990
|
+
}
|
|
8991
|
+
}
|
|
8992
|
+
}
|
|
8993
|
+
|
|
8994
|
+
// src/modules/cli/add-command.ts
|
|
8995
|
+
var EXIT_USAGE = 2;
|
|
8996
|
+
async function runAddCommand(options) {
|
|
8997
|
+
let root = normalizeFolderInput(options.cwd, options.cwd);
|
|
8998
|
+
if (options.folder != null) {
|
|
8999
|
+
root = normalizeFolderInput(options.folder, options.cwd);
|
|
9000
|
+
}
|
|
9001
|
+
if (isHomeOrDriveRoot(root) == true) {
|
|
9002
|
+
options.writeError(`"${root}" is your home folder or a drive root, not a docs folder. Run librian add inside a docs folder, or pass its path: librian add <folder>`);
|
|
9003
|
+
return EXIT_USAGE;
|
|
9004
|
+
}
|
|
9005
|
+
if (isFolder(root) == false) {
|
|
9006
|
+
options.writeError(`The folder does not exist or is not a folder: ${root}`);
|
|
9007
|
+
return EXIT_USAGE;
|
|
9008
|
+
}
|
|
9009
|
+
try {
|
|
9010
|
+
writeLine(`Docs folder \xB7 ${root}`);
|
|
9011
|
+
const outcome = await addFolderAsEntry(options.home, root);
|
|
9012
|
+
if (outcome.kind == "declined") {
|
|
9013
|
+
writeLine("Nothing added.");
|
|
9014
|
+
}
|
|
9015
|
+
if (outcome.kind == "added" && readCatalog(options.home).services.length == 0) {
|
|
9016
|
+
writeLine("Run librian and choose Register to use it in Claude Code or Codex.");
|
|
9017
|
+
}
|
|
9018
|
+
return 0;
|
|
9019
|
+
} catch (error62) {
|
|
9020
|
+
if (error62 instanceof PromptClosedError) {
|
|
9021
|
+
return 0;
|
|
9022
|
+
}
|
|
9023
|
+
if (error62 instanceof PromptBackError) {
|
|
9024
|
+
writeLine("Nothing added.");
|
|
9025
|
+
return 0;
|
|
9026
|
+
}
|
|
9027
|
+
let reason = String(error62);
|
|
9028
|
+
if (error62 instanceof Error) {
|
|
9029
|
+
reason = error62.message;
|
|
9030
|
+
}
|
|
9031
|
+
options.writeError(reason);
|
|
9032
|
+
return 1;
|
|
9033
|
+
}
|
|
9034
|
+
}
|
|
9035
|
+
|
|
8850
9036
|
// src/modules/cli/entry-form.ts
|
|
8851
9037
|
var FORM_ORDER = ["name", "folder", "exclude", "max", "check", "save", "cancel"];
|
|
8852
9038
|
function snapshotOf(draft) {
|
|
@@ -8860,14 +9046,6 @@ function nextRow(current) {
|
|
|
8860
9046
|
return FORM_ORDER[Math.min(position + 1, FORM_ORDER.length - 1)];
|
|
8861
9047
|
}
|
|
8862
9048
|
function buildRows(draft, home, lastCheck) {
|
|
8863
|
-
let nameDetail = draft.name;
|
|
8864
|
-
if (nameDetail == "") {
|
|
8865
|
-
nameDetail = "(from the folder)";
|
|
8866
|
-
}
|
|
8867
|
-
let nameHint = "";
|
|
8868
|
-
if (draft.nameTouched == false) {
|
|
8869
|
-
nameHint = "follows the folder until you change it";
|
|
8870
|
-
}
|
|
8871
9049
|
let folderDetail = draft.root;
|
|
8872
9050
|
let folderKind = "path";
|
|
8873
9051
|
let folderHint = "";
|
|
@@ -8886,7 +9064,7 @@ function buildRows(draft, home, lastCheck) {
|
|
|
8886
9064
|
checkDetail = lastCheck.summary;
|
|
8887
9065
|
}
|
|
8888
9066
|
return [
|
|
8889
|
-
{ value: "name", key: "name", label: "Name", detail:
|
|
9067
|
+
{ value: "name", key: "name", label: "Name", detail: draft.name, hint: "prefixes the tool names" },
|
|
8890
9068
|
{ value: "folder", key: "folder", label: "Docs folder", detail: folderDetail, detailKind: folderKind, hint: folderHint },
|
|
8891
9069
|
{ value: "exclude", key: "exclude", label: "Exclude", detail: excludeDetail, hint: "folder names or paths to skip" },
|
|
8892
9070
|
{ value: "max", key: "max", label: "Max bytes", detail: String(draft.maxBytes), hint: "response size limit" },
|
|
@@ -8899,33 +9077,24 @@ function buildRows(draft, home, lastCheck) {
|
|
|
8899
9077
|
async function openEntryForm(home, editing) {
|
|
8900
9078
|
const catalog = readCatalog(home);
|
|
8901
9079
|
const existing = catalog.entries.find((entry) => entry.name == editing);
|
|
8902
|
-
|
|
8903
|
-
|
|
8904
|
-
|
|
8905
|
-
if (existing != null) {
|
|
8906
|
-
draft = { name: existing.name, nameTouched: true, root: existing.root, exclude: [...existing.exclude], maxBytes: existing.maxBytes };
|
|
8907
|
-
cursor = "name";
|
|
9080
|
+
if (existing == null) {
|
|
9081
|
+
writeLine(styled(`There is no docs folder named "${editing}" any more.`, "red"));
|
|
9082
|
+
return "cancelled";
|
|
8908
9083
|
}
|
|
9084
|
+
const otherNames = () => readCatalog(home).entries.filter((entry) => entry.name != editing).map((entry) => entry.name);
|
|
9085
|
+
let draft = { name: existing.name, root: existing.root, exclude: [...existing.exclude], maxBytes: existing.maxBytes };
|
|
9086
|
+
let cursor = "name";
|
|
8909
9087
|
const openingSnapshot = snapshotOf(draft);
|
|
8910
9088
|
let lastCheck = null;
|
|
8911
|
-
let verifiedKey =
|
|
8912
|
-
|
|
8913
|
-
verifiedKey = checkKeyOf(draft);
|
|
8914
|
-
}
|
|
8915
|
-
let title = "Add docs folder";
|
|
8916
|
-
if (existing != null) {
|
|
8917
|
-
title = `Edit "${existing.name}"`;
|
|
8918
|
-
}
|
|
9089
|
+
let verifiedKey = checkKeyOf(draft);
|
|
9090
|
+
const title = `Edit "${existing.name}"`;
|
|
8919
9091
|
const askName = async () => {
|
|
8920
9092
|
let candidate = draft.name;
|
|
8921
9093
|
for (; ; ) {
|
|
8922
9094
|
const typed = (await text("Name", { initial: candidate, hint: "lowercase letters, digits and _, up to 24", transient: true })).trim();
|
|
8923
9095
|
const problem = checkEntryName(typed, otherNames());
|
|
8924
9096
|
if (problem == null) {
|
|
8925
|
-
|
|
8926
|
-
draft.name = typed;
|
|
8927
|
-
draft.nameTouched = true;
|
|
8928
|
-
}
|
|
9097
|
+
draft.name = typed;
|
|
8929
9098
|
return;
|
|
8930
9099
|
}
|
|
8931
9100
|
writeLine(styled(problem, "red"));
|
|
@@ -8935,12 +9104,6 @@ async function openEntryForm(home, editing) {
|
|
|
8935
9104
|
const askFolder = async () => {
|
|
8936
9105
|
const typed = await text("Docs folder", { initial: draft.root, hint: "the folder that holds your .md files", transient: true });
|
|
8937
9106
|
draft.root = normalizeFolderInput(typed);
|
|
8938
|
-
if (draft.nameTouched == false) {
|
|
8939
|
-
draft.name = "";
|
|
8940
|
-
if (draft.root != "") {
|
|
8941
|
-
draft.name = defaultEntryName(draft.root, otherNames());
|
|
8942
|
-
}
|
|
8943
|
-
}
|
|
8944
9107
|
};
|
|
8945
9108
|
const askExclude = async () => {
|
|
8946
9109
|
const typed = await text("Exclude", { initial: draft.exclude.join(", "), hint: "comma separated, empty for none", transient: true });
|
|
@@ -9004,7 +9167,7 @@ async function openEntryForm(home, editing) {
|
|
|
9004
9167
|
const entry = { name: draft.name, root: draft.root, exclude: draft.exclude, maxBytes: draft.maxBytes };
|
|
9005
9168
|
try {
|
|
9006
9169
|
const latest = readCatalog(home);
|
|
9007
|
-
const position = latest.entries.findIndex((item) => item.name ==
|
|
9170
|
+
const position = latest.entries.findIndex((item) => item.name == existing.name);
|
|
9008
9171
|
if (position >= 0) {
|
|
9009
9172
|
latest.entries[position] = entry;
|
|
9010
9173
|
} else {
|
|
@@ -9098,21 +9261,6 @@ var SERVICE_NAMES = { claude: "Claude Code", codex: "Codex" };
|
|
|
9098
9261
|
var ITEM_PREFIX = "item:";
|
|
9099
9262
|
var ENTRY_PATH_WIDTH = 50;
|
|
9100
9263
|
var HOME_PATH_WIDTH = 40;
|
|
9101
|
-
var LibraryCache = class {
|
|
9102
|
-
libraries = /* @__PURE__ */ new Map();
|
|
9103
|
-
countFiles(entry) {
|
|
9104
|
-
if (isFolder(entry.root) == false) {
|
|
9105
|
-
return null;
|
|
9106
|
-
}
|
|
9107
|
-
const key = JSON.stringify([entry.root, entry.exclude]);
|
|
9108
|
-
let library = this.libraries.get(key);
|
|
9109
|
-
if (library == null) {
|
|
9110
|
-
library = openLibrary({ root: entry.root, exclude: entry.exclude });
|
|
9111
|
-
this.libraries.set(key, library);
|
|
9112
|
-
}
|
|
9113
|
-
return library.refresh().length;
|
|
9114
|
-
}
|
|
9115
|
-
};
|
|
9116
9264
|
function describeServices(catalog) {
|
|
9117
9265
|
if (catalog.services.length == 0) {
|
|
9118
9266
|
return "none registered";
|
|
@@ -9133,13 +9281,13 @@ function describeRuntime(home, context) {
|
|
|
9133
9281
|
return "status unknown";
|
|
9134
9282
|
}
|
|
9135
9283
|
}
|
|
9136
|
-
function buildMainRows(home, context, catalog
|
|
9284
|
+
function buildMainRows(home, context, catalog) {
|
|
9137
9285
|
const rows = [];
|
|
9138
9286
|
for (const entry of catalog.entries) {
|
|
9139
|
-
const
|
|
9287
|
+
const counted = countMarkdownFiles(entry.root, entry.exclude);
|
|
9140
9288
|
let hint = "folder not found";
|
|
9141
|
-
if (
|
|
9142
|
-
hint =
|
|
9289
|
+
if (counted != null) {
|
|
9290
|
+
hint = formatFileCount(counted.files, counted.truncated);
|
|
9143
9291
|
}
|
|
9144
9292
|
rows.push({ value: ITEM_PREFIX + entry.name, label: entry.name, detail: entry.root, detailKind: "path", hint });
|
|
9145
9293
|
}
|
|
@@ -9147,7 +9295,7 @@ function buildMainRows(home, context, catalog, cache) {
|
|
|
9147
9295
|
rows.push("separator");
|
|
9148
9296
|
}
|
|
9149
9297
|
rows.push({ value: "add", key: "add", label: "Add docs folder" });
|
|
9150
|
-
rows.push({ value: "services", key: "services", label: "
|
|
9298
|
+
rows.push({ value: "services", key: "services", label: "Register", hint: describeServices(catalog) });
|
|
9151
9299
|
rows.push({ value: "runtime", key: "runtime", label: "Runtime", hint: describeRuntime(home, context) });
|
|
9152
9300
|
rows.push({ value: "quit", key: "quit", label: "Quit" });
|
|
9153
9301
|
return rows;
|
|
@@ -9225,7 +9373,6 @@ async function runScreen(open2) {
|
|
|
9225
9373
|
}
|
|
9226
9374
|
}
|
|
9227
9375
|
async function runMainMenu(home, context) {
|
|
9228
|
-
const cache = new LibraryCache();
|
|
9229
9376
|
let cursor;
|
|
9230
9377
|
for (; ; ) {
|
|
9231
9378
|
let catalog;
|
|
@@ -9241,7 +9388,7 @@ async function runMainMenu(home, context) {
|
|
|
9241
9388
|
}
|
|
9242
9389
|
let choice;
|
|
9243
9390
|
try {
|
|
9244
|
-
choice = await select(`librian ${context.version} \xB7 ${shortenPath(home, HOME_PATH_WIDTH)}`, buildMainRows(home, context, catalog
|
|
9391
|
+
choice = await select(`librian ${context.version} \xB7 ${shortenPath(home, HOME_PATH_WIDTH)}`, buildMainRows(home, context, catalog), { initial: cursor, transient: true });
|
|
9245
9392
|
} catch (error62) {
|
|
9246
9393
|
if (error62 instanceof PromptBackError) {
|
|
9247
9394
|
return 0;
|
|
@@ -9253,11 +9400,9 @@ async function runMainMenu(home, context) {
|
|
|
9253
9400
|
return 0;
|
|
9254
9401
|
}
|
|
9255
9402
|
if (choice == "add") {
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
cursor = ITEM_PREFIX + newest.name;
|
|
9260
|
-
}
|
|
9403
|
+
const outcome = await quickAddFromMenu(home, initialFolderFor(context.cwd ?? process.cwd()), context.cwd ?? process.cwd());
|
|
9404
|
+
if (outcome.kind != "declined") {
|
|
9405
|
+
cursor = ITEM_PREFIX + outcome.name;
|
|
9261
9406
|
}
|
|
9262
9407
|
} else if (choice == "services") {
|
|
9263
9408
|
await runScreen(() => context.openServicesScreen(home));
|
|
@@ -9281,7 +9426,8 @@ async function openMainMenu(home, context) {
|
|
|
9281
9426
|
|
|
9282
9427
|
// src/modules/mcp/arguments.ts
|
|
9283
9428
|
var USAGE = [
|
|
9284
|
-
"Usage: librian Open the menu (docs folders,
|
|
9429
|
+
"Usage: librian Open the menu (docs folders, register, runtime)",
|
|
9430
|
+
" librian add [<folder>] Add a folder (default: the current folder) as a docs folder, without the menu",
|
|
9285
9431
|
" librian serve --catalog Serve every docs folder of the catalog (what AI services run)",
|
|
9286
9432
|
" librian serve --root <folder> [--exclude <name>]... [--max-bytes <n>]",
|
|
9287
9433
|
" Serve one folder with unprefixed tools",
|
|
@@ -9289,7 +9435,7 @@ var USAGE = [
|
|
|
9289
9435
|
"",
|
|
9290
9436
|
" --catalog Read the docs folders from <LIBRIAN_HOME>/catalog.json (default ~/.librian)",
|
|
9291
9437
|
" --root <folder> Markdown docs folder to serve",
|
|
9292
|
-
" --exclude <name> Skip a folder name (e.g. evidence) or a root-relative path (e.g.
|
|
9438
|
+
" --exclude <name> Skip a folder name (e.g. evidence) or a root-relative path (e.g. guide/archive); repeatable",
|
|
9293
9439
|
` --max-bytes <n> Response size limit in UTF-8 bytes (default ${DEFAULT_MAX_BYTES}, minimum ${MIN_MAX_BYTES})`,
|
|
9294
9440
|
" --help Show this help",
|
|
9295
9441
|
" --version Show the version"
|
|
@@ -9357,6 +9503,28 @@ function parseServe(argv) {
|
|
|
9357
9503
|
}
|
|
9358
9504
|
return { kind: "serve-root", root, exclude, maxBytes: maxBytes ?? DEFAULT_MAX_BYTES };
|
|
9359
9505
|
}
|
|
9506
|
+
function parseAdd(argv) {
|
|
9507
|
+
let folder = null;
|
|
9508
|
+
for (const token of argv) {
|
|
9509
|
+
if (token == "--help") {
|
|
9510
|
+
return { kind: "help" };
|
|
9511
|
+
}
|
|
9512
|
+
if (token == "--version") {
|
|
9513
|
+
return { kind: "version" };
|
|
9514
|
+
}
|
|
9515
|
+
if (token.startsWith("-") == true) {
|
|
9516
|
+
return { kind: "error", message: `Unknown argument "${token}".` };
|
|
9517
|
+
}
|
|
9518
|
+
if (token == "") {
|
|
9519
|
+
return { kind: "error", message: "The folder must not be empty." };
|
|
9520
|
+
}
|
|
9521
|
+
if (folder != null) {
|
|
9522
|
+
return { kind: "error", message: "librian add takes one folder." };
|
|
9523
|
+
}
|
|
9524
|
+
folder = token;
|
|
9525
|
+
}
|
|
9526
|
+
return { kind: "add", folder };
|
|
9527
|
+
}
|
|
9360
9528
|
function parseArguments(argv) {
|
|
9361
9529
|
if (argv.length == 0) {
|
|
9362
9530
|
return { kind: "menu" };
|
|
@@ -9368,6 +9536,9 @@ function parseArguments(argv) {
|
|
|
9368
9536
|
if (command == "--version") {
|
|
9369
9537
|
return { kind: "version" };
|
|
9370
9538
|
}
|
|
9539
|
+
if (command == "add") {
|
|
9540
|
+
return parseAdd(argv.slice(1));
|
|
9541
|
+
}
|
|
9371
9542
|
if (command == "serve") {
|
|
9372
9543
|
return parseServe(argv.slice(1));
|
|
9373
9544
|
}
|
|
@@ -13562,7 +13733,7 @@ __export(core_exports2, {
|
|
|
13562
13733
|
memoizer: () => memoizer,
|
|
13563
13734
|
mergeValues: () => mergeValues2,
|
|
13564
13735
|
meta: () => meta,
|
|
13565
|
-
parse: () =>
|
|
13736
|
+
parse: () => parse2,
|
|
13566
13737
|
parseAsync: () => parseAsync,
|
|
13567
13738
|
parseURLObject: () => parseURLObject,
|
|
13568
13739
|
prettifyError: () => prettifyError,
|
|
@@ -14782,7 +14953,7 @@ var _parse = (_Err) => {
|
|
|
14782
14953
|
};
|
|
14783
14954
|
return fn;
|
|
14784
14955
|
};
|
|
14785
|
-
var
|
|
14956
|
+
var parse2 = /* @__PURE__ */ _parse($ZodRealError);
|
|
14786
14957
|
var _parseAsync = (_Err) => {
|
|
14787
14958
|
const fn = async (schema, value, _ctx, params) => {
|
|
14788
14959
|
const ctx = _ctx ? { ..._ctx, async: true } : { async: true };
|
|
@@ -14870,18 +15041,18 @@ var validateAsync = async (schema, value, _ctx) => {
|
|
|
14870
15041
|
return result.issues.length === 0;
|
|
14871
15042
|
};
|
|
14872
15043
|
var _encode = (_Err) => {
|
|
14873
|
-
const
|
|
15044
|
+
const parse4 = _parse(_Err);
|
|
14874
15045
|
const fn = (schema, value, _ctx, _params) => {
|
|
14875
15046
|
const ctx = _ctx ? { ..._ctx, direction: "backward" } : { direction: "backward" };
|
|
14876
|
-
return
|
|
15047
|
+
return parse4(schema, value, ctx, finalizeParams(fn, _params));
|
|
14877
15048
|
};
|
|
14878
15049
|
return fn;
|
|
14879
15050
|
};
|
|
14880
15051
|
var encode = /* @__PURE__ */ _encode($ZodRealError);
|
|
14881
15052
|
var _decode = (_Err) => {
|
|
14882
|
-
const
|
|
15053
|
+
const parse4 = _parse(_Err);
|
|
14883
15054
|
const fn = (schema, value, _ctx, _params) => {
|
|
14884
|
-
return
|
|
15055
|
+
return parse4(schema, value, _ctx, finalizeParams(fn, _params));
|
|
14885
15056
|
};
|
|
14886
15057
|
return fn;
|
|
14887
15058
|
};
|
|
@@ -16376,7 +16547,7 @@ function capSize(inst, size) {
|
|
|
16376
16547
|
if (!caps.length)
|
|
16377
16548
|
return;
|
|
16378
16549
|
const cap = Math.min(...caps.map((c) => c[0]));
|
|
16379
|
-
const
|
|
16550
|
+
const parse4 = inst._zod.parse;
|
|
16380
16551
|
inst._zod.parse = (payload, ctx) => {
|
|
16381
16552
|
const n = size(payload.value);
|
|
16382
16553
|
if (n > cap && !ctx?.skipChecks && ctx?.direction !== "backward") {
|
|
@@ -16390,7 +16561,7 @@ function capSize(inst, size) {
|
|
|
16390
16561
|
}
|
|
16391
16562
|
}
|
|
16392
16563
|
}
|
|
16393
|
-
return
|
|
16564
|
+
return parse4(payload, ctx);
|
|
16394
16565
|
};
|
|
16395
16566
|
}
|
|
16396
16567
|
var arraySize = (input2) => Array.isArray(input2) ? input2.length : -1;
|
|
@@ -17935,10 +18106,10 @@ var $ZodFunction = /* @__PURE__ */ $constructor("$ZodFunction", (inst, def) => {
|
|
|
17935
18106
|
throw new Error("implement() must be called with a function");
|
|
17936
18107
|
}
|
|
17937
18108
|
return Object.defineProperty(function(...args) {
|
|
17938
|
-
const parsedArgs = inst._def.input ?
|
|
18109
|
+
const parsedArgs = inst._def.input ? parse2(inst._def.input, args) : args;
|
|
17939
18110
|
const result = Reflect.apply(func, this, parsedArgs);
|
|
17940
18111
|
if (inst._def.output) {
|
|
17941
|
-
return
|
|
18112
|
+
return parse2(inst._def.output, result);
|
|
17942
18113
|
}
|
|
17943
18114
|
return result;
|
|
17944
18115
|
}, "_zod", { value: inst._zod, enumerable: false });
|
|
@@ -18079,7 +18250,7 @@ var recursive = /* @__PURE__ */ new WeakMap();
|
|
|
18079
18250
|
var NONE = 0;
|
|
18080
18251
|
var ASSUMED = 1;
|
|
18081
18252
|
var PROVEN = 2;
|
|
18082
|
-
function isRecursive(inst, stack,
|
|
18253
|
+
function isRecursive(inst, stack, resolve6) {
|
|
18083
18254
|
const cached2 = recursive.get(inst);
|
|
18084
18255
|
if (cached2 !== void 0)
|
|
18085
18256
|
return cached2 ? PROVEN : NONE;
|
|
@@ -18089,7 +18260,7 @@ function isRecursive(inst, stack, resolve7) {
|
|
|
18089
18260
|
let result = NONE;
|
|
18090
18261
|
const check2 = (child) => {
|
|
18091
18262
|
if (result !== PROVEN && child?._zod) {
|
|
18092
|
-
const answer = isRecursive(child, stack,
|
|
18263
|
+
const answer = isRecursive(child, stack, resolve6);
|
|
18093
18264
|
if (answer > result)
|
|
18094
18265
|
result = answer;
|
|
18095
18266
|
}
|
|
@@ -18100,7 +18271,7 @@ function isRecursive(inst, stack, resolve7) {
|
|
|
18100
18271
|
const desc = Object.getOwnPropertyDescriptor(sh, key);
|
|
18101
18272
|
if (spread && !desc.enumerable)
|
|
18102
18273
|
continue;
|
|
18103
|
-
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack,
|
|
18274
|
+
const child = desc.get ? ASSUMED : desc.value?._zod ? isRecursive(desc.value, stack, resolve6) : NONE;
|
|
18104
18275
|
if (child > answer)
|
|
18105
18276
|
answer = child;
|
|
18106
18277
|
}
|
|
@@ -18164,7 +18335,7 @@ function isRecursive(inst, stack, resolve7) {
|
|
|
18164
18335
|
break;
|
|
18165
18336
|
// `$ZodLazy` caches its inner on the def, so a resolved edge is followed exactly
|
|
18166
18337
|
case "lazy": {
|
|
18167
|
-
const inner = def._cachedInner ?? (
|
|
18338
|
+
const inner = def._cachedInner ?? (resolve6 ? inst._zod.innerType : void 0);
|
|
18168
18339
|
merge2(inner ? isRecursive(inner, stack, false) : ASSUMED);
|
|
18169
18340
|
break;
|
|
18170
18341
|
}
|
|
@@ -29998,7 +30169,7 @@ var ZodMiniType = /* @__PURE__ */ $constructor("ZodMiniType", (inst, def) => {
|
|
|
29998
30169
|
own(this, "with", value);
|
|
29999
30170
|
},
|
|
30000
30171
|
parse(data, params) {
|
|
30001
|
-
return
|
|
30172
|
+
return parse2(this, data, params, { callee: this.parse });
|
|
30002
30173
|
},
|
|
30003
30174
|
parseAsync(data, params) {
|
|
30004
30175
|
return parseAsync(this, data, params, { callee: this.parseAsync });
|
|
@@ -30561,7 +30732,7 @@ __export(external_exports, {
|
|
|
30561
30732
|
optional: () => optional,
|
|
30562
30733
|
output: () => output,
|
|
30563
30734
|
overwrite: () => _overwrite,
|
|
30564
|
-
parse: () =>
|
|
30735
|
+
parse: () => parse3,
|
|
30565
30736
|
parseAsync: () => parseAsync2,
|
|
30566
30737
|
partialRecord: () => partialRecord,
|
|
30567
30738
|
pipe: () => pipe,
|
|
@@ -30889,7 +31060,7 @@ var ZodRealError = /* @__PURE__ */ $constructor("ZodError", initializer2, void 0
|
|
|
30889
31060
|
});
|
|
30890
31061
|
|
|
30891
31062
|
// node_modules/zod/v4/classic/parse.js
|
|
30892
|
-
var
|
|
31063
|
+
var parse3 = /* @__PURE__ */ _parse(ZodRealError);
|
|
30893
31064
|
var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
|
|
30894
31065
|
var safeParse3 = /* @__PURE__ */ _safeParse(ZodRealError);
|
|
30895
31066
|
var safeParseAsync3 = /* @__PURE__ */ _safeParseAsync(ZodRealError);
|
|
@@ -31026,7 +31197,7 @@ var ZodType2 = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
|
|
|
31026
31197
|
util_exports.own(this, "~standard", value);
|
|
31027
31198
|
},
|
|
31028
31199
|
parse: function _parse2(data, params) {
|
|
31029
|
-
return
|
|
31200
|
+
return parse3(this, data, params, { callee: _parse2 });
|
|
31030
31201
|
},
|
|
31031
31202
|
parseAsync: async function _parseAsync2(data, params) {
|
|
31032
31203
|
return await parseAsync2(this, data, params, { callee: _parseAsync2 });
|
|
@@ -36602,7 +36773,7 @@ var Protocol = class {
|
|
|
36602
36773
|
return;
|
|
36603
36774
|
}
|
|
36604
36775
|
const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
|
|
36605
|
-
await new Promise((
|
|
36776
|
+
await new Promise((resolve6) => setTimeout(resolve6, pollInterval));
|
|
36606
36777
|
options?.signal?.throwIfAborted();
|
|
36607
36778
|
}
|
|
36608
36779
|
} catch (error62) {
|
|
@@ -36619,7 +36790,7 @@ var Protocol = class {
|
|
|
36619
36790
|
*/
|
|
36620
36791
|
request(request, resultSchema, options) {
|
|
36621
36792
|
const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
|
|
36622
|
-
return new Promise((
|
|
36793
|
+
return new Promise((resolve6, reject) => {
|
|
36623
36794
|
const earlyReject = (error62) => {
|
|
36624
36795
|
reject(error62);
|
|
36625
36796
|
};
|
|
@@ -36697,7 +36868,7 @@ var Protocol = class {
|
|
|
36697
36868
|
if (!parseResult.success) {
|
|
36698
36869
|
reject(parseResult.error);
|
|
36699
36870
|
} else {
|
|
36700
|
-
|
|
36871
|
+
resolve6(parseResult.data);
|
|
36701
36872
|
}
|
|
36702
36873
|
} catch (error62) {
|
|
36703
36874
|
reject(error62);
|
|
@@ -36959,12 +37130,12 @@ var Protocol = class {
|
|
|
36959
37130
|
}
|
|
36960
37131
|
} catch {
|
|
36961
37132
|
}
|
|
36962
|
-
return new Promise((
|
|
37133
|
+
return new Promise((resolve6, reject) => {
|
|
36963
37134
|
if (signal.aborted) {
|
|
36964
37135
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
36965
37136
|
return;
|
|
36966
37137
|
}
|
|
36967
|
-
const timeoutId = setTimeout(
|
|
37138
|
+
const timeoutId = setTimeout(resolve6, interval);
|
|
36968
37139
|
signal.addEventListener("abort", () => {
|
|
36969
37140
|
clearTimeout(timeoutId);
|
|
36970
37141
|
reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
|
|
@@ -38104,7 +38275,7 @@ var McpServer = class {
|
|
|
38104
38275
|
let task = createTaskResult.task;
|
|
38105
38276
|
const pollInterval = task.pollInterval ?? 5e3;
|
|
38106
38277
|
while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
|
|
38107
|
-
await new Promise((
|
|
38278
|
+
await new Promise((resolve6) => setTimeout(resolve6, pollInterval));
|
|
38108
38279
|
const updatedTask = await extra.taskStore.getTask(taskId);
|
|
38109
38280
|
if (!updatedTask) {
|
|
38110
38281
|
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
|
|
@@ -38768,12 +38939,12 @@ var StdioServerTransport = class {
|
|
|
38768
38939
|
this.onclose?.();
|
|
38769
38940
|
}
|
|
38770
38941
|
send(message) {
|
|
38771
|
-
return new Promise((
|
|
38942
|
+
return new Promise((resolve6) => {
|
|
38772
38943
|
const json2 = serializeMessage(message);
|
|
38773
38944
|
if (this._stdout.write(json2)) {
|
|
38774
|
-
|
|
38945
|
+
resolve6();
|
|
38775
38946
|
} else {
|
|
38776
|
-
this._stdout.once("drain",
|
|
38947
|
+
this._stdout.once("drain", resolve6);
|
|
38777
38948
|
}
|
|
38778
38949
|
});
|
|
38779
38950
|
}
|
|
@@ -38873,7 +39044,7 @@ function normalizePrefix(prefix) {
|
|
|
38873
39044
|
}
|
|
38874
39045
|
function runList(library, args, maxBytes) {
|
|
38875
39046
|
if (args.prefix != null && typeof args.prefix != "string") {
|
|
38876
|
-
return errorResult('prefix must be a string: the start of a path such as "
|
|
39047
|
+
return errorResult('prefix must be a string: the start of a path such as "guide/api".');
|
|
38877
39048
|
}
|
|
38878
39049
|
let prefix = "";
|
|
38879
39050
|
if (typeof args.prefix == "string") {
|
|
@@ -39337,6 +39508,8 @@ var ELLIPSIS2 = "\u2026";
|
|
|
39337
39508
|
var ELLIPSIS_BYTES = Buffer.byteLength(ELLIPSIS2);
|
|
39338
39509
|
var QUERY_ECHO_MAX_CHARS = 80;
|
|
39339
39510
|
var WORD_CHARACTERS = /[a-z0-9_]/;
|
|
39511
|
+
var BM25_K1 = 1.2;
|
|
39512
|
+
var BM25_B = 0.75;
|
|
39340
39513
|
function normalize(text2) {
|
|
39341
39514
|
return text2.normalize("NFC").toLowerCase();
|
|
39342
39515
|
}
|
|
@@ -39434,14 +39607,18 @@ function matchBlock(document, start, end, chainText, label, bodyStart, terms) {
|
|
|
39434
39607
|
}
|
|
39435
39608
|
hits += counts[termIndex];
|
|
39436
39609
|
}
|
|
39437
|
-
return { document, start, end, label, bytes: document.bytesOf(start, end), hits, titleHits, bodyStart };
|
|
39610
|
+
return { document, start, end, label, bytes: document.bytesOf(start, end), termCounts: counts, hits, titleHits, score: 0, bodyStart };
|
|
39438
39611
|
}
|
|
39439
39612
|
function collectMatches(documents, terms) {
|
|
39440
39613
|
const matches = [];
|
|
39614
|
+
let scannedBytes = 0;
|
|
39615
|
+
let scannedBlocks = 0;
|
|
39441
39616
|
for (const document of documents) {
|
|
39442
39617
|
const headings = document.headings;
|
|
39443
39618
|
const introEnd = headings.length == 0 ? document.lines.length : headings[0].line - 1;
|
|
39444
39619
|
if (introEnd >= 1 && isBlank(document, 1, introEnd) == false) {
|
|
39620
|
+
scannedBytes += document.bytesOf(1, introEnd);
|
|
39621
|
+
scannedBlocks += 1;
|
|
39445
39622
|
const introMatch = matchBlock(document, 1, introEnd, "", INTRO_TITLE, 1, terms);
|
|
39446
39623
|
if (introMatch != null) {
|
|
39447
39624
|
matches.push(introMatch);
|
|
@@ -39449,6 +39626,8 @@ function collectMatches(documents, terms) {
|
|
|
39449
39626
|
}
|
|
39450
39627
|
for (let index = 0; index < headings.length; index += 1) {
|
|
39451
39628
|
const heading = headings[index];
|
|
39629
|
+
scannedBytes += document.bytesOf(heading.line, heading.blockEnd);
|
|
39630
|
+
scannedBlocks += 1;
|
|
39452
39631
|
const chainText = chainIndices(document, index).map((position) => document.headings[position].title).join("\n");
|
|
39453
39632
|
const label = headingChain(document, index);
|
|
39454
39633
|
const match = matchBlock(document, heading.line, heading.blockEnd, chainText, label, heading.line + 1, terms);
|
|
@@ -39457,14 +39636,22 @@ function collectMatches(documents, terms) {
|
|
|
39457
39636
|
}
|
|
39458
39637
|
}
|
|
39459
39638
|
}
|
|
39460
|
-
return matches;
|
|
39639
|
+
return { matches, averageBytes: scannedBlocks == 0 ? 1 : scannedBytes / scannedBlocks };
|
|
39640
|
+
}
|
|
39641
|
+
function scoreMatch(match, averageBytes) {
|
|
39642
|
+
const lengthFactor = 1 - BM25_B + BM25_B * (match.bytes / averageBytes);
|
|
39643
|
+
let score = 0;
|
|
39644
|
+
for (const termCount of match.termCounts) {
|
|
39645
|
+
score += termCount * (BM25_K1 + 1) / (termCount + BM25_K1 * lengthFactor);
|
|
39646
|
+
}
|
|
39647
|
+
return score;
|
|
39461
39648
|
}
|
|
39462
39649
|
function compareMatches(left, right) {
|
|
39463
39650
|
if (left.titleHits != right.titleHits) {
|
|
39464
39651
|
return right.titleHits - left.titleHits;
|
|
39465
39652
|
}
|
|
39466
|
-
if (left.
|
|
39467
|
-
return right.
|
|
39653
|
+
if (left.score != right.score) {
|
|
39654
|
+
return right.score - left.score;
|
|
39468
39655
|
}
|
|
39469
39656
|
const byPath = compareText(left.document.path, right.document.path);
|
|
39470
39657
|
if (byPath != 0) {
|
|
@@ -39554,7 +39741,10 @@ function runSearch(library, args, maxBytes) {
|
|
|
39554
39741
|
return errorResult("Query is empty. Give one or more words; wrap a phrase in double quotes.");
|
|
39555
39742
|
}
|
|
39556
39743
|
const documents = library.refresh().filter((document) => document.path.startsWith(prefix));
|
|
39557
|
-
const matches = collectMatches(documents, terms);
|
|
39744
|
+
const { matches, averageBytes } = collectMatches(documents, terms);
|
|
39745
|
+
for (const match of matches) {
|
|
39746
|
+
match.score = scoreMatch(match, averageBytes);
|
|
39747
|
+
}
|
|
39558
39748
|
matches.sort(compareMatches);
|
|
39559
39749
|
const fileCount = new Set(matches.map((match) => match.document.path)).size;
|
|
39560
39750
|
const echo = JSON.stringify(truncateChars(query.trim(), QUERY_ECHO_MAX_CHARS));
|
|
@@ -39630,9 +39820,9 @@ function describeTools(folder) {
|
|
|
39630
39820
|
return [
|
|
39631
39821
|
{
|
|
39632
39822
|
name: nameOf("list"),
|
|
39633
|
-
description: `${tag}List the markdown files under ${where} with size and document title, grouped by folder. Use prefix to open one folder: \`
|
|
39823
|
+
description: `${tag}List the markdown files under ${where} with size and document title, grouped by folder. Use prefix to open one folder: \`guide/api\` matches \`guide/api/\u2026\` and \`guide/api-notes.md\`, \`guide/api/\` matches the folder only.`,
|
|
39634
39824
|
inputSchema: {
|
|
39635
|
-
prefix: external_exports.string().optional().describe("Root-relative path prefix, e.g. `
|
|
39825
|
+
prefix: external_exports.string().optional().describe("Root-relative path prefix, e.g. `guide/api/`. Omit to list everything.")
|
|
39636
39826
|
},
|
|
39637
39827
|
runner: runList
|
|
39638
39828
|
},
|
|
@@ -39807,12 +39997,12 @@ function catalogReadyLine(version2, home, catalog, opened) {
|
|
|
39807
39997
|
|
|
39808
39998
|
// src/modules/setup/runtime.ts
|
|
39809
39999
|
import { existsSync as existsSync2, lstatSync, mkdirSync as mkdirSync2, readFileSync as readFileSync3, realpathSync as realpathSync3, rmSync as rmSync2 } from "node:fs";
|
|
39810
|
-
import { dirname, join as
|
|
40000
|
+
import { dirname, join as join5, resolve as resolve4 } from "node:path";
|
|
39811
40001
|
|
|
39812
40002
|
// src/modules/setup/commands.ts
|
|
39813
40003
|
import { spawn } from "node:child_process";
|
|
39814
40004
|
import { accessSync, constants, statSync as statSync4 } from "node:fs";
|
|
39815
|
-
import { delimiter, join as
|
|
40005
|
+
import { delimiter, join as join4 } from "node:path";
|
|
39816
40006
|
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
39817
40007
|
var WINDOWS_SCRIPT_PATTERN = /\.(cmd|bat)$/i;
|
|
39818
40008
|
function quotePart(part) {
|
|
@@ -39841,7 +40031,7 @@ function findOnPath(name, env = process.env, platform = process.platform) {
|
|
|
39841
40031
|
}
|
|
39842
40032
|
for (const directory of directories) {
|
|
39843
40033
|
for (const candidate of candidates) {
|
|
39844
|
-
const path =
|
|
40034
|
+
const path = join4(directory, candidate);
|
|
39845
40035
|
try {
|
|
39846
40036
|
if (statSync4(path).isFile() == false) {
|
|
39847
40037
|
continue;
|
|
@@ -39950,17 +40140,17 @@ var PACKAGE_NAME = "librian";
|
|
|
39950
40140
|
var INSTALL_TIMEOUT_MS = 18e4;
|
|
39951
40141
|
var VIEW_TIMEOUT_MS = 3e4;
|
|
39952
40142
|
function runtimeDirectory(home) {
|
|
39953
|
-
return
|
|
40143
|
+
return join5(home, "runtime");
|
|
39954
40144
|
}
|
|
39955
40145
|
function packageDirectory(home) {
|
|
39956
|
-
return
|
|
40146
|
+
return join5(runtimeDirectory(home), "node_modules", PACKAGE_NAME);
|
|
39957
40147
|
}
|
|
39958
40148
|
function runtimeCliPath(home) {
|
|
39959
|
-
return
|
|
40149
|
+
return join5(packageDirectory(home), "dist", "cli.js");
|
|
39960
40150
|
}
|
|
39961
40151
|
function readPackageVersion(directory) {
|
|
39962
40152
|
try {
|
|
39963
|
-
const parsed = JSON.parse(readFileSync3(
|
|
40153
|
+
const parsed = JSON.parse(readFileSync3(join5(directory, "package.json"), "utf8"));
|
|
39964
40154
|
return typeof parsed.version == "string" ? parsed.version : null;
|
|
39965
40155
|
} catch {
|
|
39966
40156
|
return null;
|
|
@@ -39992,8 +40182,8 @@ function compareVersions(left, right) {
|
|
|
39992
40182
|
function findNpmCli(nodePath) {
|
|
39993
40183
|
const nodeDirectory = dirname(nodePath);
|
|
39994
40184
|
const candidates = [
|
|
39995
|
-
|
|
39996
|
-
|
|
40185
|
+
join5(nodeDirectory, "node_modules", "npm", "bin", "npm-cli.js"),
|
|
40186
|
+
join5(nodeDirectory, "..", "lib", "node_modules", "npm", "bin", "npm-cli.js")
|
|
39997
40187
|
];
|
|
39998
40188
|
for (const candidate of candidates) {
|
|
39999
40189
|
if (existsSync2(candidate) == true) {
|
|
@@ -40039,24 +40229,6 @@ async function installRuntime(home, spec, toolchain) {
|
|
|
40039
40229
|
}
|
|
40040
40230
|
return { ok: true, message: status.state == "linked" ? `linked to ${status.linkedFrom}` : `${status.version ?? "?"} installed` };
|
|
40041
40231
|
}
|
|
40042
|
-
function checkCheckout(path) {
|
|
40043
|
-
if (existsSync2(path) == false) {
|
|
40044
|
-
return `${path} does not exist.`;
|
|
40045
|
-
}
|
|
40046
|
-
let name;
|
|
40047
|
-
try {
|
|
40048
|
-
name = JSON.parse(readFileSync3(join4(path, "package.json"), "utf8")).name;
|
|
40049
|
-
} catch {
|
|
40050
|
-
return `${path} has no readable package.json.`;
|
|
40051
|
-
}
|
|
40052
|
-
if (name != PACKAGE_NAME) {
|
|
40053
|
-
return `${path} is not the ${PACKAGE_NAME} package.`;
|
|
40054
|
-
}
|
|
40055
|
-
if (existsSync2(join4(path, "dist", "cli.js")) == false) {
|
|
40056
|
-
return `${path} has no dist/cli.js; run \`npm run build\` there first.`;
|
|
40057
|
-
}
|
|
40058
|
-
return null;
|
|
40059
|
-
}
|
|
40060
40232
|
async function latestPublishedVersion(toolchain) {
|
|
40061
40233
|
const viewed = await runNpm(toolchain, ["view", PACKAGE_NAME, "version"], VIEW_TIMEOUT_MS);
|
|
40062
40234
|
if (viewed.ok == false) {
|
|
@@ -40076,12 +40248,9 @@ function uninstallRuntime(home) {
|
|
|
40076
40248
|
rmSync2(directory, { recursive: true, force: true });
|
|
40077
40249
|
}
|
|
40078
40250
|
|
|
40079
|
-
// src/modules/setup/runtime-screen.ts
|
|
40080
|
-
import { resolve as resolve5 } from "node:path";
|
|
40081
|
-
|
|
40082
40251
|
// src/modules/setup/services.ts
|
|
40083
40252
|
import { homedir as homedir3 } from "node:os";
|
|
40084
|
-
import { join as
|
|
40253
|
+
import { join as join6 } from "node:path";
|
|
40085
40254
|
|
|
40086
40255
|
// src/modules/setup/probe.ts
|
|
40087
40256
|
import { spawn as spawn2 } from "node:child_process";
|
|
@@ -40188,7 +40357,7 @@ function defaultServiceDependencies() {
|
|
|
40188
40357
|
return { ...defaultToolchain(), probe: probeServer };
|
|
40189
40358
|
}
|
|
40190
40359
|
function isDefaultHome(home) {
|
|
40191
|
-
return normalizeForCompare(home) == normalizeForCompare(
|
|
40360
|
+
return normalizeForCompare(home) == normalizeForCompare(join6(homedir3(), ".librian"));
|
|
40192
40361
|
}
|
|
40193
40362
|
function expectedRegistration(home, toolchain) {
|
|
40194
40363
|
const environment = {};
|
|
@@ -40403,7 +40572,6 @@ function buildRows2(status, latest, checked) {
|
|
|
40403
40572
|
rows.push({ value: "check", key: "check", label: "Check for updates", hint: checked == true ? "up to date" : void 0 });
|
|
40404
40573
|
}
|
|
40405
40574
|
}
|
|
40406
|
-
rows.push({ value: "link", key: "link", label: "Use a local checkout", hint: "link a built librian folder" });
|
|
40407
40575
|
if (status.state != "missing") {
|
|
40408
40576
|
rows.push({ value: "uninstall", key: "uninstall", label: "Uninstall" });
|
|
40409
40577
|
}
|
|
@@ -40497,25 +40665,6 @@ async function openRuntimeScreen(home, dependencies = defaultServiceDependencies
|
|
|
40497
40665
|
checked = false;
|
|
40498
40666
|
latest = null;
|
|
40499
40667
|
await checkRegisteredServer(home, dependencies);
|
|
40500
|
-
} else if (choice == "link") {
|
|
40501
|
-
let answer;
|
|
40502
|
-
try {
|
|
40503
|
-
answer = await text("Folder of the built librian checkout", { initial: status.linkedFrom, transient: true });
|
|
40504
|
-
} catch (error62) {
|
|
40505
|
-
if (error62 instanceof PromptBackError == false) {
|
|
40506
|
-
throw error62;
|
|
40507
|
-
}
|
|
40508
|
-
continue;
|
|
40509
|
-
}
|
|
40510
|
-
const checkout = resolve5(answer.trim().replace(/^"(.*)"$/, "$1"));
|
|
40511
|
-
const problem = checkCheckout(checkout);
|
|
40512
|
-
if (problem != null) {
|
|
40513
|
-
writeLine(styled(problem, "red"));
|
|
40514
|
-
continue;
|
|
40515
|
-
}
|
|
40516
|
-
writeLine(styled("Linking the checkout\u2026", "dim"));
|
|
40517
|
-
printResult(await installRuntime(home, checkout, dependencies), "link");
|
|
40518
|
-
await checkRegisteredServer(home, dependencies);
|
|
40519
40668
|
} else if (choice == "uninstall") {
|
|
40520
40669
|
await uninstall(home, dependencies);
|
|
40521
40670
|
}
|
|
@@ -40592,7 +40741,7 @@ async function openServicesScreen(home, dependencies = defaultServiceDependencie
|
|
|
40592
40741
|
const needsRuntime = runtimeStatus(home).state == "missing";
|
|
40593
40742
|
const registersSomething = planServiceChanges(statuses, wanted, home, dependencies).some((change) => change.action == "register");
|
|
40594
40743
|
const blockedApply = needsRuntime == true && registersSomething == true ? "install the runtime first" : null;
|
|
40595
|
-
const choice = await select("
|
|
40744
|
+
const choice = await select("Register", buildRows3(statuses, wanted, blockedApply), { initial: cursor, transient: true });
|
|
40596
40745
|
cursor = choice;
|
|
40597
40746
|
if (choice == "back") {
|
|
40598
40747
|
return;
|
|
@@ -40641,7 +40790,7 @@ async function openServicesScreen(home, dependencies = defaultServiceDependencie
|
|
|
40641
40790
|
}
|
|
40642
40791
|
|
|
40643
40792
|
// src/cli.ts
|
|
40644
|
-
var
|
|
40793
|
+
var EXIT_USAGE2 = 2;
|
|
40645
40794
|
async function main() {
|
|
40646
40795
|
const parsed = parseArguments(process.argv.slice(2));
|
|
40647
40796
|
if (parsed.kind == "help") {
|
|
@@ -40657,7 +40806,16 @@ async function main() {
|
|
|
40657
40806
|
if (parsed.kind == "error") {
|
|
40658
40807
|
writeStderrLine(`librian: ${parsed.message}`);
|
|
40659
40808
|
writeStderrLine(USAGE);
|
|
40660
|
-
process.exitCode =
|
|
40809
|
+
process.exitCode = EXIT_USAGE2;
|
|
40810
|
+
return;
|
|
40811
|
+
}
|
|
40812
|
+
if (parsed.kind == "add") {
|
|
40813
|
+
process.exitCode = await runAddCommand({
|
|
40814
|
+
home: librianHome(),
|
|
40815
|
+
folder: parsed.folder,
|
|
40816
|
+
cwd: process.cwd(),
|
|
40817
|
+
writeError: (line) => writeStderrLine(`librian: ${line}`)
|
|
40818
|
+
});
|
|
40661
40819
|
return;
|
|
40662
40820
|
}
|
|
40663
40821
|
if (parsed.kind == "menu") {
|
|
@@ -40693,7 +40851,7 @@ async function main() {
|
|
|
40693
40851
|
writeStderrLine(catalogReadyLine(package_default.version, home, catalog, opened));
|
|
40694
40852
|
return;
|
|
40695
40853
|
}
|
|
40696
|
-
const root =
|
|
40854
|
+
const root = resolve5(parsed.root);
|
|
40697
40855
|
let isFolder3 = false;
|
|
40698
40856
|
try {
|
|
40699
40857
|
isFolder3 = statSync5(root).isDirectory();
|
|
@@ -40702,7 +40860,7 @@ async function main() {
|
|
|
40702
40860
|
}
|
|
40703
40861
|
if (isFolder3 == false) {
|
|
40704
40862
|
writeStderrLine(`librian: root "${root}" does not exist or is not a folder.`);
|
|
40705
|
-
process.exitCode =
|
|
40863
|
+
process.exitCode = EXIT_USAGE2;
|
|
40706
40864
|
return;
|
|
40707
40865
|
}
|
|
40708
40866
|
const library = openLibrary({ root, exclude: parsed.exclude });
|