@claudeink/mcp-server 2.0.2 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +474 -372
- package/dist/index.js +442 -339
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24477,8 +24477,8 @@ var StdioServerTransport = class {
|
|
|
24477
24477
|
};
|
|
24478
24478
|
|
|
24479
24479
|
// src/tools/workflow.ts
|
|
24480
|
-
import { mkdir as
|
|
24481
|
-
import { join as
|
|
24480
|
+
import { mkdir as mkdir5, access, unlink as unlink2 } from "fs/promises";
|
|
24481
|
+
import { join as join5 } from "path";
|
|
24482
24482
|
|
|
24483
24483
|
// src/lib/state.ts
|
|
24484
24484
|
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
@@ -24576,160 +24576,14 @@ async function addToTagQueue(item) {
|
|
|
24576
24576
|
await writeState(state);
|
|
24577
24577
|
}
|
|
24578
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
24579
|
// src/tools/sync.ts
|
|
24599
|
-
|
|
24600
|
-
|
|
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";
|
|
24580
|
+
import { writeFile as writeFile3, mkdir as mkdir4 } from "fs/promises";
|
|
24581
|
+
import { join as join4 } from "path";
|
|
24728
24582
|
|
|
24729
24583
|
// src/lib/knowledge.ts
|
|
24730
24584
|
var import_gray_matter = __toESM(require_gray_matter(), 1);
|
|
24731
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as
|
|
24732
|
-
import { join as
|
|
24585
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, unlink } from "fs/promises";
|
|
24586
|
+
import { join as join2 } from "path";
|
|
24733
24587
|
var _lockPromise = Promise.resolve();
|
|
24734
24588
|
function withIndexLock(fn) {
|
|
24735
24589
|
const prev = _lockPromise;
|
|
@@ -24739,11 +24593,11 @@ function withIndexLock(fn) {
|
|
|
24739
24593
|
});
|
|
24740
24594
|
return prev.then(fn).finally(() => resolve());
|
|
24741
24595
|
}
|
|
24742
|
-
function
|
|
24743
|
-
return
|
|
24596
|
+
function getStoreDir(store = "knowledge") {
|
|
24597
|
+
return join2(getWorkDir(), ".claudeink", store);
|
|
24744
24598
|
}
|
|
24745
|
-
function getIndexPath() {
|
|
24746
|
-
return
|
|
24599
|
+
function getIndexPath(store = "knowledge") {
|
|
24600
|
+
return join2(getWorkDir(), ".claudeink", store, "index.json");
|
|
24747
24601
|
}
|
|
24748
24602
|
async function generateIdInternal(index) {
|
|
24749
24603
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -24765,28 +24619,28 @@ function toSlug(title) {
|
|
|
24765
24619
|
function generatePreview(content, maxLen = 200) {
|
|
24766
24620
|
return content.replace(/^#+\s.+$/gm, "").replace(/\n+/g, " ").trim().slice(0, maxLen);
|
|
24767
24621
|
}
|
|
24768
|
-
async function readIndex() {
|
|
24622
|
+
async function readIndex(store = "knowledge") {
|
|
24769
24623
|
try {
|
|
24770
|
-
const raw = await readFile2(getIndexPath(), "utf-8");
|
|
24624
|
+
const raw = await readFile2(getIndexPath(store), "utf-8");
|
|
24771
24625
|
return JSON.parse(raw);
|
|
24772
24626
|
} catch {
|
|
24773
24627
|
return { entries: {}, updated_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
24774
24628
|
}
|
|
24775
24629
|
}
|
|
24776
|
-
async function saveIndex(index) {
|
|
24630
|
+
async function saveIndex(index, store = "knowledge") {
|
|
24777
24631
|
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
24778
|
-
const dir =
|
|
24779
|
-
await
|
|
24780
|
-
await writeFile2(getIndexPath(), JSON.stringify(index, null, 2), "utf-8");
|
|
24632
|
+
const dir = getStoreDir(store);
|
|
24633
|
+
await mkdir2(dir, { recursive: true });
|
|
24634
|
+
await writeFile2(getIndexPath(store), JSON.stringify(index, null, 2), "utf-8");
|
|
24781
24635
|
}
|
|
24782
|
-
async function writeKnowledgeFile(meta, content) {
|
|
24636
|
+
async function writeKnowledgeFile(meta, content, store = "knowledge") {
|
|
24783
24637
|
const now = /* @__PURE__ */ new Date();
|
|
24784
24638
|
const monthDir = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
24785
|
-
const dir =
|
|
24786
|
-
await
|
|
24639
|
+
const dir = join2(getStoreDir(store), monthDir);
|
|
24640
|
+
await mkdir2(dir, { recursive: true });
|
|
24787
24641
|
const slug = toSlug(meta.title) || meta.id;
|
|
24788
24642
|
const filename = `${now.toISOString().slice(0, 10)}-${slug}.md`;
|
|
24789
|
-
const filePath =
|
|
24643
|
+
const filePath = join2(dir, filename);
|
|
24790
24644
|
const frontmatter = {
|
|
24791
24645
|
id: meta.id,
|
|
24792
24646
|
title: meta.title,
|
|
@@ -24799,13 +24653,13 @@ async function writeKnowledgeFile(meta, content) {
|
|
|
24799
24653
|
if (meta.url) frontmatter.url = meta.url;
|
|
24800
24654
|
const output = import_gray_matter.default.stringify(content, frontmatter);
|
|
24801
24655
|
await writeFile2(filePath, output, "utf-8");
|
|
24802
|
-
return
|
|
24656
|
+
return join2(monthDir, filename);
|
|
24803
24657
|
}
|
|
24804
|
-
async function readKnowledgeFile(id) {
|
|
24805
|
-
const index = await readIndex();
|
|
24658
|
+
async function readKnowledgeFile(id, store = "knowledge") {
|
|
24659
|
+
const index = await readIndex(store);
|
|
24806
24660
|
const entry = index.entries[id];
|
|
24807
24661
|
if (!entry) return null;
|
|
24808
|
-
const filePath =
|
|
24662
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
24809
24663
|
try {
|
|
24810
24664
|
const raw = await readFile2(filePath, "utf-8");
|
|
24811
24665
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -24819,8 +24673,9 @@ async function readKnowledgeFile(id) {
|
|
|
24819
24673
|
}
|
|
24820
24674
|
}
|
|
24821
24675
|
async function saveKnowledge(params) {
|
|
24676
|
+
const store = params.store || "knowledge";
|
|
24822
24677
|
return withIndexLock(async () => {
|
|
24823
|
-
const index = await readIndex();
|
|
24678
|
+
const index = await readIndex(store);
|
|
24824
24679
|
const id = await generateIdInternal(index);
|
|
24825
24680
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24826
24681
|
const meta = {
|
|
@@ -24833,7 +24688,7 @@ async function saveKnowledge(params) {
|
|
|
24833
24688
|
created_at: now,
|
|
24834
24689
|
updated_at: now
|
|
24835
24690
|
};
|
|
24836
|
-
const relativePath = await writeKnowledgeFile(meta, params.content);
|
|
24691
|
+
const relativePath = await writeKnowledgeFile(meta, params.content, store);
|
|
24837
24692
|
index.entries[id] = {
|
|
24838
24693
|
id,
|
|
24839
24694
|
title: params.title,
|
|
@@ -24845,13 +24700,13 @@ async function saveKnowledge(params) {
|
|
|
24845
24700
|
created_at: now,
|
|
24846
24701
|
updated_at: now
|
|
24847
24702
|
};
|
|
24848
|
-
await saveIndex(index);
|
|
24703
|
+
await saveIndex(index, store);
|
|
24849
24704
|
return { id, filePath: relativePath };
|
|
24850
24705
|
});
|
|
24851
24706
|
}
|
|
24852
|
-
async function updateKnowledgeFile(id, updates) {
|
|
24707
|
+
async function updateKnowledgeFile(id, updates, store = "knowledge") {
|
|
24853
24708
|
return withIndexLock(async () => {
|
|
24854
|
-
const file = await readKnowledgeFile(id);
|
|
24709
|
+
const file = await readKnowledgeFile(id, store);
|
|
24855
24710
|
if (!file) return null;
|
|
24856
24711
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
24857
24712
|
const meta = { ...file.meta };
|
|
@@ -24872,7 +24727,7 @@ async function updateKnowledgeFile(id, updates) {
|
|
|
24872
24727
|
if (meta.url) frontmatter.url = meta.url;
|
|
24873
24728
|
const output = import_gray_matter.default.stringify(content, frontmatter);
|
|
24874
24729
|
await writeFile2(file.filePath, output, "utf-8");
|
|
24875
|
-
const index = await readIndex();
|
|
24730
|
+
const index = await readIndex(store);
|
|
24876
24731
|
const entry = index.entries[id];
|
|
24877
24732
|
if (entry) {
|
|
24878
24733
|
entry.title = meta.title;
|
|
@@ -24880,23 +24735,23 @@ async function updateKnowledgeFile(id, updates) {
|
|
|
24880
24735
|
entry.category = meta.category;
|
|
24881
24736
|
entry.preview = generatePreview(content);
|
|
24882
24737
|
entry.updated_at = now;
|
|
24883
|
-
await saveIndex(index);
|
|
24738
|
+
await saveIndex(index, store);
|
|
24884
24739
|
}
|
|
24885
24740
|
return { meta, content, filePath: file.filePath };
|
|
24886
24741
|
});
|
|
24887
24742
|
}
|
|
24888
|
-
async function deleteKnowledgeFile(id) {
|
|
24743
|
+
async function deleteKnowledgeFile(id, store = "knowledge") {
|
|
24889
24744
|
return withIndexLock(async () => {
|
|
24890
|
-
const index = await readIndex();
|
|
24745
|
+
const index = await readIndex(store);
|
|
24891
24746
|
const entry = index.entries[id];
|
|
24892
24747
|
if (!entry) return false;
|
|
24893
|
-
const filePath =
|
|
24748
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
24894
24749
|
try {
|
|
24895
|
-
await
|
|
24750
|
+
await unlink(filePath);
|
|
24896
24751
|
} catch {
|
|
24897
24752
|
}
|
|
24898
24753
|
delete index.entries[id];
|
|
24899
|
-
await saveIndex(index);
|
|
24754
|
+
await saveIndex(index, store);
|
|
24900
24755
|
return true;
|
|
24901
24756
|
});
|
|
24902
24757
|
}
|
|
@@ -24909,16 +24764,16 @@ function getAllTags(index) {
|
|
|
24909
24764
|
}
|
|
24910
24765
|
return Object.entries(tagCounts).map(([name, count]) => ({ name, count })).sort((a, b) => b.count - a.count);
|
|
24911
24766
|
}
|
|
24912
|
-
async function renameTag(oldTag, newTag) {
|
|
24767
|
+
async function renameTag(oldTag, newTag, store = "knowledge") {
|
|
24913
24768
|
return withIndexLock(async () => {
|
|
24914
|
-
const index = await readIndex();
|
|
24769
|
+
const index = await readIndex(store);
|
|
24915
24770
|
let count = 0;
|
|
24916
24771
|
for (const entry of Object.values(index.entries)) {
|
|
24917
24772
|
const idx = entry.tags.indexOf(oldTag);
|
|
24918
24773
|
if (idx !== -1) {
|
|
24919
24774
|
entry.tags[idx] = newTag;
|
|
24920
24775
|
count++;
|
|
24921
|
-
const filePath =
|
|
24776
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
24922
24777
|
try {
|
|
24923
24778
|
const raw = await readFile2(filePath, "utf-8");
|
|
24924
24779
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -24935,14 +24790,14 @@ async function renameTag(oldTag, newTag) {
|
|
|
24935
24790
|
}
|
|
24936
24791
|
}
|
|
24937
24792
|
if (count > 0) {
|
|
24938
|
-
await saveIndex(index);
|
|
24793
|
+
await saveIndex(index, store);
|
|
24939
24794
|
}
|
|
24940
24795
|
return count;
|
|
24941
24796
|
});
|
|
24942
24797
|
}
|
|
24943
|
-
async function mergeTags(sourceTags, targetTag) {
|
|
24798
|
+
async function mergeTags(sourceTags, targetTag, store = "knowledge") {
|
|
24944
24799
|
return withIndexLock(async () => {
|
|
24945
|
-
const index = await readIndex();
|
|
24800
|
+
const index = await readIndex(store);
|
|
24946
24801
|
let count = 0;
|
|
24947
24802
|
for (const entry of Object.values(index.entries)) {
|
|
24948
24803
|
const hasSource = entry.tags.some((t) => sourceTags.includes(t));
|
|
@@ -24953,7 +24808,7 @@ async function mergeTags(sourceTags, targetTag) {
|
|
|
24953
24808
|
}
|
|
24954
24809
|
entry.tags = newTags;
|
|
24955
24810
|
count++;
|
|
24956
|
-
const filePath =
|
|
24811
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
24957
24812
|
try {
|
|
24958
24813
|
const raw = await readFile2(filePath, "utf-8");
|
|
24959
24814
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -24965,12 +24820,213 @@ async function mergeTags(sourceTags, targetTag) {
|
|
|
24965
24820
|
}
|
|
24966
24821
|
}
|
|
24967
24822
|
if (count > 0) {
|
|
24968
|
-
await saveIndex(index);
|
|
24823
|
+
await saveIndex(index, store);
|
|
24969
24824
|
}
|
|
24970
24825
|
return count;
|
|
24971
24826
|
});
|
|
24972
24827
|
}
|
|
24973
24828
|
|
|
24829
|
+
// src/lib/logger.ts
|
|
24830
|
+
import { appendFile, mkdir as mkdir3 } from "fs/promises";
|
|
24831
|
+
import { join as join3 } from "path";
|
|
24832
|
+
var currentLevel = "INFO";
|
|
24833
|
+
var LEVELS = { ERROR: 0, WARN: 1, INFO: 2, DEBUG: 3 };
|
|
24834
|
+
function setLogLevel(level) {
|
|
24835
|
+
currentLevel = level;
|
|
24836
|
+
}
|
|
24837
|
+
async function log(level, scope, message) {
|
|
24838
|
+
if (LEVELS[level] > LEVELS[currentLevel]) return;
|
|
24839
|
+
const dir = join3(getClaudeinkDir(), "logs");
|
|
24840
|
+
await mkdir3(dir, { recursive: true });
|
|
24841
|
+
const date3 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
24842
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${scope} | ${message}
|
|
24843
|
+
`;
|
|
24844
|
+
await appendFile(join3(dir, `mcp-${date3}.log`), line);
|
|
24845
|
+
console.error(`[ClaudeInk] ${line.trim()}`);
|
|
24846
|
+
}
|
|
24847
|
+
|
|
24848
|
+
// src/tools/sync.ts
|
|
24849
|
+
var syncSchema = external_exports.object({
|
|
24850
|
+
workDir: external_exports.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u914D\u7F6E\u4E2D\u7684 workflowDir\uFF09")
|
|
24851
|
+
});
|
|
24852
|
+
async function sync(input) {
|
|
24853
|
+
if (input.workDir) setWorkDir(input.workDir);
|
|
24854
|
+
const creds = await getCredentials();
|
|
24855
|
+
if (!creds?.token) {
|
|
24856
|
+
return { success: false, message: "\u672A\u6FC0\u6D3B\uFF0C\u8BF7\u5148\u4F7F\u7528 ink.init \u6FC0\u6D3B License" };
|
|
24857
|
+
}
|
|
24858
|
+
return doPull(creds.token);
|
|
24859
|
+
}
|
|
24860
|
+
async function doPull(token) {
|
|
24861
|
+
const config2 = await getConfig();
|
|
24862
|
+
try {
|
|
24863
|
+
const res = await fetch(`${config2.apiBaseUrl}/api/sync/pull`, {
|
|
24864
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
24865
|
+
});
|
|
24866
|
+
if (!res.ok) {
|
|
24867
|
+
if (res.status === 404) {
|
|
24868
|
+
return { success: true, message: "\u4E91\u7AEF\u65E0\u6570\u636E" };
|
|
24869
|
+
}
|
|
24870
|
+
await log("ERROR", "ink.sync", `pull failed: HTTP ${res.status}`);
|
|
24871
|
+
return { success: false, message: `\u62C9\u53D6\u5931\u8D25: HTTP ${res.status}` };
|
|
24872
|
+
}
|
|
24873
|
+
const data = await res.json();
|
|
24874
|
+
const results = [];
|
|
24875
|
+
if (data.configs) {
|
|
24876
|
+
const crawlerConfig = data.configs.find((c) => c.type === "crawler" && c.name === "config");
|
|
24877
|
+
if (crawlerConfig?.content) {
|
|
24878
|
+
try {
|
|
24879
|
+
const sources = JSON.parse(crawlerConfig.content);
|
|
24880
|
+
const crawlerDir = join4(config2.workflowDir || getWorkDir(), "tools", "crawler");
|
|
24881
|
+
await mkdir4(crawlerDir, { recursive: true });
|
|
24882
|
+
await writeFile3(join4(crawlerDir, "config.json"), JSON.stringify({ sources }, null, 2));
|
|
24883
|
+
results.push(`\u8BA2\u9605\u6E90: ${sources.length} \u4E2A`);
|
|
24884
|
+
} catch {
|
|
24885
|
+
}
|
|
24886
|
+
}
|
|
24887
|
+
}
|
|
24888
|
+
if (data.sources && Object.keys(data.sources).length > 0) {
|
|
24889
|
+
const index = await readIndex();
|
|
24890
|
+
let added = 0;
|
|
24891
|
+
for (const [localId, meta] of Object.entries(data.sources)) {
|
|
24892
|
+
if (!index.entries[localId]) {
|
|
24893
|
+
const entry = {
|
|
24894
|
+
id: localId,
|
|
24895
|
+
title: meta.title || "",
|
|
24896
|
+
tags: meta.tags || [],
|
|
24897
|
+
category: "reference",
|
|
24898
|
+
source_type: "url",
|
|
24899
|
+
preview: "",
|
|
24900
|
+
file_path: "",
|
|
24901
|
+
created_at: meta.publishedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
24902
|
+
updated_at: meta.updatedAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
24903
|
+
};
|
|
24904
|
+
index.entries[localId] = entry;
|
|
24905
|
+
added++;
|
|
24906
|
+
}
|
|
24907
|
+
}
|
|
24908
|
+
if (added > 0) {
|
|
24909
|
+
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
24910
|
+
const knowledgeDir = join4(getWorkDir(), ".claudeink", "knowledge");
|
|
24911
|
+
await mkdir4(knowledgeDir, { recursive: true });
|
|
24912
|
+
await writeFile3(join4(knowledgeDir, "index.json"), JSON.stringify(index, null, 2));
|
|
24913
|
+
results.push(`\u7D20\u6750\u7D22\u5F15: +${added} \u6761\uFF08\u5171 ${Object.keys(index.entries).length} \u6761\uFF09`);
|
|
24914
|
+
} else {
|
|
24915
|
+
results.push(`\u7D20\u6750\u7D22\u5F15: ${Object.keys(index.entries).length} \u6761\uFF08\u5DF2\u540C\u6B65\uFF09`);
|
|
24916
|
+
}
|
|
24917
|
+
}
|
|
24918
|
+
const draftCount = data.drafts ? Object.keys(data.drafts).length : 0;
|
|
24919
|
+
const pubCount = data.published ? Object.keys(data.published).length : 0;
|
|
24920
|
+
if (draftCount > 0 || pubCount > 0) {
|
|
24921
|
+
results.push(`\u8349\u7A3F: ${draftCount} \u7BC7, \u5DF2\u53D1\u5E03: ${pubCount} \u7BC7`);
|
|
24922
|
+
}
|
|
24923
|
+
await updateLastSyncAt();
|
|
24924
|
+
await log("INFO", "ink.sync", `pull completed: ${results.join(", ")}`);
|
|
24925
|
+
return {
|
|
24926
|
+
success: true,
|
|
24927
|
+
message: results.length > 0 ? `\u2705 \u540C\u6B65\u5B8C\u6210
|
|
24928
|
+
${results.join("\n")}` : "\u2705 \u540C\u6B65\u5B8C\u6210\uFF08\u4E91\u7AEF\u65E0\u65B0\u6570\u636E\uFF09"
|
|
24929
|
+
};
|
|
24930
|
+
} catch (err) {
|
|
24931
|
+
return { success: false, message: `\u540C\u6B65\u5931\u8D25: ${err instanceof Error ? err.message : err}` };
|
|
24932
|
+
}
|
|
24933
|
+
}
|
|
24934
|
+
async function syncPull(input) {
|
|
24935
|
+
if (input.workDir) setWorkDir(input.workDir);
|
|
24936
|
+
const creds = await getCredentials();
|
|
24937
|
+
if (!creds?.token) {
|
|
24938
|
+
return { success: false, message: "\u672A\u6FC0\u6D3B" };
|
|
24939
|
+
}
|
|
24940
|
+
return doPull(creds.token);
|
|
24941
|
+
}
|
|
24942
|
+
|
|
24943
|
+
// src/tools/workflow.ts
|
|
24944
|
+
var DEFAULT_API_BASE_URL = "https://app.claudeink.com";
|
|
24945
|
+
var workflowInitSchema = external_exports.object({
|
|
24946
|
+
workDir: external_exports.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
|
|
24947
|
+
licenseKey: external_exports.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
|
|
24948
|
+
});
|
|
24949
|
+
async function workflowInit(input) {
|
|
24950
|
+
const cwd = input.workDir;
|
|
24951
|
+
const results = [];
|
|
24952
|
+
try {
|
|
24953
|
+
setWorkDir(cwd);
|
|
24954
|
+
const claudeinkDir = join5(cwd, ".claudeink");
|
|
24955
|
+
await mkdir5(join5(claudeinkDir, "knowledge"), { recursive: true });
|
|
24956
|
+
results.push("\u2705 \u77E5\u8BC6\u5E93\u76EE\u5F55\u5DF2\u521B\u5EFA");
|
|
24957
|
+
const state = await readState();
|
|
24958
|
+
state.config.workflowDir = cwd;
|
|
24959
|
+
const oldCredsPath = join5(claudeinkDir, "credentials.json");
|
|
24960
|
+
try {
|
|
24961
|
+
await access(oldCredsPath);
|
|
24962
|
+
await unlink2(oldCredsPath);
|
|
24963
|
+
results.push("\u{1F9F9} \u5DF2\u6E05\u7406\u65E7\u7248 credentials.json");
|
|
24964
|
+
} catch {
|
|
24965
|
+
}
|
|
24966
|
+
let activated = false;
|
|
24967
|
+
if (input.licenseKey) {
|
|
24968
|
+
try {
|
|
24969
|
+
const res = await fetch(`${DEFAULT_API_BASE_URL}/api/auth/activate`, {
|
|
24970
|
+
method: "POST",
|
|
24971
|
+
headers: { "Content-Type": "application/json" },
|
|
24972
|
+
body: JSON.stringify({ key: input.licenseKey })
|
|
24973
|
+
});
|
|
24974
|
+
const data = await res.json();
|
|
24975
|
+
if (data.userId) {
|
|
24976
|
+
state.credentials = {
|
|
24977
|
+
licenseKey: input.licenseKey,
|
|
24978
|
+
token: data.token,
|
|
24979
|
+
userId: data.userId,
|
|
24980
|
+
plan: data.plan,
|
|
24981
|
+
expiresAt: data.expiresAt
|
|
24982
|
+
};
|
|
24983
|
+
results.push(`\u2705 License \u6FC0\u6D3B\u6210\u529F\uFF08\u5957\u9910: ${data.plan}\uFF09`);
|
|
24984
|
+
activated = true;
|
|
24985
|
+
} else {
|
|
24986
|
+
results.push(`\u26A0\uFE0F License \u6FC0\u6D3B\u5931\u8D25: ${JSON.stringify(data)}`);
|
|
24987
|
+
}
|
|
24988
|
+
} catch (err) {
|
|
24989
|
+
results.push(`\u26A0\uFE0F \u6FC0\u6D3B\u7F51\u7EDC\u9519\u8BEF: ${err instanceof Error ? err.message : err}`);
|
|
24990
|
+
}
|
|
24991
|
+
}
|
|
24992
|
+
await writeState(state);
|
|
24993
|
+
results.push("\u2705 state.json");
|
|
24994
|
+
if (state.credentials?.token) {
|
|
24995
|
+
try {
|
|
24996
|
+
const pullResult = await syncPull({ workDir: cwd });
|
|
24997
|
+
if (pullResult.success) {
|
|
24998
|
+
results.push("\u2705 \u5DF2\u4ECE\u4E91\u7AEF\u540C\u6B65\u6570\u636E");
|
|
24999
|
+
} else {
|
|
25000
|
+
results.push("\u2139\uFE0F \u4E91\u7AEF\u65E0\u5DF2\u6709\u6570\u636E");
|
|
25001
|
+
}
|
|
25002
|
+
} catch {
|
|
25003
|
+
results.push("\u2139\uFE0F \u4E91\u7AEF\u540C\u6B65\u8DF3\u8FC7");
|
|
25004
|
+
}
|
|
25005
|
+
}
|
|
25006
|
+
return {
|
|
25007
|
+
success: true,
|
|
25008
|
+
message: [
|
|
25009
|
+
"\u{1F389} ClaudeInk \u77E5\u8BC6\u5E93\u521D\u59CB\u5316\u5B8C\u6210\uFF01",
|
|
25010
|
+
"",
|
|
25011
|
+
...results,
|
|
25012
|
+
"",
|
|
25013
|
+
"\u{1F3AF} \u4E0B\u4E00\u6B65\uFF1A",
|
|
25014
|
+
"1. \u5728\u5BF9\u8BDD\u4E2D\u8BF4\u300C\u5E2E\u6211\u5B58\u4E00\u4E0B\u300D\u4FDD\u5B58\u6709\u4EF7\u503C\u5185\u5BB9",
|
|
25015
|
+
"2. \u7528\u300C\u627E\u4E00\u4E0B\u5173\u4E8E XX \u7684\u300D\u68C0\u7D22\u77E5\u8BC6\u5E93"
|
|
25016
|
+
].join("\n")
|
|
25017
|
+
};
|
|
25018
|
+
} catch (err) {
|
|
25019
|
+
return {
|
|
25020
|
+
success: false,
|
|
25021
|
+
message: `\u521D\u59CB\u5316\u5931\u8D25: ${err instanceof Error ? err.message : err}`
|
|
25022
|
+
};
|
|
25023
|
+
}
|
|
25024
|
+
}
|
|
25025
|
+
|
|
25026
|
+
// src/tools/ink.ts
|
|
25027
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
25028
|
+
import { extname } from "path";
|
|
25029
|
+
|
|
24974
25030
|
// src/lib/push.ts
|
|
24975
25031
|
function fireAndForgetPush(payload) {
|
|
24976
25032
|
doPush(payload).catch(() => {
|
|
@@ -25001,9 +25057,9 @@ async function doPush(partial2) {
|
|
|
25001
25057
|
|
|
25002
25058
|
// src/tools/ink.ts
|
|
25003
25059
|
var inkSaveSchema = external_exports.object({
|
|
25004
|
-
id: external_exports.string().optional().describe("\
|
|
25005
|
-
|
|
25006
|
-
|
|
25060
|
+
id: external_exports.string().optional().describe("\u672C\u5730 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\u5DF2\u6709\u7D20\u6750\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
|
|
25061
|
+
title: external_exports.string().describe("\u7D20\u6750\u6807\u9898"),
|
|
25062
|
+
content: external_exports.string().describe("Markdown \u5168\u6587"),
|
|
25007
25063
|
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
|
|
25008
25064
|
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
|
|
25009
25065
|
source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B"),
|
|
@@ -25011,120 +25067,102 @@ var inkSaveSchema = external_exports.object({
|
|
|
25011
25067
|
});
|
|
25012
25068
|
async function inkSave(input) {
|
|
25013
25069
|
try {
|
|
25070
|
+
let localId;
|
|
25014
25071
|
if (input.id) {
|
|
25015
25072
|
const result = await updateKnowledgeFile(input.id, {
|
|
25016
25073
|
title: input.title,
|
|
25017
25074
|
content: input.content,
|
|
25018
25075
|
tags: input.tags,
|
|
25019
25076
|
category: input.category
|
|
25020
|
-
});
|
|
25077
|
+
}, "knowledge");
|
|
25021
25078
|
if (!result) {
|
|
25022
|
-
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\
|
|
25079
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u7D20\u6750` };
|
|
25023
25080
|
}
|
|
25024
|
-
|
|
25025
|
-
|
|
25026
|
-
|
|
25027
|
-
|
|
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,
|
|
25081
|
+
localId = input.id;
|
|
25082
|
+
} else {
|
|
25083
|
+
const { id } = await saveKnowledge({
|
|
25084
|
+
content: input.content,
|
|
25054
25085
|
title: input.title,
|
|
25055
25086
|
tags: input.tags,
|
|
25056
25087
|
category: input.category,
|
|
25057
25088
|
source_type: input.source_type,
|
|
25058
25089
|
url: input.url,
|
|
25059
|
-
|
|
25060
|
-
|
|
25061
|
-
|
|
25062
|
-
}
|
|
25063
|
-
|
|
25090
|
+
store: "knowledge"
|
|
25091
|
+
});
|
|
25092
|
+
localId = id;
|
|
25093
|
+
}
|
|
25094
|
+
const creds = await getCredentials();
|
|
25095
|
+
if (creds?.token) {
|
|
25096
|
+
const index = await readIndex("knowledge");
|
|
25097
|
+
fireAndForgetPush({
|
|
25098
|
+
knowledge: Object.values(index.entries).map((e) => ({
|
|
25099
|
+
id: e.id,
|
|
25100
|
+
title: e.title,
|
|
25101
|
+
tags: e.tags,
|
|
25102
|
+
category: e.category,
|
|
25103
|
+
source_type: e.source_type,
|
|
25104
|
+
created_at: e.created_at,
|
|
25105
|
+
updated_at: e.updated_at
|
|
25106
|
+
})),
|
|
25107
|
+
crawlerSources: []
|
|
25108
|
+
});
|
|
25109
|
+
}
|
|
25110
|
+
await log("INFO", "ink.save", `saved source id=${localId} title="${input.title}"`);
|
|
25064
25111
|
return {
|
|
25065
25112
|
success: true,
|
|
25066
|
-
message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D
|
|
25067
|
-
data: { id }
|
|
25113
|
+
message: `\u5DF2\u4FDD\u5B58\u7D20\u6750\u300C${input.title}\u300D\u5230\u672C\u5730\u77E5\u8BC6\u5E93` + (creds?.token ? "\uFF08\u5143\u6570\u636E\u5DF2\u63A8\u4E91\u7AEF\uFF09" : "\uFF08\u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7\u4E91\u7AEF\u540C\u6B65\uFF09"),
|
|
25114
|
+
data: { id: localId }
|
|
25068
25115
|
};
|
|
25069
25116
|
} catch (err) {
|
|
25070
25117
|
await log("ERROR", "ink.save", `failed: ${err.message}`);
|
|
25071
|
-
return { success: false, message: `\u4FDD\u5B58\u5931\u8D25
|
|
25072
|
-
}
|
|
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) {
|
|
25079
|
-
try {
|
|
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
|
-
}]
|
|
25106
|
-
});
|
|
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}` };
|
|
25118
|
+
return { success: false, message: `\u4FDD\u5B58\u7D20\u6750\u5931\u8D25: ${err.message}` };
|
|
25112
25119
|
}
|
|
25113
25120
|
}
|
|
25114
25121
|
var inkWriteSchema = external_exports.object({
|
|
25122
|
+
id: external_exports.string().optional().describe("\u672C\u5730 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\u5DF2\u6709\u8349\u7A3F\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
|
|
25115
25123
|
title: external_exports.string().describe("\u6587\u7AE0\u6807\u9898"),
|
|
25116
25124
|
content: external_exports.string().describe("Markdown \u5168\u6587"),
|
|
25125
|
+
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
|
|
25126
|
+
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
|
|
25117
25127
|
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
25128
|
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
|
|
25129
|
+
source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750 ID\uFF08\u6EAF\u6E90\uFF09")
|
|
25122
25130
|
});
|
|
25123
25131
|
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
25132
|
try {
|
|
25133
|
+
let localId;
|
|
25134
|
+
if (input.id) {
|
|
25135
|
+
const result = await updateKnowledgeFile(input.id, {
|
|
25136
|
+
title: input.title,
|
|
25137
|
+
content: input.content,
|
|
25138
|
+
tags: input.tags,
|
|
25139
|
+
category: input.category
|
|
25140
|
+
}, "drafts");
|
|
25141
|
+
if (!result) {
|
|
25142
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u8349\u7A3F` };
|
|
25143
|
+
}
|
|
25144
|
+
localId = input.id;
|
|
25145
|
+
} else {
|
|
25146
|
+
const { id } = await saveKnowledge({
|
|
25147
|
+
content: input.content,
|
|
25148
|
+
title: input.title,
|
|
25149
|
+
tags: input.tags,
|
|
25150
|
+
category: input.category,
|
|
25151
|
+
source_type: "conversation",
|
|
25152
|
+
store: "drafts"
|
|
25153
|
+
});
|
|
25154
|
+
localId = id;
|
|
25155
|
+
}
|
|
25156
|
+
const creds = await getCredentials();
|
|
25157
|
+
if (!creds?.token) {
|
|
25158
|
+
await log("INFO", "ink.write", `saved draft locally id=${localId} title="${input.title}" (no cloud auth)`);
|
|
25159
|
+
return {
|
|
25160
|
+
success: true,
|
|
25161
|
+
message: `\u5DF2\u4FDD\u5B58\u8349\u7A3F\u300C${input.title}\u300D\u5230\u672C\u5730\uFF08\u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7\u4E91\u7AEF\u540C\u6B65\uFF09`,
|
|
25162
|
+
data: { id: localId }
|
|
25163
|
+
};
|
|
25164
|
+
}
|
|
25165
|
+
const config2 = await getConfig();
|
|
25128
25166
|
let coverUrl = input.cover || null;
|
|
25129
25167
|
if (coverUrl) {
|
|
25130
25168
|
if (coverUrl.startsWith("http://") || coverUrl.startsWith("https://")) {
|
|
@@ -25142,38 +25180,103 @@ async function inkWrite(input) {
|
|
|
25142
25180
|
}
|
|
25143
25181
|
const slug = `${Date.now().toString(36)}-${input.title.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-").replace(/^-|-$/g, "").slice(0, 60)}`;
|
|
25144
25182
|
const excerpt = input.excerpt || input.content.replace(/^#+\s.+$/gm, "").replace(/\n+/g, " ").trim().slice(0, 200);
|
|
25145
|
-
|
|
25146
|
-
|
|
25147
|
-
|
|
25148
|
-
|
|
25149
|
-
|
|
25150
|
-
|
|
25151
|
-
|
|
25152
|
-
|
|
25153
|
-
|
|
25154
|
-
|
|
25155
|
-
|
|
25156
|
-
|
|
25157
|
-
|
|
25158
|
-
|
|
25159
|
-
|
|
25160
|
-
|
|
25161
|
-
|
|
25162
|
-
|
|
25163
|
-
|
|
25164
|
-
|
|
25165
|
-
|
|
25183
|
+
try {
|
|
25184
|
+
const controller = new AbortController();
|
|
25185
|
+
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
25186
|
+
const res = await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
|
|
25187
|
+
method: "POST",
|
|
25188
|
+
signal: controller.signal,
|
|
25189
|
+
headers: {
|
|
25190
|
+
"Content-Type": "application/json",
|
|
25191
|
+
Authorization: `Bearer ${creds.token}`
|
|
25192
|
+
},
|
|
25193
|
+
body: JSON.stringify({
|
|
25194
|
+
title: input.title,
|
|
25195
|
+
slug,
|
|
25196
|
+
content: input.content,
|
|
25197
|
+
cover_url: coverUrl,
|
|
25198
|
+
tags: input.tags,
|
|
25199
|
+
category: input.category,
|
|
25200
|
+
excerpt,
|
|
25201
|
+
source_type: "conversation",
|
|
25202
|
+
source_ids: input.source_ids,
|
|
25203
|
+
local_id: localId
|
|
25204
|
+
})
|
|
25205
|
+
});
|
|
25206
|
+
clearTimeout(timeout);
|
|
25207
|
+
if (!res.ok) {
|
|
25208
|
+
const err = await res.text();
|
|
25209
|
+
await log("ERROR", "ink.write", `cloud save failed: ${err}`);
|
|
25210
|
+
return {
|
|
25211
|
+
success: true,
|
|
25212
|
+
message: `\u5DF2\u4FDD\u5B58\u8349\u7A3F\u300C${input.title}\u300D\u5230\u672C\u5730\uFF0C\u4F46\u4E91\u7AEF\u540C\u6B65\u5931\u8D25: ${err}`,
|
|
25213
|
+
data: { id: localId }
|
|
25214
|
+
};
|
|
25215
|
+
}
|
|
25216
|
+
const data = await res.json();
|
|
25217
|
+
await log("INFO", "ink.write", `saved draft id=${localId} cloud_id=${data.id} title="${input.title}"`);
|
|
25218
|
+
return {
|
|
25219
|
+
success: true,
|
|
25220
|
+
message: `\u5DF2\u4FDD\u5B58\u8349\u7A3F\u300C${input.title}\u300D\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09`,
|
|
25221
|
+
data: { id: localId, cloud_id: data.id, slug: data.slug, status: data.status }
|
|
25222
|
+
};
|
|
25223
|
+
} catch (cloudErr) {
|
|
25224
|
+
await log("WARN", "ink.write", `cloud upload failed (local saved): ${cloudErr.message}`);
|
|
25225
|
+
return {
|
|
25226
|
+
success: true,
|
|
25227
|
+
message: `\u5DF2\u4FDD\u5B58\u8349\u7A3F\u300C${input.title}\u300D\u5230\u672C\u5730\uFF0C\u4F46\u4E91\u7AEF\u540C\u6B65\u5931\u8D25: ${cloudErr.message}`,
|
|
25228
|
+
data: { id: localId }
|
|
25229
|
+
};
|
|
25166
25230
|
}
|
|
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
25231
|
} catch (err) {
|
|
25175
25232
|
await log("ERROR", "ink.write", `failed: ${err.message}`);
|
|
25176
|
-
return { success: false, message: `\
|
|
25233
|
+
return { success: false, message: `\u4FDD\u5B58\u8349\u7A3F\u5931\u8D25: ${err.message}` };
|
|
25234
|
+
}
|
|
25235
|
+
}
|
|
25236
|
+
var inkDeleteSchema = external_exports.object({
|
|
25237
|
+
id: external_exports.string().describe("\u6761\u76EE ID"),
|
|
25238
|
+
store: external_exports.enum(["knowledge", "drafts"]).optional().default("knowledge").describe("\u5B58\u50A8\u7C7B\u578B\uFF1Aknowledge\uFF08\u7D20\u6750\uFF09\u6216 drafts\uFF08\u8349\u7A3F\uFF09"),
|
|
25239
|
+
confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
|
|
25240
|
+
});
|
|
25241
|
+
async function inkDelete(input) {
|
|
25242
|
+
try {
|
|
25243
|
+
const store = input.store;
|
|
25244
|
+
if (!input.confirm) {
|
|
25245
|
+
const index = await readIndex(store);
|
|
25246
|
+
const entry = index.entries[input.id];
|
|
25247
|
+
if (!entry) {
|
|
25248
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
|
|
25249
|
+
}
|
|
25250
|
+
return {
|
|
25251
|
+
success: false,
|
|
25252
|
+
message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
|
|
25253
|
+
data: { id: entry.id, title: entry.title, store, category: entry.category, tags: entry.tags }
|
|
25254
|
+
};
|
|
25255
|
+
}
|
|
25256
|
+
const deleted = await deleteKnowledgeFile(input.id, store);
|
|
25257
|
+
if (!deleted) {
|
|
25258
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
|
|
25259
|
+
}
|
|
25260
|
+
try {
|
|
25261
|
+
const creds = await getCredentials();
|
|
25262
|
+
if (creds?.token) {
|
|
25263
|
+
const config2 = await getConfig();
|
|
25264
|
+
await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
|
|
25265
|
+
method: "DELETE",
|
|
25266
|
+
headers: {
|
|
25267
|
+
"Content-Type": "application/json",
|
|
25268
|
+
Authorization: `Bearer ${creds.token}`
|
|
25269
|
+
},
|
|
25270
|
+
body: JSON.stringify({ local_id: input.id })
|
|
25271
|
+
});
|
|
25272
|
+
}
|
|
25273
|
+
} catch {
|
|
25274
|
+
}
|
|
25275
|
+
await log("INFO", "ink.delete", `deleted id=${input.id} store=${store}`);
|
|
25276
|
+
return { success: true, message: `\u5DF2\u5220\u9664 ${input.id}`, data: { id: input.id } };
|
|
25277
|
+
} catch (err) {
|
|
25278
|
+
await log("ERROR", "ink.delete", `failed: ${err.message}`);
|
|
25279
|
+
return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
|
|
25177
25280
|
}
|
|
25178
25281
|
}
|
|
25179
25282
|
var inkTagsSchema = external_exports.object({
|
|
@@ -25184,7 +25287,7 @@ var inkTagsSchema = external_exports.object({
|
|
|
25184
25287
|
});
|
|
25185
25288
|
async function inkTags(input) {
|
|
25186
25289
|
try {
|
|
25187
|
-
const index = await readIndex();
|
|
25290
|
+
const index = await readIndex("knowledge");
|
|
25188
25291
|
switch (input.action) {
|
|
25189
25292
|
case "list": {
|
|
25190
25293
|
const tags = getAllTags(index);
|
|
@@ -25198,14 +25301,14 @@ async function inkTags(input) {
|
|
|
25198
25301
|
if (!input.tag || !input.new_tag) {
|
|
25199
25302
|
return { success: false, message: "rename \u9700\u8981 tag\uFF08\u539F\u6807\u7B7E\uFF09\u548C new_tag\uFF08\u65B0\u6807\u7B7E\u540D\uFF09" };
|
|
25200
25303
|
}
|
|
25201
|
-
const count = await renameTag(input.tag, input.new_tag);
|
|
25304
|
+
const count = await renameTag(input.tag, input.new_tag, "knowledge");
|
|
25202
25305
|
if (count === 0) {
|
|
25203
|
-
return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\
|
|
25306
|
+
return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u6761\u76EE` };
|
|
25204
25307
|
}
|
|
25205
25308
|
await log("INFO", "ink.tags", `renamed "${input.tag}" \u2192 "${input.new_tag}", affected=${count}`);
|
|
25206
25309
|
return {
|
|
25207
25310
|
success: true,
|
|
25208
|
-
message: `\u5DF2\u5C06 ${count} \u6761\
|
|
25311
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
|
|
25209
25312
|
data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
|
|
25210
25313
|
};
|
|
25211
25314
|
}
|
|
@@ -25213,14 +25316,14 @@ async function inkTags(input) {
|
|
|
25213
25316
|
if (!input.source_tags || input.source_tags.length === 0 || !input.new_tag) {
|
|
25214
25317
|
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
25318
|
}
|
|
25216
|
-
const count = await mergeTags(input.source_tags, input.new_tag);
|
|
25319
|
+
const count = await mergeTags(input.source_tags, input.new_tag, "knowledge");
|
|
25217
25320
|
if (count === 0) {
|
|
25218
|
-
return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\
|
|
25321
|
+
return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u6761\u76EE" };
|
|
25219
25322
|
}
|
|
25220
25323
|
await log("INFO", "ink.tags", `merged [${input.source_tags.join(",")}] \u2192 "${input.new_tag}", affected=${count}`);
|
|
25221
25324
|
return {
|
|
25222
25325
|
success: true,
|
|
25223
|
-
message: `\u5DF2\u5C06 ${count} \u6761\
|
|
25326
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
|
|
25224
25327
|
data: { source_tags: input.source_tags, target_tag: input.new_tag, affected: count }
|
|
25225
25328
|
};
|
|
25226
25329
|
}
|
|
@@ -25289,7 +25392,7 @@ async function uploadImageFromUrl(imageUrl, type, token, apiBase) {
|
|
|
25289
25392
|
// src/tools/source.ts
|
|
25290
25393
|
var import_gray_matter2 = __toESM(require_gray_matter(), 1);
|
|
25291
25394
|
import { readFile as readFile4 } from "fs/promises";
|
|
25292
|
-
import { join as
|
|
25395
|
+
import { join as join6 } from "path";
|
|
25293
25396
|
import { readdirSync } from "fs";
|
|
25294
25397
|
import { execSync } from "child_process";
|
|
25295
25398
|
var sourceCrawlSchema = external_exports.object({
|
|
@@ -25297,8 +25400,8 @@ var sourceCrawlSchema = external_exports.object({
|
|
|
25297
25400
|
});
|
|
25298
25401
|
async function sourceCrawl(input) {
|
|
25299
25402
|
const config2 = await getConfig();
|
|
25300
|
-
const crawlerDir =
|
|
25301
|
-
const configPath =
|
|
25403
|
+
const crawlerDir = join6(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
25404
|
+
const configPath = join6(crawlerDir, "config.json");
|
|
25302
25405
|
let crawlerConfig;
|
|
25303
25406
|
try {
|
|
25304
25407
|
crawlerConfig = JSON.parse(await readFile4(configPath, "utf-8"));
|
|
@@ -25315,7 +25418,7 @@ async function sourceCrawl(input) {
|
|
|
25315
25418
|
message: input.sourceId ? `\u672A\u627E\u5230\u722C\u866B\u6E90: ${input.sourceId}` : "\u6CA1\u6709\u5DF2\u542F\u7528\u7684\u722C\u866B\u6E90"
|
|
25316
25419
|
};
|
|
25317
25420
|
}
|
|
25318
|
-
const crawlScript =
|
|
25421
|
+
const crawlScript = join6(crawlerDir, "crawl.mjs");
|
|
25319
25422
|
const args = input.sourceId ? `--source ${input.sourceId}` : "";
|
|
25320
25423
|
try {
|
|
25321
25424
|
execSync(`node "${crawlScript}" ${args}`, {
|
|
@@ -25327,7 +25430,7 @@ async function sourceCrawl(input) {
|
|
|
25327
25430
|
let saved = 0;
|
|
25328
25431
|
let queued = 0;
|
|
25329
25432
|
for (const target of targets) {
|
|
25330
|
-
const sourceDir =
|
|
25433
|
+
const sourceDir = join6(config2.workflowDir, "sources", "articles", target.id);
|
|
25331
25434
|
let files;
|
|
25332
25435
|
try {
|
|
25333
25436
|
files = readdirSync(sourceDir).filter((f) => f.endsWith(".md"));
|
|
@@ -25335,7 +25438,7 @@ async function sourceCrawl(input) {
|
|
|
25335
25438
|
continue;
|
|
25336
25439
|
}
|
|
25337
25440
|
for (const f of files) {
|
|
25338
|
-
const filePath =
|
|
25441
|
+
const filePath = join6(sourceDir, f);
|
|
25339
25442
|
try {
|
|
25340
25443
|
const raw = await readFile4(filePath, "utf-8");
|
|
25341
25444
|
const { data, content } = (0, import_gray_matter2.default)(raw);
|
|
@@ -25396,8 +25499,8 @@ async function sourceCrawl(input) {
|
|
|
25396
25499
|
}
|
|
25397
25500
|
|
|
25398
25501
|
// src/tools/subscribe.ts
|
|
25399
|
-
import { readFile as readFile5, writeFile as
|
|
25400
|
-
import { join as
|
|
25502
|
+
import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
|
|
25503
|
+
import { join as join7 } from "path";
|
|
25401
25504
|
var sourceSubscribeSchema = external_exports.object({
|
|
25402
25505
|
action: external_exports.enum(["add", "remove", "list"]).describe("\u64CD\u4F5C\u7C7B\u578B"),
|
|
25403
25506
|
id: external_exports.string().optional().describe("\u8BA2\u9605\u6E90 ID"),
|
|
@@ -25426,9 +25529,9 @@ async function readCrawlerConfig(configPath) {
|
|
|
25426
25529
|
}
|
|
25427
25530
|
async function sourceSubscribe(input) {
|
|
25428
25531
|
const config2 = await getConfig();
|
|
25429
|
-
const crawlerDir =
|
|
25430
|
-
await
|
|
25431
|
-
const configPath =
|
|
25532
|
+
const crawlerDir = join7(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
25533
|
+
await mkdir6(crawlerDir, { recursive: true });
|
|
25534
|
+
const configPath = join7(crawlerDir, "config.json");
|
|
25432
25535
|
const crawlerConfig = await readCrawlerConfig(configPath);
|
|
25433
25536
|
if (input.action === "list") {
|
|
25434
25537
|
return {
|
|
@@ -25460,7 +25563,7 @@ async function sourceSubscribe(input) {
|
|
|
25460
25563
|
if (input.crawlConfig.maxArticles) newSource.maxArticles = input.crawlConfig.maxArticles;
|
|
25461
25564
|
}
|
|
25462
25565
|
crawlerConfig.sources.push(newSource);
|
|
25463
|
-
await
|
|
25566
|
+
await writeFile4(configPath, JSON.stringify(crawlerConfig, null, 2));
|
|
25464
25567
|
fireAndForgetPush({
|
|
25465
25568
|
crawlerSources: crawlerConfig.sources.map((s) => ({
|
|
25466
25569
|
id: s.id,
|
|
@@ -25478,7 +25581,7 @@ async function sourceSubscribe(input) {
|
|
|
25478
25581
|
return { success: false, message: "\u5220\u9664\u8BA2\u9605\u6E90\u9700\u8981 id \u53C2\u6570" };
|
|
25479
25582
|
}
|
|
25480
25583
|
crawlerConfig.sources = crawlerConfig.sources.filter((s) => s.id !== input.id);
|
|
25481
|
-
await
|
|
25584
|
+
await writeFile4(configPath, JSON.stringify(crawlerConfig, null, 2));
|
|
25482
25585
|
fireAndForgetPush({
|
|
25483
25586
|
crawlerSources: crawlerConfig.sources.map((s) => ({
|
|
25484
25587
|
id: s.id,
|
|
@@ -25497,7 +25600,7 @@ async function sourceSubscribe(input) {
|
|
|
25497
25600
|
// src/index.ts
|
|
25498
25601
|
var server = new McpServer({
|
|
25499
25602
|
name: "ClaudeInk",
|
|
25500
|
-
version: "2.0
|
|
25603
|
+
version: "2.2.0"
|
|
25501
25604
|
});
|
|
25502
25605
|
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) => {
|
|
25503
25606
|
const result = await workflowInit(input);
|
|
@@ -25507,23 +25610,23 @@ server.tool("ink.sync", "\u4ECE\u4E91\u7AEF\u540C\u6B65\u77E5\u8BC6\u5143\u6570\
|
|
|
25507
25610
|
const result = await sync(input);
|
|
25508
25611
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25509
25612
|
});
|
|
25510
|
-
server.tool("ink.save", "\
|
|
25613
|
+
server.tool("ink.save", "\u6536\u96C6\u7D20\u6750\u5230\u77E5\u8BC6\u5E93\uFF08\u539F\u59CB\u5185\u5BB9\u3001\u7F51\u9875\u6458\u5F55\u3001\u5BF9\u8BDD\u7247\u6BB5\u7B49\uFF09\u3002\u5B58\u5165\u672C\u5730 knowledge/ \u76EE\u5F55\uFF0C\u5143\u6570\u636E\u540C\u6B65\u5230\u4E91\u7AEF source_meta\u3002", inkSaveSchema.shape, async (input) => {
|
|
25511
25614
|
const result = await inkSave(input);
|
|
25512
25615
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25513
25616
|
});
|
|
25514
|
-
server.tool("ink.
|
|
25515
|
-
const result = await
|
|
25617
|
+
server.tool("ink.write", "\u4FDD\u5B58\u8349\u7A3F/\u6587\u7AE0\uFF08AI \u521B\u4F5C\u7684\u5B8C\u6574\u6587\u7AE0\uFF09\u3002\u5B58\u5165\u672C\u5730 drafts/ \u76EE\u5F55\uFF0C\u5168\u6587\u4E0A\u4F20\u5230\u4E91\u7AEF blog_posts\u3002", inkWriteSchema.shape, async (input) => {
|
|
25618
|
+
const result = await inkWrite(input);
|
|
25516
25619
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25517
25620
|
});
|
|
25518
|
-
server.tool("ink.
|
|
25519
|
-
const result = await
|
|
25621
|
+
server.tool("ink.delete", "\u5220\u9664\u6761\u76EE\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09", inkDeleteSchema.shape, async (input) => {
|
|
25622
|
+
const result = await inkDelete(input);
|
|
25520
25623
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25521
25624
|
});
|
|
25522
25625
|
server.tool("ink.tags", "\u6807\u7B7E\u7BA1\u7406\uFF08\u5217\u51FA / \u91CD\u547D\u540D / \u5408\u5E76\u6807\u7B7E\uFF09", inkTagsSchema.shape, async (input) => {
|
|
25523
25626
|
const result = await inkTags(input);
|
|
25524
25627
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25525
25628
|
});
|
|
25526
|
-
server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\
|
|
25629
|
+
server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\u7D20\u6750\u5B58\u5165\u672C\u5730\u77E5\u8BC6\u5E93\uFF09", sourceCrawlSchema.shape, async (input) => {
|
|
25527
25630
|
const result = await sourceCrawl(input);
|
|
25528
25631
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25529
25632
|
});
|
|
@@ -25531,6 +25634,9 @@ server.tool("ink.subscribe", "\u7BA1\u7406\u8BA2\u9605\u6E90\uFF08\u6DFB\u52A0/\
|
|
|
25531
25634
|
const result = await sourceSubscribe(input);
|
|
25532
25635
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
25533
25636
|
});
|
|
25637
|
+
process.on("unhandledRejection", (err) => {
|
|
25638
|
+
console.error(`[ClaudeInk] Unhandled rejection: ${err}`);
|
|
25639
|
+
});
|
|
25534
25640
|
async function main() {
|
|
25535
25641
|
try {
|
|
25536
25642
|
const state = await readState();
|
|
@@ -25542,11 +25648,8 @@ async function main() {
|
|
|
25542
25648
|
}
|
|
25543
25649
|
const transport = new StdioServerTransport();
|
|
25544
25650
|
await server.connect(transport);
|
|
25545
|
-
await log("INFO", "server", "started (
|
|
25651
|
+
await log("INFO", "server", "started (7 tools)");
|
|
25546
25652
|
}
|
|
25547
|
-
process.on("unhandledRejection", (err) => {
|
|
25548
|
-
console.error(`[ClaudeInk] Unhandled rejection: ${err}`);
|
|
25549
|
-
});
|
|
25550
25653
|
main().catch(async (err) => {
|
|
25551
25654
|
await log("ERROR", "server", `fatal: ${err.message || err}`);
|
|
25552
25655
|
process.exit(1);
|