exomind 0.18.1 → 0.18.3
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/dist/cli.js +189 -97
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3119,7 +3119,7 @@ var {
|
|
|
3119
3119
|
// package.json
|
|
3120
3120
|
var package_default = {
|
|
3121
3121
|
name: "exomind",
|
|
3122
|
-
version: "0.18.
|
|
3122
|
+
version: "0.18.3",
|
|
3123
3123
|
description: "ExoMind \u8DE8\u5E73\u53F0\u547D\u4EE4\u884C\u5BA2\u6237\u7AEF \u2014 \u901A\u8FC7 REST \u4E0E ExoMind \u77E5\u8BC6\u98DE\u8F6E\u4EA4\u4E92(ingest/query/search/review),\u66FF\u4EE3 Windows \u4E0D\u53EF\u7528\u7684 MCP \u5BA2\u6237\u7AEF\u3002",
|
|
3124
3124
|
bin: {
|
|
3125
3125
|
exomind: "dist/cli.js",
|
|
@@ -3326,8 +3326,8 @@ function setJsonMode(v) {
|
|
|
3326
3326
|
function isJsonMode() {
|
|
3327
3327
|
return JSON_MODE;
|
|
3328
3328
|
}
|
|
3329
|
-
function hint(
|
|
3330
|
-
if (!isJsonMode()) process.stderr.write(
|
|
3329
|
+
function hint(msg3) {
|
|
3330
|
+
if (!isJsonMode()) process.stderr.write(msg3 + "\n");
|
|
3331
3331
|
}
|
|
3332
3332
|
function output(data, pretty) {
|
|
3333
3333
|
if (JSON_MODE) {
|
|
@@ -3347,6 +3347,9 @@ var gray = import_picocolors.default.gray;
|
|
|
3347
3347
|
function ok(label) {
|
|
3348
3348
|
return import_picocolors.default.green(`\u2713 ${label}`);
|
|
3349
3349
|
}
|
|
3350
|
+
function fail(label) {
|
|
3351
|
+
return import_picocolors.default.red(`\u2717 ${label}`);
|
|
3352
|
+
}
|
|
3350
3353
|
function truncate(s, n) {
|
|
3351
3354
|
s = (s ?? "").replace(/\s+/g, " ").trim();
|
|
3352
3355
|
return s.length > n ? `${s.slice(0, n - 1)}\u2026` : s;
|
|
@@ -3542,29 +3545,29 @@ function saveDedup(d) {
|
|
|
3542
3545
|
} catch {
|
|
3543
3546
|
}
|
|
3544
3547
|
}
|
|
3545
|
-
function hasTechTerm(
|
|
3546
|
-
return /`|```|\w+\.\w{1,5}\b|[A-Z][a-z]+[A-Z]|npm |pip |git |docker|api|http/i.test(
|
|
3548
|
+
function hasTechTerm(msg3) {
|
|
3549
|
+
return /`|```|\w+\.\w{1,5}\b|[A-Z][a-z]+[A-Z]|npm |pip |git |docker|api|http/i.test(msg3);
|
|
3547
3550
|
}
|
|
3548
|
-
function isSecretWord(
|
|
3549
|
-
const m =
|
|
3551
|
+
function isSecretWord(msg3) {
|
|
3552
|
+
const m = msg3.trim();
|
|
3550
3553
|
return /^(存档|jdit)[\s!.,;:!?。?、~…]*$/i.test(m);
|
|
3551
3554
|
}
|
|
3552
|
-
function matchesExperience(
|
|
3553
|
-
if (
|
|
3555
|
+
function matchesExperience(msg3) {
|
|
3556
|
+
if (msg3.length < 50) return false;
|
|
3554
3557
|
let hits = 0;
|
|
3555
|
-
for (const re of EXPERIENCE_PATTERNS) if (re.test(
|
|
3556
|
-
const bullets = (
|
|
3557
|
-
return hits >= 1 || bullets >= 3 && hasTechTerm(
|
|
3558
|
+
for (const re of EXPERIENCE_PATTERNS) if (re.test(msg3)) hits++;
|
|
3559
|
+
const bullets = (msg3.match(/^\s*([-*]|\d+[.、)])/gm) || []).length;
|
|
3560
|
+
return hits >= 1 || bullets >= 3 && hasTechTerm(msg3);
|
|
3558
3561
|
}
|
|
3559
|
-
function matchesResearch(
|
|
3560
|
-
if (
|
|
3562
|
+
function matchesResearch(msg3) {
|
|
3563
|
+
if (msg3.length < 100) return false;
|
|
3561
3564
|
let score = 0;
|
|
3562
|
-
for (const re of RESEARCH_PATTERNS) if (re.test(
|
|
3565
|
+
for (const re of RESEARCH_PATTERNS) if (re.test(msg3)) score++;
|
|
3563
3566
|
let phases = 0;
|
|
3564
3567
|
for (const sigs of Object.values(STRUCTURE_SIGNALS)) {
|
|
3565
|
-
if (sigs.some((r) => r.test(
|
|
3568
|
+
if (sigs.some((r) => r.test(msg3))) phases++;
|
|
3566
3569
|
}
|
|
3567
|
-
const hasStructure = /(^|\n)\s*(#{1,4}\s|[-*]\s|\d+[.、)])/m.test(
|
|
3570
|
+
const hasStructure = /(^|\n)\s*(#{1,4}\s|[-*]\s|\d+[.、)])/m.test(msg3);
|
|
3568
3571
|
return score >= 2 && phases >= 3 || score >= 3 && hasStructure && phases >= 2;
|
|
3569
3572
|
}
|
|
3570
3573
|
async function getKeywordIndex(client, deadline = Number.POSITIVE_INFINITY) {
|
|
@@ -3683,13 +3686,13 @@ ${desc}
|
|
|
3683
3686
|
out += "\u4EE5\u4E0A " + ents.length + ' \u6761\u6765\u81EA\u4F60\u7684\u77E5\u8BC6\u98DE\u8F6E(\u5DF2\u6CE8\u5165\u4E0A\u4E0B\u6587)\u3002**\u9F13\u52B1\u4E3B\u52A8\u53CD\u67E5\u8BA9\u98DE\u8F6E\u8F6C\u8D77\u6765**:\u9047\u95EE\u9898\u5148 `exomind query "<\u95EE\u9898>"`(\u4E0D\u53EA"\u5B58",\u66F4\u8981"\u7528"\u2014\u2014\u53CD\u67E5\u662F\u98DE\u8F6E\u589E\u5F3A\u56DE\u8DEF\u7684\u5173\u952E),\u518D\u56DE\u7B54\u3002';
|
|
3684
3687
|
return out;
|
|
3685
3688
|
}
|
|
3686
|
-
async function buildContext(client,
|
|
3689
|
+
async function buildContext(client, msg3, dedup, now, deadline = Number.POSITIVE_INFINITY) {
|
|
3687
3690
|
const index = await getKeywordIndex(client, deadline);
|
|
3688
3691
|
if (!index) {
|
|
3689
3692
|
return '[ExoMind] \u77E5\u8BC6\u98DE\u8F6E\u4E0A\u4E0B\u6587\u672C\u6B21\u672A\u6CE8\u5165(\u5173\u952E\u8BCD\u8868\u62C9\u53D6\u8D85\u65F6\u6216\u5931\u8D25);\u9700\u8981\u53CD\u67E5\u53EF\u8FD0\u884C `exomind search "\u5173\u952E\u8BCD"`\u3002';
|
|
3690
3693
|
}
|
|
3691
3694
|
const candidates = [...index.names || [], ...index.aliases || []];
|
|
3692
|
-
const matched = matchEntities(
|
|
3695
|
+
const matched = matchEntities(msg3, candidates);
|
|
3693
3696
|
if (!matched.length) return "";
|
|
3694
3697
|
const picked = [];
|
|
3695
3698
|
const pickedCanonical = /* @__PURE__ */ new Set();
|
|
@@ -3724,23 +3727,23 @@ async function runHook(client) {
|
|
|
3724
3727
|
const deadline = Date.now() + hookDeadlineMs();
|
|
3725
3728
|
const raw = await readStdin();
|
|
3726
3729
|
if (!raw) return;
|
|
3727
|
-
let
|
|
3730
|
+
let msg3 = "";
|
|
3728
3731
|
try {
|
|
3729
3732
|
const j = JSON.parse(raw);
|
|
3730
|
-
|
|
3733
|
+
msg3 = (j.prompt || j.message || "").trim();
|
|
3731
3734
|
} catch {
|
|
3732
|
-
|
|
3735
|
+
msg3 = raw.trim();
|
|
3733
3736
|
}
|
|
3734
|
-
if (!
|
|
3737
|
+
if (!msg3) return;
|
|
3735
3738
|
const outputs = [];
|
|
3736
3739
|
const dedup = loadDedup();
|
|
3737
3740
|
const now = Date.now();
|
|
3738
|
-
const isSecret = isSecretWord(
|
|
3741
|
+
const isSecret = isSecretWord(msg3);
|
|
3739
3742
|
if (!isSecret) {
|
|
3740
|
-
if (
|
|
3741
|
-
if (CONFIRM_WORDS.has(
|
|
3743
|
+
if (msg3.length < 8) return;
|
|
3744
|
+
if (CONFIRM_WORDS.has(msg3.toLowerCase())) return;
|
|
3742
3745
|
}
|
|
3743
|
-
if (isSecret &&
|
|
3746
|
+
if (isSecret && msg3.length < 20) {
|
|
3744
3747
|
if (now - dedup.lastArchive > COOLDOWN_MS) {
|
|
3745
3748
|
outputs.push(ARCHIVE_INSTRUCTION);
|
|
3746
3749
|
dedup.lastArchive = now;
|
|
@@ -3751,11 +3754,11 @@ async function runHook(client) {
|
|
|
3751
3754
|
);
|
|
3752
3755
|
}
|
|
3753
3756
|
} else if (!isSecret) {
|
|
3754
|
-
if (matchesExperience(
|
|
3755
|
-
else if (matchesResearch(
|
|
3757
|
+
if (matchesExperience(msg3)) outputs.push(EXPERIENCE_INSTRUCTION);
|
|
3758
|
+
else if (matchesResearch(msg3)) outputs.push(RESEARCH_INSTRUCTION);
|
|
3756
3759
|
}
|
|
3757
3760
|
try {
|
|
3758
|
-
const ctx = await buildContext(client,
|
|
3761
|
+
const ctx = await buildContext(client, msg3, dedup, now, deadline);
|
|
3759
3762
|
if (ctx) outputs.push(ctx);
|
|
3760
3763
|
} catch {
|
|
3761
3764
|
}
|
|
@@ -3856,9 +3859,9 @@ async function handleTool(client, name, args) {
|
|
|
3856
3859
|
throw new Error(`\u672A\u77E5\u5DE5\u5177: ${name}`);
|
|
3857
3860
|
}
|
|
3858
3861
|
}
|
|
3859
|
-
async function handleMessage(client,
|
|
3860
|
-
const id =
|
|
3861
|
-
const method =
|
|
3862
|
+
async function handleMessage(client, msg3) {
|
|
3863
|
+
const id = msg3.id;
|
|
3864
|
+
const method = msg3.method;
|
|
3862
3865
|
if (method === "initialize") {
|
|
3863
3866
|
return {
|
|
3864
3867
|
jsonrpc: "2.0",
|
|
@@ -3874,7 +3877,7 @@ async function handleMessage(client, msg) {
|
|
|
3874
3877
|
if (method === "ping") return { jsonrpc: "2.0", id, result: {} };
|
|
3875
3878
|
if (method === "tools/list") return { jsonrpc: "2.0", id, result: { tools: TOOLS } };
|
|
3876
3879
|
if (method === "tools/call") {
|
|
3877
|
-
const params =
|
|
3880
|
+
const params = msg3.params ?? {};
|
|
3878
3881
|
try {
|
|
3879
3882
|
const data = await handleTool(client, params.name ?? "", params.arguments ?? {});
|
|
3880
3883
|
return {
|
|
@@ -3900,20 +3903,20 @@ async function runMcpServer(client) {
|
|
|
3900
3903
|
rl.on("line", async (line) => {
|
|
3901
3904
|
const trimmed = line.trim();
|
|
3902
3905
|
if (!trimmed) return;
|
|
3903
|
-
let
|
|
3906
|
+
let msg3;
|
|
3904
3907
|
try {
|
|
3905
|
-
|
|
3908
|
+
msg3 = JSON.parse(trimmed);
|
|
3906
3909
|
} catch {
|
|
3907
3910
|
return;
|
|
3908
3911
|
}
|
|
3909
3912
|
try {
|
|
3910
|
-
const resp = await handleMessage(client,
|
|
3913
|
+
const resp = await handleMessage(client, msg3);
|
|
3911
3914
|
if (resp) process.stdout.write(JSON.stringify(resp) + "\n");
|
|
3912
3915
|
} catch (e) {
|
|
3913
3916
|
process.stdout.write(
|
|
3914
3917
|
JSON.stringify({
|
|
3915
3918
|
jsonrpc: "2.0",
|
|
3916
|
-
id:
|
|
3919
|
+
id: msg3?.id ?? null,
|
|
3917
3920
|
error: { code: -32603, message: e instanceof Error ? e.message : String(e) }
|
|
3918
3921
|
}) + "\n"
|
|
3919
3922
|
);
|
|
@@ -4797,10 +4800,12 @@ async function whoami(client) {
|
|
|
4797
4800
|
|
|
4798
4801
|
// src/commands/delete.ts
|
|
4799
4802
|
var readline3 = __toESM(require("readline/promises"));
|
|
4803
|
+
|
|
4804
|
+
// src/page_path.ts
|
|
4800
4805
|
function encPath(p) {
|
|
4801
4806
|
return p.split("/").map(encodeURIComponent).join("/");
|
|
4802
4807
|
}
|
|
4803
|
-
async function
|
|
4808
|
+
async function resolvePagePath(client, page) {
|
|
4804
4809
|
const dirs = ["entities", "concepts", "summaries", "synthesis", "qa", "raw/articles"];
|
|
4805
4810
|
for (const d of dirs) {
|
|
4806
4811
|
const cand = `${d}/${page}.md`;
|
|
@@ -4810,76 +4815,159 @@ async function resolvePage(client, page) {
|
|
|
4810
4815
|
} catch {
|
|
4811
4816
|
}
|
|
4812
4817
|
}
|
|
4813
|
-
throw new Error(
|
|
4814
|
-
`\u9875\u9762\u4E0D\u5B58\u5728: ${page}(\u5148 exomind search \u6216 exomind list \u5B9A\u4F4D;\u94FE\u63A5\u6846\u5165\u5E93\u7684\u539F\u6587\u5728 raw/articles/ \u4E0B)`
|
|
4815
|
-
);
|
|
4818
|
+
throw new Error(`\u9875\u9762\u4E0D\u5B58\u5728: ${page}(\u5148 exomind search \u5B9A\u4F4D)`);
|
|
4816
4819
|
}
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4820
|
+
|
|
4821
|
+
// src/commands/delete.ts
|
|
4822
|
+
function msg(e) {
|
|
4823
|
+
return e instanceof Error ? e.message : String(e);
|
|
4824
|
+
}
|
|
4825
|
+
async function toTarget(client, page) {
|
|
4826
|
+
return !page.includes("/") && !page.endsWith(".md") ? resolvePagePath(client, page) : page;
|
|
4827
|
+
}
|
|
4828
|
+
async function fetchTitle(client, target) {
|
|
4825
4829
|
try {
|
|
4826
|
-
const
|
|
4827
|
-
|
|
4828
|
-
});
|
|
4829
|
-
title = String(detail?.title ?? "");
|
|
4830
|
+
const d = await client.get(`/pages/${encPath(target)}`, void 0, { timeoutMs: 15e3 });
|
|
4831
|
+
return String(d?.title ?? "");
|
|
4830
4832
|
} catch {
|
|
4833
|
+
return "";
|
|
4831
4834
|
}
|
|
4832
|
-
|
|
4835
|
+
}
|
|
4836
|
+
async function deletePage(client, opts, args) {
|
|
4837
|
+
const pages = (args ?? []).map((a) => String(a).trim()).filter(Boolean);
|
|
4838
|
+
if (!pages.length) throw new Error("\u8BF7\u63D0\u4F9B\u9875\u9762\u8DEF\u5F84\u6216\u5B9E\u4F53\u540D: exomind delete entities/Redis.md");
|
|
4839
|
+
const plans = [];
|
|
4840
|
+
for (const p of pages) {
|
|
4841
|
+
try {
|
|
4842
|
+
const target = await toTarget(client, p);
|
|
4843
|
+
plans.push({ requested: p, target, title: await fetchTitle(client, target) });
|
|
4844
|
+
} catch (e) {
|
|
4845
|
+
plans.push({ requested: p, target: p, title: "", error: msg(e) });
|
|
4846
|
+
}
|
|
4847
|
+
}
|
|
4848
|
+
for (const p of plans) {
|
|
4849
|
+
if (p.error) hint(yellow(`\u26A0 ${p.requested} \u672A\u5B9A\u4F4D\u5230\u9875\u9762: ${p.error}`));
|
|
4850
|
+
}
|
|
4851
|
+
const doomed = plans.filter((p) => !p.error);
|
|
4852
|
+
if (!opts.yes && !isJsonMode() && doomed.length) {
|
|
4853
|
+
const head = doomed.length === 1 ? `\u5220\u9664 ${doomed[0].target}${doomed[0].title ? `\uFF08${doomed[0].title}\uFF09` : ""}\uFF1F` : `\u5220\u9664\u4EE5\u4E0B ${doomed.length} \u9875\uFF1F
|
|
4854
|
+
${doomed.map((p) => ` ${p.target}${p.title ? `\uFF08${p.title}\uFF09` : ""}`).join("\n")}
|
|
4855
|
+
`;
|
|
4833
4856
|
const rl = readline3.createInterface({ input: process.stdin, output: process.stdout });
|
|
4834
|
-
const ans = await rl.question(
|
|
4835
|
-
`\u5220\u9664 ${target}${title ? `\uFF08${title}\uFF09` : ""}\uFF1F\u5165\u670D\u52A1\u7AEF\u56DE\u6536\u7AD9\u3001\u53EF\u6062\u590D [y/N] `
|
|
4836
|
-
);
|
|
4857
|
+
const ans = await rl.question(`${head}\u5165\u670D\u52A1\u7AEF\u56DE\u6536\u7AD9\u3001\u53EF\u6062\u590D [y/N] `);
|
|
4837
4858
|
rl.close();
|
|
4838
4859
|
if (ans.trim().toLowerCase() !== "y") {
|
|
4839
4860
|
console.log("\u5DF2\u53D6\u6D88");
|
|
4840
4861
|
return;
|
|
4841
4862
|
}
|
|
4842
4863
|
}
|
|
4843
|
-
const
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
-
|
|
4848
|
-
}
|
|
4849
|
-
|
|
4850
|
-
// src/page_path.ts
|
|
4851
|
-
function encPath2(p) {
|
|
4852
|
-
return p.split("/").map(encodeURIComponent).join("/");
|
|
4853
|
-
}
|
|
4854
|
-
async function resolvePagePath(client, page) {
|
|
4855
|
-
const dirs = ["entities", "concepts", "summaries", "synthesis", "qa", "raw/articles"];
|
|
4856
|
-
for (const d of dirs) {
|
|
4857
|
-
const cand = `${d}/${page}.md`;
|
|
4864
|
+
const done = [];
|
|
4865
|
+
for (const p of plans) {
|
|
4866
|
+
if (p.error) {
|
|
4867
|
+
done.push(p);
|
|
4868
|
+
continue;
|
|
4869
|
+
}
|
|
4858
4870
|
try {
|
|
4859
|
-
await client.
|
|
4860
|
-
|
|
4861
|
-
} catch {
|
|
4871
|
+
const r = await client.del(`/pages/${encPath(p.target)}`, { timeoutMs: 6e4 });
|
|
4872
|
+
done.push({ ...p, path: r?.path, trash_path: r?.trash_path, raw: r });
|
|
4873
|
+
} catch (e) {
|
|
4874
|
+
done.push({ ...p, error: msg(e) });
|
|
4862
4875
|
}
|
|
4863
4876
|
}
|
|
4864
|
-
|
|
4877
|
+
const failed = done.filter((d) => d.error);
|
|
4878
|
+
const succeeded = done.filter((d) => !d.error);
|
|
4879
|
+
const mismatch = (d) => d.path && d.path !== d.target ? yellow(` \u26A0 \u5B9E\u9645\u5220\u9664\u7684\u662F ${d.path}\uFF08\u8BF7\u6C42\u7684\u662F ${d.target}\uFF09`) : null;
|
|
4880
|
+
if (done.length === 1) {
|
|
4881
|
+
const d = done[0];
|
|
4882
|
+
if (d.error) {
|
|
4883
|
+
output({ deleted: false, path: d.target, error: d.error }, () => {
|
|
4884
|
+
console.log(fail(`${d.requested} \u672A\u5220\u9664: ${d.error}`));
|
|
4885
|
+
});
|
|
4886
|
+
} else {
|
|
4887
|
+
output(d.raw ?? { deleted: true, path: d.path, trash_path: d.trash_path }, () => {
|
|
4888
|
+
console.log(ok(`\u5DF2\u5220\u9664: ${d.path}`));
|
|
4889
|
+
if (d.trash_path) {
|
|
4890
|
+
console.log(dim(`\u56DE\u6536\u7AD9: ${d.trash_path} \u2014 exomind trash \u67E5\u770B / trash restore \u6062\u590D`));
|
|
4891
|
+
}
|
|
4892
|
+
const m = mismatch(d);
|
|
4893
|
+
if (m) console.log(m);
|
|
4894
|
+
});
|
|
4895
|
+
}
|
|
4896
|
+
} else {
|
|
4897
|
+
output(
|
|
4898
|
+
{
|
|
4899
|
+
ok: failed.length === 0,
|
|
4900
|
+
total: done.length,
|
|
4901
|
+
deleted: succeeded.map((d) => ({ requested: d.requested, path: d.path, trash_path: d.trash_path })),
|
|
4902
|
+
failed: failed.map((d) => ({ requested: d.requested, target: d.target, error: d.error }))
|
|
4903
|
+
},
|
|
4904
|
+
() => {
|
|
4905
|
+
for (const d of done) {
|
|
4906
|
+
if (d.error) {
|
|
4907
|
+
console.log(fail(`${d.requested} \u672A\u5220\u9664: ${d.error}`));
|
|
4908
|
+
continue;
|
|
4909
|
+
}
|
|
4910
|
+
console.log(ok(`\u5DF2\u5220\u9664: ${d.path}`));
|
|
4911
|
+
const m = mismatch(d);
|
|
4912
|
+
if (m) console.log(m);
|
|
4913
|
+
if (d.trash_path) console.log(dim(` \u56DE\u6536\u7AD9: ${d.trash_path}`));
|
|
4914
|
+
}
|
|
4915
|
+
console.log(
|
|
4916
|
+
dim(
|
|
4917
|
+
`\u5171 ${done.length} \u9875: ${succeeded.length} \u6210\u529F${failed.length ? `, ${failed.length} \u5931\u8D25` : ""} \u2014 exomind trash restore <\u56DE\u6536\u7AD9\u8DEF\u5F84> \u6062\u590D`
|
|
4918
|
+
)
|
|
4919
|
+
);
|
|
4920
|
+
}
|
|
4921
|
+
);
|
|
4922
|
+
}
|
|
4923
|
+
if (failed.length) process.exitCode = 1;
|
|
4865
4924
|
}
|
|
4866
4925
|
|
|
4867
4926
|
// src/commands/get.ts
|
|
4927
|
+
function msg2(e) {
|
|
4928
|
+
return e instanceof Error ? e.message : String(e);
|
|
4929
|
+
}
|
|
4930
|
+
function render(r) {
|
|
4931
|
+
console.log(`${bold(r.title)} ${dim(`(${r.path})`)}`);
|
|
4932
|
+
if (r.tags?.length) console.log(dim(`\u6807\u7B7E: ${r.tags.join(", ")}`));
|
|
4933
|
+
console.log(dim(`\u66F4\u65B0: ${r.mtime ?? ""} \xB7 ${r.size_bytes ?? 0} \u5B57\u8282`));
|
|
4934
|
+
console.log("");
|
|
4935
|
+
console.log(truncate(String(r.body ?? ""), 2e3));
|
|
4936
|
+
}
|
|
4868
4937
|
async function get(client, _opts, args) {
|
|
4869
|
-
const
|
|
4870
|
-
if (!
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4938
|
+
const pages = (args ?? []).map((a) => String(a).trim()).filter(Boolean);
|
|
4939
|
+
if (!pages.length) throw new Error("\u8BF7\u63D0\u4F9B\u9875\u9762\u8DEF\u5F84\u6216\u5B9E\u4F53\u540D: exomind get entities/Redis.md");
|
|
4940
|
+
const results = [];
|
|
4941
|
+
let failed = 0;
|
|
4942
|
+
for (const page of pages) {
|
|
4943
|
+
try {
|
|
4944
|
+
const target = !page.includes("/") && !page.endsWith(".md") ? await resolvePagePath(client, page) : page;
|
|
4945
|
+
results.push(await client.get(`/pages/${encPath(target)}`, void 0, { timeoutMs: 3e4 }));
|
|
4946
|
+
} catch (e) {
|
|
4947
|
+
failed++;
|
|
4948
|
+
results.push({ error: msg2(e), requested: page });
|
|
4949
|
+
}
|
|
4874
4950
|
}
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
}
|
|
4951
|
+
if (pages.length === 1) {
|
|
4952
|
+
const r = results[0];
|
|
4953
|
+
if (r.error) {
|
|
4954
|
+
output({ error: r.error, requested: r.requested }, () => console.log(fail(`${r.requested}: ${r.error}`)));
|
|
4955
|
+
} else {
|
|
4956
|
+
output(r, () => render(r));
|
|
4957
|
+
}
|
|
4958
|
+
} else {
|
|
4959
|
+
output(results, () => {
|
|
4960
|
+
results.forEach((r, i) => {
|
|
4961
|
+
if (i) console.log("");
|
|
4962
|
+
if (r.error) {
|
|
4963
|
+
console.log(fail(`${r.requested}: ${r.error}`));
|
|
4964
|
+
return;
|
|
4965
|
+
}
|
|
4966
|
+
render(r);
|
|
4967
|
+
});
|
|
4968
|
+
});
|
|
4969
|
+
}
|
|
4970
|
+
if (failed) process.exitCode = 1;
|
|
4883
4971
|
}
|
|
4884
4972
|
|
|
4885
4973
|
// src/commands/trash.ts
|
|
@@ -4889,7 +4977,7 @@ async function trash(client, opts, args) {
|
|
|
4889
4977
|
case "list":
|
|
4890
4978
|
return doList2(client, opts);
|
|
4891
4979
|
case "restore":
|
|
4892
|
-
return doRestore(client, args
|
|
4980
|
+
return doRestore(client, args.slice(1));
|
|
4893
4981
|
default:
|
|
4894
4982
|
throw new Error(
|
|
4895
4983
|
`\u672A\u77E5 trash \u5B50\u547D\u4EE4: ${action ?? "(\u7A7A)"}\u3002\u53EF\u7528: list \u5217\u8868 / restore <\u56DE\u6536\u7AD9\u8DEF\u5F84> \u6062\u590D`
|
|
@@ -4915,9 +5003,13 @@ async function doList2(client, opts) {
|
|
|
4915
5003
|
);
|
|
4916
5004
|
});
|
|
4917
5005
|
}
|
|
4918
|
-
async function doRestore(client,
|
|
4919
|
-
const
|
|
4920
|
-
if (!
|
|
5006
|
+
async function doRestore(client, targets) {
|
|
5007
|
+
const list2 = targets.map((t) => t.trim()).filter(Boolean);
|
|
5008
|
+
if (!list2.length) throw new Error('\u8BF7\u63D0\u4F9B\u56DE\u6536\u7AD9\u8DEF\u5F84: exomind trash restore ".trash/202609/entities/Redis.md"');
|
|
5009
|
+
if (list2.length > 1) {
|
|
5010
|
+
throw new Error(`\u4E00\u6B21\u53EA\u80FD\u6062\u590D\u4E00\u4E2A:\u6536\u5230 ${list2.length} \u4E2A\u8DEF\u5F84,\u8BF7\u9010\u4E2A\u6062\u590D(\u7B2C 1 \u4E2A: ${list2[0]})`);
|
|
5011
|
+
}
|
|
5012
|
+
const p = list2[0];
|
|
4921
5013
|
console.log(dim("\u6062\u590D\u4E2D\u2026\u5927\u77E5\u8BC6\u98DE\u8F6E\u5237\u7D22\u5F15\u53EF\u80FD\u9700\u8981\u4E00\u4E24\u5206\u949F,\u8BF7\u52FF\u5173\u95ED"));
|
|
4922
5014
|
const r = await client.post("/trash/restore", { trash_path: p }, { timeoutMs: opTimeout(3e5) });
|
|
4923
5015
|
output(r, () => console.log(ok(`\u5DF2\u6062\u590D \u2192 ${r.path}`)));
|
|
@@ -5349,11 +5441,11 @@ function rootOptions(cmd) {
|
|
|
5349
5441
|
return c.opts();
|
|
5350
5442
|
}
|
|
5351
5443
|
function handleError(e) {
|
|
5352
|
-
const
|
|
5444
|
+
const msg3 = e instanceof ApiError ? e.message : e instanceof Error ? e.message : String(e);
|
|
5353
5445
|
if (isJsonMode()) {
|
|
5354
|
-
console.log(JSON.stringify({ error:
|
|
5446
|
+
console.log(JSON.stringify({ error: msg3 }));
|
|
5355
5447
|
} else {
|
|
5356
|
-
console.error(red(`\u2717 ${
|
|
5448
|
+
console.error(red(`\u2717 ${msg3}`));
|
|
5357
5449
|
}
|
|
5358
5450
|
process.exit(1);
|
|
5359
5451
|
}
|