@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/cli.js
CHANGED
|
@@ -28848,179 +28848,6 @@ var init_state = __esm({
|
|
|
28848
28848
|
}
|
|
28849
28849
|
});
|
|
28850
28850
|
|
|
28851
|
-
// src/lib/logger.ts
|
|
28852
|
-
import { appendFile, mkdir as mkdir2 } from "fs/promises";
|
|
28853
|
-
import { join as join2 } from "path";
|
|
28854
|
-
function setLogLevel(level) {
|
|
28855
|
-
currentLevel = level;
|
|
28856
|
-
}
|
|
28857
|
-
async function log(level, scope, message) {
|
|
28858
|
-
if (LEVELS[level] > LEVELS[currentLevel]) return;
|
|
28859
|
-
const dir = join2(getClaudeinkDir(), "logs");
|
|
28860
|
-
await mkdir2(dir, { recursive: true });
|
|
28861
|
-
const date3 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
28862
|
-
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${scope} | ${message}
|
|
28863
|
-
`;
|
|
28864
|
-
await appendFile(join2(dir, `mcp-${date3}.log`), line);
|
|
28865
|
-
console.error(`[ClaudeInk] ${line.trim()}`);
|
|
28866
|
-
}
|
|
28867
|
-
var currentLevel, LEVELS;
|
|
28868
|
-
var init_logger = __esm({
|
|
28869
|
-
"src/lib/logger.ts"() {
|
|
28870
|
-
"use strict";
|
|
28871
|
-
init_state();
|
|
28872
|
-
currentLevel = "INFO";
|
|
28873
|
-
LEVELS = { ERROR: 0, WARN: 1, INFO: 2, DEBUG: 3 };
|
|
28874
|
-
}
|
|
28875
|
-
});
|
|
28876
|
-
|
|
28877
|
-
// src/tools/sync.ts
|
|
28878
|
-
async function sync2(input) {
|
|
28879
|
-
if (input.workDir) setWorkDir(input.workDir);
|
|
28880
|
-
const creds = await getCredentials();
|
|
28881
|
-
if (!creds?.token) {
|
|
28882
|
-
return { success: false, message: "\u672A\u6FC0\u6D3B\uFF0C\u8BF7\u5148\u4F7F\u7528 workflow.init \u6FC0\u6D3B License" };
|
|
28883
|
-
}
|
|
28884
|
-
return doPull(creds.token);
|
|
28885
|
-
}
|
|
28886
|
-
async function doPull(token) {
|
|
28887
|
-
const config2 = await getConfig();
|
|
28888
|
-
try {
|
|
28889
|
-
const res = await fetch(`${config2.apiBaseUrl}/api/sync/pull`, {
|
|
28890
|
-
headers: { Authorization: `Bearer ${token}` }
|
|
28891
|
-
});
|
|
28892
|
-
if (!res.ok) {
|
|
28893
|
-
if (res.status === 404) {
|
|
28894
|
-
return { success: true, message: "\u4E91\u7AEF\u65E0\u6570\u636E" };
|
|
28895
|
-
}
|
|
28896
|
-
await log("ERROR", "ink.sync", `pull failed: HTTP ${res.status}`);
|
|
28897
|
-
return { success: false, message: `\u62C9\u53D6\u5931\u8D25: HTTP ${res.status}` };
|
|
28898
|
-
}
|
|
28899
|
-
await updateLastSyncAt();
|
|
28900
|
-
await log("INFO", "ink.sync", "pull completed");
|
|
28901
|
-
return {
|
|
28902
|
-
success: true,
|
|
28903
|
-
message: "\u2705 \u540C\u6B65\u5B8C\u6210"
|
|
28904
|
-
};
|
|
28905
|
-
} catch (err) {
|
|
28906
|
-
return { success: false, message: `\u540C\u6B65\u5931\u8D25: ${err instanceof Error ? err.message : err}` };
|
|
28907
|
-
}
|
|
28908
|
-
}
|
|
28909
|
-
async function syncPull(input) {
|
|
28910
|
-
if (input.workDir) setWorkDir(input.workDir);
|
|
28911
|
-
const creds = await getCredentials();
|
|
28912
|
-
if (!creds?.token) {
|
|
28913
|
-
return { success: false, message: "\u672A\u6FC0\u6D3B" };
|
|
28914
|
-
}
|
|
28915
|
-
return doPull(creds.token);
|
|
28916
|
-
}
|
|
28917
|
-
var syncSchema;
|
|
28918
|
-
var init_sync = __esm({
|
|
28919
|
-
"src/tools/sync.ts"() {
|
|
28920
|
-
"use strict";
|
|
28921
|
-
init_zod();
|
|
28922
|
-
init_state();
|
|
28923
|
-
init_logger();
|
|
28924
|
-
syncSchema = external_exports.object({
|
|
28925
|
-
workDir: external_exports.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u914D\u7F6E\u4E2D\u7684 workflowDir\uFF09")
|
|
28926
|
-
});
|
|
28927
|
-
}
|
|
28928
|
-
});
|
|
28929
|
-
|
|
28930
|
-
// src/tools/workflow.ts
|
|
28931
|
-
import { mkdir as mkdir3, access, unlink } from "fs/promises";
|
|
28932
|
-
import { join as join3 } from "path";
|
|
28933
|
-
async function workflowInit(input) {
|
|
28934
|
-
const cwd = input.workDir;
|
|
28935
|
-
const results = [];
|
|
28936
|
-
try {
|
|
28937
|
-
setWorkDir(cwd);
|
|
28938
|
-
const claudeinkDir = join3(cwd, ".claudeink");
|
|
28939
|
-
await mkdir3(join3(claudeinkDir, "knowledge"), { recursive: true });
|
|
28940
|
-
results.push("\u2705 \u77E5\u8BC6\u5E93\u76EE\u5F55\u5DF2\u521B\u5EFA");
|
|
28941
|
-
const state = await readState();
|
|
28942
|
-
state.config.workflowDir = cwd;
|
|
28943
|
-
const oldCredsPath = join3(claudeinkDir, "credentials.json");
|
|
28944
|
-
try {
|
|
28945
|
-
await access(oldCredsPath);
|
|
28946
|
-
await unlink(oldCredsPath);
|
|
28947
|
-
results.push("\u{1F9F9} \u5DF2\u6E05\u7406\u65E7\u7248 credentials.json");
|
|
28948
|
-
} catch {
|
|
28949
|
-
}
|
|
28950
|
-
let activated = false;
|
|
28951
|
-
if (input.licenseKey) {
|
|
28952
|
-
try {
|
|
28953
|
-
const res = await fetch(`${DEFAULT_API_BASE_URL}/api/auth/activate`, {
|
|
28954
|
-
method: "POST",
|
|
28955
|
-
headers: { "Content-Type": "application/json" },
|
|
28956
|
-
body: JSON.stringify({ key: input.licenseKey })
|
|
28957
|
-
});
|
|
28958
|
-
const data = await res.json();
|
|
28959
|
-
if (data.userId) {
|
|
28960
|
-
state.credentials = {
|
|
28961
|
-
licenseKey: input.licenseKey,
|
|
28962
|
-
token: data.token,
|
|
28963
|
-
userId: data.userId,
|
|
28964
|
-
plan: data.plan,
|
|
28965
|
-
expiresAt: data.expiresAt
|
|
28966
|
-
};
|
|
28967
|
-
results.push(`\u2705 License \u6FC0\u6D3B\u6210\u529F\uFF08\u5957\u9910: ${data.plan}\uFF09`);
|
|
28968
|
-
activated = true;
|
|
28969
|
-
} else {
|
|
28970
|
-
results.push(`\u26A0\uFE0F License \u6FC0\u6D3B\u5931\u8D25: ${JSON.stringify(data)}`);
|
|
28971
|
-
}
|
|
28972
|
-
} catch (err) {
|
|
28973
|
-
results.push(`\u26A0\uFE0F \u6FC0\u6D3B\u7F51\u7EDC\u9519\u8BEF: ${err instanceof Error ? err.message : err}`);
|
|
28974
|
-
}
|
|
28975
|
-
}
|
|
28976
|
-
await writeState(state);
|
|
28977
|
-
results.push("\u2705 state.json");
|
|
28978
|
-
if (activated) {
|
|
28979
|
-
try {
|
|
28980
|
-
const pullResult = await syncPull({ workDir: cwd });
|
|
28981
|
-
if (pullResult.success) {
|
|
28982
|
-
results.push("\u2705 \u5DF2\u4ECE\u4E91\u7AEF\u540C\u6B65\u6570\u636E");
|
|
28983
|
-
} else {
|
|
28984
|
-
results.push("\u2139\uFE0F \u4E91\u7AEF\u65E0\u5DF2\u6709\u6570\u636E");
|
|
28985
|
-
}
|
|
28986
|
-
} catch {
|
|
28987
|
-
results.push("\u2139\uFE0F \u4E91\u7AEF\u540C\u6B65\u8DF3\u8FC7");
|
|
28988
|
-
}
|
|
28989
|
-
}
|
|
28990
|
-
return {
|
|
28991
|
-
success: true,
|
|
28992
|
-
message: [
|
|
28993
|
-
"\u{1F389} ClaudeInk \u77E5\u8BC6\u5E93\u521D\u59CB\u5316\u5B8C\u6210\uFF01",
|
|
28994
|
-
"",
|
|
28995
|
-
...results,
|
|
28996
|
-
"",
|
|
28997
|
-
"\u{1F3AF} \u4E0B\u4E00\u6B65\uFF1A",
|
|
28998
|
-
"1. \u5728\u5BF9\u8BDD\u4E2D\u8BF4\u300C\u5E2E\u6211\u5B58\u4E00\u4E0B\u300D\u4FDD\u5B58\u6709\u4EF7\u503C\u5185\u5BB9",
|
|
28999
|
-
"2. \u7528\u300C\u627E\u4E00\u4E0B\u5173\u4E8E XX \u7684\u300D\u68C0\u7D22\u77E5\u8BC6\u5E93"
|
|
29000
|
-
].join("\n")
|
|
29001
|
-
};
|
|
29002
|
-
} catch (err) {
|
|
29003
|
-
return {
|
|
29004
|
-
success: false,
|
|
29005
|
-
message: `\u521D\u59CB\u5316\u5931\u8D25: ${err instanceof Error ? err.message : err}`
|
|
29006
|
-
};
|
|
29007
|
-
}
|
|
29008
|
-
}
|
|
29009
|
-
var DEFAULT_API_BASE_URL, workflowInitSchema;
|
|
29010
|
-
var init_workflow = __esm({
|
|
29011
|
-
"src/tools/workflow.ts"() {
|
|
29012
|
-
"use strict";
|
|
29013
|
-
init_zod();
|
|
29014
|
-
init_state();
|
|
29015
|
-
init_sync();
|
|
29016
|
-
DEFAULT_API_BASE_URL = "https://app.claudeink.com";
|
|
29017
|
-
workflowInitSchema = external_exports.object({
|
|
29018
|
-
workDir: external_exports.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
|
|
29019
|
-
licenseKey: external_exports.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
|
|
29020
|
-
});
|
|
29021
|
-
}
|
|
29022
|
-
});
|
|
29023
|
-
|
|
29024
28851
|
// ../node_modules/kind-of/index.js
|
|
29025
28852
|
var require_kind_of = __commonJS({
|
|
29026
28853
|
"../node_modules/kind-of/index.js"(exports2, module2) {
|
|
@@ -32506,8 +32333,8 @@ var require_gray_matter = __commonJS({
|
|
|
32506
32333
|
});
|
|
32507
32334
|
|
|
32508
32335
|
// src/lib/knowledge.ts
|
|
32509
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as
|
|
32510
|
-
import { join as
|
|
32336
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, unlink } from "fs/promises";
|
|
32337
|
+
import { join as join2 } from "path";
|
|
32511
32338
|
function withIndexLock(fn) {
|
|
32512
32339
|
const prev = _lockPromise;
|
|
32513
32340
|
let resolve;
|
|
@@ -32516,11 +32343,11 @@ function withIndexLock(fn) {
|
|
|
32516
32343
|
});
|
|
32517
32344
|
return prev.then(fn).finally(() => resolve());
|
|
32518
32345
|
}
|
|
32519
|
-
function
|
|
32520
|
-
return
|
|
32346
|
+
function getStoreDir(store = "knowledge") {
|
|
32347
|
+
return join2(getWorkDir(), ".claudeink", store);
|
|
32521
32348
|
}
|
|
32522
|
-
function getIndexPath() {
|
|
32523
|
-
return
|
|
32349
|
+
function getIndexPath(store = "knowledge") {
|
|
32350
|
+
return join2(getWorkDir(), ".claudeink", store, "index.json");
|
|
32524
32351
|
}
|
|
32525
32352
|
async function generateIdInternal(index) {
|
|
32526
32353
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -32542,28 +32369,28 @@ function toSlug(title) {
|
|
|
32542
32369
|
function generatePreview(content, maxLen = 200) {
|
|
32543
32370
|
return content.replace(/^#+\s.+$/gm, "").replace(/\n+/g, " ").trim().slice(0, maxLen);
|
|
32544
32371
|
}
|
|
32545
|
-
async function readIndex() {
|
|
32372
|
+
async function readIndex(store = "knowledge") {
|
|
32546
32373
|
try {
|
|
32547
|
-
const raw = await readFile2(getIndexPath(), "utf-8");
|
|
32374
|
+
const raw = await readFile2(getIndexPath(store), "utf-8");
|
|
32548
32375
|
return JSON.parse(raw);
|
|
32549
32376
|
} catch {
|
|
32550
32377
|
return { entries: {}, updated_at: (/* @__PURE__ */ new Date()).toISOString() };
|
|
32551
32378
|
}
|
|
32552
32379
|
}
|
|
32553
|
-
async function saveIndex(index) {
|
|
32380
|
+
async function saveIndex(index, store = "knowledge") {
|
|
32554
32381
|
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
32555
|
-
const dir =
|
|
32556
|
-
await
|
|
32557
|
-
await writeFile2(getIndexPath(), JSON.stringify(index, null, 2), "utf-8");
|
|
32382
|
+
const dir = getStoreDir(store);
|
|
32383
|
+
await mkdir2(dir, { recursive: true });
|
|
32384
|
+
await writeFile2(getIndexPath(store), JSON.stringify(index, null, 2), "utf-8");
|
|
32558
32385
|
}
|
|
32559
|
-
async function writeKnowledgeFile(meta, content) {
|
|
32386
|
+
async function writeKnowledgeFile(meta, content, store = "knowledge") {
|
|
32560
32387
|
const now = /* @__PURE__ */ new Date();
|
|
32561
32388
|
const monthDir = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
32562
|
-
const dir =
|
|
32563
|
-
await
|
|
32389
|
+
const dir = join2(getStoreDir(store), monthDir);
|
|
32390
|
+
await mkdir2(dir, { recursive: true });
|
|
32564
32391
|
const slug = toSlug(meta.title) || meta.id;
|
|
32565
32392
|
const filename = `${now.toISOString().slice(0, 10)}-${slug}.md`;
|
|
32566
|
-
const filePath =
|
|
32393
|
+
const filePath = join2(dir, filename);
|
|
32567
32394
|
const frontmatter = {
|
|
32568
32395
|
id: meta.id,
|
|
32569
32396
|
title: meta.title,
|
|
@@ -32576,13 +32403,13 @@ async function writeKnowledgeFile(meta, content) {
|
|
|
32576
32403
|
if (meta.url) frontmatter.url = meta.url;
|
|
32577
32404
|
const output = import_gray_matter.default.stringify(content, frontmatter);
|
|
32578
32405
|
await writeFile2(filePath, output, "utf-8");
|
|
32579
|
-
return
|
|
32406
|
+
return join2(monthDir, filename);
|
|
32580
32407
|
}
|
|
32581
|
-
async function readKnowledgeFile(id) {
|
|
32582
|
-
const index = await readIndex();
|
|
32408
|
+
async function readKnowledgeFile(id, store = "knowledge") {
|
|
32409
|
+
const index = await readIndex(store);
|
|
32583
32410
|
const entry = index.entries[id];
|
|
32584
32411
|
if (!entry) return null;
|
|
32585
|
-
const filePath =
|
|
32412
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
32586
32413
|
try {
|
|
32587
32414
|
const raw = await readFile2(filePath, "utf-8");
|
|
32588
32415
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -32596,8 +32423,9 @@ async function readKnowledgeFile(id) {
|
|
|
32596
32423
|
}
|
|
32597
32424
|
}
|
|
32598
32425
|
async function saveKnowledge(params) {
|
|
32426
|
+
const store = params.store || "knowledge";
|
|
32599
32427
|
return withIndexLock(async () => {
|
|
32600
|
-
const index = await readIndex();
|
|
32428
|
+
const index = await readIndex(store);
|
|
32601
32429
|
const id = await generateIdInternal(index);
|
|
32602
32430
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
32603
32431
|
const meta = {
|
|
@@ -32610,7 +32438,7 @@ async function saveKnowledge(params) {
|
|
|
32610
32438
|
created_at: now,
|
|
32611
32439
|
updated_at: now
|
|
32612
32440
|
};
|
|
32613
|
-
const relativePath = await writeKnowledgeFile(meta, params.content);
|
|
32441
|
+
const relativePath = await writeKnowledgeFile(meta, params.content, store);
|
|
32614
32442
|
index.entries[id] = {
|
|
32615
32443
|
id,
|
|
32616
32444
|
title: params.title,
|
|
@@ -32622,13 +32450,13 @@ async function saveKnowledge(params) {
|
|
|
32622
32450
|
created_at: now,
|
|
32623
32451
|
updated_at: now
|
|
32624
32452
|
};
|
|
32625
|
-
await saveIndex(index);
|
|
32453
|
+
await saveIndex(index, store);
|
|
32626
32454
|
return { id, filePath: relativePath };
|
|
32627
32455
|
});
|
|
32628
32456
|
}
|
|
32629
|
-
async function updateKnowledgeFile(id, updates) {
|
|
32457
|
+
async function updateKnowledgeFile(id, updates, store = "knowledge") {
|
|
32630
32458
|
return withIndexLock(async () => {
|
|
32631
|
-
const file = await readKnowledgeFile(id);
|
|
32459
|
+
const file = await readKnowledgeFile(id, store);
|
|
32632
32460
|
if (!file) return null;
|
|
32633
32461
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
32634
32462
|
const meta = { ...file.meta };
|
|
@@ -32649,7 +32477,7 @@ async function updateKnowledgeFile(id, updates) {
|
|
|
32649
32477
|
if (meta.url) frontmatter.url = meta.url;
|
|
32650
32478
|
const output = import_gray_matter.default.stringify(content, frontmatter);
|
|
32651
32479
|
await writeFile2(file.filePath, output, "utf-8");
|
|
32652
|
-
const index = await readIndex();
|
|
32480
|
+
const index = await readIndex(store);
|
|
32653
32481
|
const entry = index.entries[id];
|
|
32654
32482
|
if (entry) {
|
|
32655
32483
|
entry.title = meta.title;
|
|
@@ -32657,23 +32485,23 @@ async function updateKnowledgeFile(id, updates) {
|
|
|
32657
32485
|
entry.category = meta.category;
|
|
32658
32486
|
entry.preview = generatePreview(content);
|
|
32659
32487
|
entry.updated_at = now;
|
|
32660
|
-
await saveIndex(index);
|
|
32488
|
+
await saveIndex(index, store);
|
|
32661
32489
|
}
|
|
32662
32490
|
return { meta, content, filePath: file.filePath };
|
|
32663
32491
|
});
|
|
32664
32492
|
}
|
|
32665
|
-
async function deleteKnowledgeFile(id) {
|
|
32493
|
+
async function deleteKnowledgeFile(id, store = "knowledge") {
|
|
32666
32494
|
return withIndexLock(async () => {
|
|
32667
|
-
const index = await readIndex();
|
|
32495
|
+
const index = await readIndex(store);
|
|
32668
32496
|
const entry = index.entries[id];
|
|
32669
32497
|
if (!entry) return false;
|
|
32670
|
-
const filePath =
|
|
32498
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
32671
32499
|
try {
|
|
32672
|
-
await
|
|
32500
|
+
await unlink(filePath);
|
|
32673
32501
|
} catch {
|
|
32674
32502
|
}
|
|
32675
32503
|
delete index.entries[id];
|
|
32676
|
-
await saveIndex(index);
|
|
32504
|
+
await saveIndex(index, store);
|
|
32677
32505
|
return true;
|
|
32678
32506
|
});
|
|
32679
32507
|
}
|
|
@@ -32686,16 +32514,16 @@ function getAllTags(index) {
|
|
|
32686
32514
|
}
|
|
32687
32515
|
return Object.entries(tagCounts).map(([name, count]) => ({ name, count })).sort((a, b) => b.count - a.count);
|
|
32688
32516
|
}
|
|
32689
|
-
async function renameTag(oldTag, newTag) {
|
|
32517
|
+
async function renameTag(oldTag, newTag, store = "knowledge") {
|
|
32690
32518
|
return withIndexLock(async () => {
|
|
32691
|
-
const index = await readIndex();
|
|
32519
|
+
const index = await readIndex(store);
|
|
32692
32520
|
let count = 0;
|
|
32693
32521
|
for (const entry of Object.values(index.entries)) {
|
|
32694
32522
|
const idx = entry.tags.indexOf(oldTag);
|
|
32695
32523
|
if (idx !== -1) {
|
|
32696
32524
|
entry.tags[idx] = newTag;
|
|
32697
32525
|
count++;
|
|
32698
|
-
const filePath =
|
|
32526
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
32699
32527
|
try {
|
|
32700
32528
|
const raw = await readFile2(filePath, "utf-8");
|
|
32701
32529
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -32712,14 +32540,14 @@ async function renameTag(oldTag, newTag) {
|
|
|
32712
32540
|
}
|
|
32713
32541
|
}
|
|
32714
32542
|
if (count > 0) {
|
|
32715
|
-
await saveIndex(index);
|
|
32543
|
+
await saveIndex(index, store);
|
|
32716
32544
|
}
|
|
32717
32545
|
return count;
|
|
32718
32546
|
});
|
|
32719
32547
|
}
|
|
32720
|
-
async function mergeTags(sourceTags, targetTag) {
|
|
32548
|
+
async function mergeTags(sourceTags, targetTag, store = "knowledge") {
|
|
32721
32549
|
return withIndexLock(async () => {
|
|
32722
|
-
const index = await readIndex();
|
|
32550
|
+
const index = await readIndex(store);
|
|
32723
32551
|
let count = 0;
|
|
32724
32552
|
for (const entry of Object.values(index.entries)) {
|
|
32725
32553
|
const hasSource = entry.tags.some((t) => sourceTags.includes(t));
|
|
@@ -32730,7 +32558,7 @@ async function mergeTags(sourceTags, targetTag) {
|
|
|
32730
32558
|
}
|
|
32731
32559
|
entry.tags = newTags;
|
|
32732
32560
|
count++;
|
|
32733
|
-
const filePath =
|
|
32561
|
+
const filePath = join2(getStoreDir(store), entry.file_path);
|
|
32734
32562
|
try {
|
|
32735
32563
|
const raw = await readFile2(filePath, "utf-8");
|
|
32736
32564
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -32742,7 +32570,7 @@ async function mergeTags(sourceTags, targetTag) {
|
|
|
32742
32570
|
}
|
|
32743
32571
|
}
|
|
32744
32572
|
if (count > 0) {
|
|
32745
|
-
await saveIndex(index);
|
|
32573
|
+
await saveIndex(index, store);
|
|
32746
32574
|
}
|
|
32747
32575
|
return count;
|
|
32748
32576
|
});
|
|
@@ -32757,6 +32585,233 @@ var init_knowledge = __esm({
|
|
|
32757
32585
|
}
|
|
32758
32586
|
});
|
|
32759
32587
|
|
|
32588
|
+
// src/lib/logger.ts
|
|
32589
|
+
import { appendFile, mkdir as mkdir3 } from "fs/promises";
|
|
32590
|
+
import { join as join3 } from "path";
|
|
32591
|
+
function setLogLevel(level) {
|
|
32592
|
+
currentLevel = level;
|
|
32593
|
+
}
|
|
32594
|
+
async function log(level, scope, message) {
|
|
32595
|
+
if (LEVELS[level] > LEVELS[currentLevel]) return;
|
|
32596
|
+
const dir = join3(getClaudeinkDir(), "logs");
|
|
32597
|
+
await mkdir3(dir, { recursive: true });
|
|
32598
|
+
const date3 = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
32599
|
+
const line = `${(/* @__PURE__ */ new Date()).toISOString()} [${level}] ${scope} | ${message}
|
|
32600
|
+
`;
|
|
32601
|
+
await appendFile(join3(dir, `mcp-${date3}.log`), line);
|
|
32602
|
+
console.error(`[ClaudeInk] ${line.trim()}`);
|
|
32603
|
+
}
|
|
32604
|
+
var currentLevel, LEVELS;
|
|
32605
|
+
var init_logger = __esm({
|
|
32606
|
+
"src/lib/logger.ts"() {
|
|
32607
|
+
"use strict";
|
|
32608
|
+
init_state();
|
|
32609
|
+
currentLevel = "INFO";
|
|
32610
|
+
LEVELS = { ERROR: 0, WARN: 1, INFO: 2, DEBUG: 3 };
|
|
32611
|
+
}
|
|
32612
|
+
});
|
|
32613
|
+
|
|
32614
|
+
// src/tools/sync.ts
|
|
32615
|
+
import { writeFile as writeFile3, mkdir as mkdir4 } from "fs/promises";
|
|
32616
|
+
import { join as join4 } from "path";
|
|
32617
|
+
async function sync2(input) {
|
|
32618
|
+
if (input.workDir) setWorkDir(input.workDir);
|
|
32619
|
+
const creds = await getCredentials();
|
|
32620
|
+
if (!creds?.token) {
|
|
32621
|
+
return { success: false, message: "\u672A\u6FC0\u6D3B\uFF0C\u8BF7\u5148\u4F7F\u7528 ink.init \u6FC0\u6D3B License" };
|
|
32622
|
+
}
|
|
32623
|
+
return doPull(creds.token);
|
|
32624
|
+
}
|
|
32625
|
+
async function doPull(token) {
|
|
32626
|
+
const config2 = await getConfig();
|
|
32627
|
+
try {
|
|
32628
|
+
const res = await fetch(`${config2.apiBaseUrl}/api/sync/pull`, {
|
|
32629
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
32630
|
+
});
|
|
32631
|
+
if (!res.ok) {
|
|
32632
|
+
if (res.status === 404) {
|
|
32633
|
+
return { success: true, message: "\u4E91\u7AEF\u65E0\u6570\u636E" };
|
|
32634
|
+
}
|
|
32635
|
+
await log("ERROR", "ink.sync", `pull failed: HTTP ${res.status}`);
|
|
32636
|
+
return { success: false, message: `\u62C9\u53D6\u5931\u8D25: HTTP ${res.status}` };
|
|
32637
|
+
}
|
|
32638
|
+
const data = await res.json();
|
|
32639
|
+
const results = [];
|
|
32640
|
+
if (data.configs) {
|
|
32641
|
+
const crawlerConfig = data.configs.find((c) => c.type === "crawler" && c.name === "config");
|
|
32642
|
+
if (crawlerConfig?.content) {
|
|
32643
|
+
try {
|
|
32644
|
+
const sources = JSON.parse(crawlerConfig.content);
|
|
32645
|
+
const crawlerDir = join4(config2.workflowDir || getWorkDir(), "tools", "crawler");
|
|
32646
|
+
await mkdir4(crawlerDir, { recursive: true });
|
|
32647
|
+
await writeFile3(join4(crawlerDir, "config.json"), JSON.stringify({ sources }, null, 2));
|
|
32648
|
+
results.push(`\u8BA2\u9605\u6E90: ${sources.length} \u4E2A`);
|
|
32649
|
+
} catch {
|
|
32650
|
+
}
|
|
32651
|
+
}
|
|
32652
|
+
}
|
|
32653
|
+
if (data.sources && Object.keys(data.sources).length > 0) {
|
|
32654
|
+
const index = await readIndex();
|
|
32655
|
+
let added = 0;
|
|
32656
|
+
for (const [localId, meta] of Object.entries(data.sources)) {
|
|
32657
|
+
if (!index.entries[localId]) {
|
|
32658
|
+
const entry = {
|
|
32659
|
+
id: localId,
|
|
32660
|
+
title: meta.title || "",
|
|
32661
|
+
tags: meta.tags || [],
|
|
32662
|
+
category: "reference",
|
|
32663
|
+
source_type: "url",
|
|
32664
|
+
preview: "",
|
|
32665
|
+
file_path: "",
|
|
32666
|
+
created_at: meta.publishedAt || (/* @__PURE__ */ new Date()).toISOString(),
|
|
32667
|
+
updated_at: meta.updatedAt || (/* @__PURE__ */ new Date()).toISOString()
|
|
32668
|
+
};
|
|
32669
|
+
index.entries[localId] = entry;
|
|
32670
|
+
added++;
|
|
32671
|
+
}
|
|
32672
|
+
}
|
|
32673
|
+
if (added > 0) {
|
|
32674
|
+
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
32675
|
+
const knowledgeDir = join4(getWorkDir(), ".claudeink", "knowledge");
|
|
32676
|
+
await mkdir4(knowledgeDir, { recursive: true });
|
|
32677
|
+
await writeFile3(join4(knowledgeDir, "index.json"), JSON.stringify(index, null, 2));
|
|
32678
|
+
results.push(`\u7D20\u6750\u7D22\u5F15: +${added} \u6761\uFF08\u5171 ${Object.keys(index.entries).length} \u6761\uFF09`);
|
|
32679
|
+
} else {
|
|
32680
|
+
results.push(`\u7D20\u6750\u7D22\u5F15: ${Object.keys(index.entries).length} \u6761\uFF08\u5DF2\u540C\u6B65\uFF09`);
|
|
32681
|
+
}
|
|
32682
|
+
}
|
|
32683
|
+
const draftCount = data.drafts ? Object.keys(data.drafts).length : 0;
|
|
32684
|
+
const pubCount = data.published ? Object.keys(data.published).length : 0;
|
|
32685
|
+
if (draftCount > 0 || pubCount > 0) {
|
|
32686
|
+
results.push(`\u8349\u7A3F: ${draftCount} \u7BC7, \u5DF2\u53D1\u5E03: ${pubCount} \u7BC7`);
|
|
32687
|
+
}
|
|
32688
|
+
await updateLastSyncAt();
|
|
32689
|
+
await log("INFO", "ink.sync", `pull completed: ${results.join(", ")}`);
|
|
32690
|
+
return {
|
|
32691
|
+
success: true,
|
|
32692
|
+
message: results.length > 0 ? `\u2705 \u540C\u6B65\u5B8C\u6210
|
|
32693
|
+
${results.join("\n")}` : "\u2705 \u540C\u6B65\u5B8C\u6210\uFF08\u4E91\u7AEF\u65E0\u65B0\u6570\u636E\uFF09"
|
|
32694
|
+
};
|
|
32695
|
+
} catch (err) {
|
|
32696
|
+
return { success: false, message: `\u540C\u6B65\u5931\u8D25: ${err instanceof Error ? err.message : err}` };
|
|
32697
|
+
}
|
|
32698
|
+
}
|
|
32699
|
+
async function syncPull(input) {
|
|
32700
|
+
if (input.workDir) setWorkDir(input.workDir);
|
|
32701
|
+
const creds = await getCredentials();
|
|
32702
|
+
if (!creds?.token) {
|
|
32703
|
+
return { success: false, message: "\u672A\u6FC0\u6D3B" };
|
|
32704
|
+
}
|
|
32705
|
+
return doPull(creds.token);
|
|
32706
|
+
}
|
|
32707
|
+
var syncSchema;
|
|
32708
|
+
var init_sync = __esm({
|
|
32709
|
+
"src/tools/sync.ts"() {
|
|
32710
|
+
"use strict";
|
|
32711
|
+
init_zod();
|
|
32712
|
+
init_state();
|
|
32713
|
+
init_knowledge();
|
|
32714
|
+
init_logger();
|
|
32715
|
+
syncSchema = external_exports.object({
|
|
32716
|
+
workDir: external_exports.string().optional().describe("\u5DE5\u4F5C\u76EE\u5F55\uFF08\u9ED8\u8BA4\u4F7F\u7528\u914D\u7F6E\u4E2D\u7684 workflowDir\uFF09")
|
|
32717
|
+
});
|
|
32718
|
+
}
|
|
32719
|
+
});
|
|
32720
|
+
|
|
32721
|
+
// src/tools/workflow.ts
|
|
32722
|
+
import { mkdir as mkdir5, access, unlink as unlink2 } from "fs/promises";
|
|
32723
|
+
import { join as join5 } from "path";
|
|
32724
|
+
async function workflowInit(input) {
|
|
32725
|
+
const cwd = input.workDir;
|
|
32726
|
+
const results = [];
|
|
32727
|
+
try {
|
|
32728
|
+
setWorkDir(cwd);
|
|
32729
|
+
const claudeinkDir = join5(cwd, ".claudeink");
|
|
32730
|
+
await mkdir5(join5(claudeinkDir, "knowledge"), { recursive: true });
|
|
32731
|
+
results.push("\u2705 \u77E5\u8BC6\u5E93\u76EE\u5F55\u5DF2\u521B\u5EFA");
|
|
32732
|
+
const state = await readState();
|
|
32733
|
+
state.config.workflowDir = cwd;
|
|
32734
|
+
const oldCredsPath = join5(claudeinkDir, "credentials.json");
|
|
32735
|
+
try {
|
|
32736
|
+
await access(oldCredsPath);
|
|
32737
|
+
await unlink2(oldCredsPath);
|
|
32738
|
+
results.push("\u{1F9F9} \u5DF2\u6E05\u7406\u65E7\u7248 credentials.json");
|
|
32739
|
+
} catch {
|
|
32740
|
+
}
|
|
32741
|
+
let activated = false;
|
|
32742
|
+
if (input.licenseKey) {
|
|
32743
|
+
try {
|
|
32744
|
+
const res = await fetch(`${DEFAULT_API_BASE_URL}/api/auth/activate`, {
|
|
32745
|
+
method: "POST",
|
|
32746
|
+
headers: { "Content-Type": "application/json" },
|
|
32747
|
+
body: JSON.stringify({ key: input.licenseKey })
|
|
32748
|
+
});
|
|
32749
|
+
const data = await res.json();
|
|
32750
|
+
if (data.userId) {
|
|
32751
|
+
state.credentials = {
|
|
32752
|
+
licenseKey: input.licenseKey,
|
|
32753
|
+
token: data.token,
|
|
32754
|
+
userId: data.userId,
|
|
32755
|
+
plan: data.plan,
|
|
32756
|
+
expiresAt: data.expiresAt
|
|
32757
|
+
};
|
|
32758
|
+
results.push(`\u2705 License \u6FC0\u6D3B\u6210\u529F\uFF08\u5957\u9910: ${data.plan}\uFF09`);
|
|
32759
|
+
activated = true;
|
|
32760
|
+
} else {
|
|
32761
|
+
results.push(`\u26A0\uFE0F License \u6FC0\u6D3B\u5931\u8D25: ${JSON.stringify(data)}`);
|
|
32762
|
+
}
|
|
32763
|
+
} catch (err) {
|
|
32764
|
+
results.push(`\u26A0\uFE0F \u6FC0\u6D3B\u7F51\u7EDC\u9519\u8BEF: ${err instanceof Error ? err.message : err}`);
|
|
32765
|
+
}
|
|
32766
|
+
}
|
|
32767
|
+
await writeState(state);
|
|
32768
|
+
results.push("\u2705 state.json");
|
|
32769
|
+
if (state.credentials?.token) {
|
|
32770
|
+
try {
|
|
32771
|
+
const pullResult = await syncPull({ workDir: cwd });
|
|
32772
|
+
if (pullResult.success) {
|
|
32773
|
+
results.push("\u2705 \u5DF2\u4ECE\u4E91\u7AEF\u540C\u6B65\u6570\u636E");
|
|
32774
|
+
} else {
|
|
32775
|
+
results.push("\u2139\uFE0F \u4E91\u7AEF\u65E0\u5DF2\u6709\u6570\u636E");
|
|
32776
|
+
}
|
|
32777
|
+
} catch {
|
|
32778
|
+
results.push("\u2139\uFE0F \u4E91\u7AEF\u540C\u6B65\u8DF3\u8FC7");
|
|
32779
|
+
}
|
|
32780
|
+
}
|
|
32781
|
+
return {
|
|
32782
|
+
success: true,
|
|
32783
|
+
message: [
|
|
32784
|
+
"\u{1F389} ClaudeInk \u77E5\u8BC6\u5E93\u521D\u59CB\u5316\u5B8C\u6210\uFF01",
|
|
32785
|
+
"",
|
|
32786
|
+
...results,
|
|
32787
|
+
"",
|
|
32788
|
+
"\u{1F3AF} \u4E0B\u4E00\u6B65\uFF1A",
|
|
32789
|
+
"1. \u5728\u5BF9\u8BDD\u4E2D\u8BF4\u300C\u5E2E\u6211\u5B58\u4E00\u4E0B\u300D\u4FDD\u5B58\u6709\u4EF7\u503C\u5185\u5BB9",
|
|
32790
|
+
"2. \u7528\u300C\u627E\u4E00\u4E0B\u5173\u4E8E XX \u7684\u300D\u68C0\u7D22\u77E5\u8BC6\u5E93"
|
|
32791
|
+
].join("\n")
|
|
32792
|
+
};
|
|
32793
|
+
} catch (err) {
|
|
32794
|
+
return {
|
|
32795
|
+
success: false,
|
|
32796
|
+
message: `\u521D\u59CB\u5316\u5931\u8D25: ${err instanceof Error ? err.message : err}`
|
|
32797
|
+
};
|
|
32798
|
+
}
|
|
32799
|
+
}
|
|
32800
|
+
var DEFAULT_API_BASE_URL, workflowInitSchema;
|
|
32801
|
+
var init_workflow = __esm({
|
|
32802
|
+
"src/tools/workflow.ts"() {
|
|
32803
|
+
"use strict";
|
|
32804
|
+
init_zod();
|
|
32805
|
+
init_state();
|
|
32806
|
+
init_sync();
|
|
32807
|
+
DEFAULT_API_BASE_URL = "https://app.claudeink.com";
|
|
32808
|
+
workflowInitSchema = external_exports.object({
|
|
32809
|
+
workDir: external_exports.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
|
|
32810
|
+
licenseKey: external_exports.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
|
|
32811
|
+
});
|
|
32812
|
+
}
|
|
32813
|
+
});
|
|
32814
|
+
|
|
32760
32815
|
// src/lib/push.ts
|
|
32761
32816
|
function fireAndForgetPush(payload) {
|
|
32762
32817
|
doPush(payload).catch(() => {
|
|
@@ -32797,107 +32852,92 @@ import { readFile as readFile3 } from "fs/promises";
|
|
|
32797
32852
|
import { extname } from "path";
|
|
32798
32853
|
async function inkSave(input) {
|
|
32799
32854
|
try {
|
|
32855
|
+
let localId;
|
|
32800
32856
|
if (input.id) {
|
|
32801
32857
|
const result = await updateKnowledgeFile(input.id, {
|
|
32802
32858
|
title: input.title,
|
|
32803
32859
|
content: input.content,
|
|
32804
32860
|
tags: input.tags,
|
|
32805
32861
|
category: input.category
|
|
32806
|
-
});
|
|
32862
|
+
}, "knowledge");
|
|
32807
32863
|
if (!result) {
|
|
32808
|
-
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\
|
|
32864
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u7D20\u6750` };
|
|
32809
32865
|
}
|
|
32810
|
-
|
|
32811
|
-
|
|
32812
|
-
|
|
32813
|
-
|
|
32814
|
-
tags: result.meta.tags,
|
|
32815
|
-
category: result.meta.category,
|
|
32816
|
-
source_type: result.meta.source_type,
|
|
32817
|
-
url: result.meta.url,
|
|
32818
|
-
created_at: result.meta.created_at,
|
|
32819
|
-
updated_at: result.meta.updated_at
|
|
32820
|
-
}]
|
|
32821
|
-
});
|
|
32822
|
-
await log("INFO", "ink.save", `updated id=${input.id} title="${input.title}"`);
|
|
32823
|
-
return {
|
|
32824
|
-
success: true,
|
|
32825
|
-
message: `\u5DF2\u66F4\u65B0\u300C${result.meta.title}\u300D`,
|
|
32826
|
-
data: { id: result.meta.id }
|
|
32827
|
-
};
|
|
32828
|
-
}
|
|
32829
|
-
const { id } = await saveKnowledge({
|
|
32830
|
-
content: input.content,
|
|
32831
|
-
title: input.title,
|
|
32832
|
-
tags: input.tags,
|
|
32833
|
-
category: input.category,
|
|
32834
|
-
source_type: input.source_type,
|
|
32835
|
-
url: input.url
|
|
32836
|
-
});
|
|
32837
|
-
fireAndForgetPush({
|
|
32838
|
-
knowledge: [{
|
|
32839
|
-
id,
|
|
32866
|
+
localId = input.id;
|
|
32867
|
+
} else {
|
|
32868
|
+
const { id } = await saveKnowledge({
|
|
32869
|
+
content: input.content,
|
|
32840
32870
|
title: input.title,
|
|
32841
32871
|
tags: input.tags,
|
|
32842
32872
|
category: input.category,
|
|
32843
32873
|
source_type: input.source_type,
|
|
32844
32874
|
url: input.url,
|
|
32845
|
-
|
|
32846
|
-
|
|
32847
|
-
|
|
32848
|
-
}
|
|
32849
|
-
|
|
32875
|
+
store: "knowledge"
|
|
32876
|
+
});
|
|
32877
|
+
localId = id;
|
|
32878
|
+
}
|
|
32879
|
+
const creds = await getCredentials();
|
|
32880
|
+
if (creds?.token) {
|
|
32881
|
+
const index = await readIndex("knowledge");
|
|
32882
|
+
fireAndForgetPush({
|
|
32883
|
+
knowledge: Object.values(index.entries).map((e) => ({
|
|
32884
|
+
id: e.id,
|
|
32885
|
+
title: e.title,
|
|
32886
|
+
tags: e.tags,
|
|
32887
|
+
category: e.category,
|
|
32888
|
+
source_type: e.source_type,
|
|
32889
|
+
created_at: e.created_at,
|
|
32890
|
+
updated_at: e.updated_at
|
|
32891
|
+
})),
|
|
32892
|
+
crawlerSources: []
|
|
32893
|
+
});
|
|
32894
|
+
}
|
|
32895
|
+
await log("INFO", "ink.save", `saved source id=${localId} title="${input.title}"`);
|
|
32850
32896
|
return {
|
|
32851
32897
|
success: true,
|
|
32852
|
-
message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D
|
|
32853
|
-
data: { id }
|
|
32898
|
+
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"),
|
|
32899
|
+
data: { id: localId }
|
|
32854
32900
|
};
|
|
32855
32901
|
} catch (err) {
|
|
32856
32902
|
await log("ERROR", "ink.save", `failed: ${err.message}`);
|
|
32857
|
-
return { success: false, message: `\u4FDD\u5B58\u5931\u8D25
|
|
32903
|
+
return { success: false, message: `\u4FDD\u5B58\u7D20\u6750\u5931\u8D25: ${err.message}` };
|
|
32858
32904
|
}
|
|
32859
32905
|
}
|
|
32860
|
-
async function
|
|
32906
|
+
async function inkWrite(input) {
|
|
32861
32907
|
try {
|
|
32862
|
-
|
|
32863
|
-
|
|
32864
|
-
const
|
|
32865
|
-
|
|
32866
|
-
|
|
32908
|
+
let localId;
|
|
32909
|
+
if (input.id) {
|
|
32910
|
+
const result = await updateKnowledgeFile(input.id, {
|
|
32911
|
+
title: input.title,
|
|
32912
|
+
content: input.content,
|
|
32913
|
+
tags: input.tags,
|
|
32914
|
+
category: input.category
|
|
32915
|
+
}, "drafts");
|
|
32916
|
+
if (!result) {
|
|
32917
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u8349\u7A3F` };
|
|
32867
32918
|
}
|
|
32919
|
+
localId = input.id;
|
|
32920
|
+
} else {
|
|
32921
|
+
const { id } = await saveKnowledge({
|
|
32922
|
+
content: input.content,
|
|
32923
|
+
title: input.title,
|
|
32924
|
+
tags: input.tags,
|
|
32925
|
+
category: input.category,
|
|
32926
|
+
source_type: "conversation",
|
|
32927
|
+
store: "drafts"
|
|
32928
|
+
});
|
|
32929
|
+
localId = id;
|
|
32930
|
+
}
|
|
32931
|
+
const creds = await getCredentials();
|
|
32932
|
+
if (!creds?.token) {
|
|
32933
|
+
await log("INFO", "ink.write", `saved draft locally id=${localId} title="${input.title}" (no cloud auth)`);
|
|
32868
32934
|
return {
|
|
32869
|
-
success:
|
|
32870
|
-
message: `\
|
|
32871
|
-
data: { id:
|
|
32935
|
+
success: true,
|
|
32936
|
+
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`,
|
|
32937
|
+
data: { id: localId }
|
|
32872
32938
|
};
|
|
32873
32939
|
}
|
|
32874
|
-
const
|
|
32875
|
-
if (!deleted) {
|
|
32876
|
-
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
32877
|
-
}
|
|
32878
|
-
fireAndForgetPush({
|
|
32879
|
-
knowledge: [{
|
|
32880
|
-
id: input.id,
|
|
32881
|
-
title: "",
|
|
32882
|
-
tags: [],
|
|
32883
|
-
category: "reference",
|
|
32884
|
-
source_type: "conversation",
|
|
32885
|
-
created_at: "",
|
|
32886
|
-
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
32887
|
-
}]
|
|
32888
|
-
});
|
|
32889
|
-
await log("INFO", "ink.delete", `deleted id=${input.id}`);
|
|
32890
|
-
return { success: true, message: `\u5DF2\u5220\u9664\u77E5\u8BC6\u7247\u6BB5 ${input.id}`, data: { id: input.id } };
|
|
32891
|
-
} catch (err) {
|
|
32892
|
-
await log("ERROR", "ink.delete", `failed: ${err.message}`);
|
|
32893
|
-
return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
|
|
32894
|
-
}
|
|
32895
|
-
}
|
|
32896
|
-
async function inkWrite(input) {
|
|
32897
|
-
const creds = await getCredentials();
|
|
32898
|
-
if (!creds?.token) return { success: false, message: "\u672A\u8BA4\u8BC1\uFF0C\u8BF7\u5148\u8FD0\u884C ink.init" };
|
|
32899
|
-
const config2 = await getConfig();
|
|
32900
|
-
try {
|
|
32940
|
+
const config2 = await getConfig();
|
|
32901
32941
|
let coverUrl = input.cover || null;
|
|
32902
32942
|
if (coverUrl) {
|
|
32903
32943
|
if (coverUrl.startsWith("http://") || coverUrl.startsWith("https://")) {
|
|
@@ -32915,43 +32955,103 @@ async function inkWrite(input) {
|
|
|
32915
32955
|
}
|
|
32916
32956
|
const slug = `${Date.now().toString(36)}-${input.title.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-").replace(/^-|-$/g, "").slice(0, 60)}`;
|
|
32917
32957
|
const excerpt = input.excerpt || input.content.replace(/^#+\s.+$/gm, "").replace(/\n+/g, " ").trim().slice(0, 200);
|
|
32918
|
-
|
|
32919
|
-
|
|
32920
|
-
|
|
32921
|
-
|
|
32922
|
-
|
|
32923
|
-
|
|
32924
|
-
|
|
32925
|
-
|
|
32926
|
-
|
|
32927
|
-
|
|
32928
|
-
|
|
32929
|
-
|
|
32930
|
-
|
|
32931
|
-
|
|
32932
|
-
|
|
32933
|
-
|
|
32934
|
-
|
|
32935
|
-
|
|
32936
|
-
|
|
32937
|
-
|
|
32938
|
-
|
|
32958
|
+
try {
|
|
32959
|
+
const controller = new AbortController();
|
|
32960
|
+
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
32961
|
+
const res = await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
|
|
32962
|
+
method: "POST",
|
|
32963
|
+
signal: controller.signal,
|
|
32964
|
+
headers: {
|
|
32965
|
+
"Content-Type": "application/json",
|
|
32966
|
+
Authorization: `Bearer ${creds.token}`
|
|
32967
|
+
},
|
|
32968
|
+
body: JSON.stringify({
|
|
32969
|
+
title: input.title,
|
|
32970
|
+
slug,
|
|
32971
|
+
content: input.content,
|
|
32972
|
+
cover_url: coverUrl,
|
|
32973
|
+
tags: input.tags,
|
|
32974
|
+
category: input.category,
|
|
32975
|
+
excerpt,
|
|
32976
|
+
source_type: "conversation",
|
|
32977
|
+
source_ids: input.source_ids,
|
|
32978
|
+
local_id: localId
|
|
32979
|
+
})
|
|
32980
|
+
});
|
|
32981
|
+
clearTimeout(timeout);
|
|
32982
|
+
if (!res.ok) {
|
|
32983
|
+
const err = await res.text();
|
|
32984
|
+
await log("ERROR", "ink.write", `cloud save failed: ${err}`);
|
|
32985
|
+
return {
|
|
32986
|
+
success: true,
|
|
32987
|
+
message: `\u5DF2\u4FDD\u5B58\u8349\u7A3F\u300C${input.title}\u300D\u5230\u672C\u5730\uFF0C\u4F46\u4E91\u7AEF\u540C\u6B65\u5931\u8D25: ${err}`,
|
|
32988
|
+
data: { id: localId }
|
|
32989
|
+
};
|
|
32990
|
+
}
|
|
32991
|
+
const data = await res.json();
|
|
32992
|
+
await log("INFO", "ink.write", `saved draft id=${localId} cloud_id=${data.id} title="${input.title}"`);
|
|
32993
|
+
return {
|
|
32994
|
+
success: true,
|
|
32995
|
+
message: `\u5DF2\u4FDD\u5B58\u8349\u7A3F\u300C${input.title}\u300D\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09`,
|
|
32996
|
+
data: { id: localId, cloud_id: data.id, slug: data.slug, status: data.status }
|
|
32997
|
+
};
|
|
32998
|
+
} catch (cloudErr) {
|
|
32999
|
+
await log("WARN", "ink.write", `cloud upload failed (local saved): ${cloudErr.message}`);
|
|
33000
|
+
return {
|
|
33001
|
+
success: true,
|
|
33002
|
+
message: `\u5DF2\u4FDD\u5B58\u8349\u7A3F\u300C${input.title}\u300D\u5230\u672C\u5730\uFF0C\u4F46\u4E91\u7AEF\u540C\u6B65\u5931\u8D25: ${cloudErr.message}`,
|
|
33003
|
+
data: { id: localId }
|
|
33004
|
+
};
|
|
32939
33005
|
}
|
|
32940
|
-
const data = await res.json();
|
|
32941
|
-
await log("INFO", "ink.write", `saved article="${input.title}" id=${data.id} slug=${data.slug}`);
|
|
32942
|
-
return {
|
|
32943
|
-
success: true,
|
|
32944
|
-
message: `\u6587\u7AE0\u300C${input.title}\u300D\u5DF2\u4FDD\u5B58\u4E3A\u8349\u7A3F\uFF0C\u8BF7\u5230 Dashboard \u53D1\u5E03`,
|
|
32945
|
-
data: { id: data.id, slug: data.slug, status: data.status }
|
|
32946
|
-
};
|
|
32947
33006
|
} catch (err) {
|
|
32948
33007
|
await log("ERROR", "ink.write", `failed: ${err.message}`);
|
|
32949
|
-
return { success: false, message: `\
|
|
33008
|
+
return { success: false, message: `\u4FDD\u5B58\u8349\u7A3F\u5931\u8D25: ${err.message}` };
|
|
33009
|
+
}
|
|
33010
|
+
}
|
|
33011
|
+
async function inkDelete(input) {
|
|
33012
|
+
try {
|
|
33013
|
+
const store = input.store;
|
|
33014
|
+
if (!input.confirm) {
|
|
33015
|
+
const index = await readIndex(store);
|
|
33016
|
+
const entry = index.entries[input.id];
|
|
33017
|
+
if (!entry) {
|
|
33018
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
|
|
33019
|
+
}
|
|
33020
|
+
return {
|
|
33021
|
+
success: false,
|
|
33022
|
+
message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
|
|
33023
|
+
data: { id: entry.id, title: entry.title, store, category: entry.category, tags: entry.tags }
|
|
33024
|
+
};
|
|
33025
|
+
}
|
|
33026
|
+
const deleted = await deleteKnowledgeFile(input.id, store);
|
|
33027
|
+
if (!deleted) {
|
|
33028
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u6761\u76EE` };
|
|
33029
|
+
}
|
|
33030
|
+
try {
|
|
33031
|
+
const creds = await getCredentials();
|
|
33032
|
+
if (creds?.token) {
|
|
33033
|
+
const config2 = await getConfig();
|
|
33034
|
+
await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
|
|
33035
|
+
method: "DELETE",
|
|
33036
|
+
headers: {
|
|
33037
|
+
"Content-Type": "application/json",
|
|
33038
|
+
Authorization: `Bearer ${creds.token}`
|
|
33039
|
+
},
|
|
33040
|
+
body: JSON.stringify({ local_id: input.id })
|
|
33041
|
+
});
|
|
33042
|
+
}
|
|
33043
|
+
} catch {
|
|
33044
|
+
}
|
|
33045
|
+
await log("INFO", "ink.delete", `deleted id=${input.id} store=${store}`);
|
|
33046
|
+
return { success: true, message: `\u5DF2\u5220\u9664 ${input.id}`, data: { id: input.id } };
|
|
33047
|
+
} catch (err) {
|
|
33048
|
+
await log("ERROR", "ink.delete", `failed: ${err.message}`);
|
|
33049
|
+
return { success: false, message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}` };
|
|
32950
33050
|
}
|
|
32951
33051
|
}
|
|
32952
33052
|
async function inkTags(input) {
|
|
32953
33053
|
try {
|
|
32954
|
-
const index = await readIndex();
|
|
33054
|
+
const index = await readIndex("knowledge");
|
|
32955
33055
|
switch (input.action) {
|
|
32956
33056
|
case "list": {
|
|
32957
33057
|
const tags = getAllTags(index);
|
|
@@ -32965,14 +33065,14 @@ async function inkTags(input) {
|
|
|
32965
33065
|
if (!input.tag || !input.new_tag) {
|
|
32966
33066
|
return { success: false, message: "rename \u9700\u8981 tag\uFF08\u539F\u6807\u7B7E\uFF09\u548C new_tag\uFF08\u65B0\u6807\u7B7E\u540D\uFF09" };
|
|
32967
33067
|
}
|
|
32968
|
-
const count = await renameTag(input.tag, input.new_tag);
|
|
33068
|
+
const count = await renameTag(input.tag, input.new_tag, "knowledge");
|
|
32969
33069
|
if (count === 0) {
|
|
32970
|
-
return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\
|
|
33070
|
+
return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u6761\u76EE` };
|
|
32971
33071
|
}
|
|
32972
33072
|
await log("INFO", "ink.tags", `renamed "${input.tag}" \u2192 "${input.new_tag}", affected=${count}`);
|
|
32973
33073
|
return {
|
|
32974
33074
|
success: true,
|
|
32975
|
-
message: `\u5DF2\u5C06 ${count} \u6761\
|
|
33075
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
|
|
32976
33076
|
data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
|
|
32977
33077
|
};
|
|
32978
33078
|
}
|
|
@@ -32980,14 +33080,14 @@ async function inkTags(input) {
|
|
|
32980
33080
|
if (!input.source_tags || input.source_tags.length === 0 || !input.new_tag) {
|
|
32981
33081
|
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" };
|
|
32982
33082
|
}
|
|
32983
|
-
const count = await mergeTags(input.source_tags, input.new_tag);
|
|
33083
|
+
const count = await mergeTags(input.source_tags, input.new_tag, "knowledge");
|
|
32984
33084
|
if (count === 0) {
|
|
32985
|
-
return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\
|
|
33085
|
+
return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u6761\u76EE" };
|
|
32986
33086
|
}
|
|
32987
33087
|
await log("INFO", "ink.tags", `merged [${input.source_tags.join(",")}] \u2192 "${input.new_tag}", affected=${count}`);
|
|
32988
33088
|
return {
|
|
32989
33089
|
success: true,
|
|
32990
|
-
message: `\u5DF2\u5C06 ${count} \u6761\
|
|
33090
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
|
|
32991
33091
|
data: { source_tags: input.source_tags, target_tag: input.new_tag, affected: count }
|
|
32992
33092
|
};
|
|
32993
33093
|
}
|
|
@@ -33052,36 +33152,38 @@ async function uploadImageFromUrl(imageUrl, type, token, apiBase) {
|
|
|
33052
33152
|
return { success: false, error: err.message };
|
|
33053
33153
|
}
|
|
33054
33154
|
}
|
|
33055
|
-
var inkSaveSchema,
|
|
33155
|
+
var inkSaveSchema, inkWriteSchema, inkDeleteSchema, inkTagsSchema;
|
|
33056
33156
|
var init_ink = __esm({
|
|
33057
33157
|
"src/tools/ink.ts"() {
|
|
33058
33158
|
"use strict";
|
|
33059
33159
|
init_zod();
|
|
33060
33160
|
init_knowledge();
|
|
33061
|
-
init_push();
|
|
33062
33161
|
init_state();
|
|
33162
|
+
init_push();
|
|
33063
33163
|
init_logger();
|
|
33064
33164
|
inkSaveSchema = external_exports.object({
|
|
33065
|
-
id: external_exports.string().optional().describe("\
|
|
33066
|
-
|
|
33067
|
-
|
|
33165
|
+
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"),
|
|
33166
|
+
title: external_exports.string().describe("\u7D20\u6750\u6807\u9898"),
|
|
33167
|
+
content: external_exports.string().describe("Markdown \u5168\u6587"),
|
|
33068
33168
|
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
|
|
33069
33169
|
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
|
|
33070
33170
|
source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B"),
|
|
33071
33171
|
url: external_exports.string().optional().describe("\u6765\u6E90 URL")
|
|
33072
33172
|
});
|
|
33073
|
-
inkDeleteSchema = external_exports.object({
|
|
33074
|
-
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
|
|
33075
|
-
confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
|
|
33076
|
-
});
|
|
33077
33173
|
inkWriteSchema = external_exports.object({
|
|
33174
|
+
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"),
|
|
33078
33175
|
title: external_exports.string().describe("\u6587\u7AE0\u6807\u9898"),
|
|
33079
33176
|
content: external_exports.string().describe("Markdown \u5168\u6587"),
|
|
33177
|
+
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
|
|
33178
|
+
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
|
|
33080
33179
|
cover: external_exports.string().optional().describe("\u5C01\u9762\u56FE\uFF08\u672C\u5730\u8DEF\u5F84\u6216 URL\uFF0C\u81EA\u52A8\u4E0A\u4F20\uFF09"),
|
|
33081
|
-
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6587\u7AE0\u6807\u7B7E"),
|
|
33082
|
-
category: external_exports.string().optional().describe("\u6587\u7AE0\u5206\u7C7B"),
|
|
33083
33180
|
excerpt: external_exports.string().optional().describe("\u6458\u8981\uFF08\u4E0D\u586B\u81EA\u52A8\u622A\u53D6\u524D 200 \u5B57\uFF09"),
|
|
33084
|
-
source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750
|
|
33181
|
+
source_ids: external_exports.array(external_exports.string()).optional().describe("\u5173\u8054\u7684\u7D20\u6750 ID\uFF08\u6EAF\u6E90\uFF09")
|
|
33182
|
+
});
|
|
33183
|
+
inkDeleteSchema = external_exports.object({
|
|
33184
|
+
id: external_exports.string().describe("\u6761\u76EE ID"),
|
|
33185
|
+
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"),
|
|
33186
|
+
confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
|
|
33085
33187
|
});
|
|
33086
33188
|
inkTagsSchema = external_exports.object({
|
|
33087
33189
|
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"),
|
|
@@ -33094,13 +33196,13 @@ var init_ink = __esm({
|
|
|
33094
33196
|
|
|
33095
33197
|
// src/tools/source.ts
|
|
33096
33198
|
import { readFile as readFile4 } from "fs/promises";
|
|
33097
|
-
import { join as
|
|
33199
|
+
import { join as join6 } from "path";
|
|
33098
33200
|
import { readdirSync as readdirSync2 } from "fs";
|
|
33099
33201
|
import { execSync } from "child_process";
|
|
33100
33202
|
async function sourceCrawl(input) {
|
|
33101
33203
|
const config2 = await getConfig();
|
|
33102
|
-
const crawlerDir =
|
|
33103
|
-
const configPath =
|
|
33204
|
+
const crawlerDir = join6(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
33205
|
+
const configPath = join6(crawlerDir, "config.json");
|
|
33104
33206
|
let crawlerConfig;
|
|
33105
33207
|
try {
|
|
33106
33208
|
crawlerConfig = JSON.parse(await readFile4(configPath, "utf-8"));
|
|
@@ -33117,7 +33219,7 @@ async function sourceCrawl(input) {
|
|
|
33117
33219
|
message: input.sourceId ? `\u672A\u627E\u5230\u722C\u866B\u6E90: ${input.sourceId}` : "\u6CA1\u6709\u5DF2\u542F\u7528\u7684\u722C\u866B\u6E90"
|
|
33118
33220
|
};
|
|
33119
33221
|
}
|
|
33120
|
-
const crawlScript =
|
|
33222
|
+
const crawlScript = join6(crawlerDir, "crawl.mjs");
|
|
33121
33223
|
const args2 = input.sourceId ? `--source ${input.sourceId}` : "";
|
|
33122
33224
|
try {
|
|
33123
33225
|
execSync(`node "${crawlScript}" ${args2}`, {
|
|
@@ -33129,7 +33231,7 @@ async function sourceCrawl(input) {
|
|
|
33129
33231
|
let saved = 0;
|
|
33130
33232
|
let queued = 0;
|
|
33131
33233
|
for (const target of targets) {
|
|
33132
|
-
const sourceDir =
|
|
33234
|
+
const sourceDir = join6(config2.workflowDir, "sources", "articles", target.id);
|
|
33133
33235
|
let files;
|
|
33134
33236
|
try {
|
|
33135
33237
|
files = readdirSync2(sourceDir).filter((f) => f.endsWith(".md"));
|
|
@@ -33137,7 +33239,7 @@ async function sourceCrawl(input) {
|
|
|
33137
33239
|
continue;
|
|
33138
33240
|
}
|
|
33139
33241
|
for (const f of files) {
|
|
33140
|
-
const filePath =
|
|
33242
|
+
const filePath = join6(sourceDir, f);
|
|
33141
33243
|
try {
|
|
33142
33244
|
const raw = await readFile4(filePath, "utf-8");
|
|
33143
33245
|
const { data, content } = (0, import_gray_matter2.default)(raw);
|
|
@@ -33212,8 +33314,8 @@ var init_source = __esm({
|
|
|
33212
33314
|
});
|
|
33213
33315
|
|
|
33214
33316
|
// src/tools/subscribe.ts
|
|
33215
|
-
import { readFile as readFile5, writeFile as
|
|
33216
|
-
import { join as
|
|
33317
|
+
import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir6 } from "fs/promises";
|
|
33318
|
+
import { join as join7 } from "path";
|
|
33217
33319
|
async function readCrawlerConfig(configPath) {
|
|
33218
33320
|
try {
|
|
33219
33321
|
return JSON.parse(await readFile5(configPath, "utf-8"));
|
|
@@ -33223,9 +33325,9 @@ async function readCrawlerConfig(configPath) {
|
|
|
33223
33325
|
}
|
|
33224
33326
|
async function sourceSubscribe(input) {
|
|
33225
33327
|
const config2 = await getConfig();
|
|
33226
|
-
const crawlerDir =
|
|
33227
|
-
await
|
|
33228
|
-
const configPath =
|
|
33328
|
+
const crawlerDir = join7(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
33329
|
+
await mkdir6(crawlerDir, { recursive: true });
|
|
33330
|
+
const configPath = join7(crawlerDir, "config.json");
|
|
33229
33331
|
const crawlerConfig = await readCrawlerConfig(configPath);
|
|
33230
33332
|
if (input.action === "list") {
|
|
33231
33333
|
return {
|
|
@@ -33257,7 +33359,7 @@ async function sourceSubscribe(input) {
|
|
|
33257
33359
|
if (input.crawlConfig.maxArticles) newSource.maxArticles = input.crawlConfig.maxArticles;
|
|
33258
33360
|
}
|
|
33259
33361
|
crawlerConfig.sources.push(newSource);
|
|
33260
|
-
await
|
|
33362
|
+
await writeFile4(configPath, JSON.stringify(crawlerConfig, null, 2));
|
|
33261
33363
|
fireAndForgetPush({
|
|
33262
33364
|
crawlerSources: crawlerConfig.sources.map((s) => ({
|
|
33263
33365
|
id: s.id,
|
|
@@ -33275,7 +33377,7 @@ async function sourceSubscribe(input) {
|
|
|
33275
33377
|
return { success: false, message: "\u5220\u9664\u8BA2\u9605\u6E90\u9700\u8981 id \u53C2\u6570" };
|
|
33276
33378
|
}
|
|
33277
33379
|
crawlerConfig.sources = crawlerConfig.sources.filter((s) => s.id !== input.id);
|
|
33278
|
-
await
|
|
33380
|
+
await writeFile4(configPath, JSON.stringify(crawlerConfig, null, 2));
|
|
33279
33381
|
fireAndForgetPush({
|
|
33280
33382
|
crawlerSources: crawlerConfig.sources.map((s) => ({
|
|
33281
33383
|
id: s.id,
|
|
@@ -33332,7 +33434,7 @@ async function main() {
|
|
|
33332
33434
|
}
|
|
33333
33435
|
const transport = new StdioServerTransport();
|
|
33334
33436
|
await server.connect(transport);
|
|
33335
|
-
await log("INFO", "server", "started (
|
|
33437
|
+
await log("INFO", "server", "started (7 tools)");
|
|
33336
33438
|
}
|
|
33337
33439
|
var server;
|
|
33338
33440
|
var init_index = __esm({
|
|
@@ -33349,7 +33451,7 @@ var init_index = __esm({
|
|
|
33349
33451
|
init_logger();
|
|
33350
33452
|
server = new McpServer({
|
|
33351
33453
|
name: "ClaudeInk",
|
|
33352
|
-
version: "2.0
|
|
33454
|
+
version: "2.2.0"
|
|
33353
33455
|
});
|
|
33354
33456
|
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) => {
|
|
33355
33457
|
const result = await workflowInit(input);
|
|
@@ -33359,23 +33461,23 @@ var init_index = __esm({
|
|
|
33359
33461
|
const result = await sync2(input);
|
|
33360
33462
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33361
33463
|
});
|
|
33362
|
-
server.tool("ink.save", "\
|
|
33464
|
+
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) => {
|
|
33363
33465
|
const result = await inkSave(input);
|
|
33364
33466
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33365
33467
|
});
|
|
33366
|
-
server.tool("ink.
|
|
33367
|
-
const result = await
|
|
33468
|
+
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) => {
|
|
33469
|
+
const result = await inkWrite(input);
|
|
33368
33470
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33369
33471
|
});
|
|
33370
|
-
server.tool("ink.
|
|
33371
|
-
const result = await
|
|
33472
|
+
server.tool("ink.delete", "\u5220\u9664\u6761\u76EE\uFF08\u672C\u5730 + \u4E91\u7AEF\uFF09", inkDeleteSchema.shape, async (input) => {
|
|
33473
|
+
const result = await inkDelete(input);
|
|
33372
33474
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33373
33475
|
});
|
|
33374
33476
|
server.tool("ink.tags", "\u6807\u7B7E\u7BA1\u7406\uFF08\u5217\u51FA / \u91CD\u547D\u540D / \u5408\u5E76\u6807\u7B7E\uFF09", inkTagsSchema.shape, async (input) => {
|
|
33375
33477
|
const result = await inkTags(input);
|
|
33376
33478
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33377
33479
|
});
|
|
33378
|
-
server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\
|
|
33480
|
+
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) => {
|
|
33379
33481
|
const result = await sourceCrawl(input);
|
|
33380
33482
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33381
33483
|
});
|
|
@@ -33394,14 +33496,14 @@ var init_index = __esm({
|
|
|
33394
33496
|
});
|
|
33395
33497
|
|
|
33396
33498
|
// src/cli.ts
|
|
33397
|
-
import { writeFile as
|
|
33398
|
-
import { join as
|
|
33499
|
+
import { writeFile as writeFile5, readFile as readFile6, mkdir as mkdir7, cp, access as access2 } from "fs/promises";
|
|
33500
|
+
import { join as join8, dirname } from "path";
|
|
33399
33501
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
33400
33502
|
var args = process.argv.slice(2);
|
|
33401
33503
|
var command = args[0];
|
|
33402
33504
|
var __filename = fileURLToPath3(import.meta.url);
|
|
33403
33505
|
var __dirname = dirname(__filename);
|
|
33404
|
-
var WORKFLOW_SRC =
|
|
33506
|
+
var WORKFLOW_SRC = join8(__dirname, "..", "workflow");
|
|
33405
33507
|
async function init() {
|
|
33406
33508
|
const keyIdx = args.indexOf("--key");
|
|
33407
33509
|
const key = keyIdx >= 0 ? args[keyIdx + 1] : void 0;
|
|
@@ -33417,8 +33519,8 @@ async function init() {
|
|
|
33417
33519
|
console.log("\u{1F4E6} \u91CA\u653E\u5DE5\u4F5C\u6D41\u6A21\u677F...");
|
|
33418
33520
|
const items = ["CLAUDE.md", "base-rules.md", "platforms", "accounts", "tools"];
|
|
33419
33521
|
for (const item of items) {
|
|
33420
|
-
const src =
|
|
33421
|
-
const dest =
|
|
33522
|
+
const src = join8(WORKFLOW_SRC, item);
|
|
33523
|
+
const dest = join8(cwd, item);
|
|
33422
33524
|
try {
|
|
33423
33525
|
await access2(dest);
|
|
33424
33526
|
console.log(` \u23ED\uFE0F ${item} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7`);
|
|
@@ -33438,14 +33540,14 @@ async function init() {
|
|
|
33438
33540
|
".claudeink"
|
|
33439
33541
|
];
|
|
33440
33542
|
for (const dir of dirs) {
|
|
33441
|
-
await
|
|
33543
|
+
await mkdir7(join8(cwd, dir), { recursive: true });
|
|
33442
33544
|
}
|
|
33443
33545
|
console.log(" \u2705 sources/, templates/, .claudeink/");
|
|
33444
33546
|
const { glob: glob2 } = await Promise.resolve().then(() => (init_esm5(), esm_exports));
|
|
33445
33547
|
const yamlFiles = await glob2("accounts/*.yaml", { cwd, ignore: "accounts/_template.yaml" });
|
|
33446
33548
|
for (const yamlFile of yamlFiles) {
|
|
33447
33549
|
try {
|
|
33448
|
-
const content = await readFile6(
|
|
33550
|
+
const content = await readFile6(join8(cwd, yamlFile), "utf-8");
|
|
33449
33551
|
const idMatch = content.match(/^id:\s*"?([^"\n]+)"?/m);
|
|
33450
33552
|
if (idMatch) {
|
|
33451
33553
|
const id = idMatch[1].trim();
|
|
@@ -33455,9 +33557,9 @@ async function init() {
|
|
|
33455
33557
|
const drafts = (draftsMatch?.[1] || `accounts/${id}/drafts/`).replace("{id}", id).trim();
|
|
33456
33558
|
const published = (publishedMatch?.[1] || `accounts/${id}/published/`).replace("{id}", id).trim();
|
|
33457
33559
|
const assets = (assetsMatch?.[1] || `accounts/${id}/assets/`).replace("{id}", id).trim();
|
|
33458
|
-
await
|
|
33459
|
-
await
|
|
33460
|
-
await
|
|
33560
|
+
await mkdir7(join8(cwd, drafts), { recursive: true });
|
|
33561
|
+
await mkdir7(join8(cwd, published), { recursive: true });
|
|
33562
|
+
await mkdir7(join8(cwd, assets), { recursive: true });
|
|
33461
33563
|
console.log(` \u2705 \u8D26\u53F7 ${id}: ${drafts}, ${published}, ${assets}`);
|
|
33462
33564
|
}
|
|
33463
33565
|
} catch {
|
|
@@ -33472,8 +33574,8 @@ async function init() {
|
|
|
33472
33574
|
});
|
|
33473
33575
|
const data = await res.json();
|
|
33474
33576
|
if (data.userId) {
|
|
33475
|
-
await
|
|
33476
|
-
|
|
33577
|
+
await writeFile5(
|
|
33578
|
+
join8(cwd, ".claudeink", "credentials.json"),
|
|
33477
33579
|
JSON.stringify(data, null, 2),
|
|
33478
33580
|
{ mode: 384 }
|
|
33479
33581
|
);
|
|
@@ -33487,11 +33589,11 @@ async function init() {
|
|
|
33487
33589
|
console.log(" \u53EF\u7A0D\u540E\u624B\u52A8\u6FC0\u6D3B\u3002");
|
|
33488
33590
|
}
|
|
33489
33591
|
try {
|
|
33490
|
-
await access2(
|
|
33592
|
+
await access2(join8(cwd, "tools", "crawler", "package.json"));
|
|
33491
33593
|
console.log("\n\u{1F4E6} \u5B89\u88C5\u722C\u866B\u4F9D\u8D56...");
|
|
33492
33594
|
const { execSync: execSync2 } = await import("child_process");
|
|
33493
33595
|
execSync2("npm install --silent", {
|
|
33494
|
-
cwd:
|
|
33596
|
+
cwd: join8(cwd, "tools", "crawler"),
|
|
33495
33597
|
stdio: "pipe"
|
|
33496
33598
|
});
|
|
33497
33599
|
console.log(" \u2705 \u722C\u866B\u4F9D\u8D56\u5DF2\u5B89\u88C5");
|