@claudeink/mcp-server 1.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +728 -940
- package/dist/index.js +523 -745
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -24510,11 +24510,11 @@ var require_core = __commonJS({
|
|
|
24510
24510
|
Ajv2.ValidationError = validation_error_1.default;
|
|
24511
24511
|
Ajv2.MissingRefError = ref_error_1.default;
|
|
24512
24512
|
exports2.default = Ajv2;
|
|
24513
|
-
function checkOptions(checkOpts, options2, msg,
|
|
24513
|
+
function checkOptions(checkOpts, options2, msg, log2 = "error") {
|
|
24514
24514
|
for (const key in checkOpts) {
|
|
24515
24515
|
const opt = key;
|
|
24516
24516
|
if (opt in options2)
|
|
24517
|
-
this.logger[
|
|
24517
|
+
this.logger[log2](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
24518
24518
|
}
|
|
24519
24519
|
}
|
|
24520
24520
|
function getSchEnv(keyRef) {
|
|
@@ -27350,8 +27350,8 @@ var init_server2 = __esm({
|
|
|
27350
27350
|
this._loggingLevels = /* @__PURE__ */ new Map();
|
|
27351
27351
|
this.LOG_LEVEL_SEVERITY = new Map(LoggingLevelSchema.options.map((level, index) => [level, index]));
|
|
27352
27352
|
this.isMessageIgnored = (level, sessionId) => {
|
|
27353
|
-
const
|
|
27354
|
-
return
|
|
27353
|
+
const currentLevel2 = this._loggingLevels.get(sessionId);
|
|
27354
|
+
return currentLevel2 ? this.LOG_LEVEL_SEVERITY.get(level) < this.LOG_LEVEL_SEVERITY.get(currentLevel2) : false;
|
|
27355
27355
|
};
|
|
27356
27356
|
this._capabilities = options2?.capabilities ?? {};
|
|
27357
27357
|
this._instructions = options2?.instructions;
|
|
@@ -28746,6 +28746,281 @@ var init_stdio2 = __esm({
|
|
|
28746
28746
|
}
|
|
28747
28747
|
});
|
|
28748
28748
|
|
|
28749
|
+
// src/lib/state.ts
|
|
28750
|
+
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
28751
|
+
import { join } from "path";
|
|
28752
|
+
function setWorkDir(dir) {
|
|
28753
|
+
_workDirCache = dir;
|
|
28754
|
+
}
|
|
28755
|
+
function getWorkDir() {
|
|
28756
|
+
return _workDirCache || process.env.CLAUDEINK_WORK_DIR || process.cwd();
|
|
28757
|
+
}
|
|
28758
|
+
function getClaudeinkDir() {
|
|
28759
|
+
return join(getWorkDir(), ".claudeink");
|
|
28760
|
+
}
|
|
28761
|
+
function getStatePath() {
|
|
28762
|
+
return join(getClaudeinkDir(), "state.json");
|
|
28763
|
+
}
|
|
28764
|
+
async function ensureDir() {
|
|
28765
|
+
await mkdir(getClaudeinkDir(), { recursive: true });
|
|
28766
|
+
}
|
|
28767
|
+
async function readState() {
|
|
28768
|
+
const statePath = getStatePath();
|
|
28769
|
+
let raw;
|
|
28770
|
+
try {
|
|
28771
|
+
raw = await readFile(statePath, "utf-8");
|
|
28772
|
+
} catch {
|
|
28773
|
+
const state = { ...DEFAULT_STATE };
|
|
28774
|
+
state.config.workflowDir = getWorkDir();
|
|
28775
|
+
return state;
|
|
28776
|
+
}
|
|
28777
|
+
try {
|
|
28778
|
+
const parsed = JSON.parse(raw);
|
|
28779
|
+
const state = {
|
|
28780
|
+
credentials: parsed.credentials ?? null,
|
|
28781
|
+
config: { ...DEFAULT_STATE.config, ...parsed.config },
|
|
28782
|
+
tagQueue: parsed.tagQueue ?? { ...DEFAULT_STATE.tagQueue },
|
|
28783
|
+
lastSyncAt: parsed.lastSyncAt ?? ""
|
|
28784
|
+
};
|
|
28785
|
+
state.config.workflowDir = getWorkDir();
|
|
28786
|
+
return state;
|
|
28787
|
+
} catch {
|
|
28788
|
+
const backupPath = statePath + ".corrupted." + Date.now();
|
|
28789
|
+
try {
|
|
28790
|
+
await writeFile(backupPath, raw, "utf-8");
|
|
28791
|
+
} catch {
|
|
28792
|
+
}
|
|
28793
|
+
console.error(`[ClaudeInk] state.json corrupted, backed up to ${backupPath}`);
|
|
28794
|
+
const state = { ...DEFAULT_STATE };
|
|
28795
|
+
state.config.workflowDir = getWorkDir();
|
|
28796
|
+
return state;
|
|
28797
|
+
}
|
|
28798
|
+
}
|
|
28799
|
+
async function writeState(state) {
|
|
28800
|
+
await ensureDir();
|
|
28801
|
+
await writeFile(getStatePath(), JSON.stringify(state, null, 2), "utf-8");
|
|
28802
|
+
await chmod(getStatePath(), 384);
|
|
28803
|
+
}
|
|
28804
|
+
async function getCredentials() {
|
|
28805
|
+
const state = await readState();
|
|
28806
|
+
if (!state.credentials) return null;
|
|
28807
|
+
return {
|
|
28808
|
+
licenseKey: state.credentials.licenseKey,
|
|
28809
|
+
token: state.credentials.token,
|
|
28810
|
+
userId: state.credentials.userId,
|
|
28811
|
+
plan: state.credentials.plan,
|
|
28812
|
+
expiresAt: state.credentials.expiresAt
|
|
28813
|
+
};
|
|
28814
|
+
}
|
|
28815
|
+
async function getConfig() {
|
|
28816
|
+
const state = await readState();
|
|
28817
|
+
return state.config;
|
|
28818
|
+
}
|
|
28819
|
+
async function updateLastSyncAt() {
|
|
28820
|
+
const state = await readState();
|
|
28821
|
+
state.lastSyncAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
28822
|
+
await writeState(state);
|
|
28823
|
+
}
|
|
28824
|
+
async function addToTagQueue(item) {
|
|
28825
|
+
const state = await readState();
|
|
28826
|
+
if (state.tagQueue.queue.some((q) => q.knowledgeId === item.knowledgeId)) return;
|
|
28827
|
+
state.tagQueue.queue.push(item);
|
|
28828
|
+
await writeState(state);
|
|
28829
|
+
}
|
|
28830
|
+
var _workDirCache, DEFAULT_STATE;
|
|
28831
|
+
var init_state = __esm({
|
|
28832
|
+
"src/lib/state.ts"() {
|
|
28833
|
+
"use strict";
|
|
28834
|
+
_workDirCache = null;
|
|
28835
|
+
DEFAULT_STATE = {
|
|
28836
|
+
credentials: null,
|
|
28837
|
+
config: {
|
|
28838
|
+
apiBaseUrl: "https://app.claudeink.com",
|
|
28839
|
+
workflowDir: "",
|
|
28840
|
+
logLevel: "INFO"
|
|
28841
|
+
},
|
|
28842
|
+
tagQueue: {
|
|
28843
|
+
queue: [],
|
|
28844
|
+
failed: []
|
|
28845
|
+
},
|
|
28846
|
+
lastSyncAt: ""
|
|
28847
|
+
};
|
|
28848
|
+
}
|
|
28849
|
+
});
|
|
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
|
+
|
|
28749
29024
|
// ../node_modules/kind-of/index.js
|
|
28750
29025
|
var require_kind_of = __commonJS({
|
|
28751
29026
|
"../node_modules/kind-of/index.js"(exports2, module2) {
|
|
@@ -32230,110 +32505,9 @@ var require_gray_matter = __commonJS({
|
|
|
32230
32505
|
}
|
|
32231
32506
|
});
|
|
32232
32507
|
|
|
32233
|
-
// src/lib/state.ts
|
|
32234
|
-
import { readFile, writeFile, mkdir, chmod } from "fs/promises";
|
|
32235
|
-
import { join } from "path";
|
|
32236
|
-
function setWorkDir(dir) {
|
|
32237
|
-
_workDirCache = dir;
|
|
32238
|
-
}
|
|
32239
|
-
function getWorkDir() {
|
|
32240
|
-
return _workDirCache || process.env.CLAUDEINK_WORK_DIR || process.cwd();
|
|
32241
|
-
}
|
|
32242
|
-
function getClaudeinkDir() {
|
|
32243
|
-
return join(getWorkDir(), ".claudeink");
|
|
32244
|
-
}
|
|
32245
|
-
function getStatePath() {
|
|
32246
|
-
return join(getClaudeinkDir(), "state.json");
|
|
32247
|
-
}
|
|
32248
|
-
async function ensureDir() {
|
|
32249
|
-
await mkdir(getClaudeinkDir(), { recursive: true });
|
|
32250
|
-
}
|
|
32251
|
-
async function readState() {
|
|
32252
|
-
const statePath = getStatePath();
|
|
32253
|
-
let raw;
|
|
32254
|
-
try {
|
|
32255
|
-
raw = await readFile(statePath, "utf-8");
|
|
32256
|
-
} catch {
|
|
32257
|
-
const state = { ...DEFAULT_STATE };
|
|
32258
|
-
state.config.workflowDir = getWorkDir();
|
|
32259
|
-
return state;
|
|
32260
|
-
}
|
|
32261
|
-
try {
|
|
32262
|
-
const parsed = JSON.parse(raw);
|
|
32263
|
-
const state = {
|
|
32264
|
-
credentials: parsed.credentials ?? null,
|
|
32265
|
-
config: { ...DEFAULT_STATE.config, ...parsed.config },
|
|
32266
|
-
tagQueue: parsed.tagQueue ?? { ...DEFAULT_STATE.tagQueue },
|
|
32267
|
-
lastSyncAt: parsed.lastSyncAt ?? ""
|
|
32268
|
-
};
|
|
32269
|
-
state.config.workflowDir = getWorkDir();
|
|
32270
|
-
return state;
|
|
32271
|
-
} catch {
|
|
32272
|
-
const backupPath = statePath + ".corrupted." + Date.now();
|
|
32273
|
-
try {
|
|
32274
|
-
await writeFile(backupPath, raw, "utf-8");
|
|
32275
|
-
} catch {
|
|
32276
|
-
}
|
|
32277
|
-
console.error(`[ClaudeInk] state.json corrupted, backed up to ${backupPath}`);
|
|
32278
|
-
const state = { ...DEFAULT_STATE };
|
|
32279
|
-
state.config.workflowDir = getWorkDir();
|
|
32280
|
-
return state;
|
|
32281
|
-
}
|
|
32282
|
-
}
|
|
32283
|
-
async function writeState(state) {
|
|
32284
|
-
await ensureDir();
|
|
32285
|
-
await writeFile(getStatePath(), JSON.stringify(state, null, 2), "utf-8");
|
|
32286
|
-
await chmod(getStatePath(), 384);
|
|
32287
|
-
}
|
|
32288
|
-
async function getCredentials() {
|
|
32289
|
-
const state = await readState();
|
|
32290
|
-
if (!state.credentials) return null;
|
|
32291
|
-
return {
|
|
32292
|
-
licenseKey: state.credentials.licenseKey,
|
|
32293
|
-
token: state.credentials.token,
|
|
32294
|
-
userId: state.credentials.userId,
|
|
32295
|
-
plan: state.credentials.plan,
|
|
32296
|
-
expiresAt: state.credentials.expiresAt
|
|
32297
|
-
};
|
|
32298
|
-
}
|
|
32299
|
-
async function getConfig() {
|
|
32300
|
-
const state = await readState();
|
|
32301
|
-
return state.config;
|
|
32302
|
-
}
|
|
32303
|
-
async function updateLastSyncAt() {
|
|
32304
|
-
const state = await readState();
|
|
32305
|
-
state.lastSyncAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
32306
|
-
await writeState(state);
|
|
32307
|
-
}
|
|
32308
|
-
async function addToTagQueue(item) {
|
|
32309
|
-
const state = await readState();
|
|
32310
|
-
if (state.tagQueue.queue.some((q) => q.knowledgeId === item.knowledgeId)) return;
|
|
32311
|
-
state.tagQueue.queue.push(item);
|
|
32312
|
-
await writeState(state);
|
|
32313
|
-
}
|
|
32314
|
-
var _workDirCache, DEFAULT_STATE;
|
|
32315
|
-
var init_state = __esm({
|
|
32316
|
-
"src/lib/state.ts"() {
|
|
32317
|
-
"use strict";
|
|
32318
|
-
_workDirCache = null;
|
|
32319
|
-
DEFAULT_STATE = {
|
|
32320
|
-
credentials: null,
|
|
32321
|
-
config: {
|
|
32322
|
-
apiBaseUrl: "https://app.claudeink.com",
|
|
32323
|
-
workflowDir: ""
|
|
32324
|
-
},
|
|
32325
|
-
tagQueue: {
|
|
32326
|
-
queue: [],
|
|
32327
|
-
failed: []
|
|
32328
|
-
},
|
|
32329
|
-
lastSyncAt: ""
|
|
32330
|
-
};
|
|
32331
|
-
}
|
|
32332
|
-
});
|
|
32333
|
-
|
|
32334
32508
|
// src/lib/knowledge.ts
|
|
32335
|
-
import { readFile as readFile2, writeFile as writeFile2, mkdir as
|
|
32336
|
-
import { join as
|
|
32509
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir4, unlink as unlink2 } from "fs/promises";
|
|
32510
|
+
import { join as join4 } from "path";
|
|
32337
32511
|
function withIndexLock(fn) {
|
|
32338
32512
|
const prev = _lockPromise;
|
|
32339
32513
|
let resolve;
|
|
@@ -32343,10 +32517,10 @@ function withIndexLock(fn) {
|
|
|
32343
32517
|
return prev.then(fn).finally(() => resolve());
|
|
32344
32518
|
}
|
|
32345
32519
|
function getKnowledgeDir() {
|
|
32346
|
-
return
|
|
32520
|
+
return join4(getWorkDir(), ".claudeink", "knowledge");
|
|
32347
32521
|
}
|
|
32348
32522
|
function getIndexPath() {
|
|
32349
|
-
return
|
|
32523
|
+
return join4(getWorkDir(), ".claudeink", "knowledge", "index.json");
|
|
32350
32524
|
}
|
|
32351
32525
|
async function generateIdInternal(index) {
|
|
32352
32526
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -32379,17 +32553,17 @@ async function readIndex() {
|
|
|
32379
32553
|
async function saveIndex(index) {
|
|
32380
32554
|
index.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
32381
32555
|
const dir = getKnowledgeDir();
|
|
32382
|
-
await
|
|
32556
|
+
await mkdir4(dir, { recursive: true });
|
|
32383
32557
|
await writeFile2(getIndexPath(), JSON.stringify(index, null, 2), "utf-8");
|
|
32384
32558
|
}
|
|
32385
32559
|
async function writeKnowledgeFile(meta, content) {
|
|
32386
32560
|
const now = /* @__PURE__ */ new Date();
|
|
32387
32561
|
const monthDir = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}`;
|
|
32388
|
-
const dir =
|
|
32389
|
-
await
|
|
32562
|
+
const dir = join4(getKnowledgeDir(), monthDir);
|
|
32563
|
+
await mkdir4(dir, { recursive: true });
|
|
32390
32564
|
const slug = toSlug(meta.title) || meta.id;
|
|
32391
32565
|
const filename = `${now.toISOString().slice(0, 10)}-${slug}.md`;
|
|
32392
|
-
const filePath =
|
|
32566
|
+
const filePath = join4(dir, filename);
|
|
32393
32567
|
const frontmatter = {
|
|
32394
32568
|
id: meta.id,
|
|
32395
32569
|
title: meta.title,
|
|
@@ -32402,13 +32576,13 @@ async function writeKnowledgeFile(meta, content) {
|
|
|
32402
32576
|
if (meta.url) frontmatter.url = meta.url;
|
|
32403
32577
|
const output = import_gray_matter.default.stringify(content, frontmatter);
|
|
32404
32578
|
await writeFile2(filePath, output, "utf-8");
|
|
32405
|
-
return
|
|
32579
|
+
return join4(monthDir, filename);
|
|
32406
32580
|
}
|
|
32407
32581
|
async function readKnowledgeFile(id) {
|
|
32408
32582
|
const index = await readIndex();
|
|
32409
32583
|
const entry = index.entries[id];
|
|
32410
32584
|
if (!entry) return null;
|
|
32411
|
-
const filePath =
|
|
32585
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
32412
32586
|
try {
|
|
32413
32587
|
const raw = await readFile2(filePath, "utf-8");
|
|
32414
32588
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -32493,9 +32667,9 @@ async function deleteKnowledgeFile(id) {
|
|
|
32493
32667
|
const index = await readIndex();
|
|
32494
32668
|
const entry = index.entries[id];
|
|
32495
32669
|
if (!entry) return false;
|
|
32496
|
-
const filePath =
|
|
32670
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
32497
32671
|
try {
|
|
32498
|
-
await
|
|
32672
|
+
await unlink2(filePath);
|
|
32499
32673
|
} catch {
|
|
32500
32674
|
}
|
|
32501
32675
|
delete index.entries[id];
|
|
@@ -32503,55 +32677,6 @@ async function deleteKnowledgeFile(id) {
|
|
|
32503
32677
|
return true;
|
|
32504
32678
|
});
|
|
32505
32679
|
}
|
|
32506
|
-
function searchKnowledge(index, filters) {
|
|
32507
|
-
let entries = Object.values(index.entries);
|
|
32508
|
-
if (filters.tags && filters.tags.length > 0) {
|
|
32509
|
-
const filterTags = filters.tags.map((t) => t.toLowerCase());
|
|
32510
|
-
entries = entries.filter(
|
|
32511
|
-
(e) => e.tags.some((t) => filterTags.includes(t.toLowerCase()))
|
|
32512
|
-
);
|
|
32513
|
-
}
|
|
32514
|
-
if (filters.category) {
|
|
32515
|
-
entries = entries.filter((e) => e.category === filters.category);
|
|
32516
|
-
}
|
|
32517
|
-
if (filters.date_from) {
|
|
32518
|
-
entries = entries.filter((e) => e.created_at >= filters.date_from);
|
|
32519
|
-
}
|
|
32520
|
-
if (filters.date_to) {
|
|
32521
|
-
entries = entries.filter((e) => e.created_at <= filters.date_to);
|
|
32522
|
-
}
|
|
32523
|
-
if (filters.query) {
|
|
32524
|
-
const q = filters.query.toLowerCase();
|
|
32525
|
-
entries = entries.map((e) => {
|
|
32526
|
-
let score = 0;
|
|
32527
|
-
if (e.title.toLowerCase().includes(q)) score += 10;
|
|
32528
|
-
if (e.preview.toLowerCase().includes(q)) score += 5;
|
|
32529
|
-
if (e.tags.some((t) => t.toLowerCase().includes(q))) score += 3;
|
|
32530
|
-
return { ...e, _score: score };
|
|
32531
|
-
}).filter((e) => e._score > 0).sort((a, b) => b._score - a._score);
|
|
32532
|
-
} else {
|
|
32533
|
-
entries.sort((a, b) => b.created_at.localeCompare(a.created_at));
|
|
32534
|
-
}
|
|
32535
|
-
const total = entries.length;
|
|
32536
|
-
const limit = filters.limit || 10;
|
|
32537
|
-
const results = entries.slice(0, limit).map((e) => ({
|
|
32538
|
-
id: e.id,
|
|
32539
|
-
title: e.title,
|
|
32540
|
-
tags: e.tags,
|
|
32541
|
-
category: e.category,
|
|
32542
|
-
created_at: e.created_at,
|
|
32543
|
-
preview: e.preview
|
|
32544
|
-
}));
|
|
32545
|
-
return { results, total };
|
|
32546
|
-
}
|
|
32547
|
-
async function readMultipleKnowledgeFiles(ids) {
|
|
32548
|
-
const results = [];
|
|
32549
|
-
for (const id of ids) {
|
|
32550
|
-
const file = await readKnowledgeFile(id);
|
|
32551
|
-
if (file) results.push(file);
|
|
32552
|
-
}
|
|
32553
|
-
return results;
|
|
32554
|
-
}
|
|
32555
32680
|
function getAllTags(index) {
|
|
32556
32681
|
const tagCounts = {};
|
|
32557
32682
|
for (const entry of Object.values(index.entries)) {
|
|
@@ -32570,7 +32695,7 @@ async function renameTag(oldTag, newTag) {
|
|
|
32570
32695
|
if (idx !== -1) {
|
|
32571
32696
|
entry.tags[idx] = newTag;
|
|
32572
32697
|
count++;
|
|
32573
|
-
const filePath =
|
|
32698
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
32574
32699
|
try {
|
|
32575
32700
|
const raw = await readFile2(filePath, "utf-8");
|
|
32576
32701
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -32605,7 +32730,7 @@ async function mergeTags(sourceTags, targetTag) {
|
|
|
32605
32730
|
}
|
|
32606
32731
|
entry.tags = newTags;
|
|
32607
32732
|
count++;
|
|
32608
|
-
const filePath =
|
|
32733
|
+
const filePath = join4(getKnowledgeDir(), entry.file_path);
|
|
32609
32734
|
try {
|
|
32610
32735
|
const raw = await readFile2(filePath, "utf-8");
|
|
32611
32736
|
const { data, content } = (0, import_gray_matter.default)(raw);
|
|
@@ -32645,6 +32770,7 @@ async function doPush(partial2) {
|
|
|
32645
32770
|
knowledge: partial2.knowledge || [],
|
|
32646
32771
|
crawlerSources: partial2.crawlerSources || []
|
|
32647
32772
|
};
|
|
32773
|
+
await log("DEBUG", "push", `payload: ${partial2.knowledge?.length || 0} knowledge, ${partial2.crawlerSources?.length || 0} sources`);
|
|
32648
32774
|
try {
|
|
32649
32775
|
await fetch(`${config2.apiBaseUrl}/api/sync/batch`, {
|
|
32650
32776
|
method: "POST",
|
|
@@ -32655,107 +32781,408 @@ async function doPush(partial2) {
|
|
|
32655
32781
|
body: JSON.stringify(payload)
|
|
32656
32782
|
});
|
|
32657
32783
|
} catch (err) {
|
|
32658
|
-
|
|
32784
|
+
await log("WARN", "push", `failed: ${err instanceof Error ? err.message : err}`);
|
|
32659
32785
|
}
|
|
32660
32786
|
}
|
|
32661
32787
|
var init_push = __esm({
|
|
32662
32788
|
"src/lib/push.ts"() {
|
|
32663
32789
|
"use strict";
|
|
32664
32790
|
init_state();
|
|
32791
|
+
init_logger();
|
|
32665
32792
|
}
|
|
32666
32793
|
});
|
|
32667
32794
|
|
|
32668
|
-
// src/tools/
|
|
32795
|
+
// src/tools/ink.ts
|
|
32669
32796
|
import { readFile as readFile3 } from "fs/promises";
|
|
32670
|
-
import {
|
|
32671
|
-
|
|
32672
|
-
import { execSync } from "child_process";
|
|
32673
|
-
async function sourceCrawl(input) {
|
|
32674
|
-
const config2 = await getConfig();
|
|
32675
|
-
const crawlerDir = join3(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
32676
|
-
const configPath = join3(crawlerDir, "config.json");
|
|
32677
|
-
let crawlerConfig;
|
|
32797
|
+
import { extname } from "path";
|
|
32798
|
+
async function inkSave(input) {
|
|
32678
32799
|
try {
|
|
32679
|
-
|
|
32680
|
-
|
|
32681
|
-
|
|
32682
|
-
|
|
32683
|
-
|
|
32684
|
-
|
|
32685
|
-
|
|
32686
|
-
|
|
32687
|
-
|
|
32800
|
+
if (input.id) {
|
|
32801
|
+
const result = await updateKnowledgeFile(input.id, {
|
|
32802
|
+
title: input.title,
|
|
32803
|
+
content: input.content,
|
|
32804
|
+
tags: input.tags,
|
|
32805
|
+
category: input.category
|
|
32806
|
+
});
|
|
32807
|
+
if (!result) {
|
|
32808
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
32809
|
+
}
|
|
32810
|
+
fireAndForgetPush({
|
|
32811
|
+
knowledge: [{
|
|
32812
|
+
id: result.meta.id,
|
|
32813
|
+
title: result.meta.title,
|
|
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,
|
|
32840
|
+
title: input.title,
|
|
32841
|
+
tags: input.tags,
|
|
32842
|
+
category: input.category,
|
|
32843
|
+
source_type: input.source_type,
|
|
32844
|
+
url: input.url,
|
|
32845
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32846
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
32847
|
+
}]
|
|
32848
|
+
});
|
|
32849
|
+
await log("INFO", "ink.save", `created id=${id} title="${input.title}" tags=${JSON.stringify(input.tags)}`);
|
|
32688
32850
|
return {
|
|
32689
|
-
success:
|
|
32690
|
-
message:
|
|
32851
|
+
success: true,
|
|
32852
|
+
message: `\u5DF2\u4FDD\u5B58\u300C${input.title}\u300D`,
|
|
32853
|
+
data: { id }
|
|
32691
32854
|
};
|
|
32855
|
+
} catch (err) {
|
|
32856
|
+
await log("ERROR", "ink.save", `failed: ${err.message}`);
|
|
32857
|
+
return { success: false, message: `\u4FDD\u5B58\u5931\u8D25\uFF1A${err.message}` };
|
|
32692
32858
|
}
|
|
32693
|
-
|
|
32694
|
-
|
|
32859
|
+
}
|
|
32860
|
+
async function inkDelete(input) {
|
|
32695
32861
|
try {
|
|
32696
|
-
|
|
32697
|
-
|
|
32698
|
-
|
|
32699
|
-
|
|
32700
|
-
|
|
32701
|
-
});
|
|
32702
|
-
let saved = 0;
|
|
32703
|
-
let queued = 0;
|
|
32704
|
-
for (const target of targets) {
|
|
32705
|
-
const sourceDir = join3(config2.workflowDir, "sources", "articles", target.id);
|
|
32706
|
-
let files;
|
|
32707
|
-
try {
|
|
32708
|
-
files = readdirSync2(sourceDir).filter((f) => f.endsWith(".md"));
|
|
32709
|
-
} catch {
|
|
32710
|
-
continue;
|
|
32862
|
+
if (!input.confirm) {
|
|
32863
|
+
const index = await readIndex();
|
|
32864
|
+
const entry = index.entries[input.id];
|
|
32865
|
+
if (!entry) {
|
|
32866
|
+
return { success: false, message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
32711
32867
|
}
|
|
32712
|
-
|
|
32713
|
-
|
|
32714
|
-
|
|
32715
|
-
|
|
32716
|
-
|
|
32717
|
-
|
|
32718
|
-
|
|
32719
|
-
|
|
32720
|
-
|
|
32721
|
-
|
|
32722
|
-
|
|
32723
|
-
|
|
32724
|
-
|
|
32725
|
-
|
|
32726
|
-
|
|
32727
|
-
|
|
32728
|
-
|
|
32729
|
-
|
|
32730
|
-
|
|
32731
|
-
|
|
32732
|
-
|
|
32733
|
-
|
|
32734
|
-
|
|
32735
|
-
|
|
32736
|
-
|
|
32737
|
-
|
|
32738
|
-
|
|
32739
|
-
|
|
32740
|
-
|
|
32741
|
-
|
|
32742
|
-
|
|
32743
|
-
|
|
32744
|
-
|
|
32745
|
-
|
|
32746
|
-
|
|
32747
|
-
|
|
32748
|
-
|
|
32749
|
-
|
|
32750
|
-
|
|
32868
|
+
return {
|
|
32869
|
+
success: false,
|
|
32870
|
+
message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
|
|
32871
|
+
data: { id: entry.id, title: entry.title, category: entry.category, tags: entry.tags }
|
|
32872
|
+
};
|
|
32873
|
+
}
|
|
32874
|
+
const deleted = await deleteKnowledgeFile(input.id);
|
|
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 {
|
|
32901
|
+
let coverUrl = input.cover || null;
|
|
32902
|
+
if (coverUrl) {
|
|
32903
|
+
if (coverUrl.startsWith("http://") || coverUrl.startsWith("https://")) {
|
|
32904
|
+
const uploadResult = await uploadImageFromUrl(coverUrl, "cover", creds.token, config2.apiBaseUrl);
|
|
32905
|
+
if (uploadResult.success) coverUrl = uploadResult.url;
|
|
32906
|
+
} else {
|
|
32907
|
+
const uploadResult = await uploadImage(coverUrl, "cover", creds.token, config2.apiBaseUrl);
|
|
32908
|
+
if (uploadResult.success) {
|
|
32909
|
+
coverUrl = uploadResult.url;
|
|
32910
|
+
} else {
|
|
32911
|
+
await log("WARN", "ink.write", `cover upload failed: ${uploadResult.error}`);
|
|
32912
|
+
coverUrl = null;
|
|
32751
32913
|
}
|
|
32752
32914
|
}
|
|
32753
32915
|
}
|
|
32916
|
+
const slug = `${Date.now().toString(36)}-${input.title.toLowerCase().replace(/[^a-z0-9\u4e00-\u9fff]+/g, "-").replace(/^-|-$/g, "").slice(0, 60)}`;
|
|
32917
|
+
const excerpt = input.excerpt || input.content.replace(/^#+\s.+$/gm, "").replace(/\n+/g, " ").trim().slice(0, 200);
|
|
32918
|
+
const res = await fetch(`${config2.apiBaseUrl}/api/blog/manage`, {
|
|
32919
|
+
method: "POST",
|
|
32920
|
+
headers: {
|
|
32921
|
+
"Content-Type": "application/json",
|
|
32922
|
+
Authorization: `Bearer ${creds.token}`
|
|
32923
|
+
},
|
|
32924
|
+
body: JSON.stringify({
|
|
32925
|
+
title: input.title,
|
|
32926
|
+
slug,
|
|
32927
|
+
content: input.content,
|
|
32928
|
+
cover_url: coverUrl,
|
|
32929
|
+
tags: input.tags,
|
|
32930
|
+
category: input.category,
|
|
32931
|
+
excerpt,
|
|
32932
|
+
source_ids: input.source_ids
|
|
32933
|
+
})
|
|
32934
|
+
});
|
|
32935
|
+
if (!res.ok) {
|
|
32936
|
+
const err = await res.text();
|
|
32937
|
+
await log("ERROR", "ink.write", `save failed: ${err}`);
|
|
32938
|
+
return { success: false, message: `\u4FDD\u5B58\u5931\u8D25: ${err}` };
|
|
32939
|
+
}
|
|
32940
|
+
const data = await res.json();
|
|
32941
|
+
await log("INFO", "ink.write", `saved article="${input.title}" id=${data.id} slug=${data.slug}`);
|
|
32754
32942
|
return {
|
|
32755
32943
|
success: true,
|
|
32756
|
-
message:
|
|
32757
|
-
|
|
32758
|
-
|
|
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
|
+
} catch (err) {
|
|
32948
|
+
await log("ERROR", "ink.write", `failed: ${err.message}`);
|
|
32949
|
+
return { success: false, message: `\u5199\u6587\u7AE0\u5931\u8D25: ${err.message}` };
|
|
32950
|
+
}
|
|
32951
|
+
}
|
|
32952
|
+
async function inkTags(input) {
|
|
32953
|
+
try {
|
|
32954
|
+
const index = await readIndex();
|
|
32955
|
+
switch (input.action) {
|
|
32956
|
+
case "list": {
|
|
32957
|
+
const tags = getAllTags(index);
|
|
32958
|
+
return {
|
|
32959
|
+
success: true,
|
|
32960
|
+
message: tags.length > 0 ? `\u5171 ${tags.length} \u4E2A\u6807\u7B7E` : "\u6682\u65E0\u6807\u7B7E",
|
|
32961
|
+
data: { tags }
|
|
32962
|
+
};
|
|
32963
|
+
}
|
|
32964
|
+
case "rename": {
|
|
32965
|
+
if (!input.tag || !input.new_tag) {
|
|
32966
|
+
return { success: false, message: "rename \u9700\u8981 tag\uFF08\u539F\u6807\u7B7E\uFF09\u548C new_tag\uFF08\u65B0\u6807\u7B7E\u540D\uFF09" };
|
|
32967
|
+
}
|
|
32968
|
+
const count = await renameTag(input.tag, input.new_tag);
|
|
32969
|
+
if (count === 0) {
|
|
32970
|
+
return { success: false, message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u77E5\u8BC6\u7247\u6BB5` };
|
|
32971
|
+
}
|
|
32972
|
+
await log("INFO", "ink.tags", `renamed "${input.tag}" \u2192 "${input.new_tag}", affected=${count}`);
|
|
32973
|
+
return {
|
|
32974
|
+
success: true,
|
|
32975
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
|
|
32976
|
+
data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
|
|
32977
|
+
};
|
|
32978
|
+
}
|
|
32979
|
+
case "merge": {
|
|
32980
|
+
if (!input.source_tags || input.source_tags.length === 0 || !input.new_tag) {
|
|
32981
|
+
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
|
+
}
|
|
32983
|
+
const count = await mergeTags(input.source_tags, input.new_tag);
|
|
32984
|
+
if (count === 0) {
|
|
32985
|
+
return { success: false, message: "\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u77E5\u8BC6\u7247\u6BB5" };
|
|
32986
|
+
}
|
|
32987
|
+
await log("INFO", "ink.tags", `merged [${input.source_tags.join(",")}] \u2192 "${input.new_tag}", affected=${count}`);
|
|
32988
|
+
return {
|
|
32989
|
+
success: true,
|
|
32990
|
+
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
|
|
32991
|
+
data: { source_tags: input.source_tags, target_tag: input.new_tag, affected: count }
|
|
32992
|
+
};
|
|
32993
|
+
}
|
|
32994
|
+
}
|
|
32995
|
+
} catch (err) {
|
|
32996
|
+
await log("ERROR", "ink.tags", `failed: ${err.message}`);
|
|
32997
|
+
return { success: false, message: `\u6807\u7B7E\u64CD\u4F5C\u5931\u8D25\uFF1A${err.message}` };
|
|
32998
|
+
}
|
|
32999
|
+
}
|
|
33000
|
+
async function uploadImage(localPath, type, token, apiBase) {
|
|
33001
|
+
try {
|
|
33002
|
+
const fileBuffer = await readFile3(localPath);
|
|
33003
|
+
const ext2 = extname(localPath) || ".jpg";
|
|
33004
|
+
const extMap = {
|
|
33005
|
+
".jpg": "image/jpeg",
|
|
33006
|
+
".jpeg": "image/jpeg",
|
|
33007
|
+
".png": "image/png",
|
|
33008
|
+
".webp": "image/webp",
|
|
33009
|
+
".gif": "image/gif"
|
|
33010
|
+
};
|
|
33011
|
+
const contentType = extMap[ext2.toLowerCase()] || "application/octet-stream";
|
|
33012
|
+
const filename = `${type}-${Date.now()}${ext2}`;
|
|
33013
|
+
const res = await fetch(`${apiBase}/api/blog/upload-image`, {
|
|
33014
|
+
method: "POST",
|
|
33015
|
+
headers: {
|
|
33016
|
+
Authorization: `Bearer ${token}`,
|
|
33017
|
+
"Content-Type": contentType,
|
|
33018
|
+
"X-Filename": filename,
|
|
33019
|
+
"X-Image-Type": type
|
|
33020
|
+
},
|
|
33021
|
+
body: fileBuffer
|
|
33022
|
+
});
|
|
33023
|
+
if (!res.ok) return { success: false, error: await res.text() };
|
|
33024
|
+
const { url } = await res.json();
|
|
33025
|
+
return { success: true, url };
|
|
33026
|
+
} catch (err) {
|
|
33027
|
+
return { success: false, error: err.message };
|
|
33028
|
+
}
|
|
33029
|
+
}
|
|
33030
|
+
async function uploadImageFromUrl(imageUrl, type, token, apiBase) {
|
|
33031
|
+
try {
|
|
33032
|
+
const res = await fetch(imageUrl);
|
|
33033
|
+
if (!res.ok) return { success: false, error: `download failed: HTTP ${res.status}` };
|
|
33034
|
+
const fileBuffer = Buffer.from(await res.arrayBuffer());
|
|
33035
|
+
const ext2 = extname(new URL(imageUrl).pathname) || ".jpg";
|
|
33036
|
+
const contentType = res.headers.get("content-type") || "image/jpeg";
|
|
33037
|
+
const filename = `${type}-${Date.now()}${ext2}`;
|
|
33038
|
+
const uploadRes = await fetch(`${apiBase}/api/blog/upload-image`, {
|
|
33039
|
+
method: "POST",
|
|
33040
|
+
headers: {
|
|
33041
|
+
Authorization: `Bearer ${token}`,
|
|
33042
|
+
"Content-Type": contentType,
|
|
33043
|
+
"X-Filename": filename,
|
|
33044
|
+
"X-Image-Type": type
|
|
33045
|
+
},
|
|
33046
|
+
body: fileBuffer
|
|
33047
|
+
});
|
|
33048
|
+
if (!uploadRes.ok) return { success: false, error: await uploadRes.text() };
|
|
33049
|
+
const { url } = await uploadRes.json();
|
|
33050
|
+
return { success: true, url };
|
|
33051
|
+
} catch (err) {
|
|
33052
|
+
return { success: false, error: err.message };
|
|
33053
|
+
}
|
|
33054
|
+
}
|
|
33055
|
+
var inkSaveSchema, inkDeleteSchema, inkWriteSchema, inkTagsSchema;
|
|
33056
|
+
var init_ink = __esm({
|
|
33057
|
+
"src/tools/ink.ts"() {
|
|
33058
|
+
"use strict";
|
|
33059
|
+
init_zod();
|
|
33060
|
+
init_knowledge();
|
|
33061
|
+
init_push();
|
|
33062
|
+
init_state();
|
|
33063
|
+
init_logger();
|
|
33064
|
+
inkSaveSchema = external_exports.object({
|
|
33065
|
+
id: external_exports.string().optional().describe("\u77E5\u8BC6\u7247\u6BB5 ID\uFF08\u63D0\u4F9B\u5219\u66F4\u65B0\uFF0C\u4E0D\u63D0\u4F9B\u5219\u65B0\u5EFA\uFF09"),
|
|
33066
|
+
content: external_exports.string().describe("\u8981\u4FDD\u5B58\u7684\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"),
|
|
33067
|
+
title: external_exports.string().describe("\u6807\u9898\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF09"),
|
|
33068
|
+
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E"),
|
|
33069
|
+
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B"),
|
|
33070
|
+
source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B"),
|
|
33071
|
+
url: external_exports.string().optional().describe("\u6765\u6E90 URL")
|
|
33072
|
+
});
|
|
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
|
+
inkWriteSchema = external_exports.object({
|
|
33078
|
+
title: external_exports.string().describe("\u6587\u7AE0\u6807\u9898"),
|
|
33079
|
+
content: external_exports.string().describe("Markdown \u5168\u6587"),
|
|
33080
|
+
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
|
+
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 ink ID\uFF08\u6EAF\u6E90\uFF09")
|
|
33085
|
+
});
|
|
33086
|
+
inkTagsSchema = external_exports.object({
|
|
33087
|
+
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"),
|
|
33088
|
+
tag: external_exports.string().optional().describe("\u76EE\u6807\u6807\u7B7E\uFF08rename/merge \u65F6\u4F7F\u7528\uFF09"),
|
|
33089
|
+
new_tag: external_exports.string().optional().describe("\u65B0\u6807\u7B7E\u540D\uFF08rename \u65F6\u4F7F\u7528\uFF09"),
|
|
33090
|
+
source_tags: external_exports.array(external_exports.string()).optional().describe("\u8981\u5408\u5E76\u7684\u6E90\u6807\u7B7E\u5217\u8868\uFF08merge \u65F6\u4F7F\u7528\uFF09")
|
|
33091
|
+
});
|
|
33092
|
+
}
|
|
33093
|
+
});
|
|
33094
|
+
|
|
33095
|
+
// src/tools/source.ts
|
|
33096
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
33097
|
+
import { join as join5 } from "path";
|
|
33098
|
+
import { readdirSync as readdirSync2 } from "fs";
|
|
33099
|
+
import { execSync } from "child_process";
|
|
33100
|
+
async function sourceCrawl(input) {
|
|
33101
|
+
const config2 = await getConfig();
|
|
33102
|
+
const crawlerDir = join5(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
33103
|
+
const configPath = join5(crawlerDir, "config.json");
|
|
33104
|
+
let crawlerConfig;
|
|
33105
|
+
try {
|
|
33106
|
+
crawlerConfig = JSON.parse(await readFile4(configPath, "utf-8"));
|
|
33107
|
+
} catch {
|
|
33108
|
+
crawlerConfig = { sources: [] };
|
|
33109
|
+
}
|
|
33110
|
+
if (crawlerConfig.sources.length === 0) {
|
|
33111
|
+
return { success: false, message: "\u6682\u65E0\u914D\u7F6E\u722C\u866B\u6E90\u3002\u8BF7\u5148\u7528 source.subscribe \u6DFB\u52A0\u3002" };
|
|
33112
|
+
}
|
|
33113
|
+
const targets = input.sourceId ? crawlerConfig.sources.filter((s) => s.id === input.sourceId) : crawlerConfig.sources.filter((s) => s.enabled !== false);
|
|
33114
|
+
if (targets.length === 0) {
|
|
33115
|
+
return {
|
|
33116
|
+
success: false,
|
|
33117
|
+
message: input.sourceId ? `\u672A\u627E\u5230\u722C\u866B\u6E90: ${input.sourceId}` : "\u6CA1\u6709\u5DF2\u542F\u7528\u7684\u722C\u866B\u6E90"
|
|
33118
|
+
};
|
|
33119
|
+
}
|
|
33120
|
+
const crawlScript = join5(crawlerDir, "crawl.mjs");
|
|
33121
|
+
const args2 = input.sourceId ? `--source ${input.sourceId}` : "";
|
|
33122
|
+
try {
|
|
33123
|
+
execSync(`node "${crawlScript}" ${args2}`, {
|
|
33124
|
+
cwd: crawlerDir,
|
|
33125
|
+
encoding: "utf-8",
|
|
33126
|
+
timeout: 5 * 60 * 1e3,
|
|
33127
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
33128
|
+
});
|
|
33129
|
+
let saved = 0;
|
|
33130
|
+
let queued = 0;
|
|
33131
|
+
for (const target of targets) {
|
|
33132
|
+
const sourceDir = join5(config2.workflowDir, "sources", "articles", target.id);
|
|
33133
|
+
let files;
|
|
33134
|
+
try {
|
|
33135
|
+
files = readdirSync2(sourceDir).filter((f) => f.endsWith(".md"));
|
|
33136
|
+
} catch {
|
|
33137
|
+
continue;
|
|
33138
|
+
}
|
|
33139
|
+
for (const f of files) {
|
|
33140
|
+
const filePath = join5(sourceDir, f);
|
|
33141
|
+
try {
|
|
33142
|
+
const raw = await readFile4(filePath, "utf-8");
|
|
33143
|
+
const { data, content } = (0, import_gray_matter2.default)(raw);
|
|
33144
|
+
const title = data.title || f.replace(/^\d{4}-\d{2}-\d{2}-/, "").replace(/\.md$/, "").replace(/-/g, " ");
|
|
33145
|
+
const url = data.url || "";
|
|
33146
|
+
const { id } = await saveKnowledge({
|
|
33147
|
+
content: content.trim(),
|
|
33148
|
+
title,
|
|
33149
|
+
tags: data.tags || [],
|
|
33150
|
+
category: "reference",
|
|
33151
|
+
source_type: "url",
|
|
33152
|
+
url
|
|
33153
|
+
});
|
|
33154
|
+
saved++;
|
|
33155
|
+
if (!data.tags || data.tags.length === 0) {
|
|
33156
|
+
await addToTagQueue({
|
|
33157
|
+
knowledgeId: id,
|
|
33158
|
+
title,
|
|
33159
|
+
addedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33160
|
+
source: "crawl",
|
|
33161
|
+
retryCount: 0
|
|
33162
|
+
});
|
|
33163
|
+
queued++;
|
|
33164
|
+
}
|
|
33165
|
+
fireAndForgetPush({
|
|
33166
|
+
knowledge: [{
|
|
33167
|
+
id,
|
|
33168
|
+
title,
|
|
33169
|
+
tags: data.tags || [],
|
|
33170
|
+
category: "reference",
|
|
33171
|
+
source_type: "url",
|
|
33172
|
+
url,
|
|
33173
|
+
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33174
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
33175
|
+
}]
|
|
33176
|
+
});
|
|
33177
|
+
} catch {
|
|
33178
|
+
}
|
|
33179
|
+
}
|
|
33180
|
+
}
|
|
33181
|
+
return {
|
|
33182
|
+
success: true,
|
|
33183
|
+
message: [
|
|
33184
|
+
`\u2705 \u722C\u53D6\u5B8C\u6210`,
|
|
33185
|
+
` \u76EE\u6807\u6E90: ${targets.map((t) => t.name).join(", ")}`,
|
|
32759
33186
|
` \u4FDD\u5B58\u5230\u77E5\u8BC6\u5E93: ${saved} \u7BC7`,
|
|
32760
33187
|
queued > 0 ? ` \u52A0\u5165\u6807\u7B7E\u961F\u5217: ${queued} \u7BC7\uFF08\u7B49\u5F85 AI \u6253\u6807\u7B7E\uFF09` : ""
|
|
32761
33188
|
].filter(Boolean).join("\n"),
|
|
@@ -32785,20 +33212,20 @@ var init_source = __esm({
|
|
|
32785
33212
|
});
|
|
32786
33213
|
|
|
32787
33214
|
// src/tools/subscribe.ts
|
|
32788
|
-
import { readFile as
|
|
32789
|
-
import { join as
|
|
33215
|
+
import { readFile as readFile5, writeFile as writeFile3, mkdir as mkdir5 } from "fs/promises";
|
|
33216
|
+
import { join as join6 } from "path";
|
|
32790
33217
|
async function readCrawlerConfig(configPath) {
|
|
32791
33218
|
try {
|
|
32792
|
-
return JSON.parse(await
|
|
33219
|
+
return JSON.parse(await readFile5(configPath, "utf-8"));
|
|
32793
33220
|
} catch {
|
|
32794
33221
|
return { sources: [] };
|
|
32795
33222
|
}
|
|
32796
33223
|
}
|
|
32797
33224
|
async function sourceSubscribe(input) {
|
|
32798
33225
|
const config2 = await getConfig();
|
|
32799
|
-
const crawlerDir =
|
|
32800
|
-
await
|
|
32801
|
-
const configPath =
|
|
33226
|
+
const crawlerDir = join6(config2.workflowDir || process.cwd(), "tools", "crawler");
|
|
33227
|
+
await mkdir5(crawlerDir, { recursive: true });
|
|
33228
|
+
const configPath = join6(crawlerDir, "config.json");
|
|
32802
33229
|
const crawlerConfig = await readCrawlerConfig(configPath);
|
|
32803
33230
|
if (input.action === "list") {
|
|
32804
33231
|
return {
|
|
@@ -32892,725 +33319,86 @@ var init_subscribe = __esm({
|
|
|
32892
33319
|
}
|
|
32893
33320
|
});
|
|
32894
33321
|
|
|
32895
|
-
// src/
|
|
32896
|
-
|
|
32897
|
-
|
|
32898
|
-
const creds = await getCredentials();
|
|
32899
|
-
if (!creds?.token) {
|
|
32900
|
-
return { success: false, message: "\u672A\u6FC0\u6D3B\uFF0C\u8BF7\u5148\u4F7F\u7528 workflow.init \u6FC0\u6D3B License" };
|
|
32901
|
-
}
|
|
32902
|
-
return doPull(creds.token);
|
|
32903
|
-
}
|
|
32904
|
-
async function doPull(token) {
|
|
32905
|
-
const config2 = await getConfig();
|
|
33322
|
+
// src/index.ts
|
|
33323
|
+
var index_exports = {};
|
|
33324
|
+
async function main() {
|
|
32906
33325
|
try {
|
|
32907
|
-
const
|
|
32908
|
-
|
|
32909
|
-
|
|
32910
|
-
if (!res.ok) {
|
|
32911
|
-
if (res.status === 404) {
|
|
32912
|
-
return { success: true, message: "\u4E91\u7AEF\u65E0\u6570\u636E" };
|
|
32913
|
-
}
|
|
32914
|
-
return { success: false, message: `\u62C9\u53D6\u5931\u8D25: HTTP ${res.status}` };
|
|
33326
|
+
const state = await readState();
|
|
33327
|
+
if (state.config.workflowDir) {
|
|
33328
|
+
setWorkDir(state.config.workflowDir);
|
|
32915
33329
|
}
|
|
32916
|
-
|
|
32917
|
-
|
|
32918
|
-
success: true,
|
|
32919
|
-
message: "\u2705 \u540C\u6B65\u5B8C\u6210"
|
|
32920
|
-
};
|
|
32921
|
-
} catch (err) {
|
|
32922
|
-
return { success: false, message: `\u540C\u6B65\u5931\u8D25: ${err instanceof Error ? err.message : err}` };
|
|
32923
|
-
}
|
|
32924
|
-
}
|
|
32925
|
-
async function syncPull(input) {
|
|
32926
|
-
if (input.workDir) setWorkDir(input.workDir);
|
|
32927
|
-
const creds = await getCredentials();
|
|
32928
|
-
if (!creds?.token) {
|
|
32929
|
-
return { success: false, message: "\u672A\u6FC0\u6D3B" };
|
|
33330
|
+
setLogLevel(state.config.logLevel || "INFO");
|
|
33331
|
+
} catch {
|
|
32930
33332
|
}
|
|
32931
|
-
|
|
33333
|
+
const transport = new StdioServerTransport();
|
|
33334
|
+
await server.connect(transport);
|
|
33335
|
+
await log("INFO", "server", "started (8 tools)");
|
|
32932
33336
|
}
|
|
32933
|
-
var
|
|
32934
|
-
var
|
|
32935
|
-
"src/
|
|
33337
|
+
var server;
|
|
33338
|
+
var init_index = __esm({
|
|
33339
|
+
"src/index.ts"() {
|
|
32936
33340
|
"use strict";
|
|
32937
|
-
|
|
33341
|
+
init_mcp();
|
|
33342
|
+
init_stdio2();
|
|
33343
|
+
init_workflow();
|
|
33344
|
+
init_sync();
|
|
33345
|
+
init_ink();
|
|
33346
|
+
init_source();
|
|
33347
|
+
init_subscribe();
|
|
32938
33348
|
init_state();
|
|
32939
|
-
|
|
32940
|
-
|
|
33349
|
+
init_logger();
|
|
33350
|
+
server = new McpServer({
|
|
33351
|
+
name: "ClaudeInk",
|
|
33352
|
+
version: "2.0.1"
|
|
32941
33353
|
});
|
|
32942
|
-
|
|
32943
|
-
});
|
|
32944
|
-
|
|
32945
|
-
// src/tools/workflow.ts
|
|
32946
|
-
import { mkdir as mkdir4, access, unlink as unlink2 } from "fs/promises";
|
|
32947
|
-
import { join as join5 } from "path";
|
|
32948
|
-
async function workflowInit(input) {
|
|
32949
|
-
const cwd = input.workDir;
|
|
32950
|
-
const results = [];
|
|
32951
|
-
try {
|
|
32952
|
-
setWorkDir(cwd);
|
|
32953
|
-
const claudeinkDir = join5(cwd, ".claudeink");
|
|
32954
|
-
await mkdir4(join5(claudeinkDir, "knowledge"), { recursive: true });
|
|
32955
|
-
results.push("\u2705 \u77E5\u8BC6\u5E93\u76EE\u5F55\u5DF2\u521B\u5EFA");
|
|
32956
|
-
const state = await readState();
|
|
32957
|
-
state.config.workflowDir = cwd;
|
|
32958
|
-
const oldCredsPath = join5(claudeinkDir, "credentials.json");
|
|
32959
|
-
try {
|
|
32960
|
-
await access(oldCredsPath);
|
|
32961
|
-
await unlink2(oldCredsPath);
|
|
32962
|
-
results.push("\u{1F9F9} \u5DF2\u6E05\u7406\u65E7\u7248 credentials.json");
|
|
32963
|
-
} catch {
|
|
32964
|
-
}
|
|
32965
|
-
let activated = false;
|
|
32966
|
-
if (input.licenseKey) {
|
|
32967
|
-
try {
|
|
32968
|
-
const res = await fetch(`${DEFAULT_API_BASE_URL}/api/auth/activate`, {
|
|
32969
|
-
method: "POST",
|
|
32970
|
-
headers: { "Content-Type": "application/json" },
|
|
32971
|
-
body: JSON.stringify({ key: input.licenseKey })
|
|
32972
|
-
});
|
|
32973
|
-
const data = await res.json();
|
|
32974
|
-
if (data.userId) {
|
|
32975
|
-
state.credentials = {
|
|
32976
|
-
licenseKey: input.licenseKey,
|
|
32977
|
-
token: data.token,
|
|
32978
|
-
userId: data.userId,
|
|
32979
|
-
plan: data.plan,
|
|
32980
|
-
expiresAt: data.expiresAt
|
|
32981
|
-
};
|
|
32982
|
-
results.push(`\u2705 License \u6FC0\u6D3B\u6210\u529F\uFF08\u5957\u9910: ${data.plan}\uFF09`);
|
|
32983
|
-
activated = true;
|
|
32984
|
-
} else {
|
|
32985
|
-
results.push(`\u26A0\uFE0F License \u6FC0\u6D3B\u5931\u8D25: ${JSON.stringify(data)}`);
|
|
32986
|
-
}
|
|
32987
|
-
} catch (err) {
|
|
32988
|
-
results.push(`\u26A0\uFE0F \u6FC0\u6D3B\u7F51\u7EDC\u9519\u8BEF: ${err instanceof Error ? err.message : err}`);
|
|
32989
|
-
}
|
|
32990
|
-
}
|
|
32991
|
-
await writeState(state);
|
|
32992
|
-
results.push("\u2705 state.json");
|
|
32993
|
-
if (activated) {
|
|
32994
|
-
try {
|
|
32995
|
-
const pullResult = await syncPull({ workDir: cwd });
|
|
32996
|
-
if (pullResult.success) {
|
|
32997
|
-
results.push("\u2705 \u5DF2\u4ECE\u4E91\u7AEF\u540C\u6B65\u6570\u636E");
|
|
32998
|
-
} else {
|
|
32999
|
-
results.push("\u2139\uFE0F \u4E91\u7AEF\u65E0\u5DF2\u6709\u6570\u636E");
|
|
33000
|
-
}
|
|
33001
|
-
} catch {
|
|
33002
|
-
results.push("\u2139\uFE0F \u4E91\u7AEF\u540C\u6B65\u8DF3\u8FC7");
|
|
33003
|
-
}
|
|
33004
|
-
}
|
|
33005
|
-
return {
|
|
33006
|
-
success: true,
|
|
33007
|
-
message: [
|
|
33008
|
-
"\u{1F389} ClaudeInk \u77E5\u8BC6\u5E93\u521D\u59CB\u5316\u5B8C\u6210\uFF01",
|
|
33009
|
-
"",
|
|
33010
|
-
...results,
|
|
33011
|
-
"",
|
|
33012
|
-
"\u{1F3AF} \u4E0B\u4E00\u6B65\uFF1A",
|
|
33013
|
-
"1. \u5728\u5BF9\u8BDD\u4E2D\u8BF4\u300C\u5E2E\u6211\u5B58\u4E00\u4E0B\u300D\u4FDD\u5B58\u6709\u4EF7\u503C\u5185\u5BB9",
|
|
33014
|
-
"2. \u7528\u300C\u627E\u4E00\u4E0B\u5173\u4E8E XX \u7684\u300D\u68C0\u7D22\u77E5\u8BC6\u5E93"
|
|
33015
|
-
].join("\n")
|
|
33016
|
-
};
|
|
33017
|
-
} catch (err) {
|
|
33018
|
-
return {
|
|
33019
|
-
success: false,
|
|
33020
|
-
message: `\u521D\u59CB\u5316\u5931\u8D25: ${err instanceof Error ? err.message : err}`
|
|
33021
|
-
};
|
|
33022
|
-
}
|
|
33023
|
-
}
|
|
33024
|
-
var DEFAULT_API_BASE_URL, workflowInitSchema;
|
|
33025
|
-
var init_workflow = __esm({
|
|
33026
|
-
"src/tools/workflow.ts"() {
|
|
33027
|
-
"use strict";
|
|
33028
|
-
init_zod();
|
|
33029
|
-
init_state();
|
|
33030
|
-
init_sync();
|
|
33031
|
-
DEFAULT_API_BASE_URL = "https://app.claudeink.com";
|
|
33032
|
-
workflowInitSchema = external_exports.object({
|
|
33033
|
-
workDir: external_exports.string().describe("\u5DE5\u4F5C\u6D41\u521D\u59CB\u5316\u76EE\u6807\u76EE\u5F55\uFF08\u7EDD\u5BF9\u8DEF\u5F84\uFF09"),
|
|
33034
|
-
licenseKey: external_exports.string().optional().describe("License Key\uFF08\u53EF\u9009\uFF0C\u4F20\u5165\u5219\u81EA\u52A8\u6FC0\u6D3B\uFF09")
|
|
33035
|
-
});
|
|
33036
|
-
}
|
|
33037
|
-
});
|
|
33038
|
-
|
|
33039
|
-
// src/tools/ink.ts
|
|
33040
|
-
async function inkSave(input) {
|
|
33041
|
-
try {
|
|
33042
|
-
const { id } = await saveKnowledge({
|
|
33043
|
-
content: input.content,
|
|
33044
|
-
title: input.title,
|
|
33045
|
-
tags: input.tags,
|
|
33046
|
-
category: input.category,
|
|
33047
|
-
source_type: input.source_type,
|
|
33048
|
-
url: input.url
|
|
33049
|
-
});
|
|
33050
|
-
const categoryNames = {
|
|
33051
|
-
insight: "\u6D1E\u5BDF",
|
|
33052
|
-
decision: "\u51B3\u7B56",
|
|
33053
|
-
analysis: "\u5206\u6790",
|
|
33054
|
-
idea: "\u60F3\u6CD5",
|
|
33055
|
-
reference: "\u53C2\u8003",
|
|
33056
|
-
action: "\u884C\u52A8"
|
|
33057
|
-
};
|
|
33058
|
-
const catName = categoryNames[input.category] || input.category;
|
|
33059
|
-
const tagStr = input.tags.length > 0 ? input.tags.join("\u3001") : "\u65E0\u6807\u7B7E";
|
|
33060
|
-
fireAndForgetPush({
|
|
33061
|
-
knowledge: [{
|
|
33062
|
-
id,
|
|
33063
|
-
title: input.title,
|
|
33064
|
-
tags: input.tags,
|
|
33065
|
-
category: input.category,
|
|
33066
|
-
source_type: input.source_type,
|
|
33067
|
-
url: input.url,
|
|
33068
|
-
created_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
33069
|
-
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
33070
|
-
}]
|
|
33071
|
-
});
|
|
33072
|
-
return {
|
|
33073
|
-
success: true,
|
|
33074
|
-
message: `\u5DF2\u4FDD\u5B58\u5230\u300C${catName}\u300D\uFF0C\u6807\u7B7E\uFF1A${tagStr}`,
|
|
33075
|
-
data: { id }
|
|
33076
|
-
};
|
|
33077
|
-
} catch (err) {
|
|
33078
|
-
return {
|
|
33079
|
-
success: false,
|
|
33080
|
-
message: `\u4FDD\u5B58\u5931\u8D25\uFF1A${err.message}`
|
|
33081
|
-
};
|
|
33082
|
-
}
|
|
33083
|
-
}
|
|
33084
|
-
async function inkSearch(input) {
|
|
33085
|
-
try {
|
|
33086
|
-
const index = await readIndex();
|
|
33087
|
-
const { results, total } = searchKnowledge(index, {
|
|
33088
|
-
query: input.query,
|
|
33089
|
-
tags: input.tags,
|
|
33090
|
-
category: input.category,
|
|
33091
|
-
date_from: input.date_from,
|
|
33092
|
-
date_to: input.date_to,
|
|
33093
|
-
limit: input.limit
|
|
33094
|
-
});
|
|
33095
|
-
if (total === 0) {
|
|
33096
|
-
return {
|
|
33097
|
-
success: true,
|
|
33098
|
-
message: "\u6CA1\u6709\u627E\u5230\u5339\u914D\u7684\u77E5\u8BC6\u7247\u6BB5",
|
|
33099
|
-
data: { results: [], total: 0 }
|
|
33100
|
-
};
|
|
33101
|
-
}
|
|
33102
|
-
return {
|
|
33103
|
-
success: true,
|
|
33104
|
-
message: `\u627E\u5230 ${total} \u6761\u76F8\u5173\u8BB0\u5F55${total > results.length ? `\uFF0C\u663E\u793A\u524D ${results.length} \u6761` : ""}`,
|
|
33105
|
-
data: { results, total }
|
|
33106
|
-
};
|
|
33107
|
-
} catch (err) {
|
|
33108
|
-
return {
|
|
33109
|
-
success: false,
|
|
33110
|
-
message: `\u641C\u7D22\u5931\u8D25\uFF1A${err.message}`
|
|
33111
|
-
};
|
|
33112
|
-
}
|
|
33113
|
-
}
|
|
33114
|
-
async function inkGet(input) {
|
|
33115
|
-
try {
|
|
33116
|
-
const file = await readKnowledgeFile(input.id);
|
|
33117
|
-
if (!file) {
|
|
33118
|
-
return {
|
|
33119
|
-
success: false,
|
|
33120
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
33121
|
-
};
|
|
33122
|
-
}
|
|
33123
|
-
return {
|
|
33124
|
-
success: true,
|
|
33125
|
-
message: file.meta.title,
|
|
33126
|
-
data: {
|
|
33127
|
-
id: file.meta.id,
|
|
33128
|
-
title: file.meta.title,
|
|
33129
|
-
content: file.content,
|
|
33130
|
-
tags: file.meta.tags,
|
|
33131
|
-
category: file.meta.category,
|
|
33132
|
-
source_type: file.meta.source_type,
|
|
33133
|
-
url: file.meta.url,
|
|
33134
|
-
created_at: file.meta.created_at,
|
|
33135
|
-
updated_at: file.meta.updated_at
|
|
33136
|
-
}
|
|
33137
|
-
};
|
|
33138
|
-
} catch (err) {
|
|
33139
|
-
return {
|
|
33140
|
-
success: false,
|
|
33141
|
-
message: `\u83B7\u53D6\u5931\u8D25\uFF1A${err.message}`
|
|
33142
|
-
};
|
|
33143
|
-
}
|
|
33144
|
-
}
|
|
33145
|
-
async function inkReview(input) {
|
|
33146
|
-
try {
|
|
33147
|
-
const index = await readIndex();
|
|
33148
|
-
const entries = Object.values(index.entries);
|
|
33149
|
-
const now = /* @__PURE__ */ new Date();
|
|
33150
|
-
let dateFrom;
|
|
33151
|
-
let dateTo = now.toISOString();
|
|
33152
|
-
switch (input.period) {
|
|
33153
|
-
case "today":
|
|
33154
|
-
dateFrom = new Date(now.getFullYear(), now.getMonth(), now.getDate()).toISOString();
|
|
33155
|
-
break;
|
|
33156
|
-
case "week": {
|
|
33157
|
-
const weekAgo = new Date(now);
|
|
33158
|
-
weekAgo.setDate(weekAgo.getDate() - 7);
|
|
33159
|
-
dateFrom = weekAgo.toISOString();
|
|
33160
|
-
break;
|
|
33161
|
-
}
|
|
33162
|
-
case "month": {
|
|
33163
|
-
const monthAgo = new Date(now);
|
|
33164
|
-
monthAgo.setMonth(monthAgo.getMonth() - 1);
|
|
33165
|
-
dateFrom = monthAgo.toISOString();
|
|
33166
|
-
break;
|
|
33167
|
-
}
|
|
33168
|
-
case "custom":
|
|
33169
|
-
dateFrom = input.date_from || (/* @__PURE__ */ new Date(0)).toISOString();
|
|
33170
|
-
dateTo = input.date_to || now.toISOString();
|
|
33171
|
-
break;
|
|
33172
|
-
}
|
|
33173
|
-
let filtered = entries.filter(
|
|
33174
|
-
(e) => e.created_at >= dateFrom && e.created_at <= dateTo
|
|
33175
|
-
);
|
|
33176
|
-
if (input.category) {
|
|
33177
|
-
filtered = filtered.filter((e) => e.category === input.category);
|
|
33178
|
-
}
|
|
33179
|
-
filtered.sort((a, b) => b.created_at.localeCompare(a.created_at));
|
|
33180
|
-
const byCategory = {};
|
|
33181
|
-
for (const e of filtered) {
|
|
33182
|
-
byCategory[e.category] = (byCategory[e.category] || 0) + 1;
|
|
33183
|
-
}
|
|
33184
|
-
const tagCounts = {};
|
|
33185
|
-
for (const e of filtered) {
|
|
33186
|
-
for (const t of e.tags) {
|
|
33187
|
-
tagCounts[t] = (tagCounts[t] || 0) + 1;
|
|
33188
|
-
}
|
|
33189
|
-
}
|
|
33190
|
-
const topTags = Object.entries(tagCounts).sort((a, b) => b[1] - a[1]).slice(0, 10).map(([tag, count]) => ({ tag, count }));
|
|
33191
|
-
const categoryNames = {
|
|
33192
|
-
insight: "\u6D1E\u5BDF",
|
|
33193
|
-
decision: "\u51B3\u7B56",
|
|
33194
|
-
analysis: "\u5206\u6790",
|
|
33195
|
-
idea: "\u60F3\u6CD5",
|
|
33196
|
-
reference: "\u53C2\u8003",
|
|
33197
|
-
action: "\u884C\u52A8"
|
|
33198
|
-
};
|
|
33199
|
-
const periodNames = {
|
|
33200
|
-
today: "\u4ECA\u65E5",
|
|
33201
|
-
week: "\u672C\u5468",
|
|
33202
|
-
month: "\u672C\u6708",
|
|
33203
|
-
custom: "\u81EA\u5B9A\u4E49\u65F6\u6BB5"
|
|
33204
|
-
};
|
|
33205
|
-
return {
|
|
33206
|
-
success: true,
|
|
33207
|
-
message: `${periodNames[input.period]}\u77E5\u8BC6\u56DE\u987E\uFF1A\u5171 ${filtered.length} \u6761\u8BB0\u5F55`,
|
|
33208
|
-
data: {
|
|
33209
|
-
period: input.period,
|
|
33210
|
-
date_from: dateFrom,
|
|
33211
|
-
date_to: dateTo,
|
|
33212
|
-
total: filtered.length,
|
|
33213
|
-
by_category: Object.entries(byCategory).map(([cat, count]) => ({
|
|
33214
|
-
category: cat,
|
|
33215
|
-
label: categoryNames[cat] || cat,
|
|
33216
|
-
count
|
|
33217
|
-
})),
|
|
33218
|
-
top_tags: topTags,
|
|
33219
|
-
items: filtered.map((e) => ({
|
|
33220
|
-
id: e.id,
|
|
33221
|
-
title: e.title,
|
|
33222
|
-
category: e.category,
|
|
33223
|
-
tags: e.tags,
|
|
33224
|
-
created_at: e.created_at,
|
|
33225
|
-
preview: e.preview
|
|
33226
|
-
}))
|
|
33227
|
-
}
|
|
33228
|
-
};
|
|
33229
|
-
} catch (err) {
|
|
33230
|
-
return {
|
|
33231
|
-
success: false,
|
|
33232
|
-
message: `\u56DE\u987E\u5931\u8D25\uFF1A${err.message}`
|
|
33233
|
-
};
|
|
33234
|
-
}
|
|
33235
|
-
}
|
|
33236
|
-
async function inkUpdate(input) {
|
|
33237
|
-
try {
|
|
33238
|
-
const { id, ...updates } = input;
|
|
33239
|
-
if (!updates.title && !updates.content && !updates.tags && !updates.category) {
|
|
33240
|
-
return {
|
|
33241
|
-
success: false,
|
|
33242
|
-
message: "\u8BF7\u81F3\u5C11\u63D0\u4F9B\u4E00\u4E2A\u8981\u66F4\u65B0\u7684\u5B57\u6BB5\uFF08title / content / tags / category\uFF09"
|
|
33243
|
-
};
|
|
33244
|
-
}
|
|
33245
|
-
const result = await updateKnowledgeFile(id, updates);
|
|
33246
|
-
if (!result) {
|
|
33247
|
-
return {
|
|
33248
|
-
success: false,
|
|
33249
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
33250
|
-
};
|
|
33251
|
-
}
|
|
33252
|
-
const changed = Object.keys(updates).filter(
|
|
33253
|
-
(k) => updates[k] !== void 0
|
|
33254
|
-
);
|
|
33255
|
-
fireAndForgetPush({
|
|
33256
|
-
knowledge: [{
|
|
33257
|
-
id: result.meta.id,
|
|
33258
|
-
title: result.meta.title,
|
|
33259
|
-
tags: result.meta.tags,
|
|
33260
|
-
category: result.meta.category,
|
|
33261
|
-
source_type: result.meta.source_type,
|
|
33262
|
-
url: result.meta.url,
|
|
33263
|
-
created_at: result.meta.created_at,
|
|
33264
|
-
updated_at: result.meta.updated_at
|
|
33265
|
-
}]
|
|
33266
|
-
});
|
|
33267
|
-
return {
|
|
33268
|
-
success: true,
|
|
33269
|
-
message: `\u5DF2\u66F4\u65B0\u300C${result.meta.title}\u300D\u7684 ${changed.join("\u3001")}`,
|
|
33270
|
-
data: {
|
|
33271
|
-
id: result.meta.id,
|
|
33272
|
-
title: result.meta.title,
|
|
33273
|
-
tags: result.meta.tags,
|
|
33274
|
-
category: result.meta.category,
|
|
33275
|
-
updated_at: result.meta.updated_at
|
|
33276
|
-
}
|
|
33277
|
-
};
|
|
33278
|
-
} catch (err) {
|
|
33279
|
-
return {
|
|
33280
|
-
success: false,
|
|
33281
|
-
message: `\u66F4\u65B0\u5931\u8D25\uFF1A${err.message}`
|
|
33282
|
-
};
|
|
33283
|
-
}
|
|
33284
|
-
}
|
|
33285
|
-
async function inkDelete(input) {
|
|
33286
|
-
try {
|
|
33287
|
-
if (!input.confirm) {
|
|
33288
|
-
const index = await readIndex();
|
|
33289
|
-
const entry = index.entries[input.id];
|
|
33290
|
-
if (!entry) {
|
|
33291
|
-
return {
|
|
33292
|
-
success: false,
|
|
33293
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
33294
|
-
};
|
|
33295
|
-
}
|
|
33296
|
-
return {
|
|
33297
|
-
success: false,
|
|
33298
|
-
message: `\u786E\u8BA4\u5220\u9664\u300C${entry.title}\u300D\uFF1F\u8BF7\u5C06 confirm \u8BBE\u4E3A true \u4EE5\u786E\u8BA4\u5220\u9664\u3002`,
|
|
33299
|
-
data: {
|
|
33300
|
-
id: entry.id,
|
|
33301
|
-
title: entry.title,
|
|
33302
|
-
category: entry.category,
|
|
33303
|
-
tags: entry.tags,
|
|
33304
|
-
created_at: entry.created_at
|
|
33305
|
-
}
|
|
33306
|
-
};
|
|
33307
|
-
}
|
|
33308
|
-
const deleted = await deleteKnowledgeFile(input.id);
|
|
33309
|
-
if (!deleted) {
|
|
33310
|
-
return {
|
|
33311
|
-
success: false,
|
|
33312
|
-
message: `\u672A\u627E\u5230 ID \u4E3A ${input.id} \u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
33313
|
-
};
|
|
33314
|
-
}
|
|
33315
|
-
fireAndForgetPush({
|
|
33316
|
-
knowledge: [{
|
|
33317
|
-
id: input.id,
|
|
33318
|
-
title: "",
|
|
33319
|
-
tags: [],
|
|
33320
|
-
category: "reference",
|
|
33321
|
-
source_type: "conversation",
|
|
33322
|
-
created_at: "",
|
|
33323
|
-
updated_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
33324
|
-
}]
|
|
33325
|
-
});
|
|
33326
|
-
return {
|
|
33327
|
-
success: true,
|
|
33328
|
-
message: `\u5DF2\u5220\u9664\u77E5\u8BC6\u7247\u6BB5 ${input.id}`,
|
|
33329
|
-
data: { id: input.id }
|
|
33330
|
-
};
|
|
33331
|
-
} catch (err) {
|
|
33332
|
-
return {
|
|
33333
|
-
success: false,
|
|
33334
|
-
message: `\u5220\u9664\u5931\u8D25\uFF1A${err.message}`
|
|
33335
|
-
};
|
|
33336
|
-
}
|
|
33337
|
-
}
|
|
33338
|
-
async function inkCompile(input) {
|
|
33339
|
-
try {
|
|
33340
|
-
let ids = [];
|
|
33341
|
-
if (input.ids && input.ids.length > 0) {
|
|
33342
|
-
ids = input.ids;
|
|
33343
|
-
} else if (input.query || input.tags && input.tags.length > 0) {
|
|
33344
|
-
const index = await readIndex();
|
|
33345
|
-
const { results } = searchKnowledge(index, {
|
|
33346
|
-
query: input.query,
|
|
33347
|
-
tags: input.tags,
|
|
33348
|
-
limit: 20
|
|
33349
|
-
});
|
|
33350
|
-
ids = results.map((r) => r.id);
|
|
33351
|
-
}
|
|
33352
|
-
if (ids.length === 0) {
|
|
33353
|
-
return {
|
|
33354
|
-
success: false,
|
|
33355
|
-
message: "\u6CA1\u6709\u627E\u5230\u8981\u6574\u5408\u7684\u77E5\u8BC6\u7247\u6BB5\uFF0C\u8BF7\u6307\u5B9A ids \u6216\u63D0\u4F9B\u641C\u7D22\u6761\u4EF6"
|
|
33356
|
-
};
|
|
33357
|
-
}
|
|
33358
|
-
const files = await readMultipleKnowledgeFiles(ids);
|
|
33359
|
-
if (files.length === 0) {
|
|
33360
|
-
return {
|
|
33361
|
-
success: false,
|
|
33362
|
-
message: "\u672A\u80FD\u8BFB\u53D6\u4EFB\u4F55\u77E5\u8BC6\u7247\u6BB5\u5185\u5BB9"
|
|
33363
|
-
};
|
|
33364
|
-
}
|
|
33365
|
-
const sections = files.map((f, i) => {
|
|
33366
|
-
const tagStr = f.meta.tags.length > 0 ? ` [${f.meta.tags.join(", ")}]` : "";
|
|
33367
|
-
return `### ${i + 1}. ${f.meta.title}${tagStr}
|
|
33368
|
-
> ${f.meta.category} | ${f.meta.created_at.slice(0, 10)}
|
|
33369
|
-
|
|
33370
|
-
${f.content}`;
|
|
33371
|
-
});
|
|
33372
|
-
const formatLabels = {
|
|
33373
|
-
outline: "\u5927\u7EB2",
|
|
33374
|
-
article: "\u6587\u7AE0",
|
|
33375
|
-
summary: "\u6458\u8981"
|
|
33376
|
-
};
|
|
33377
|
-
const compiled = sections.join("\n\n---\n\n");
|
|
33378
|
-
return {
|
|
33379
|
-
success: true,
|
|
33380
|
-
message: `\u5DF2\u6574\u5408 ${files.length} \u6761\u77E5\u8BC6\u7247\u6BB5\uFF0C\u683C\u5F0F\uFF1A${formatLabels[input.format]}`,
|
|
33381
|
-
data: {
|
|
33382
|
-
source_count: files.length,
|
|
33383
|
-
source_ids: files.map((f) => f.meta.id),
|
|
33384
|
-
format: input.format,
|
|
33385
|
-
instruction: input.instruction || null,
|
|
33386
|
-
compiled_content: compiled
|
|
33387
|
-
}
|
|
33388
|
-
};
|
|
33389
|
-
} catch (err) {
|
|
33390
|
-
return {
|
|
33391
|
-
success: false,
|
|
33392
|
-
message: `\u6574\u5408\u5931\u8D25\uFF1A${err.message}`
|
|
33393
|
-
};
|
|
33394
|
-
}
|
|
33395
|
-
}
|
|
33396
|
-
async function inkTags(input) {
|
|
33397
|
-
try {
|
|
33398
|
-
const index = await readIndex();
|
|
33399
|
-
switch (input.action) {
|
|
33400
|
-
case "list": {
|
|
33401
|
-
const tags = getAllTags(index);
|
|
33402
|
-
return {
|
|
33403
|
-
success: true,
|
|
33404
|
-
message: tags.length > 0 ? `\u5171 ${tags.length} \u4E2A\u6807\u7B7E` : "\u6682\u65E0\u6807\u7B7E",
|
|
33405
|
-
data: { tags }
|
|
33406
|
-
};
|
|
33407
|
-
}
|
|
33408
|
-
case "rename": {
|
|
33409
|
-
if (!input.tag || !input.new_tag) {
|
|
33410
|
-
return {
|
|
33411
|
-
success: false,
|
|
33412
|
-
message: "rename \u64CD\u4F5C\u9700\u8981\u63D0\u4F9B tag\uFF08\u539F\u6807\u7B7E\uFF09\u548C new_tag\uFF08\u65B0\u6807\u7B7E\u540D\uFF09"
|
|
33413
|
-
};
|
|
33414
|
-
}
|
|
33415
|
-
const count = await renameTag(input.tag, input.new_tag);
|
|
33416
|
-
if (count === 0) {
|
|
33417
|
-
return {
|
|
33418
|
-
success: false,
|
|
33419
|
-
message: `\u672A\u627E\u5230\u4F7F\u7528\u6807\u7B7E\u300C${input.tag}\u300D\u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
33420
|
-
};
|
|
33421
|
-
}
|
|
33422
|
-
return {
|
|
33423
|
-
success: true,
|
|
33424
|
-
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u300C${input.tag}\u300D\u91CD\u547D\u540D\u4E3A\u300C${input.new_tag}\u300D`,
|
|
33425
|
-
data: { old_tag: input.tag, new_tag: input.new_tag, affected: count }
|
|
33426
|
-
};
|
|
33427
|
-
}
|
|
33428
|
-
case "merge": {
|
|
33429
|
-
if (!input.source_tags || input.source_tags.length === 0 || !input.new_tag) {
|
|
33430
|
-
return {
|
|
33431
|
-
success: false,
|
|
33432
|
-
message: "merge \u64CD\u4F5C\u9700\u8981\u63D0\u4F9B source_tags\uFF08\u6E90\u6807\u7B7E\u5217\u8868\uFF09\u548C new_tag\uFF08\u76EE\u6807\u6807\u7B7E\uFF09"
|
|
33433
|
-
};
|
|
33434
|
-
}
|
|
33435
|
-
const count = await mergeTags(input.source_tags, input.new_tag);
|
|
33436
|
-
if (count === 0) {
|
|
33437
|
-
return {
|
|
33438
|
-
success: false,
|
|
33439
|
-
message: `\u672A\u627E\u5230\u4F7F\u7528\u8FD9\u4E9B\u6807\u7B7E\u7684\u77E5\u8BC6\u7247\u6BB5`
|
|
33440
|
-
};
|
|
33441
|
-
}
|
|
33442
|
-
return {
|
|
33443
|
-
success: true,
|
|
33444
|
-
message: `\u5DF2\u5C06 ${count} \u6761\u77E5\u8BC6\u7247\u6BB5\u7684\u6807\u7B7E\u5408\u5E76\u4E3A\u300C${input.new_tag}\u300D`,
|
|
33445
|
-
data: {
|
|
33446
|
-
source_tags: input.source_tags,
|
|
33447
|
-
target_tag: input.new_tag,
|
|
33448
|
-
affected: count
|
|
33449
|
-
}
|
|
33450
|
-
};
|
|
33451
|
-
}
|
|
33452
|
-
}
|
|
33453
|
-
} catch (err) {
|
|
33454
|
-
return {
|
|
33455
|
-
success: false,
|
|
33456
|
-
message: `\u6807\u7B7E\u64CD\u4F5C\u5931\u8D25\uFF1A${err.message}`
|
|
33457
|
-
};
|
|
33458
|
-
}
|
|
33459
|
-
}
|
|
33460
|
-
var inkSaveSchema, inkSearchSchema, inkGetSchema, inkReviewSchema, inkUpdateSchema, inkDeleteSchema, inkCompileSchema, inkTagsSchema;
|
|
33461
|
-
var init_ink = __esm({
|
|
33462
|
-
"src/tools/ink.ts"() {
|
|
33463
|
-
"use strict";
|
|
33464
|
-
init_zod();
|
|
33465
|
-
init_knowledge();
|
|
33466
|
-
init_push();
|
|
33467
|
-
inkSaveSchema = external_exports.object({
|
|
33468
|
-
content: external_exports.string().describe("\u8981\u4FDD\u5B58\u7684\u5185\u5BB9\uFF08\u5FC5\u586B\uFF09"),
|
|
33469
|
-
title: external_exports.string().describe("\u6807\u9898\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF09"),
|
|
33470
|
-
tags: external_exports.array(external_exports.string()).optional().default([]).describe("\u6807\u7B7E\uFF08Claude \u81EA\u52A8\u751F\u6210\uFF0C\u7528\u6237\u53EF\u6307\u5B9A\uFF09"),
|
|
33471
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().default("reference").describe("\u5206\u7C7B\uFF1Ainsight / decision / analysis / idea / reference / action"),
|
|
33472
|
-
source_type: external_exports.enum(["conversation", "url", "manual"]).optional().default("conversation").describe("\u6765\u6E90\u7C7B\u578B\uFF1Aconversation / url / manual"),
|
|
33473
|
-
url: external_exports.string().optional().describe("\u6765\u6E90 URL\uFF08\u5982\u679C\u662F\u5916\u90E8\u7D20\u6750\uFF09")
|
|
33474
|
-
});
|
|
33475
|
-
inkSearchSchema = external_exports.object({
|
|
33476
|
-
query: external_exports.string().optional().describe("\u641C\u7D22\u5173\u952E\u8BCD"),
|
|
33477
|
-
tags: external_exports.array(external_exports.string()).optional().describe("\u6309\u6807\u7B7E\u8FC7\u6EE4"),
|
|
33478
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().describe("\u6309\u5206\u7C7B\u8FC7\u6EE4"),
|
|
33479
|
-
date_from: external_exports.string().optional().describe("\u8D77\u59CB\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF09"),
|
|
33480
|
-
date_to: external_exports.string().optional().describe("\u622A\u6B62\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF09"),
|
|
33481
|
-
limit: external_exports.number().optional().default(10).describe("\u8FD4\u56DE\u6570\u91CF\uFF0C\u9ED8\u8BA4 10")
|
|
33482
|
-
});
|
|
33483
|
-
inkGetSchema = external_exports.object({
|
|
33484
|
-
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID")
|
|
33485
|
-
});
|
|
33486
|
-
inkReviewSchema = external_exports.object({
|
|
33487
|
-
period: external_exports.enum(["today", "week", "month", "custom"]).optional().default("week").describe("\u56DE\u987E\u65F6\u95F4\u6BB5\uFF1Atoday / week / month / custom"),
|
|
33488
|
-
date_from: external_exports.string().optional().describe("\u81EA\u5B9A\u4E49\u8D77\u59CB\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF0Cperiod=custom \u65F6\u4F7F\u7528\uFF09"),
|
|
33489
|
-
date_to: external_exports.string().optional().describe("\u81EA\u5B9A\u4E49\u622A\u6B62\u65E5\u671F\uFF08ISO \u683C\u5F0F\uFF0Cperiod=custom \u65F6\u4F7F\u7528\uFF09"),
|
|
33490
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().describe("\u6309\u5206\u7C7B\u8FC7\u6EE4")
|
|
33491
|
-
});
|
|
33492
|
-
inkUpdateSchema = external_exports.object({
|
|
33493
|
-
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
|
|
33494
|
-
title: external_exports.string().optional().describe("\u65B0\u6807\u9898"),
|
|
33495
|
-
content: external_exports.string().optional().describe("\u65B0\u5185\u5BB9"),
|
|
33496
|
-
tags: external_exports.array(external_exports.string()).optional().describe("\u65B0\u6807\u7B7E\uFF08\u5B8C\u6574\u66FF\u6362\uFF09"),
|
|
33497
|
-
category: external_exports.enum(["insight", "decision", "analysis", "idea", "reference", "action"]).optional().describe("\u65B0\u5206\u7C7B")
|
|
33498
|
-
});
|
|
33499
|
-
inkDeleteSchema = external_exports.object({
|
|
33500
|
-
id: external_exports.string().describe("\u77E5\u8BC6\u7247\u6BB5 ID"),
|
|
33501
|
-
confirm: external_exports.boolean().optional().default(false).describe("\u786E\u8BA4\u5220\u9664\uFF08\u5FC5\u987B\u4E3A true \u624D\u4F1A\u6267\u884C\u5220\u9664\uFF09")
|
|
33502
|
-
});
|
|
33503
|
-
inkCompileSchema = external_exports.object({
|
|
33504
|
-
ids: external_exports.array(external_exports.string()).optional().describe("\u6307\u5B9A\u8981\u6574\u5408\u7684\u77E5\u8BC6\u7247\u6BB5 ID \u5217\u8868"),
|
|
33505
|
-
query: external_exports.string().optional().describe("\u641C\u7D22\u6761\u4EF6\uFF08\u4E0E ids \u4E8C\u9009\u4E00\uFF09"),
|
|
33506
|
-
tags: external_exports.array(external_exports.string()).optional().describe("\u6309\u6807\u7B7E\u7B5B\u9009\uFF08\u4E0E query \u642D\u914D\uFF09"),
|
|
33507
|
-
format: external_exports.enum(["outline", "article", "summary"]).optional().default("summary").describe("\u8F93\u51FA\u683C\u5F0F\uFF1Aoutline\uFF08\u5927\u7EB2\uFF09/ article\uFF08\u6587\u7AE0\uFF09/ summary\uFF08\u6458\u8981\uFF09"),
|
|
33508
|
-
instruction: external_exports.string().optional().describe("\u989D\u5916\u6574\u5408\u6307\u4EE4")
|
|
33509
|
-
});
|
|
33510
|
-
inkTagsSchema = external_exports.object({
|
|
33511
|
-
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"),
|
|
33512
|
-
tag: external_exports.string().optional().describe("\u76EE\u6807\u6807\u7B7E\uFF08rename/merge \u65F6\u4F7F\u7528\uFF09"),
|
|
33513
|
-
new_tag: external_exports.string().optional().describe("\u65B0\u6807\u7B7E\u540D\uFF08rename \u65F6\u4F7F\u7528\uFF09"),
|
|
33514
|
-
source_tags: external_exports.array(external_exports.string()).optional().describe("\u8981\u5408\u5E76\u7684\u6E90\u6807\u7B7E\u5217\u8868\uFF08merge \u65F6\u4F7F\u7528\uFF09")
|
|
33515
|
-
});
|
|
33516
|
-
}
|
|
33517
|
-
});
|
|
33518
|
-
|
|
33519
|
-
// src/index.ts
|
|
33520
|
-
var index_exports = {};
|
|
33521
|
-
async function main() {
|
|
33522
|
-
try {
|
|
33523
|
-
const state = await readState();
|
|
33524
|
-
if (state.config.workflowDir) {
|
|
33525
|
-
setWorkDir(state.config.workflowDir);
|
|
33526
|
-
console.error(`[ClaudeInk MCP] workDir restored: ${state.config.workflowDir}`);
|
|
33527
|
-
}
|
|
33528
|
-
} catch {
|
|
33529
|
-
}
|
|
33530
|
-
const transport = new StdioServerTransport();
|
|
33531
|
-
await server.connect(transport);
|
|
33532
|
-
console.error("[ClaudeInk MCP] Server started on stdio (12 tools)");
|
|
33533
|
-
}
|
|
33534
|
-
var server;
|
|
33535
|
-
var init_index = __esm({
|
|
33536
|
-
"src/index.ts"() {
|
|
33537
|
-
"use strict";
|
|
33538
|
-
init_mcp();
|
|
33539
|
-
init_stdio2();
|
|
33540
|
-
init_source();
|
|
33541
|
-
init_subscribe();
|
|
33542
|
-
init_sync();
|
|
33543
|
-
init_workflow();
|
|
33544
|
-
init_ink();
|
|
33545
|
-
init_state();
|
|
33546
|
-
server = new McpServer({
|
|
33547
|
-
name: "ClaudeInk",
|
|
33548
|
-
version: "1.0.0"
|
|
33549
|
-
});
|
|
33550
|
-
server.tool("workflow.init", "\u521D\u59CB\u5316\u77E5\u8BC6\u5E93\uFF08\u521B\u5EFA\u76EE\u5F55 + \u6FC0\u6D3B License + \u540C\u6B65\u4E91\u7AEF\uFF09", workflowInitSchema.shape, async (input) => {
|
|
33354
|
+
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) => {
|
|
33551
33355
|
const result = await workflowInit(input);
|
|
33552
33356
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33553
33357
|
});
|
|
33554
|
-
server.tool("sync", "\u4ECE\u4E91\u7AEF\u540C\u6B65\u77E5\u8BC6\u5143\u6570\u636E", syncSchema.shape, async (input) => {
|
|
33358
|
+
server.tool("ink.sync", "\u4ECE\u4E91\u7AEF\u540C\u6B65\u77E5\u8BC6\u5143\u6570\u636E", syncSchema.shape, async (input) => {
|
|
33555
33359
|
const result = await sync2(input);
|
|
33556
33360
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33557
33361
|
});
|
|
33558
|
-
server.tool("ink.save", "\u4FDD\u5B58\
|
|
33362
|
+
server.tool("ink.save", "\u4FDD\u5B58\u6216\u66F4\u65B0\u77E5\u8BC6\u7D20\u6750\uFF08\u6709 id \u66F4\u65B0\uFF0C\u65E0 id \u65B0\u5EFA\uFF09", inkSaveSchema.shape, async (input) => {
|
|
33559
33363
|
const result = await inkSave(input);
|
|
33560
33364
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33561
33365
|
});
|
|
33562
|
-
server.tool("ink.search", "\u641C\u7D22\u77E5\u8BC6\u5E93\uFF08\u652F\u6301\u5173\u952E\u8BCD\u3001\u6807\u7B7E\u3001\u5206\u7C7B\u3001\u65F6\u95F4\u8303\u56F4\u8FC7\u6EE4\uFF09", inkSearchSchema.shape, async (input) => {
|
|
33563
|
-
const result = await inkSearch(input);
|
|
33564
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33565
|
-
});
|
|
33566
|
-
server.tool("ink.get", "\u83B7\u53D6\u77E5\u8BC6\u7247\u6BB5\u5B8C\u6574\u5185\u5BB9", inkGetSchema.shape, async (input) => {
|
|
33567
|
-
const result = await inkGet(input);
|
|
33568
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33569
|
-
});
|
|
33570
|
-
server.tool("ink.review", "\u6309\u65F6\u95F4\u6BB5\u56DE\u987E\u77E5\u8BC6\u5E93\uFF08\u7EDF\u8BA1 + \u5217\u8868\uFF09", inkReviewSchema.shape, async (input) => {
|
|
33571
|
-
const result = await inkReview(input);
|
|
33572
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33573
|
-
});
|
|
33574
|
-
server.tool("ink.update", "\u66F4\u65B0\u5DF2\u4FDD\u5B58\u7684\u77E5\u8BC6\u7247\u6BB5\uFF08\u6807\u9898/\u5185\u5BB9/\u6807\u7B7E/\u5206\u7C7B\uFF09", inkUpdateSchema.shape, async (input) => {
|
|
33575
|
-
const result = await inkUpdate(input);
|
|
33576
|
-
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33577
|
-
});
|
|
33578
33366
|
server.tool("ink.delete", "\u5220\u9664\u77E5\u8BC6\u7247\u6BB5\uFF08\u9700\u786E\u8BA4\uFF09", inkDeleteSchema.shape, async (input) => {
|
|
33579
33367
|
const result = await inkDelete(input);
|
|
33580
33368
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33581
33369
|
});
|
|
33582
|
-
server.tool("ink.
|
|
33583
|
-
const result = await
|
|
33370
|
+
server.tool("ink.write", "\u5199\u6587\u7AE0\u4FDD\u5B58\u4E3A\u8349\u7A3F\u3002Claude \u5199\u5B8C\u535A\u5BA2\u6587\u7AE0\u540E\u81EA\u52A8\u8C03\u7528\uFF0C\u63D0\u4F9B\u6807\u9898\u3001Markdown \u5185\u5BB9\u3001\u5C01\u9762\u56FE\u548C\u6807\u7B7E\u3002", inkWriteSchema.shape, async (input) => {
|
|
33371
|
+
const result = await inkWrite(input);
|
|
33584
33372
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33585
33373
|
});
|
|
33586
33374
|
server.tool("ink.tags", "\u6807\u7B7E\u7BA1\u7406\uFF08\u5217\u51FA / \u91CD\u547D\u540D / \u5408\u5E76\u6807\u7B7E\uFF09", inkTagsSchema.shape, async (input) => {
|
|
33587
33375
|
const result = await inkTags(input);
|
|
33588
33376
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33589
33377
|
});
|
|
33590
|
-
server.tool("
|
|
33378
|
+
server.tool("ink.crawl", "\u89E6\u53D1\u722C\u866B\u6293\u53D6\uFF08\u5185\u5BB9\u81EA\u52A8\u5B58\u5165\u77E5\u8BC6\u5E93\uFF09", sourceCrawlSchema.shape, async (input) => {
|
|
33591
33379
|
const result = await sourceCrawl(input);
|
|
33592
33380
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33593
33381
|
});
|
|
33594
|
-
server.tool("
|
|
33382
|
+
server.tool("ink.subscribe", "\u7BA1\u7406\u8BA2\u9605\u6E90\uFF08\u6DFB\u52A0/\u5220\u9664/\u5217\u51FA\u722C\u866B\u6E90\uFF09", sourceSubscribeSchema.shape, async (input) => {
|
|
33595
33383
|
const result = await sourceSubscribe(input);
|
|
33596
33384
|
return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
|
|
33597
33385
|
});
|
|
33598
|
-
main().catch((err) => {
|
|
33599
|
-
|
|
33386
|
+
main().catch(async (err) => {
|
|
33387
|
+
await log("ERROR", "server", `fatal: ${err.message || err}`);
|
|
33600
33388
|
process.exit(1);
|
|
33601
33389
|
});
|
|
33602
33390
|
}
|
|
33603
33391
|
});
|
|
33604
33392
|
|
|
33605
33393
|
// src/cli.ts
|
|
33606
|
-
import { writeFile as writeFile4, readFile as
|
|
33607
|
-
import { join as
|
|
33394
|
+
import { writeFile as writeFile4, readFile as readFile6, mkdir as mkdir6, cp, access as access2 } from "fs/promises";
|
|
33395
|
+
import { join as join7, dirname } from "path";
|
|
33608
33396
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
33609
33397
|
var args = process.argv.slice(2);
|
|
33610
33398
|
var command = args[0];
|
|
33611
33399
|
var __filename = fileURLToPath3(import.meta.url);
|
|
33612
33400
|
var __dirname = dirname(__filename);
|
|
33613
|
-
var WORKFLOW_SRC =
|
|
33401
|
+
var WORKFLOW_SRC = join7(__dirname, "..", "workflow");
|
|
33614
33402
|
async function init() {
|
|
33615
33403
|
const keyIdx = args.indexOf("--key");
|
|
33616
33404
|
const key = keyIdx >= 0 ? args[keyIdx + 1] : void 0;
|
|
@@ -33626,8 +33414,8 @@ async function init() {
|
|
|
33626
33414
|
console.log("\u{1F4E6} \u91CA\u653E\u5DE5\u4F5C\u6D41\u6A21\u677F...");
|
|
33627
33415
|
const items = ["CLAUDE.md", "base-rules.md", "platforms", "accounts", "tools"];
|
|
33628
33416
|
for (const item of items) {
|
|
33629
|
-
const src =
|
|
33630
|
-
const dest =
|
|
33417
|
+
const src = join7(WORKFLOW_SRC, item);
|
|
33418
|
+
const dest = join7(cwd, item);
|
|
33631
33419
|
try {
|
|
33632
33420
|
await access2(dest);
|
|
33633
33421
|
console.log(` \u23ED\uFE0F ${item} \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7`);
|
|
@@ -33647,14 +33435,14 @@ async function init() {
|
|
|
33647
33435
|
".claudeink"
|
|
33648
33436
|
];
|
|
33649
33437
|
for (const dir of dirs) {
|
|
33650
|
-
await
|
|
33438
|
+
await mkdir6(join7(cwd, dir), { recursive: true });
|
|
33651
33439
|
}
|
|
33652
33440
|
console.log(" \u2705 sources/, templates/, .claudeink/");
|
|
33653
33441
|
const { glob: glob2 } = await Promise.resolve().then(() => (init_esm5(), esm_exports));
|
|
33654
33442
|
const yamlFiles = await glob2("accounts/*.yaml", { cwd, ignore: "accounts/_template.yaml" });
|
|
33655
33443
|
for (const yamlFile of yamlFiles) {
|
|
33656
33444
|
try {
|
|
33657
|
-
const content = await
|
|
33445
|
+
const content = await readFile6(join7(cwd, yamlFile), "utf-8");
|
|
33658
33446
|
const idMatch = content.match(/^id:\s*"?([^"\n]+)"?/m);
|
|
33659
33447
|
if (idMatch) {
|
|
33660
33448
|
const id = idMatch[1].trim();
|
|
@@ -33664,9 +33452,9 @@ async function init() {
|
|
|
33664
33452
|
const drafts = (draftsMatch?.[1] || `accounts/${id}/drafts/`).replace("{id}", id).trim();
|
|
33665
33453
|
const published = (publishedMatch?.[1] || `accounts/${id}/published/`).replace("{id}", id).trim();
|
|
33666
33454
|
const assets = (assetsMatch?.[1] || `accounts/${id}/assets/`).replace("{id}", id).trim();
|
|
33667
|
-
await
|
|
33668
|
-
await
|
|
33669
|
-
await
|
|
33455
|
+
await mkdir6(join7(cwd, drafts), { recursive: true });
|
|
33456
|
+
await mkdir6(join7(cwd, published), { recursive: true });
|
|
33457
|
+
await mkdir6(join7(cwd, assets), { recursive: true });
|
|
33670
33458
|
console.log(` \u2705 \u8D26\u53F7 ${id}: ${drafts}, ${published}, ${assets}`);
|
|
33671
33459
|
}
|
|
33672
33460
|
} catch {
|
|
@@ -33682,7 +33470,7 @@ async function init() {
|
|
|
33682
33470
|
const data = await res.json();
|
|
33683
33471
|
if (data.userId) {
|
|
33684
33472
|
await writeFile4(
|
|
33685
|
-
|
|
33473
|
+
join7(cwd, ".claudeink", "credentials.json"),
|
|
33686
33474
|
JSON.stringify(data, null, 2),
|
|
33687
33475
|
{ mode: 384 }
|
|
33688
33476
|
);
|
|
@@ -33696,11 +33484,11 @@ async function init() {
|
|
|
33696
33484
|
console.log(" \u53EF\u7A0D\u540E\u624B\u52A8\u6FC0\u6D3B\u3002");
|
|
33697
33485
|
}
|
|
33698
33486
|
try {
|
|
33699
|
-
await access2(
|
|
33487
|
+
await access2(join7(cwd, "tools", "crawler", "package.json"));
|
|
33700
33488
|
console.log("\n\u{1F4E6} \u5B89\u88C5\u722C\u866B\u4F9D\u8D56...");
|
|
33701
33489
|
const { execSync: execSync2 } = await import("child_process");
|
|
33702
33490
|
execSync2("npm install --silent", {
|
|
33703
|
-
cwd:
|
|
33491
|
+
cwd: join7(cwd, "tools", "crawler"),
|
|
33704
33492
|
stdio: "pipe"
|
|
33705
33493
|
});
|
|
33706
33494
|
console.log(" \u2705 \u722C\u866B\u4F9D\u8D56\u5DF2\u5B89\u88C5");
|