@claudeink/mcp-server 1.0.0 → 2.0.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/dist/cli.js +728 -940
- package/dist/index.js +523 -745
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4320,11 +4320,11 @@ var require_core = __commonJS({
|
|
|
4320
4320
|
Ajv2.ValidationError = validation_error_1.default;
|
|
4321
4321
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
4322
4322
|
exports2.default = Ajv2;
|
|
4323
|
-
function checkOptions(checkOpts, options2, msg,
|
|
4323
|
+
function checkOptions(checkOpts, options2, msg, log2 = "error") {
|
|
4324
4324
|
for (const key in checkOpts) {
|
|
4325
4325
|
const opt = key;
|
|
4326
4326
|
if (opt in options2)
|
|
4327
|
-
this.logger[
|
|
4327
|
+
this.logger[log2](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
4328
4328
|
}
|
|
4329
4329
|
}
|
|
4330
4330
|
function getSchEnv(keyRef) {
|
|
@@ -23142,8 +23142,8 @@ var Server = class extends Protocol {
|
|
|
23142
23142
|
this._loggingLevels = /* @__PURE__ */ new Map();
|
|
23143
23143
|
this.LOG_LEVEL_SEVERITY = new Map(LoggingLevelSchema.options.map((level, index) => [level, index]));
|
|
23144
23144
|
this.isMessageIgnored = (level, sessionId) => {
|
|
23145
|
-
const
|
|
23146
|
-
return
|
|
23145
|
+
const currentLevel2 = this._loggingLevels.get(sessionId);
|
|
23146
|
+
return currentLevel2 ? this.LOG_LEVEL_SEVERITY.get(level) < this.LOG_LEVEL_SEVERITY.get(currentLevel2) : false;
|
|
23147
23147
|
};
|
|
23148
23148
|
this._capabilities = options2?.capabilities ?? {};
|
|
23149
23149
|
this._instructions = options2?.instructions;
|
|
@@ -24476,12 +24476,9 @@ var StdioServerTransport = class {
|
|
|
24476
24476
|
}
|
|
24477
24477
|
};
|
|
24478
24478
|
|
|
24479
|
-
// src/tools/
|
|
24480
|
-
|
|
24481
|
-
import { readFile as readFile3 } from "fs/promises";
|
|
24479
|
+
// src/tools/workflow.ts
|
|
24480
|
+
import { mkdir as mkdir3, access, unlink } from "fs/promises";
|
|
24482
24481
|
import { join as join3 } from "path";
|
|
24483
|
-
import { readdirSync } from "fs";
|
|
24484
|
-
import { execSync } from "child_process";
|
|
24485
24482
|
|
|
24486
24483
|
// src/lib/state.ts
|
|
24487
24484
|
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
@@ -24503,7 +24500,8 @@ var DEFAULT_STATE = {
|
|
|
24503
24500
|
credentials: null,
|
|
24504
24501
|
config: {
|
|
24505
24502
|
apiBaseUrl: "https://app.claudeink.com",
|
|
24506
|
-
workflowDir: ""
|
|
24503
|
+
workflowDir: "",
|
|
24504
|
+
logLevel: "INFO"
|
|
24507
24505
|
},
|
|
24508
24506
|
tagQueue: {
|
|
24509
24507
|
queue: [],
|
|
@@ -24578,10 +24576,160 @@ async function addToTagQueue(item) {
|
|
|
24578
24576
|
await writeState(state);
|
|
24579
24577
|
}
|
|
24580
24578
|
|
|
24579
|
+
// src/lib/logger.ts
|
|
24580
|
+
import { appendFile, mkdir as mkdir2 } from "fs/promises";
|
|
24581
|
+
import { join as join2 } from "path";
|
|
24582
|
+
var currentLevel = "INFO";
|
|
24583
|
+
var LEVELS = { ERROR: 0, WARN: 1, INFO: 2, DEBUG: 3 };
|
|
24584
|
+
function setLogLevel(level) {
|
|
24585
|
+
currentLevel = level;
|
|
24586
|
+
}
|
|
24587
|
+
async function log(level, scope, message) {
|
|
24588
|
+
if (LEVELS[level] > LEVELS[currentLevel]) return;
|
|
24589
|
+
const dir = join2(getClaudeinkDir(), "logs");
|
|
24590
|
+
await mkdir2(dir, { recursive: true });
|
|
24591
|
+
const date3 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
24592
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${scope} | ${message}
|
|
24593
|
+
`;
|
|
24594
|
+
await appendFile(join2(dir, `mcp-${date3}.log`), line);
|
|
24595
|
+
console.error(`[ClaudeInk] ${line.trim()}`);
|
|
24596
|
+
}
|
|
24597
|
+
|
|
24598
|
+
// src/tools/sync.ts
|
|
24599
|
+
var syncSchema = external_exports.object({
|
|
24600
|
+
workDir: external_exports.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u914D\u7F6E\u4E2D\u7684 workflowDir\uFF09")
|
|
24601
|
+
});
|
|
24602
|
+
async function sync(input) {
|
|
24603
|
+
if (input.workDir) setWorkDir(input.workDir);
|
|
24604
|
+
const creds = await getCredentials();
|
|
24605
|
+
if (!creds?.token) {
|
|
24606
|
+
return { success: false, message: "\u672A\u6FC0\u6D3B\uFF0C\u8BF7\u5148\u4F7F\u7528 workflow.init \u6FC0\u6D3B License" };
|
|
24607
|
+
}
|
|
24608
|
+
return doPull(creds.token);
|
|
24609
|
+
}
|
|
24610
|
+
async function doPull(token) {
|
|
24611
|
+
const config2 = await getConfig();
|
|
24612
|
+
try {
|
|
24613
|
+
const res = await fetch(`${config2.apiBaseUrl}/api/sync/pull`, {
|
|
24614
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
24615
|
+
});
|
|
24616
|
+
if (!res.ok) {
|
|
24617
|
+
if (res.status === 404) {
|
|
24618
|
+
return { success: true, message: "\u4E91\u7AEF\u65E0\u6570\u636E" };
|
|
24619
|
+
}
|
|
24620
|
+
await log("ERROR", "ink.sync", `pull failed: HTTP ${res.status}`);
|
|
24621
|
+
return { success: false, message: `\u62C9\u53D6\u5931\u8D25: HTTP ${res.status}` };
|
|
24622
|
+
}
|
|
24623
|
+
await updateLastSyncAt();
|
|
24624
|
+
await log("INFO", "ink.sync", "pull completed");
|
|
24625
|
+
return {
|
|
24626
|
+
success: true,
|
|
24627
|
+
message: "\u2705 \u540C\u6B65\u5B8C\u6210"
|
|
24628
|
+
};
|
|
24629
|
+
} catch (err) {
|
|
24630
|
+
return { success: false, message: `\u540C\u6B65\u5931\u8D25: ${err instanceof Error ? err.message : err}` };
|
|
24631
|
+
}
|
|
24632
|
+
}
|
|
24633
|
+
async function syncPull(input) {
|
|
24634
|
+
if (input.workDir) setWorkDir(input.workDir);
|
|
24635
|
+
const creds = await getCredentials();
|
|
24636
|
+
if (!creds?.token) {
|
|
24637
|
+
return { success: false, message: "\u672A\u6FC0\u6D3B" };
|
|
24638
|
+
}
|
|
24639
|
+
return doPull(creds.token);
|
|
24640
|
+
}
|
|
24641
|
+
|
|
24642
|
+
// src/tools/workflow.ts
|
|
24643
|
+
var DEFAULT_API_BASE_URL = "https://app.claudeink.com";
|
|
24644
|
+
var workflowInitSchema = external_exports.object({
|
|
24645
|
+
workDir: external_exports.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
|
|
24646
|
+
licenseKey: external_exports.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
|
|
24647
|
+
});
|
|
24648
|
+
async function workflowInit(input) {
|
|
24649
|
+
const cwd = input.workDir;
|
|
24650
|
+
const results = [];
|
|
24651
|
+
try {
|
|
24652
|
+
setWorkDir(cwd);
|
|
24653
|
+
const claudeinkDir = join3(cwd, ".claudeink");
|
|
24654
|
+
await mkdir3(join3(claudeinkDir, "knowledge"), { recursive: true });
|
|
24655
|
+
results.push("\u2705 \u77E5\u8BC6\u5E93\u76EE\u5F55\u5DF2\u521B\u5EFA");
|
|
24656
|
+
const state = await readState();
|
|
24657
|
+
state.config.workflowDir = cwd;
|
|
24658
|
+
const oldCredsPath = join3(claudeinkDir, "credentials.json");
|
|
24659
|
+
try {
|
|
24660
|
+
await access(oldCredsPath);
|
|
24661
|
+
await unlink(oldCredsPath);
|
|
24662
|
+
results.push("\u{1F9F9} \u5DF2\u6E05\u7406\u65E7\u7248 credentials.json");
|
|
24663
|
+
} catch {
|
|
24664
|
+
}
|
|
24665
|
+
let activated = false;
|
|
24666
|
+
if (input.licenseKey) {
|
|
24667
|
+
try {
|
|
24668
|
+
const res = await fetch(`${DEFAULT_API_BASE_URL}/api/auth/activate`, {
|
|
24669
|
+
method: "POST",
|
|
24670
|
+
headers: { "Content-Type": "application/json" },
|
|
24671
|
+
body: JSON.stringify({ key: input.licenseKey })
|
|
24672
|
+
});
|
|
24673
|
+
const data = await res.json();
|
|
24674
|
+
if (data.userId) {
|
|
24675
|
+
state.credentials = {
|
|
24676
|
+
licenseKey: input.licenseKey,
|
|
24677
|
+
token: data.token,
|
|
24678
|
+
userId: data.userId,
|
|
24679
|
+
plan: data.plan,
|
|
24680
|
+
expiresAt: data.expiresAt
|
|
24681
|
+
};
|
|
24682
|
+
results.push(`\u2705 License \u6FC0\u6D3B\u6210\u529F\uFF08\u5957\u9910: ${data.plan}\uFF09`);
|
|
24683
|
+
activated = true;
|
|
24684
|
+
} else {
|
|
24685
|
+
results.push(`\u26A0\uFE0F License \u6FC0\u6D3B\u5931\u8D25: ${JSON.stringify(data)}`);
|
|
24686
|
+
}
|
|
24687
|
+
} catch (err) {
|
|
24688
|
+
results.push(`\u26A0\uFE0F \u6FC0\u6D3B\u7F51\u7EDC\u9519\u8BEF: ${err instanceof Error ? err.message : err}`);
|
|
24689
|
+
}
|
|
24690
|
+
}
|
|
24691
|
+
await writeState(state);
|
|
24692
|
+
results.push("\u2705 state.json");
|
|
24693
|
+
if (activated) {
|
|
24694
|
+
try {
|
|
24695
|
+
const pullResult = await syncPull({ workDir: cwd });
|
|
24696
|
+
if (pullResult.success) {
|
|
24697
|
+
results.push("\u2705 \u5DF2\u4ECE\u4E91\u7AEF\u540C\u6B65\u6570\u636E");
|
|
24698
|
+
} else {
|
|
24699
|
+
results.push("\u2139\uFE0F \u4E91\u7AEF\u65E0\u5DF2\u6709\u6570\u636E");
|
|
24700
|
+
}
|
|
24701
|
+
} catch {
|
|
24702
|
+
results.push("\u2139\uFE0F \u4E91\u7AEF\u540C\u6B65\u8DF3\u8FC7");
|
|
24703
|
+
}
|
|
24704
|
+
}
|
|
24705
|
+
return {
|
|
24706
|
+
success: true,
|
|
24707
|
+
message: [
|
|
24708
|
+
"\u{1F389} ClaudeInk \u77E5\u8BC6\u5E93\u521D\u59CB\u5316\u5B8C\u6210\uFF01",
|
|
24709
|
+
"",
|
|
24710
|
+
...results,
|
|
24711
|
+
"",
|
|
24712
|
+
"\u{1F3AF} \u4E0B\u4E00\u6B65\uFF1A",
|
|
24713
|
+
"1. \u5728\u5BF9\u8BDD\u4E2D\u8BF4\u300C\u5E2E\u6211\u5B58\u4E00\u4E0B\u300D\u4FDD\u5B58\u6709\u4EF7\u503C\u5185\u5BB9",
|
|
24714
|
+
"2. \u7528\u300C\u627E\u4E00\u4E0B\u5173\u4E8E XX \u7684\u300D\u68C0\u7D22\u77E5\u8BC6\u5E93"
|
|
24715
|
+
].join("\n")
|
|
24716
|
+
};
|
|
24717
|
+
} catch (err) {
|
|
24718
|
+
return {
|
|
24719
|
+
success: false,
|
|
24720
|
+
message: `\u521D\u59CB\u5316\u5931\u8D25: ${err instanceof Error ? err.message : err}`
|
|
24721
|
+
};
|
|
24722
|
+
}
|
|
24723
|
+
}
|
|
24724
|
+
|
|
24725
|
+
// src/tools/ink.ts
|
|
24726
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
24727
|
+
import { extname } from "path";
|
|
24728
|
+
|
|
24581
24729
|
// src/lib/knowledge.ts
|
|
24582
24730
|
var import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
24583
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as
|
|
24584
|
-
import { join as
|
|
24731
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir4, unlink as unlink2 } from "fs/promises";
|
|
24732
|
+
import { join as join4 } from "path";
|
|
24585
24733
|
var _lockPromise = Promise.resolve();
|
|
24586
24734
|
function withIndexLock(fn) {
|
|
24587
24735
|
const prev = _lockPromise;
|
|
@@ -24592,10 +24740,10 @@ function withIndexLock(fn) {
|
|
|
24592
24740
|
return prev.then(fn).finally(() => resolve());
|
|
24593
24741
|
}
|
|
24594
24742
|
function getKnowledgeDir() {
|
|
24595
|
-
return
|
|
24743
|
+
return join4(getWorkDir(), ".claudeink", "knowledge");
|
|
24596
24744
|
}
|
|
24597
24745
|
function getIndexPath() {
|
|
24598
|
-
return
|
|
24746
|
+
return join4(getWorkDir(), ".claudeink", "knowledge", "index.json");
|
|
24599
24747
|
}
|
|
24600
24748
|
async function generateIdInternal(index) {
|
|
24601
24749
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -24628,17 +24776,17 @@ async function readIndex() {
|
|
|
24628
24776
|
async function saveIndex(index) {
|
|
24629
24777
|
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
24630
24778
|
const dir = getKnowledgeDir();
|
|
24631
|
-
await
|
|
24779
|
+
await mkdir4(dir, { recursive: true });
|
|
24632
24780
|
await writeFile2(getIndexPath(), JSON.stringify(index, null, 2), "utf-8");
|
|
24633
24781
|
}
|
|
24634
24782
|
async function writeKnowledgeFile(meta, content) {
|
|
24635
24783
|
const now = /* @__PURE__ */ new Date();
|
|
24636
24784
|
const monthDir = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
24637
|
-
const dir =
|
|
24638
|
-
await
|
|
24785
|
+
const dir = join4(getKnowledgeDir(), monthDir);
|
|
24786
|
+
await mkdir4(dir, { recursive: true });
|
|
24639
24787
|
const slug = toSlug(meta.title) || meta.id;
|
|
24640
24788
|
const filename = `${now.toISOString().slice(0, 10)}-${slug}.md`;
|
|
24641
|
-
const filePath =
|
|
24789
|
+
const filePath = join4(dir, filename);
|
|
24642
24790
|
const frontmatter = {
|
|
24643
24791
|
id: meta.id,
|
|
24644
24792
|
title: meta.title,
|
|
@@ -24651,13 +24799,13 @@ async function writeKnowledgeFile(meta, content) {
|
|
|
24651
24799
|
if (meta.url) frontmatter.url = meta.url;
|
|
24652
24800
|
const output = import_gray_matter.default.stringify(content, frontmatter);
|
|
24653
24801
|
await writeFile2(filePath, output, "utf-8");
|
|
24654
|
-
return
|
|
24802
|
+
return join4(monthDir, filename);
|
|
24655
24803
|
}
|
|
24656
24804
|
async function readKnowledgeFile(id) {
|
|
24657
24805
|
const index = await readIndex();
|
|
24658
24806
|
const entry = index.entries[id];
|
|
24659
24807
|
if (!entry) return null;
|
|
24660
|
-
const filePath =
|
|
24808
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
24661
24809
|
try {
|
|
24662
24810
|
const raw = await readFile2(filePath, "utf-8");
|
|
24663
24811
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -24742,9 +24890,9 @@ async function deleteKnowledgeFile(id) {
|
|
|
24742
24890
|
const index = await readIndex();
|
|
24743
24891
|
const entry = index.entries[id];
|
|
24744
24892
|
if (!entry) return false;
|
|
24745
|
-
const filePath =
|
|
24893
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
24746
24894
|
try {
|
|
24747
|
-
await
|
|
24895
|
+
await unlink2(filePath);
|
|
24748
24896
|
} catch {
|
|
24749
24897
|
}
|
|
24750
24898
|
delete index.entries[id];
|
|
@@ -24752,55 +24900,6 @@ async function deleteKnowledgeFile(id) {
|
|
|
24752
24900
|
return true;
|
|
24753
24901
|
});
|
|
24754
24902
|
}
|
|
24755
|
-
function searchKnowledge(index, filters) {
|
|
24756
|
-
let entries = Object.values(index.entries);
|
|
24757
|
-
if (filters.tags && filters.tags.length > 0) {
|
|
24758
|
-
const filterTags = filters.tags.map((t) => t.toLowerCase());
|
|
24759
|
-
entries = entries.filter(
|
|
24760
|
-
(e) => e.tags.some((t) => filterTags.includes(t.toLowerCase()))
|
|
24761
|
-
);
|
|
24762
|
-
}
|
|
24763
|
-
if (filters.category) {
|
|
24764
|
-
entries = entries.filter((e) => e.category === filters.category);
|
|
24765
|
-
}
|
|
24766
|
-
if (filters.date_from) {
|
|
24767
|
-
entries = entries.filter((e) => e.created_at >= filters.date_from);
|
|
24768
|
-
}
|
|
24769
|
-
if (filters.date_to) {
|
|
24770
|
-
entries = entries.filter((e) => e.created_at <= filters.date_to);
|
|
24771
|
-
}
|
|
24772
|
-
if (filters.query) {
|
|
24773
|
-
const q = filters.query.toLowerCase();
|
|
24774
|
-
entries = entries.map((e) => {
|
|
24775
|
-
let score = 0;
|
|
24776
|
-
if (e.title.toLowerCase().includes(q)) score += 10;
|
|
24777
|
-
if (e.preview.toLowerCase().includes(q)) score += 5;
|
|
24778
|
-
if (e.tags.some((t) => t.toLowerCase().includes(q))) score += 3;
|
|
24779
|
-
return { ...e, _score: score };
|
|
24780
|
-
}).filter((e) => e._score > 0).sort((a, b) => b._score - a._score);
|
|
24781
|
-
} else {
|
|
24782
|
-
entries.sort((a, b) => b.created_at.localeCompare(a.created_at));
|
|
24783
|
-
}
|
|
24784
|
-
const total = entries.length;
|
|
24785
|
-
const limit = filters.limit || 10;
|
|
24786
|
-
const results = entries.slice(0, limit).map((e) => ({
|
|
24787
|
-
id: e.id,
|
|
24788
|
-
title: e.title,
|
|
24789
|
-
tags: e.tags,
|
|
24790
|
-
category: e.category,
|
|
24791
|
-
created_at: e.created_at,
|
|
24792
|
-
preview: e.preview
|
|
24793
|
-
}));
|
|
24794
|
-
return { results, total };
|
|
24795
|
-
}
|
|
24796
|
-
async function readMultipleKnowledgeFiles(ids) {
|
|
24797
|
-
const results = [];
|
|
24798
|
-
for (const id of ids) {
|
|
24799
|
-
const file = await readKnowledgeFile(id);
|
|
24800
|
-
if (file) results.push(file);
|
|
24801
|
-
}
|
|
24802
|
-
return results;
|
|
24803
|
-
}
|
|
24804
24903
|
function getAllTags(index) {
|
|
24805
24904
|
const tagCounts = {};
|
|
24806
24905
|
for (const entry of Object.values(index.entries)) {
|
|
@@ -24819,7 +24918,7 @@ async function renameTag(oldTag, newTag) {
|
|
|
24819
24918
|
if (idx !== -1) {
|
|
24820
24919
|
entry.tags[idx] = newTag;
|
|
24821
24920
|
count++;
|
|
24822
|
-
const filePath =
|
|
24921
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
24823
24922
|
try {
|
|
24824
24923
|
const raw = await readFile2(filePath, "utf-8");
|
|
24825
24924
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -24854,7 +24953,7 @@ async function mergeTags(sourceTags, targetTag) {
|
|
|
24854
24953
|
}
|
|
24855
24954
|
entry.tags = newTags;
|
|
24856
24955
|
count++;
|
|
24857
|
-
const filePath =
|
|
24956
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
24858
24957
|
try {
|
|
24859
24958
|
const raw = await readFile2(filePath, "utf-8");
|
|
24860
24959
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -24885,6 +24984,7 @@ async function doPush(partial2) {
|
|
|
24885
24984
|
knowledge: partial2.knowledge || [],
|
|
24886
24985
|
crawlerSources: partial2.crawlerSources || []
|
|
24887
24986
|
};
|
|
24987
|
+
await log("DEBUG", "push", `payload: ${partial2.knowledge?.length || 0} knowledge, ${partial2.crawlerSources?.length || 0} sources`);
|
|
24888
24988
|
try {
|
|
24889
24989
|
await fetch(`${config2.apiBaseUrl}/api/sync/batch`, {
|
|
24890
24990
|
method: "POST",
|
|
@@ -24895,57 +24995,349 @@ async function doPush(partial2) {
|
|
|
24895
24995
|
body: JSON.stringify(payload)
|
|
24896
24996
|
});
|
|
24897
24997
|
} catch (err) {
|
|
24898
|
-
|
|
24998
|
+
await log("WARN", "push", `failed: ${err instanceof Error ? err.message : err}`);
|
|
24899
24999
|
}
|
|
24900
25000
|
}
|
|
24901
25001
|
|
|
24902
|
-
// src/tools/
|
|
24903
|
-
var
|
|
24904
|
-
|
|
25002
|
+
// src/tools/ink.ts
|
|
25003
|
+
var inkSaveSchema = external_exports.object({
|
|
25004
|
+
id: external_exports.string().optional().describe("\u77E5\u8BC6\u7247\u6BB5 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
|
|
25005
|
+
content: external_exports.string().describe("\u8981\u4FDD\u5B58\u7684\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"),
|
|
25006
|
+
title: external_exports.string().describe("\u6807\u9898\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF09"),
|
|
25007
|
+
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
|
|
25008
|
+
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
|
|
25009
|
+
source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B"),
|
|
25010
|
+
url: external_exports.string().optional().describe("\u6765\u6E90 URL")
|
|
24905
25011
|
});
|
|
24906
|
-
async function
|
|
24907
|
-
const config2 = await getConfig();
|
|
24908
|
-
const crawlerDir = join3(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
24909
|
-
const configPath = join3(crawlerDir, "config.json");
|
|
24910
|
-
let crawlerConfig;
|
|
25012
|
+
async function inkSave(input) {
|
|
24911
25013
|
try {
|
|
24912
|
-
|
|
24913
|
-
|
|
24914
|
-
|
|
24915
|
-
|
|
24916
|
-
|
|
24917
|
-
|
|
24918
|
-
|
|
24919
|
-
|
|
24920
|
-
|
|
25014
|
+
if (input.id) {
|
|
25015
|
+
const result = await updateKnowledgeFile(input.id, {
|
|
25016
|
+
title: input.title,
|
|
25017
|
+
content: input.content,
|
|
25018
|
+
tags: input.tags,
|
|
25019
|
+
category: input.category
|
|
25020
|
+
});
|
|
25021
|
+
if (!result) {
|
|
25022
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
25023
|
+
}
|
|
25024
|
+
fireAndForgetPush({
|
|
25025
|
+
knowledge: [{
|
|
25026
|
+
id: result.meta.id,
|
|
25027
|
+
title: result.meta.title,
|
|
25028
|
+
tags: result.meta.tags,
|
|
25029
|
+
category: result.meta.category,
|
|
25030
|
+
source_type: result.meta.source_type,
|
|
25031
|
+
url: result.meta.url,
|
|
25032
|
+
created_at: result.meta.created_at,
|
|
25033
|
+
updated_at: result.meta.updated_at
|
|
25034
|
+
}]
|
|
25035
|
+
});
|
|
25036
|
+
await log("INFO", "ink.save", `updated id=${input.id} title="${input.title}"`);
|
|
25037
|
+
return {
|
|
25038
|
+
success: true,
|
|
25039
|
+
message: `\u5DF2\u66F4\u65B0\u300C${result.meta.title}\u300D`,
|
|
25040
|
+
data: { id: result.meta.id }
|
|
25041
|
+
};
|
|
25042
|
+
}
|
|
25043
|
+
const { id } = await saveKnowledge({
|
|
25044
|
+
content: input.content,
|
|
25045
|
+
title: input.title,
|
|
25046
|
+
tags: input.tags,
|
|
25047
|
+
category: input.category,
|
|
25048
|
+
source_type: input.source_type,
|
|
25049
|
+
url: input.url
|
|
25050
|
+
});
|
|
25051
|
+
fireAndForgetPush({
|
|
25052
|
+
knowledge: [{
|
|
25053
|
+
id,
|
|
25054
|
+
title: input.title,
|
|
25055
|
+
tags: input.tags,
|
|
25056
|
+
category: input.category,
|
|
25057
|
+
source_type: input.source_type,
|
|
25058
|
+
url: input.url,
|
|
25059
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25060
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
25061
|
+
}]
|
|
25062
|
+
});
|
|
25063
|
+
await log("INFO", "ink.save", `created id=${id} title="${input.title}" tags=${JSON.stringify(input.tags)}`);
|
|
24921
25064
|
return {
|
|
24922
|
-
success:
|
|
24923
|
-
message:
|
|
25065
|
+
success: true,
|
|
25066
|
+
message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D`,
|
|
25067
|
+
data: { id }
|
|
24924
25068
|
};
|
|
25069
|
+
} catch (err) {
|
|
25070
|
+
await log("ERROR", "ink.save", `failed: ${err.message}`);
|
|
25071
|
+
return { success: false, message: `\u4FDD\u5B58\u5931\u8D25\uFF1A${err.message}` };
|
|
24925
25072
|
}
|
|
24926
|
-
|
|
24927
|
-
|
|
25073
|
+
}
|
|
25074
|
+
var inkDeleteSchema = external_exports.object({
|
|
25075
|
+
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
|
|
25076
|
+
confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
|
|
25077
|
+
});
|
|
25078
|
+
async function inkDelete(input) {
|
|
24928
25079
|
try {
|
|
24929
|
-
|
|
24930
|
-
|
|
24931
|
-
|
|
24932
|
-
|
|
24933
|
-
|
|
25080
|
+
if (!input.confirm) {
|
|
25081
|
+
const index = await readIndex();
|
|
25082
|
+
const entry = index.entries[input.id];
|
|
25083
|
+
if (!entry) {
|
|
25084
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
25085
|
+
}
|
|
25086
|
+
return {
|
|
25087
|
+
success: false,
|
|
25088
|
+
message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
|
|
25089
|
+
data: { id: entry.id, title: entry.title, category: entry.category, tags: entry.tags }
|
|
25090
|
+
};
|
|
25091
|
+
}
|
|
25092
|
+
const deleted = await deleteKnowledgeFile(input.id);
|
|
25093
|
+
if (!deleted) {
|
|
25094
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
25095
|
+
}
|
|
25096
|
+
fireAndForgetPush({
|
|
25097
|
+
knowledge: [{
|
|
25098
|
+
id: input.id,
|
|
25099
|
+
title: "",
|
|
25100
|
+
tags: [],
|
|
25101
|
+
category: "reference",
|
|
25102
|
+
source_type: "conversation",
|
|
25103
|
+
created_at: "",
|
|
25104
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
25105
|
+
}]
|
|
24934
25106
|
});
|
|
24935
|
-
|
|
24936
|
-
|
|
24937
|
-
|
|
24938
|
-
|
|
24939
|
-
|
|
24940
|
-
|
|
24941
|
-
|
|
24942
|
-
|
|
24943
|
-
|
|
25107
|
+
await log("INFO", "ink.delete", `deleted id=${input.id}`);
|
|
25108
|
+
return { success: true, message: `\u5DF2\u5220\u9664\u77E5\u8BC6\u7247\u6BB5 ${input.id}`, data: { id: input.id } };
|
|
25109
|
+
} catch (err) {
|
|
25110
|
+
await log("ERROR", "ink.delete", `failed: ${err.message}`);
|
|
25111
|
+
return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
|
|
25112
|
+
}
|
|
25113
|
+
}
|
|
25114
|
+
var inkWriteSchema = external_exports.object({
|
|
25115
|
+
title: external_exports.string().describe("\u6587\u7AE0\u6807\u9898"),
|
|
25116
|
+
content: external_exports.string().describe("Markdown \u5168\u6587"),
|
|
25117
|
+
cover: external_exports.string().optional().describe("\u5C01\u9762\u56FE\uFF08\u672C\u5730\u8DEF\u5F84\u6216 URL\uFF0C\u81EA\u52A8\u4E0A\u4F20\uFF09"),
|
|
25118
|
+
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6587\u7AE0\u6807\u7B7E"),
|
|
25119
|
+
category: external_exports.string().optional().describe("\u6587\u7AE0\u5206\u7C7B"),
|
|
25120
|
+
excerpt: external_exports.string().optional().describe("\u6458\u8981\uFF08\u4E0D\u586B\u81EA\u52A8\u622A\u53D6\u524D 200 \u5B57\uFF09"),
|
|
25121
|
+
source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750 ink ID\uFF08\u6EAF\u6E90\uFF09")
|
|
25122
|
+
});
|
|
25123
|
+
async function inkWrite(input) {
|
|
25124
|
+
const creds = await getCredentials();
|
|
25125
|
+
if (!creds?.token) return { success: false, message: "\u672A\u8BA4\u8BC1\uFF0C\u8BF7\u5148\u8FD0\u884C ink.init" };
|
|
25126
|
+
const config2 = await getConfig();
|
|
25127
|
+
try {
|
|
25128
|
+
let coverUrl = input.cover || null;
|
|
25129
|
+
if (coverUrl) {
|
|
25130
|
+
if (coverUrl.startsWith("http://") || coverUrl.startsWith("https://")) {
|
|
25131
|
+
const uploadResult = await uploadImageFromUrl(coverUrl, "cover", creds.token, config2.apiBaseUrl);
|
|
25132
|
+
if (uploadResult.success) coverUrl = uploadResult.url;
|
|
25133
|
+
} else {
|
|
25134
|
+
const uploadResult = await uploadImage(coverUrl, "cover", creds.token, config2.apiBaseUrl);
|
|
25135
|
+
if (uploadResult.success) {
|
|
25136
|
+
coverUrl = uploadResult.url;
|
|
25137
|
+
} else {
|
|
25138
|
+
await log("WARN", "ink.write", `cover upload failed: ${uploadResult.error}`);
|
|
25139
|
+
coverUrl = null;
|
|
25140
|
+
}
|
|
24944
25141
|
}
|
|
24945
|
-
|
|
24946
|
-
|
|
24947
|
-
|
|
24948
|
-
|
|
25142
|
+
}
|
|
25143
|
+
const slug = `${Date.now().toString(36)}-${input.title.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-").replace(/^-|-$/g, "").slice(0, 60)}`;
|
|
25144
|
+
const excerpt = input.excerpt || input.content.replace(/^#+\s.+$/gm, "").replace(/\n+/g, " ").trim().slice(0, 200);
|
|
25145
|
+
const res = await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
|
|
25146
|
+
method: "POST",
|
|
25147
|
+
headers: {
|
|
25148
|
+
"Content-Type": "application/json",
|
|
25149
|
+
Authorization: `Bearer ${creds.token}`
|
|
25150
|
+
},
|
|
25151
|
+
body: JSON.stringify({
|
|
25152
|
+
title: input.title,
|
|
25153
|
+
slug,
|
|
25154
|
+
content: input.content,
|
|
25155
|
+
cover_url: coverUrl,
|
|
25156
|
+
tags: input.tags,
|
|
25157
|
+
category: input.category,
|
|
25158
|
+
excerpt,
|
|
25159
|
+
source_ids: input.source_ids
|
|
25160
|
+
})
|
|
25161
|
+
});
|
|
25162
|
+
if (!res.ok) {
|
|
25163
|
+
const err = await res.text();
|
|
25164
|
+
await log("ERROR", "ink.write", `save failed: ${err}`);
|
|
25165
|
+
return { success: false, message: `\u4FDD\u5B58\u5931\u8D25: ${err}` };
|
|
25166
|
+
}
|
|
25167
|
+
const data = await res.json();
|
|
25168
|
+
await log("INFO", "ink.write", `saved article="${input.title}" id=${data.id} slug=${data.slug}`);
|
|
25169
|
+
return {
|
|
25170
|
+
success: true,
|
|
25171
|
+
message: `\u6587\u7AE0\u300C${input.title}\u300D\u5DF2\u4FDD\u5B58\u4E3A\u8349\u7A3F\uFF0C\u8BF7\u5230 Dashboard \u53D1\u5E03`,
|
|
25172
|
+
data: { id: data.id, slug: data.slug, status: data.status }
|
|
25173
|
+
};
|
|
25174
|
+
} catch (err) {
|
|
25175
|
+
await log("ERROR", "ink.write", `failed: ${err.message}`);
|
|
25176
|
+
return { success: false, message: `\u5199\u6587\u7AE0\u5931\u8D25: ${err.message}` };
|
|
25177
|
+
}
|
|
25178
|
+
}
|
|
25179
|
+
var inkTagsSchema = external_exports.object({
|
|
25180
|
+
action: external_exports.enum(["list", "rename", "merge"]).describe("\u64CD\u4F5C\uFF1Alist\uFF08\u5217\u51FA\u6240\u6709\u6807\u7B7E\uFF09/ rename\uFF08\u91CD\u547D\u540D\uFF09/ merge\uFF08\u5408\u5E76\uFF09"),
|
|
25181
|
+
tag: external_exports.string().optional().describe("\u76EE\u6807\u6807\u7B7E\uFF08rename/merge \u65F6\u4F7F\u7528\uFF09"),
|
|
25182
|
+
new_tag: external_exports.string().optional().describe("\u65B0\u6807\u7B7E\u540D\uFF08rename \u65F6\u4F7F\u7528\uFF09"),
|
|
25183
|
+
source_tags: external_exports.array(external_exports.string()).optional().describe("\u8981\u5408\u5E76\u7684\u6E90\u6807\u7B7E\u5217\u8868\uFF08merge \u65F6\u4F7F\u7528\uFF09")
|
|
25184
|
+
});
|
|
25185
|
+
async function inkTags(input) {
|
|
25186
|
+
try {
|
|
25187
|
+
const index = await readIndex();
|
|
25188
|
+
switch (input.action) {
|
|
25189
|
+
case "list": {
|
|
25190
|
+
const tags = getAllTags(index);
|
|
25191
|
+
return {
|
|
25192
|
+
success: true,
|
|
25193
|
+
message: tags.length > 0 ? `\u5171 ${tags.length} \u4E2A\u6807\u7B7E` : "\u6682\u65E0\u6807\u7B7E",
|
|
25194
|
+
data: { tags }
|
|
25195
|
+
};
|
|
25196
|
+
}
|
|
25197
|
+
case "rename": {
|
|
25198
|
+
if (!input.tag || !input.new_tag) {
|
|
25199
|
+
return { success: false, message: "rename \u9700\u8981 tag\uFF08\u539F\u6807\u7B7E\uFF09\u548C new_tag\uFF08\u65B0\u6807\u7B7E\u540D\uFF09" };
|
|
25200
|
+
}
|
|
25201
|
+
const count = await renameTag(input.tag, input.new_tag);
|
|
25202
|
+
if (count === 0) {
|
|
25203
|
+
return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
25204
|
+
}
|
|
25205
|
+
await log("INFO", "ink.tags", `renamed "${input.tag}" \u2192 "${input.new_tag}", affected=${count}`);
|
|
25206
|
+
return {
|
|
25207
|
+
success: true,
|
|
25208
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
|
|
25209
|
+
data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
|
|
25210
|
+
};
|
|
25211
|
+
}
|
|
25212
|
+
case "merge": {
|
|
25213
|
+
if (!input.source_tags || input.source_tags.length === 0 || !input.new_tag) {
|
|
25214
|
+
return { success: false, message: "merge \u9700\u8981 source_tags\uFF08\u6E90\u6807\u7B7E\u5217\u8868\uFF09\u548C new_tag\uFF08\u76EE\u6807\u6807\u7B7E\uFF09" };
|
|
25215
|
+
}
|
|
25216
|
+
const count = await mergeTags(input.source_tags, input.new_tag);
|
|
25217
|
+
if (count === 0) {
|
|
25218
|
+
return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u77E5\u8BC6\u7247\u6BB5" };
|
|
25219
|
+
}
|
|
25220
|
+
await log("INFO", "ink.tags", `merged [${input.source_tags.join(",")}] \u2192 "${input.new_tag}", affected=${count}`);
|
|
25221
|
+
return {
|
|
25222
|
+
success: true,
|
|
25223
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
|
|
25224
|
+
data: { source_tags: input.source_tags, target_tag: input.new_tag, affected: count }
|
|
25225
|
+
};
|
|
25226
|
+
}
|
|
25227
|
+
}
|
|
25228
|
+
} catch (err) {
|
|
25229
|
+
await log("ERROR", "ink.tags", `failed: ${err.message}`);
|
|
25230
|
+
return { success: false, message: `\u6807\u7B7E\u64CD\u4F5C\u5931\u8D25\uFF1A${err.message}` };
|
|
25231
|
+
}
|
|
25232
|
+
}
|
|
25233
|
+
async function uploadImage(localPath, type, token, apiBase) {
|
|
25234
|
+
try {
|
|
25235
|
+
const fileBuffer = await readFile3(localPath);
|
|
25236
|
+
const ext = extname(localPath) || ".jpg";
|
|
25237
|
+
const extMap = {
|
|
25238
|
+
".jpg": "image/jpeg",
|
|
25239
|
+
".jpeg": "image/jpeg",
|
|
25240
|
+
".png": "image/png",
|
|
25241
|
+
".webp": "image/webp",
|
|
25242
|
+
".gif": "image/gif"
|
|
25243
|
+
};
|
|
25244
|
+
const contentType = extMap[ext.toLowerCase()] || "application/octet-stream";
|
|
25245
|
+
const filename = `${type}-${Date.now()}${ext}`;
|
|
25246
|
+
const res = await fetch(`${apiBase}/api/blog/upload-image`, {
|
|
25247
|
+
method: "POST",
|
|
25248
|
+
headers: {
|
|
25249
|
+
Authorization: `Bearer ${token}`,
|
|
25250
|
+
"Content-Type": contentType,
|
|
25251
|
+
"X-Filename": filename,
|
|
25252
|
+
"X-Image-Type": type
|
|
25253
|
+
},
|
|
25254
|
+
body: fileBuffer
|
|
25255
|
+
});
|
|
25256
|
+
if (!res.ok) return { success: false, error: await res.text() };
|
|
25257
|
+
const { url } = await res.json();
|
|
25258
|
+
return { success: true, url };
|
|
25259
|
+
} catch (err) {
|
|
25260
|
+
return { success: false, error: err.message };
|
|
25261
|
+
}
|
|
25262
|
+
}
|
|
25263
|
+
async function uploadImageFromUrl(imageUrl, type, token, apiBase) {
|
|
25264
|
+
try {
|
|
25265
|
+
const res = await fetch(imageUrl);
|
|
25266
|
+
if (!res.ok) return { success: false, error: `download failed: HTTP ${res.status}` };
|
|
25267
|
+
const fileBuffer = Buffer.from(await res.arrayBuffer());
|
|
25268
|
+
const ext = extname(new URL(imageUrl).pathname) || ".jpg";
|
|
25269
|
+
const contentType = res.headers.get("content-type") || "image/jpeg";
|
|
25270
|
+
const filename = `${type}-${Date.now()}${ext}`;
|
|
25271
|
+
const uploadRes = await fetch(`${apiBase}/api/blog/upload-image`, {
|
|
25272
|
+
method: "POST",
|
|
25273
|
+
headers: {
|
|
25274
|
+
Authorization: `Bearer ${token}`,
|
|
25275
|
+
"Content-Type": contentType,
|
|
25276
|
+
"X-Filename": filename,
|
|
25277
|
+
"X-Image-Type": type
|
|
25278
|
+
},
|
|
25279
|
+
body: fileBuffer
|
|
25280
|
+
});
|
|
25281
|
+
if (!uploadRes.ok) return { success: false, error: await uploadRes.text() };
|
|
25282
|
+
const { url } = await uploadRes.json();
|
|
25283
|
+
return { success: true, url };
|
|
25284
|
+
} catch (err) {
|
|
25285
|
+
return { success: false, error: err.message };
|
|
25286
|
+
}
|
|
25287
|
+
}
|
|
25288
|
+
|
|
25289
|
+
// src/tools/source.ts
|
|
25290
|
+
var import_gray_matter2 = __toESM(require_gray_matter(), 1);
|
|
25291
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
25292
|
+
import { join as join5 } from "path";
|
|
25293
|
+
import { readdirSync } from "fs";
|
|
25294
|
+
import { execSync } from "child_process";
|
|
25295
|
+
var sourceCrawlSchema = external_exports.object({
|
|
25296
|
+
sourceId: external_exports.string().optional().describe("\u6307\u5B9A\u722C\u866B\u6E90\u540D\u79F0\uFF0C\u4E0D\u4F20\u5219\u5168\u91CF")
|
|
25297
|
+
});
|
|
25298
|
+
async function sourceCrawl(input) {
|
|
25299
|
+
const config2 = await getConfig();
|
|
25300
|
+
const crawlerDir = join5(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
25301
|
+
const configPath = join5(crawlerDir, "config.json");
|
|
25302
|
+
let crawlerConfig;
|
|
25303
|
+
try {
|
|
25304
|
+
crawlerConfig = JSON.parse(await readFile4(configPath, "utf-8"));
|
|
25305
|
+
} catch {
|
|
25306
|
+
crawlerConfig = { sources: [] };
|
|
25307
|
+
}
|
|
25308
|
+
if (crawlerConfig.sources.length === 0) {
|
|
25309
|
+
return { success: false, message: "\u6682\u65E0\u914D\u7F6E\u722C\u866B\u6E90\u3002\u8BF7\u5148\u7528 source.subscribe \u6DFB\u52A0\u3002" };
|
|
25310
|
+
}
|
|
25311
|
+
const targets = input.sourceId ? crawlerConfig.sources.filter((s) => s.id === input.sourceId) : crawlerConfig.sources.filter((s) => s.enabled !== false);
|
|
25312
|
+
if (targets.length === 0) {
|
|
25313
|
+
return {
|
|
25314
|
+
success: false,
|
|
25315
|
+
message: input.sourceId ? `\u672A\u627E\u5230\u722C\u866B\u6E90: ${input.sourceId}` : "\u6CA1\u6709\u5DF2\u542F\u7528\u7684\u722C\u866B\u6E90"
|
|
25316
|
+
};
|
|
25317
|
+
}
|
|
25318
|
+
const crawlScript = join5(crawlerDir, "crawl.mjs");
|
|
25319
|
+
const args = input.sourceId ? `--source ${input.sourceId}` : "";
|
|
25320
|
+
try {
|
|
25321
|
+
execSync(`node "${crawlScript}" ${args}`, {
|
|
25322
|
+
cwd: crawlerDir,
|
|
25323
|
+
encoding: "utf-8",
|
|
25324
|
+
timeout: 5 * 60 * 1e3,
|
|
25325
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
25326
|
+
});
|
|
25327
|
+
let saved = 0;
|
|
25328
|
+
let queued = 0;
|
|
25329
|
+
for (const target of targets) {
|
|
25330
|
+
const sourceDir = join5(config2.workflowDir, "sources", "articles", target.id);
|
|
25331
|
+
let files;
|
|
25332
|
+
try {
|
|
25333
|
+
files = readdirSync(sourceDir).filter((f) => f.endsWith(".md"));
|
|
25334
|
+
} catch {
|
|
25335
|
+
continue;
|
|
25336
|
+
}
|
|
25337
|
+
for (const f of files) {
|
|
25338
|
+
const filePath = join5(sourceDir, f);
|
|
25339
|
+
try {
|
|
25340
|
+
const raw = await readFile4(filePath, "utf-8");
|
|
24949
25341
|
const { data, content } = (0, import_gray_matter2.default)(raw);
|
|
24950
25342
|
const title = data.title || f.replace(/^\d{4}-\d{2}-\d{2}-/, "").replace(/\.md$/, "").replace(/-/g, " ");
|
|
24951
25343
|
const url = data.url || "";
|
|
@@ -25004,8 +25396,8 @@ async function sourceCrawl(input) {
|
|
|
25004
25396
|
}
|
|
25005
25397
|
|
|
25006
25398
|
// src/tools/subscribe.ts
|
|
25007
|
-
import { readFile as
|
|
25008
|
-
import { join as
|
|
25399
|
+
import { readFile as readFile5, writeFile as writeFile3, mkdir as mkdir5 } from "fs/promises";
|
|
25400
|
+
import { join as join6 } from "path";
|
|
25009
25401
|
var sourceSubscribeSchema = external_exports.object({
|
|
25010
25402
|
action: external_exports.enum(["add", "remove", "list"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
|
|
25011
25403
|
id: external_exports.string().optional().describe("\u8BA2\u9605\u6E90 ID"),
|
|
@@ -25027,16 +25419,16 @@ var sourceSubscribeSchema = external_exports.object({
|
|
|
25027
25419
|
});
|
|
25028
25420
|
async function readCrawlerConfig(configPath) {
|
|
25029
25421
|
try {
|
|
25030
|
-
return JSON.parse(await
|
|
25422
|
+
return JSON.parse(await readFile5(configPath, "utf-8"));
|
|
25031
25423
|
} catch {
|
|
25032
25424
|
return { sources: [] };
|
|
25033
25425
|
}
|
|
25034
25426
|
}
|
|
25035
25427
|
async function sourceSubscribe(input) {
|
|
25036
25428
|
const config2 = await getConfig();
|
|
25037
|
-
const crawlerDir =
|
|
25038
|
-
await
|
|
25039
|
-
const configPath =
|
|
25429
|
+
const crawlerDir = join6(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
25430
|
+
await mkdir5(crawlerDir, { recursive: true });
|
|
25431
|
+
const configPath = join6(crawlerDir, "config.json");
|
|
25040
25432
|
const crawlerConfig = await readCrawlerConfig(configPath);
|
|
25041
25433
|
if (input.action === "list") {
|
|
25042
25434
|
return {
|
|
@@ -25102,654 +25494,40 @@ async function sourceSubscribe(input) {
|
|
|
25102
25494
|
return { success: false, message: "\u672A\u77E5\u64CD\u4F5C" };
|
|
25103
25495
|
}
|
|
25104
25496
|
|
|
25105
|
-
// src/tools/sync.ts
|
|
25106
|
-
var syncSchema = external_exports.object({
|
|
25107
|
-
workDir: external_exports.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u914D\u7F6E\u4E2D\u7684 workflowDir\uFF09")
|
|
25108
|
-
});
|
|
25109
|
-
async function sync(input) {
|
|
25110
|
-
if (input.workDir) setWorkDir(input.workDir);
|
|
25111
|
-
const creds = await getCredentials();
|
|
25112
|
-
if (!creds?.token) {
|
|
25113
|
-
return { success: false, message: "\u672A\u6FC0\u6D3B\uFF0C\u8BF7\u5148\u4F7F\u7528 workflow.init \u6FC0\u6D3B License" };
|
|
25114
|
-
}
|
|
25115
|
-
return doPull(creds.token);
|
|
25116
|
-
}
|
|
25117
|
-
async function doPull(token) {
|
|
25118
|
-
const config2 = await getConfig();
|
|
25119
|
-
try {
|
|
25120
|
-
const res = await fetch(`${config2.apiBaseUrl}/api/sync/pull`, {
|
|
25121
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
25122
|
-
});
|
|
25123
|
-
if (!res.ok) {
|
|
25124
|
-
if (res.status === 404) {
|
|
25125
|
-
return { success: true, message: "\u4E91\u7AEF\u65E0\u6570\u636E" };
|
|
25126
|
-
}
|
|
25127
|
-
return { success: false, message: `\u62C9\u53D6\u5931\u8D25: HTTP ${res.status}` };
|
|
25128
|
-
}
|
|
25129
|
-
await updateLastSyncAt();
|
|
25130
|
-
return {
|
|
25131
|
-
success: true,
|
|
25132
|
-
message: "\u2705 \u540C\u6B65\u5B8C\u6210"
|
|
25133
|
-
};
|
|
25134
|
-
} catch (err) {
|
|
25135
|
-
return { success: false, message: `\u540C\u6B65\u5931\u8D25: ${err instanceof Error ? err.message : err}` };
|
|
25136
|
-
}
|
|
25137
|
-
}
|
|
25138
|
-
async function syncPull(input) {
|
|
25139
|
-
if (input.workDir) setWorkDir(input.workDir);
|
|
25140
|
-
const creds = await getCredentials();
|
|
25141
|
-
if (!creds?.token) {
|
|
25142
|
-
return { success: false, message: "\u672A\u6FC0\u6D3B" };
|
|
25143
|
-
}
|
|
25144
|
-
return doPull(creds.token);
|
|
25145
|
-
}
|
|
25146
|
-
|
|
25147
|
-
// src/tools/workflow.ts
|
|
25148
|
-
import { mkdir as mkdir4, access, unlink as unlink2 } from "fs/promises";
|
|
25149
|
-
import { join as join5 } from "path";
|
|
25150
|
-
var DEFAULT_API_BASE_URL = "https://app.claudeink.com";
|
|
25151
|
-
var workflowInitSchema = external_exports.object({
|
|
25152
|
-
workDir: external_exports.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
|
|
25153
|
-
licenseKey: external_exports.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
|
|
25154
|
-
});
|
|
25155
|
-
async function workflowInit(input) {
|
|
25156
|
-
const cwd = input.workDir;
|
|
25157
|
-
const results = [];
|
|
25158
|
-
try {
|
|
25159
|
-
setWorkDir(cwd);
|
|
25160
|
-
const claudeinkDir = join5(cwd, ".claudeink");
|
|
25161
|
-
await mkdir4(join5(claudeinkDir, "knowledge"), { recursive: true });
|
|
25162
|
-
results.push("\u2705 \u77E5\u8BC6\u5E93\u76EE\u5F55\u5DF2\u521B\u5EFA");
|
|
25163
|
-
const state = await readState();
|
|
25164
|
-
state.config.workflowDir = cwd;
|
|
25165
|
-
const oldCredsPath = join5(claudeinkDir, "credentials.json");
|
|
25166
|
-
try {
|
|
25167
|
-
await access(oldCredsPath);
|
|
25168
|
-
await unlink2(oldCredsPath);
|
|
25169
|
-
results.push("\u{1F9F9} \u5DF2\u6E05\u7406\u65E7\u7248 credentials.json");
|
|
25170
|
-
} catch {
|
|
25171
|
-
}
|
|
25172
|
-
let activated = false;
|
|
25173
|
-
if (input.licenseKey) {
|
|
25174
|
-
try {
|
|
25175
|
-
const res = await fetch(`${DEFAULT_API_BASE_URL}/api/auth/activate`, {
|
|
25176
|
-
method: "POST",
|
|
25177
|
-
headers: { "Content-Type": "application/json" },
|
|
25178
|
-
body: JSON.stringify({ key: input.licenseKey })
|
|
25179
|
-
});
|
|
25180
|
-
const data = await res.json();
|
|
25181
|
-
if (data.userId) {
|
|
25182
|
-
state.credentials = {
|
|
25183
|
-
licenseKey: input.licenseKey,
|
|
25184
|
-
token: data.token,
|
|
25185
|
-
userId: data.userId,
|
|
25186
|
-
plan: data.plan,
|
|
25187
|
-
expiresAt: data.expiresAt
|
|
25188
|
-
};
|
|
25189
|
-
results.push(`\u2705 License \u6FC0\u6D3B\u6210\u529F\uFF08\u5957\u9910: ${data.plan}\uFF09`);
|
|
25190
|
-
activated = true;
|
|
25191
|
-
} else {
|
|
25192
|
-
results.push(`\u26A0\uFE0F License \u6FC0\u6D3B\u5931\u8D25: ${JSON.stringify(data)}`);
|
|
25193
|
-
}
|
|
25194
|
-
} catch (err) {
|
|
25195
|
-
results.push(`\u26A0\uFE0F \u6FC0\u6D3B\u7F51\u7EDC\u9519\u8BEF: ${err instanceof Error ? err.message : err}`);
|
|
25196
|
-
}
|
|
25197
|
-
}
|
|
25198
|
-
await writeState(state);
|
|
25199
|
-
results.push("\u2705 state.json");
|
|
25200
|
-
if (activated) {
|
|
25201
|
-
try {
|
|
25202
|
-
const pullResult = await syncPull({ workDir: cwd });
|
|
25203
|
-
if (pullResult.success) {
|
|
25204
|
-
results.push("\u2705 \u5DF2\u4ECE\u4E91\u7AEF\u540C\u6B65\u6570\u636E");
|
|
25205
|
-
} else {
|
|
25206
|
-
results.push("\u2139\uFE0F \u4E91\u7AEF\u65E0\u5DF2\u6709\u6570\u636E");
|
|
25207
|
-
}
|
|
25208
|
-
} catch {
|
|
25209
|
-
results.push("\u2139\uFE0F \u4E91\u7AEF\u540C\u6B65\u8DF3\u8FC7");
|
|
25210
|
-
}
|
|
25211
|
-
}
|
|
25212
|
-
return {
|
|
25213
|
-
success: true,
|
|
25214
|
-
message: [
|
|
25215
|
-
"\u{1F389} ClaudeInk \u77E5\u8BC6\u5E93\u521D\u59CB\u5316\u5B8C\u6210\uFF01",
|
|
25216
|
-
"",
|
|
25217
|
-
...results,
|
|
25218
|
-
"",
|
|
25219
|
-
"\u{1F3AF} \u4E0B\u4E00\u6B65\uFF1A",
|
|
25220
|
-
"1. \u5728\u5BF9\u8BDD\u4E2D\u8BF4\u300C\u5E2E\u6211\u5B58\u4E00\u4E0B\u300D\u4FDD\u5B58\u6709\u4EF7\u503C\u5185\u5BB9",
|
|
25221
|
-
"2. \u7528\u300C\u627E\u4E00\u4E0B\u5173\u4E8E XX \u7684\u300D\u68C0\u7D22\u77E5\u8BC6\u5E93"
|
|
25222
|
-
].join("\n")
|
|
25223
|
-
};
|
|
25224
|
-
} catch (err) {
|
|
25225
|
-
return {
|
|
25226
|
-
success: false,
|
|
25227
|
-
message: `\u521D\u59CB\u5316\u5931\u8D25: ${err instanceof Error ? err.message : err}`
|
|
25228
|
-
};
|
|
25229
|
-
}
|
|
25230
|
-
}
|
|
25231
|
-
|
|
25232
|
-
// src/tools/ink.ts
|
|
25233
|
-
var inkSaveSchema = external_exports.object({
|
|
25234
|
-
content: external_exports.string().describe("\u8981\u4FDD\u5B58\u7684\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"),
|
|
25235
|
-
title: external_exports.string().describe("\u6807\u9898\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF09"),
|
|
25236
|
-
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF0C\u7528\u6237\u53EF\u6307\u5B9A\uFF09"),
|
|
25237
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B\uFF1Ainsight / decision / analysis / idea / reference / action"),
|
|
25238
|
-
source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B\uFF1Aconversation / url / manual"),
|
|
25239
|
-
url: external_exports.string().optional().describe("\u6765\u6E90 URL\uFF08\u5982\u679C\u662F\u5916\u90E8\u7D20\u6750\uFF09")
|
|
25240
|
-
});
|
|
25241
|
-
async function inkSave(input) {
|
|
25242
|
-
try {
|
|
25243
|
-
const { id } = await saveKnowledge({
|
|
25244
|
-
content: input.content,
|
|
25245
|
-
title: input.title,
|
|
25246
|
-
tags: input.tags,
|
|
25247
|
-
category: input.category,
|
|
25248
|
-
source_type: input.source_type,
|
|
25249
|
-
url: input.url
|
|
25250
|
-
});
|
|
25251
|
-
const categoryNames = {
|
|
25252
|
-
insight: "\u6D1E\u5BDF",
|
|
25253
|
-
decision: "\u51B3\u7B56",
|
|
25254
|
-
analysis: "\u5206\u6790",
|
|
25255
|
-
idea: "\u60F3\u6CD5",
|
|
25256
|
-
reference: "\u53C2\u8003",
|
|
25257
|
-
action: "\u884C\u52A8"
|
|
25258
|
-
};
|
|
25259
|
-
const catName = categoryNames[input.category] || input.category;
|
|
25260
|
-
const tagStr = input.tags.length > 0 ? input.tags.join("\u3001") : "\u65E0\u6807\u7B7E";
|
|
25261
|
-
fireAndForgetPush({
|
|
25262
|
-
knowledge: [{
|
|
25263
|
-
id,
|
|
25264
|
-
title: input.title,
|
|
25265
|
-
tags: input.tags,
|
|
25266
|
-
category: input.category,
|
|
25267
|
-
source_type: input.source_type,
|
|
25268
|
-
url: input.url,
|
|
25269
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
25270
|
-
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
25271
|
-
}]
|
|
25272
|
-
});
|
|
25273
|
-
return {
|
|
25274
|
-
success: true,
|
|
25275
|
-
message: `\u5DF2\u4FDD\u5B58\u5230\u300C${catName}\u300D\uFF0C\u6807\u7B7E\uFF1A${tagStr}`,
|
|
25276
|
-
data: { id }
|
|
25277
|
-
};
|
|
25278
|
-
} catch (err) {
|
|
25279
|
-
return {
|
|
25280
|
-
success: false,
|
|
25281
|
-
message: `\u4FDD\u5B58\u5931\u8D25\uFF1A${err.message}`
|
|
25282
|
-
};
|
|
25283
|
-
}
|
|
25284
|
-
}
|
|
25285
|
-
var inkSearchSchema = external_exports.object({
|
|
25286
|
-
query: external_exports.string().optional().describe("\u641C\u7D22\u5173\u952E\u8BCD"),
|
|
25287
|
-
tags: external_exports.array(external_exports.string()).optional().describe("\u6309\u6807\u7B7E\u8FC7\u6EE4"),
|
|
25288
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().describe("\u6309\u5206\u7C7B\u8FC7\u6EE4"),
|
|
25289
|
-
date_from: external_exports.string().optional().describe("\u8D77\u59CB\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF09"),
|
|
25290
|
-
date_to: external_exports.string().optional().describe("\u622A\u6B62\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF09"),
|
|
25291
|
-
limit: external_exports.number().optional().default(10).describe("\u8FD4\u56DE\u6570\u91CF\uFF0C\u9ED8\u8BA4 10")
|
|
25292
|
-
});
|
|
25293
|
-
async function inkSearch(input) {
|
|
25294
|
-
try {
|
|
25295
|
-
const index = await readIndex();
|
|
25296
|
-
const { results, total } = searchKnowledge(index, {
|
|
25297
|
-
query: input.query,
|
|
25298
|
-
tags: input.tags,
|
|
25299
|
-
category: input.category,
|
|
25300
|
-
date_from: input.date_from,
|
|
25301
|
-
date_to: input.date_to,
|
|
25302
|
-
limit: input.limit
|
|
25303
|
-
});
|
|
25304
|
-
if (total === 0) {
|
|
25305
|
-
return {
|
|
25306
|
-
success: true,
|
|
25307
|
-
message: "\u6CA1\u6709\u627E\u5230\u5339\u914D\u7684\u77E5\u8BC6\u7247\u6BB5",
|
|
25308
|
-
data: { results: [], total: 0 }
|
|
25309
|
-
};
|
|
25310
|
-
}
|
|
25311
|
-
return {
|
|
25312
|
-
success: true,
|
|
25313
|
-
message: `\u627E\u5230 ${total} \u6761\u76F8\u5173\u8BB0\u5F55${total > results.length ? `\uFF0C\u663E\u793A\u524D ${results.length} \u6761` : ""}`,
|
|
25314
|
-
data: { results, total }
|
|
25315
|
-
};
|
|
25316
|
-
} catch (err) {
|
|
25317
|
-
return {
|
|
25318
|
-
success: false,
|
|
25319
|
-
message: `\u641C\u7D22\u5931\u8D25\uFF1A${err.message}`
|
|
25320
|
-
};
|
|
25321
|
-
}
|
|
25322
|
-
}
|
|
25323
|
-
var inkGetSchema = external_exports.object({
|
|
25324
|
-
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID")
|
|
25325
|
-
});
|
|
25326
|
-
async function inkGet(input) {
|
|
25327
|
-
try {
|
|
25328
|
-
const file = await readKnowledgeFile(input.id);
|
|
25329
|
-
if (!file) {
|
|
25330
|
-
return {
|
|
25331
|
-
success: false,
|
|
25332
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
25333
|
-
};
|
|
25334
|
-
}
|
|
25335
|
-
return {
|
|
25336
|
-
success: true,
|
|
25337
|
-
message: file.meta.title,
|
|
25338
|
-
data: {
|
|
25339
|
-
id: file.meta.id,
|
|
25340
|
-
title: file.meta.title,
|
|
25341
|
-
content: file.content,
|
|
25342
|
-
tags: file.meta.tags,
|
|
25343
|
-
category: file.meta.category,
|
|
25344
|
-
source_type: file.meta.source_type,
|
|
25345
|
-
url: file.meta.url,
|
|
25346
|
-
created_at: file.meta.created_at,
|
|
25347
|
-
updated_at: file.meta.updated_at
|
|
25348
|
-
}
|
|
25349
|
-
};
|
|
25350
|
-
} catch (err) {
|
|
25351
|
-
return {
|
|
25352
|
-
success: false,
|
|
25353
|
-
message: `\u83B7\u53D6\u5931\u8D25\uFF1A${err.message}`
|
|
25354
|
-
};
|
|
25355
|
-
}
|
|
25356
|
-
}
|
|
25357
|
-
var inkReviewSchema = external_exports.object({
|
|
25358
|
-
period: external_exports.enum(["today", "week", "month", "custom"]).optional().default("week").describe("\u56DE\u987E\u65F6\u95F4\u6BB5\uFF1Atoday / week / month / custom"),
|
|
25359
|
-
date_from: external_exports.string().optional().describe("\u81EA\u5B9A\u4E49\u8D77\u59CB\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF0Cperiod=custom \u65F6\u4F7F\u7528\uFF09"),
|
|
25360
|
-
date_to: external_exports.string().optional().describe("\u81EA\u5B9A\u4E49\u622A\u6B62\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF0Cperiod=custom \u65F6\u4F7F\u7528\uFF09"),
|
|
25361
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().describe("\u6309\u5206\u7C7B\u8FC7\u6EE4")
|
|
25362
|
-
});
|
|
25363
|
-
async function inkReview(input) {
|
|
25364
|
-
try {
|
|
25365
|
-
const index = await readIndex();
|
|
25366
|
-
const entries = Object.values(index.entries);
|
|
25367
|
-
const now = /* @__PURE__ */ new Date();
|
|
25368
|
-
let dateFrom;
|
|
25369
|
-
let dateTo = now.toISOString();
|
|
25370
|
-
switch (input.period) {
|
|
25371
|
-
case "today":
|
|
25372
|
-
dateFrom = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString();
|
|
25373
|
-
break;
|
|
25374
|
-
case "week": {
|
|
25375
|
-
const weekAgo = new Date(now);
|
|
25376
|
-
weekAgo.setDate(weekAgo.getDate() - 7);
|
|
25377
|
-
dateFrom = weekAgo.toISOString();
|
|
25378
|
-
break;
|
|
25379
|
-
}
|
|
25380
|
-
case "month": {
|
|
25381
|
-
const monthAgo = new Date(now);
|
|
25382
|
-
monthAgo.setMonth(monthAgo.getMonth() - 1);
|
|
25383
|
-
dateFrom = monthAgo.toISOString();
|
|
25384
|
-
break;
|
|
25385
|
-
}
|
|
25386
|
-
case "custom":
|
|
25387
|
-
dateFrom = input.date_from || (/* @__PURE__ */ new Date(0)).toISOString();
|
|
25388
|
-
dateTo = input.date_to || now.toISOString();
|
|
25389
|
-
break;
|
|
25390
|
-
}
|
|
25391
|
-
let filtered = entries.filter(
|
|
25392
|
-
(e) => e.created_at >= dateFrom && e.created_at <= dateTo
|
|
25393
|
-
);
|
|
25394
|
-
if (input.category) {
|
|
25395
|
-
filtered = filtered.filter((e) => e.category === input.category);
|
|
25396
|
-
}
|
|
25397
|
-
filtered.sort((a, b) => b.created_at.localeCompare(a.created_at));
|
|
25398
|
-
const byCategory = {};
|
|
25399
|
-
for (const e of filtered) {
|
|
25400
|
-
byCategory[e.category] = (byCategory[e.category] || 0) + 1;
|
|
25401
|
-
}
|
|
25402
|
-
const tagCounts = {};
|
|
25403
|
-
for (const e of filtered) {
|
|
25404
|
-
for (const t of e.tags) {
|
|
25405
|
-
tagCounts[t] = (tagCounts[t] || 0) + 1;
|
|
25406
|
-
}
|
|
25407
|
-
}
|
|
25408
|
-
const topTags = Object.entries(tagCounts).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([tag, count]) => ({ tag, count }));
|
|
25409
|
-
const categoryNames = {
|
|
25410
|
-
insight: "\u6D1E\u5BDF",
|
|
25411
|
-
decision: "\u51B3\u7B56",
|
|
25412
|
-
analysis: "\u5206\u6790",
|
|
25413
|
-
idea: "\u60F3\u6CD5",
|
|
25414
|
-
reference: "\u53C2\u8003",
|
|
25415
|
-
action: "\u884C\u52A8"
|
|
25416
|
-
};
|
|
25417
|
-
const periodNames = {
|
|
25418
|
-
today: "\u4ECA\u65E5",
|
|
25419
|
-
week: "\u672C\u5468",
|
|
25420
|
-
month: "\u672C\u6708",
|
|
25421
|
-
custom: "\u81EA\u5B9A\u4E49\u65F6\u6BB5"
|
|
25422
|
-
};
|
|
25423
|
-
return {
|
|
25424
|
-
success: true,
|
|
25425
|
-
message: `${periodNames[input.period]}\u77E5\u8BC6\u56DE\u987E\uFF1A\u5171 ${filtered.length} \u6761\u8BB0\u5F55`,
|
|
25426
|
-
data: {
|
|
25427
|
-
period: input.period,
|
|
25428
|
-
date_from: dateFrom,
|
|
25429
|
-
date_to: dateTo,
|
|
25430
|
-
total: filtered.length,
|
|
25431
|
-
by_category: Object.entries(byCategory).map(([cat, count]) => ({
|
|
25432
|
-
category: cat,
|
|
25433
|
-
label: categoryNames[cat] || cat,
|
|
25434
|
-
count
|
|
25435
|
-
})),
|
|
25436
|
-
top_tags: topTags,
|
|
25437
|
-
items: filtered.map((e) => ({
|
|
25438
|
-
id: e.id,
|
|
25439
|
-
title: e.title,
|
|
25440
|
-
category: e.category,
|
|
25441
|
-
tags: e.tags,
|
|
25442
|
-
created_at: e.created_at,
|
|
25443
|
-
preview: e.preview
|
|
25444
|
-
}))
|
|
25445
|
-
}
|
|
25446
|
-
};
|
|
25447
|
-
} catch (err) {
|
|
25448
|
-
return {
|
|
25449
|
-
success: false,
|
|
25450
|
-
message: `\u56DE\u987E\u5931\u8D25\uFF1A${err.message}`
|
|
25451
|
-
};
|
|
25452
|
-
}
|
|
25453
|
-
}
|
|
25454
|
-
var inkUpdateSchema = external_exports.object({
|
|
25455
|
-
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
|
|
25456
|
-
title: external_exports.string().optional().describe("\u65B0\u6807\u9898"),
|
|
25457
|
-
content: external_exports.string().optional().describe("\u65B0\u5185\u5BB9"),
|
|
25458
|
-
tags: external_exports.array(external_exports.string()).optional().describe("\u65B0\u6807\u7B7E\uFF08\u5B8C\u6574\u66FF\u6362\uFF09"),
|
|
25459
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().describe("\u65B0\u5206\u7C7B")
|
|
25460
|
-
});
|
|
25461
|
-
async function inkUpdate(input) {
|
|
25462
|
-
try {
|
|
25463
|
-
const { id, ...updates } = input;
|
|
25464
|
-
if (!updates.title && !updates.content && !updates.tags && !updates.category) {
|
|
25465
|
-
return {
|
|
25466
|
-
success: false,
|
|
25467
|
-
message: "\u8BF7\u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u8981\u66F4\u65B0\u7684\u5B57\u6BB5\uFF08title / content / tags / category\uFF09"
|
|
25468
|
-
};
|
|
25469
|
-
}
|
|
25470
|
-
const result = await updateKnowledgeFile(id, updates);
|
|
25471
|
-
if (!result) {
|
|
25472
|
-
return {
|
|
25473
|
-
success: false,
|
|
25474
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
25475
|
-
};
|
|
25476
|
-
}
|
|
25477
|
-
const changed = Object.keys(updates).filter(
|
|
25478
|
-
(k) => updates[k] !== void 0
|
|
25479
|
-
);
|
|
25480
|
-
fireAndForgetPush({
|
|
25481
|
-
knowledge: [{
|
|
25482
|
-
id: result.meta.id,
|
|
25483
|
-
title: result.meta.title,
|
|
25484
|
-
tags: result.meta.tags,
|
|
25485
|
-
category: result.meta.category,
|
|
25486
|
-
source_type: result.meta.source_type,
|
|
25487
|
-
url: result.meta.url,
|
|
25488
|
-
created_at: result.meta.created_at,
|
|
25489
|
-
updated_at: result.meta.updated_at
|
|
25490
|
-
}]
|
|
25491
|
-
});
|
|
25492
|
-
return {
|
|
25493
|
-
success: true,
|
|
25494
|
-
message: `\u5DF2\u66F4\u65B0\u300C${result.meta.title}\u300D\u7684 ${changed.join("\u3001")}`,
|
|
25495
|
-
data: {
|
|
25496
|
-
id: result.meta.id,
|
|
25497
|
-
title: result.meta.title,
|
|
25498
|
-
tags: result.meta.tags,
|
|
25499
|
-
category: result.meta.category,
|
|
25500
|
-
updated_at: result.meta.updated_at
|
|
25501
|
-
}
|
|
25502
|
-
};
|
|
25503
|
-
} catch (err) {
|
|
25504
|
-
return {
|
|
25505
|
-
success: false,
|
|
25506
|
-
message: `\u66F4\u65B0\u5931\u8D25\uFF1A${err.message}`
|
|
25507
|
-
};
|
|
25508
|
-
}
|
|
25509
|
-
}
|
|
25510
|
-
var inkDeleteSchema = external_exports.object({
|
|
25511
|
-
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
|
|
25512
|
-
confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
|
|
25513
|
-
});
|
|
25514
|
-
async function inkDelete(input) {
|
|
25515
|
-
try {
|
|
25516
|
-
if (!input.confirm) {
|
|
25517
|
-
const index = await readIndex();
|
|
25518
|
-
const entry = index.entries[input.id];
|
|
25519
|
-
if (!entry) {
|
|
25520
|
-
return {
|
|
25521
|
-
success: false,
|
|
25522
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
25523
|
-
};
|
|
25524
|
-
}
|
|
25525
|
-
return {
|
|
25526
|
-
success: false,
|
|
25527
|
-
message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
|
|
25528
|
-
data: {
|
|
25529
|
-
id: entry.id,
|
|
25530
|
-
title: entry.title,
|
|
25531
|
-
category: entry.category,
|
|
25532
|
-
tags: entry.tags,
|
|
25533
|
-
created_at: entry.created_at
|
|
25534
|
-
}
|
|
25535
|
-
};
|
|
25536
|
-
}
|
|
25537
|
-
const deleted = await deleteKnowledgeFile(input.id);
|
|
25538
|
-
if (!deleted) {
|
|
25539
|
-
return {
|
|
25540
|
-
success: false,
|
|
25541
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
25542
|
-
};
|
|
25543
|
-
}
|
|
25544
|
-
fireAndForgetPush({
|
|
25545
|
-
knowledge: [{
|
|
25546
|
-
id: input.id,
|
|
25547
|
-
title: "",
|
|
25548
|
-
tags: [],
|
|
25549
|
-
category: "reference",
|
|
25550
|
-
source_type: "conversation",
|
|
25551
|
-
created_at: "",
|
|
25552
|
-
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
25553
|
-
}]
|
|
25554
|
-
});
|
|
25555
|
-
return {
|
|
25556
|
-
success: true,
|
|
25557
|
-
message: `\u5DF2\u5220\u9664\u77E5\u8BC6\u7247\u6BB5 ${input.id}`,
|
|
25558
|
-
data: { id: input.id }
|
|
25559
|
-
};
|
|
25560
|
-
} catch (err) {
|
|
25561
|
-
return {
|
|
25562
|
-
success: false,
|
|
25563
|
-
message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}`
|
|
25564
|
-
};
|
|
25565
|
-
}
|
|
25566
|
-
}
|
|
25567
|
-
var inkCompileSchema = external_exports.object({
|
|
25568
|
-
ids: external_exports.array(external_exports.string()).optional().describe("\u6307\u5B9A\u8981\u6574\u5408\u7684\u77E5\u8BC6\u7247\u6BB5 ID \u5217\u8868"),
|
|
25569
|
-
query: external_exports.string().optional().describe("\u641C\u7D22\u6761\u4EF6\uFF08\u4E0E ids \u4E8C\u9009\u4E00\uFF09"),
|
|
25570
|
-
tags: external_exports.array(external_exports.string()).optional().describe("\u6309\u6807\u7B7E\u7B5B\u9009\uFF08\u4E0E query \u642D\u914D\uFF09"),
|
|
25571
|
-
format: external_exports.enum(["outline", "article", "summary"]).optional().default("summary").describe("\u8F93\u51FA\u683C\u5F0F\uFF1Aoutline\uFF08\u5927\u7EB2\uFF09/ article\uFF08\u6587\u7AE0\uFF09/ summary\uFF08\u6458\u8981\uFF09"),
|
|
25572
|
-
instruction: external_exports.string().optional().describe("\u989D\u5916\u6574\u5408\u6307\u4EE4")
|
|
25573
|
-
});
|
|
25574
|
-
async function inkCompile(input) {
|
|
25575
|
-
try {
|
|
25576
|
-
let ids = [];
|
|
25577
|
-
if (input.ids && input.ids.length > 0) {
|
|
25578
|
-
ids = input.ids;
|
|
25579
|
-
} else if (input.query || input.tags && input.tags.length > 0) {
|
|
25580
|
-
const index = await readIndex();
|
|
25581
|
-
const { results } = searchKnowledge(index, {
|
|
25582
|
-
query: input.query,
|
|
25583
|
-
tags: input.tags,
|
|
25584
|
-
limit: 20
|
|
25585
|
-
});
|
|
25586
|
-
ids = results.map((r) => r.id);
|
|
25587
|
-
}
|
|
25588
|
-
if (ids.length === 0) {
|
|
25589
|
-
return {
|
|
25590
|
-
success: false,
|
|
25591
|
-
message: "\u6CA1\u6709\u627E\u5230\u8981\u6574\u5408\u7684\u77E5\u8BC6\u7247\u6BB5\uFF0C\u8BF7\u6307\u5B9A ids \u6216\u63D0\u4F9B\u641C\u7D22\u6761\u4EF6"
|
|
25592
|
-
};
|
|
25593
|
-
}
|
|
25594
|
-
const files = await readMultipleKnowledgeFiles(ids);
|
|
25595
|
-
if (files.length === 0) {
|
|
25596
|
-
return {
|
|
25597
|
-
success: false,
|
|
25598
|
-
message: "\u672A\u80FD\u8BFB\u53D6\u4EFB\u4F55\u77E5\u8BC6\u7247\u6BB5\u5185\u5BB9"
|
|
25599
|
-
};
|
|
25600
|
-
}
|
|
25601
|
-
const sections = files.map((f, i) => {
|
|
25602
|
-
const tagStr = f.meta.tags.length > 0 ? ` [${f.meta.tags.join(", ")}]` : "";
|
|
25603
|
-
return `### ${i + 1}. ${f.meta.title}${tagStr}
|
|
25604
|
-
> ${f.meta.category} | ${f.meta.created_at.slice(0, 10)}
|
|
25605
|
-
|
|
25606
|
-
${f.content}`;
|
|
25607
|
-
});
|
|
25608
|
-
const formatLabels = {
|
|
25609
|
-
outline: "\u5927\u7EB2",
|
|
25610
|
-
article: "\u6587\u7AE0",
|
|
25611
|
-
summary: "\u6458\u8981"
|
|
25612
|
-
};
|
|
25613
|
-
const compiled = sections.join("\n\n---\n\n");
|
|
25614
|
-
return {
|
|
25615
|
-
success: true,
|
|
25616
|
-
message: `\u5DF2\u6574\u5408 ${files.length} \u6761\u77E5\u8BC6\u7247\u6BB5\uFF0C\u683C\u5F0F\uFF1A${formatLabels[input.format]}`,
|
|
25617
|
-
data: {
|
|
25618
|
-
source_count: files.length,
|
|
25619
|
-
source_ids: files.map((f) => f.meta.id),
|
|
25620
|
-
format: input.format,
|
|
25621
|
-
instruction: input.instruction || null,
|
|
25622
|
-
compiled_content: compiled
|
|
25623
|
-
}
|
|
25624
|
-
};
|
|
25625
|
-
} catch (err) {
|
|
25626
|
-
return {
|
|
25627
|
-
success: false,
|
|
25628
|
-
message: `\u6574\u5408\u5931\u8D25\uFF1A${err.message}`
|
|
25629
|
-
};
|
|
25630
|
-
}
|
|
25631
|
-
}
|
|
25632
|
-
var inkTagsSchema = external_exports.object({
|
|
25633
|
-
action: external_exports.enum(["list", "rename", "merge"]).describe("\u64CD\u4F5C\uFF1Alist\uFF08\u5217\u51FA\u6240\u6709\u6807\u7B7E\uFF09/ rename\uFF08\u91CD\u547D\u540D\uFF09/ merge\uFF08\u5408\u5E76\uFF09"),
|
|
25634
|
-
tag: external_exports.string().optional().describe("\u76EE\u6807\u6807\u7B7E\uFF08rename/merge \u65F6\u4F7F\u7528\uFF09"),
|
|
25635
|
-
new_tag: external_exports.string().optional().describe("\u65B0\u6807\u7B7E\u540D\uFF08rename \u65F6\u4F7F\u7528\uFF09"),
|
|
25636
|
-
source_tags: external_exports.array(external_exports.string()).optional().describe("\u8981\u5408\u5E76\u7684\u6E90\u6807\u7B7E\u5217\u8868\uFF08merge \u65F6\u4F7F\u7528\uFF09")
|
|
25637
|
-
});
|
|
25638
|
-
async function inkTags(input) {
|
|
25639
|
-
try {
|
|
25640
|
-
const index = await readIndex();
|
|
25641
|
-
switch (input.action) {
|
|
25642
|
-
case "list": {
|
|
25643
|
-
const tags = getAllTags(index);
|
|
25644
|
-
return {
|
|
25645
|
-
success: true,
|
|
25646
|
-
message: tags.length > 0 ? `\u5171 ${tags.length} \u4E2A\u6807\u7B7E` : "\u6682\u65E0\u6807\u7B7E",
|
|
25647
|
-
data: { tags }
|
|
25648
|
-
};
|
|
25649
|
-
}
|
|
25650
|
-
case "rename": {
|
|
25651
|
-
if (!input.tag || !input.new_tag) {
|
|
25652
|
-
return {
|
|
25653
|
-
success: false,
|
|
25654
|
-
message: "rename \u64CD\u4F5C\u9700\u8981\u63D0\u4F9B tag\uFF08\u539F\u6807\u7B7E\uFF09\u548C new_tag\uFF08\u65B0\u6807\u7B7E\u540D\uFF09"
|
|
25655
|
-
};
|
|
25656
|
-
}
|
|
25657
|
-
const count = await renameTag(input.tag, input.new_tag);
|
|
25658
|
-
if (count === 0) {
|
|
25659
|
-
return {
|
|
25660
|
-
success: false,
|
|
25661
|
-
message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
25662
|
-
};
|
|
25663
|
-
}
|
|
25664
|
-
return {
|
|
25665
|
-
success: true,
|
|
25666
|
-
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
|
|
25667
|
-
data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
|
|
25668
|
-
};
|
|
25669
|
-
}
|
|
25670
|
-
case "merge": {
|
|
25671
|
-
if (!input.source_tags || input.source_tags.length === 0 || !input.new_tag) {
|
|
25672
|
-
return {
|
|
25673
|
-
success: false,
|
|
25674
|
-
message: "merge \u64CD\u4F5C\u9700\u8981\u63D0\u4F9B source_tags\uFF08\u6E90\u6807\u7B7E\u5217\u8868\uFF09\u548C new_tag\uFF08\u76EE\u6807\u6807\u7B7E\uFF09"
|
|
25675
|
-
};
|
|
25676
|
-
}
|
|
25677
|
-
const count = await mergeTags(input.source_tags, input.new_tag);
|
|
25678
|
-
if (count === 0) {
|
|
25679
|
-
return {
|
|
25680
|
-
success: false,
|
|
25681
|
-
message: `\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
25682
|
-
};
|
|
25683
|
-
}
|
|
25684
|
-
return {
|
|
25685
|
-
success: true,
|
|
25686
|
-
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
|
|
25687
|
-
data: {
|
|
25688
|
-
source_tags: input.source_tags,
|
|
25689
|
-
target_tag: input.new_tag,
|
|
25690
|
-
affected: count
|
|
25691
|
-
}
|
|
25692
|
-
};
|
|
25693
|
-
}
|
|
25694
|
-
}
|
|
25695
|
-
} catch (err) {
|
|
25696
|
-
return {
|
|
25697
|
-
success: false,
|
|
25698
|
-
message: `\u6807\u7B7E\u64CD\u4F5C\u5931\u8D25\uFF1A${err.message}`
|
|
25699
|
-
};
|
|
25700
|
-
}
|
|
25701
|
-
}
|
|
25702
|
-
|
|
25703
25497
|
// src/index.ts
|
|
25704
25498
|
var server = new McpServer({
|
|
25705
25499
|
name: "ClaudeInk",
|
|
25706
|
-
version: "
|
|
25500
|
+
version: "2.0.1"
|
|
25707
25501
|
});
|
|
25708
|
-
server.tool("
|
|
25502
|
+
server.tool("ink.init", "\u521D\u59CB\u5316\u77E5\u8BC6\u5E93\uFF08\u521B\u5EFA\u76EE\u5F55 + \u6FC0\u6D3B License + \u540C\u6B65\u4E91\u7AEF\uFF09", workflowInitSchema.shape, async (input) => {
|
|
25709
25503
|
const result = await workflowInit(input);
|
|
25710
25504
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25711
25505
|
});
|
|
25712
|
-
server.tool("sync", "\u4ECE\u4E91\u7AEF\u540C\u6B65\u77E5\u8BC6\u5143\u6570\u636E", syncSchema.shape, async (input) => {
|
|
25506
|
+
server.tool("ink.sync", "\u4ECE\u4E91\u7AEF\u540C\u6B65\u77E5\u8BC6\u5143\u6570\u636E", syncSchema.shape, async (input) => {
|
|
25713
25507
|
const result = await sync(input);
|
|
25714
25508
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25715
25509
|
});
|
|
25716
|
-
server.tool("ink.save", "\u4FDD\u5B58\
|
|
25510
|
+
server.tool("ink.save", "\u4FDD\u5B58\u6216\u66F4\u65B0\u77E5\u8BC6\u7D20\u6750\uFF08\u6709 id \u66F4\u65B0\uFF0C\u65E0 id \u65B0\u5EFA\uFF09", inkSaveSchema.shape, async (input) => {
|
|
25717
25511
|
const result = await inkSave(input);
|
|
25718
25512
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25719
25513
|
});
|
|
25720
|
-
server.tool("ink.search", "\u641C\u7D22\u77E5\u8BC6\u5E93\uFF08\u652F\u6301\u5173\u952E\u8BCD\u3001\u6807\u7B7E\u3001\u5206\u7C7B\u3001\u65F6\u95F4\u8303\u56F4\u8FC7\u6EE4\uFF09", inkSearchSchema.shape, async (input) => {
|
|
25721
|
-
const result = await inkSearch(input);
|
|
25722
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25723
|
-
});
|
|
25724
|
-
server.tool("ink.get", "\u83B7\u53D6\u77E5\u8BC6\u7247\u6BB5\u5B8C\u6574\u5185\u5BB9", inkGetSchema.shape, async (input) => {
|
|
25725
|
-
const result = await inkGet(input);
|
|
25726
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25727
|
-
});
|
|
25728
|
-
server.tool("ink.review", "\u6309\u65F6\u95F4\u6BB5\u56DE\u987E\u77E5\u8BC6\u5E93\uFF08\u7EDF\u8BA1 + \u5217\u8868\uFF09", inkReviewSchema.shape, async (input) => {
|
|
25729
|
-
const result = await inkReview(input);
|
|
25730
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25731
|
-
});
|
|
25732
|
-
server.tool("ink.update", "\u66F4\u65B0\u5DF2\u4FDD\u5B58\u7684\u77E5\u8BC6\u7247\u6BB5\uFF08\u6807\u9898/\u5185\u5BB9/\u6807\u7B7E/\u5206\u7C7B\uFF09", inkUpdateSchema.shape, async (input) => {
|
|
25733
|
-
const result = await inkUpdate(input);
|
|
25734
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25735
|
-
});
|
|
25736
25514
|
server.tool("ink.delete", "\u5220\u9664\u77E5\u8BC6\u7247\u6BB5\uFF08\u9700\u786E\u8BA4\uFF09", inkDeleteSchema.shape, async (input) => {
|
|
25737
25515
|
const result = await inkDelete(input);
|
|
25738
25516
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25739
25517
|
});
|
|
25740
|
-
server.tool("ink.
|
|
25741
|
-
const result = await
|
|
25518
|
+
server.tool("ink.write", "\u5199\u6587\u7AE0\u4FDD\u5B58\u4E3A\u8349\u7A3F\u3002Claude \u5199\u5B8C\u535A\u5BA2\u6587\u7AE0\u540E\u81EA\u52A8\u8C03\u7528\uFF0C\u63D0\u4F9B\u6807\u9898\u3001Markdown \u5185\u5BB9\u3001\u5C01\u9762\u56FE\u548C\u6807\u7B7E\u3002", inkWriteSchema.shape, async (input) => {
|
|
25519
|
+
const result = await inkWrite(input);
|
|
25742
25520
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25743
25521
|
});
|
|
25744
25522
|
server.tool("ink.tags", "\u6807\u7B7E\u7BA1\u7406\uFF08\u5217\u51FA / \u91CD\u547D\u540D / \u5408\u5E76\u6807\u7B7E\uFF09", inkTagsSchema.shape, async (input) => {
|
|
25745
25523
|
const result = await inkTags(input);
|
|
25746
25524
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25747
25525
|
});
|
|
25748
|
-
server.tool("
|
|
25526
|
+
server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\u5185\u5BB9\u81EA\u52A8\u5B58\u5165\u77E5\u8BC6\u5E93\uFF09", sourceCrawlSchema.shape, async (input) => {
|
|
25749
25527
|
const result = await sourceCrawl(input);
|
|
25750
25528
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25751
25529
|
});
|
|
25752
|
-
server.tool("
|
|
25530
|
+
server.tool("ink.subscribe", "\u7BA1\u7406\u8BA2\u9605\u6E90\uFF08\u6DFB\u52A0/\u5220\u9664/\u5217\u51FA\u722C\u866B\u6E90\uFF09", sourceSubscribeSchema.shape, async (input) => {
|
|
25753
25531
|
const result = await sourceSubscribe(input);
|
|
25754
25532
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25755
25533
|
});
|
|
@@ -25758,16 +25536,16 @@ async function main() {
|
|
|
25758
25536
|
const state = await readState();
|
|
25759
25537
|
if (state.config.workflowDir) {
|
|
25760
25538
|
setWorkDir(state.config.workflowDir);
|
|
25761
|
-
console.error(`[ClaudeInk MCP] workDir restored: ${state.config.workflowDir}`);
|
|
25762
25539
|
}
|
|
25540
|
+
setLogLevel(state.config.logLevel || "INFO");
|
|
25763
25541
|
} catch {
|
|
25764
25542
|
}
|
|
25765
25543
|
const transport = new StdioServerTransport();
|
|
25766
25544
|
await server.connect(transport);
|
|
25767
|
-
|
|
25545
|
+
await log("INFO", "server", "started (8 tools)");
|
|
25768
25546
|
}
|
|
25769
|
-
main().catch((err) => {
|
|
25770
|
-
|
|
25547
|
+
main().catch(async (err) => {
|
|
25548
|
+
await log("ERROR", "server", `fatal: ${err.message || err}`);
|
|
25771
25549
|
process.exit(1);
|
|
25772
25550
|
});
|
|
25773
25551
|
/*! Bundled license information:
|