nextclaw-core 0.4.4 → 0.4.5
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/index.d.ts +177 -149
- package/dist/index.js +557 -161
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
// src/agent/context.ts
|
|
2
|
-
import { readFileSync as
|
|
2
|
+
import { readFileSync as readFileSync4, existsSync as existsSync4 } from "fs";
|
|
3
3
|
import { join as join3, extname } from "path";
|
|
4
4
|
|
|
5
5
|
// src/agent/memory.ts
|
|
6
|
-
import { readFileSync, writeFileSync, existsSync as existsSync2, readdirSync } from "fs";
|
|
6
|
+
import { readFileSync as readFileSync2, writeFileSync, existsSync as existsSync2, readdirSync } from "fs";
|
|
7
7
|
import { join } from "path";
|
|
8
8
|
|
|
9
9
|
// src/utils/helpers.ts
|
|
10
|
-
import { existsSync, mkdirSync } from "fs";
|
|
10
|
+
import { existsSync, mkdirSync, readFileSync } from "fs";
|
|
11
11
|
import { homedir } from "os";
|
|
12
12
|
import { resolve } from "path";
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
13
14
|
|
|
14
15
|
// src/config/brand.ts
|
|
15
16
|
var ENV_APP_NAME_KEY = "NEXTCLAW_APP_NAME";
|
|
@@ -85,6 +86,17 @@ function expandHome(value) {
|
|
|
85
86
|
}
|
|
86
87
|
return value;
|
|
87
88
|
}
|
|
89
|
+
function getPackageVersion() {
|
|
90
|
+
try {
|
|
91
|
+
const dir = resolve(fileURLToPath(new URL(".", import.meta.url)));
|
|
92
|
+
const pkgPath = resolve(dir, "..", "..", "package.json");
|
|
93
|
+
const raw = readFileSync(pkgPath, "utf-8");
|
|
94
|
+
const parsed = JSON.parse(raw);
|
|
95
|
+
return typeof parsed.version === "string" ? parsed.version : "0.0.0";
|
|
96
|
+
} catch {
|
|
97
|
+
return "0.0.0";
|
|
98
|
+
}
|
|
99
|
+
}
|
|
88
100
|
|
|
89
101
|
// src/agent/memory.ts
|
|
90
102
|
var MemoryStore = class {
|
|
@@ -103,7 +115,7 @@ var MemoryStore = class {
|
|
|
103
115
|
readToday() {
|
|
104
116
|
const todayFile = this.getTodayFile();
|
|
105
117
|
if (existsSync2(todayFile)) {
|
|
106
|
-
return
|
|
118
|
+
return readFileSync2(todayFile, "utf-8");
|
|
107
119
|
}
|
|
108
120
|
return "";
|
|
109
121
|
}
|
|
@@ -111,7 +123,7 @@ var MemoryStore = class {
|
|
|
111
123
|
const todayFile = this.getTodayFile();
|
|
112
124
|
let nextContent = content;
|
|
113
125
|
if (existsSync2(todayFile)) {
|
|
114
|
-
const existing =
|
|
126
|
+
const existing = readFileSync2(todayFile, "utf-8");
|
|
115
127
|
nextContent = `${existing}
|
|
116
128
|
${content}`;
|
|
117
129
|
} else {
|
|
@@ -124,13 +136,13 @@ ${content}`;
|
|
|
124
136
|
}
|
|
125
137
|
readLongTerm() {
|
|
126
138
|
if (existsSync2(this.memoryFile)) {
|
|
127
|
-
return
|
|
139
|
+
return readFileSync2(this.memoryFile, "utf-8");
|
|
128
140
|
}
|
|
129
141
|
return "";
|
|
130
142
|
}
|
|
131
143
|
readWorkspaceMemory() {
|
|
132
144
|
if (existsSync2(this.workspaceMemoryFile)) {
|
|
133
|
-
return
|
|
145
|
+
return readFileSync2(this.workspaceMemoryFile, "utf-8");
|
|
134
146
|
}
|
|
135
147
|
return "";
|
|
136
148
|
}
|
|
@@ -146,7 +158,7 @@ ${content}`;
|
|
|
146
158
|
const dateStr = date.toISOString().slice(0, 10);
|
|
147
159
|
const path = join(this.memoryDir, `${dateStr}.md`);
|
|
148
160
|
if (existsSync2(path)) {
|
|
149
|
-
memories.push(
|
|
161
|
+
memories.push(readFileSync2(path, "utf-8"));
|
|
150
162
|
}
|
|
151
163
|
}
|
|
152
164
|
return memories.length ? memories.join("\n\n---\n\n") : "";
|
|
@@ -179,10 +191,10 @@ ${today}`);
|
|
|
179
191
|
};
|
|
180
192
|
|
|
181
193
|
// src/agent/skills.ts
|
|
182
|
-
import { readFileSync as
|
|
194
|
+
import { readFileSync as readFileSync3, existsSync as existsSync3, readdirSync as readdirSync2 } from "fs";
|
|
183
195
|
import { join as join2 } from "path";
|
|
184
|
-
import { fileURLToPath } from "url";
|
|
185
|
-
var BUILTIN_SKILLS_DIR = join2(
|
|
196
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
197
|
+
var BUILTIN_SKILLS_DIR = join2(fileURLToPath2(new URL(".", import.meta.url)), "skills");
|
|
186
198
|
var SkillsLoader = class {
|
|
187
199
|
constructor(workspace, builtinSkillsDir) {
|
|
188
200
|
this.workspace = workspace;
|
|
@@ -223,11 +235,11 @@ var SkillsLoader = class {
|
|
|
223
235
|
loadSkill(name) {
|
|
224
236
|
const workspaceSkill = join2(this.workspaceSkills, name, "SKILL.md");
|
|
225
237
|
if (existsSync3(workspaceSkill)) {
|
|
226
|
-
return
|
|
238
|
+
return readFileSync3(workspaceSkill, "utf-8");
|
|
227
239
|
}
|
|
228
240
|
const builtinSkill = join2(this.builtinSkills, name, "SKILL.md");
|
|
229
241
|
if (existsSync3(builtinSkill)) {
|
|
230
|
-
return
|
|
242
|
+
return readFileSync3(builtinSkill, "utf-8");
|
|
231
243
|
}
|
|
232
244
|
return null;
|
|
233
245
|
}
|
|
@@ -601,7 +613,7 @@ Your workspace is at: ${this.workspace}
|
|
|
601
613
|
for (const filename of fileList) {
|
|
602
614
|
const filePath = join3(this.workspace, filename);
|
|
603
615
|
if (existsSync4(filePath)) {
|
|
604
|
-
const raw =
|
|
616
|
+
const raw = readFileSync4(filePath, "utf-8").trim();
|
|
605
617
|
if (!raw) {
|
|
606
618
|
continue;
|
|
607
619
|
}
|
|
@@ -674,7 +686,7 @@ ${truncated}`;
|
|
|
674
686
|
continue;
|
|
675
687
|
}
|
|
676
688
|
try {
|
|
677
|
-
const b64 =
|
|
689
|
+
const b64 = readFileSync4(path).toString("base64");
|
|
678
690
|
images.push({ type: "image_url", image_url: { url: `data:${mime};base64,${b64}` } });
|
|
679
691
|
} catch {
|
|
680
692
|
continue;
|
|
@@ -746,7 +758,7 @@ var ToolRegistry = class {
|
|
|
746
758
|
};
|
|
747
759
|
|
|
748
760
|
// src/agent/tools/filesystem.ts
|
|
749
|
-
import { readFileSync as
|
|
761
|
+
import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync5, readdirSync as readdirSync3, statSync } from "fs";
|
|
750
762
|
import { resolve as resolve2, dirname } from "path";
|
|
751
763
|
|
|
752
764
|
// src/agent/tools/base.ts
|
|
@@ -861,7 +873,7 @@ var ReadFileTool = class extends Tool {
|
|
|
861
873
|
if (!existsSync5(path)) {
|
|
862
874
|
return `Error: File not found: ${path}`;
|
|
863
875
|
}
|
|
864
|
-
return
|
|
876
|
+
return readFileSync5(path, "utf-8");
|
|
865
877
|
}
|
|
866
878
|
};
|
|
867
879
|
var WriteFileTool = class extends Tool {
|
|
@@ -925,7 +937,7 @@ var EditFileTool = class extends Tool {
|
|
|
925
937
|
}
|
|
926
938
|
const oldText = String(params.oldText ?? "");
|
|
927
939
|
const newText = String(params.newText ?? "");
|
|
928
|
-
const content =
|
|
940
|
+
const content = readFileSync5(path, "utf-8");
|
|
929
941
|
if (!content.includes(oldText)) {
|
|
930
942
|
return "Error: Text to replace not found";
|
|
931
943
|
}
|
|
@@ -1670,7 +1682,7 @@ var SessionsSendTool = class extends Tool {
|
|
|
1670
1682
|
};
|
|
1671
1683
|
|
|
1672
1684
|
// src/agent/tools/memory.ts
|
|
1673
|
-
import { existsSync as existsSync6, readFileSync as
|
|
1685
|
+
import { existsSync as existsSync6, readFileSync as readFileSync6, readdirSync as readdirSync4 } from "fs";
|
|
1674
1686
|
import { join as join4, resolve as resolve4 } from "path";
|
|
1675
1687
|
var DEFAULT_LIMIT2 = 20;
|
|
1676
1688
|
var DEFAULT_CONTEXT_LINES = 0;
|
|
@@ -1735,7 +1747,7 @@ var MemorySearchTool = class extends Tool {
|
|
|
1735
1747
|
const results = [];
|
|
1736
1748
|
const files = getMemoryFiles(this.workspace);
|
|
1737
1749
|
for (const filePath of files) {
|
|
1738
|
-
const content =
|
|
1750
|
+
const content = readFileSync6(filePath, "utf-8");
|
|
1739
1751
|
const lines = content.split("\n");
|
|
1740
1752
|
for (let i = 0; i < lines.length; i += 1) {
|
|
1741
1753
|
if (lines[i].toLowerCase().includes(lowerQuery)) {
|
|
@@ -1799,7 +1811,7 @@ var MemoryGetTool = class extends Tool {
|
|
|
1799
1811
|
if (!existsSync6(resolvedPath)) {
|
|
1800
1812
|
return `Error: file not found: ${resolvedPath}`;
|
|
1801
1813
|
}
|
|
1802
|
-
const content =
|
|
1814
|
+
const content = readFileSync6(resolvedPath, "utf-8");
|
|
1803
1815
|
const lines = content.split("\n");
|
|
1804
1816
|
const startLine = toInt2(params.from ?? params.startLine, 1);
|
|
1805
1817
|
const requestedLines = toInt2(params.lines ?? params.endLine, Math.max(lines.length - startLine + 1, 1));
|
|
@@ -2268,7 +2280,7 @@ When you have completed the task, provide a clear summary of your findings or ac
|
|
|
2268
2280
|
};
|
|
2269
2281
|
|
|
2270
2282
|
// src/session/manager.ts
|
|
2271
|
-
import { readFileSync as
|
|
2283
|
+
import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync7, readdirSync as readdirSync5, unlinkSync } from "fs";
|
|
2272
2284
|
import { join as join5 } from "path";
|
|
2273
2285
|
var SessionManager = class {
|
|
2274
2286
|
constructor(workspace) {
|
|
@@ -2350,7 +2362,7 @@ var SessionManager = class {
|
|
|
2350
2362
|
return null;
|
|
2351
2363
|
}
|
|
2352
2364
|
try {
|
|
2353
|
-
const lines =
|
|
2365
|
+
const lines = readFileSync7(path, "utf-8").split("\n").filter(Boolean);
|
|
2354
2366
|
const messages = [];
|
|
2355
2367
|
let metadata = {};
|
|
2356
2368
|
let createdAt = /* @__PURE__ */ new Date();
|
|
@@ -2409,7 +2421,7 @@ var SessionManager = class {
|
|
|
2409
2421
|
continue;
|
|
2410
2422
|
}
|
|
2411
2423
|
const path = join5(this.sessionsDir, entry.name);
|
|
2412
|
-
const firstLine =
|
|
2424
|
+
const firstLine = readFileSync7(path, "utf-8").split("\n")[0];
|
|
2413
2425
|
if (!firstLine) {
|
|
2414
2426
|
continue;
|
|
2415
2427
|
}
|
|
@@ -3634,7 +3646,7 @@ function parseMdTable(tableText) {
|
|
|
3634
3646
|
import { io } from "socket.io-client";
|
|
3635
3647
|
import { fetch as fetch5 } from "undici";
|
|
3636
3648
|
import { join as join8 } from "path";
|
|
3637
|
-
import { mkdirSync as mkdirSync4, existsSync as existsSync9, readFileSync as
|
|
3649
|
+
import { mkdirSync as mkdirSync4, existsSync as existsSync9, readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
3638
3650
|
var MAX_SEEN_MESSAGE_IDS = 2e3;
|
|
3639
3651
|
var CURSOR_SAVE_DEBOUNCE_MS = 500;
|
|
3640
3652
|
var AsyncLock = class {
|
|
@@ -4347,7 +4359,7 @@ var MochatChannel = class extends BaseChannel {
|
|
|
4347
4359
|
return;
|
|
4348
4360
|
}
|
|
4349
4361
|
try {
|
|
4350
|
-
const raw =
|
|
4362
|
+
const raw = readFileSync8(this.cursorPath, "utf-8");
|
|
4351
4363
|
const data = JSON.parse(raw);
|
|
4352
4364
|
const cursors = data.cursors;
|
|
4353
4365
|
if (cursors && typeof cursors === "object") {
|
|
@@ -5303,12 +5315,13 @@ var ChannelManager = class {
|
|
|
5303
5315
|
};
|
|
5304
5316
|
|
|
5305
5317
|
// src/config/loader.ts
|
|
5306
|
-
import { readFileSync as
|
|
5318
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync6, existsSync as existsSync10, mkdirSync as mkdirSync5 } from "fs";
|
|
5307
5319
|
import { resolve as resolve5 } from "path";
|
|
5308
|
-
import { z as
|
|
5320
|
+
import { z as z3 } from "zod";
|
|
5309
5321
|
|
|
5310
5322
|
// src/config/schema.ts
|
|
5311
|
-
import { z } from "zod";
|
|
5323
|
+
import { z as z2 } from "zod";
|
|
5324
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
5312
5325
|
|
|
5313
5326
|
// src/providers/registry.ts
|
|
5314
5327
|
var PROVIDERS = [
|
|
@@ -5541,117 +5554,419 @@ function providerLabel(spec) {
|
|
|
5541
5554
|
return spec.displayName || spec.name;
|
|
5542
5555
|
}
|
|
5543
5556
|
|
|
5557
|
+
// src/config/schema.hints.ts
|
|
5558
|
+
import { z } from "zod";
|
|
5559
|
+
|
|
5560
|
+
// src/config/schema.help.ts
|
|
5561
|
+
var FIELD_HELP = {
|
|
5562
|
+
"agents.defaults.workspace": "Workspace directory for agent context files and memory.",
|
|
5563
|
+
"agents.defaults.model": "Default model identifier used by the agent.",
|
|
5564
|
+
"agents.defaults.maxTokens": "Maximum tokens per response.",
|
|
5565
|
+
"agents.defaults.temperature": "Sampling temperature for model responses.",
|
|
5566
|
+
"agents.defaults.maxToolIterations": "Maximum tool calls per turn.",
|
|
5567
|
+
"agents.context.bootstrap.files": "Files injected into the system prompt at startup.",
|
|
5568
|
+
"agents.context.bootstrap.minimalFiles": "Minimal file set used for low-context runs.",
|
|
5569
|
+
"agents.context.bootstrap.heartbeatFiles": "Files checked periodically for tasks.",
|
|
5570
|
+
"agents.context.bootstrap.perFileChars": "Max chars per bootstrap file.",
|
|
5571
|
+
"agents.context.bootstrap.totalChars": "Max total chars across bootstrap files.",
|
|
5572
|
+
"agents.context.memory.enabled": "Enable memory injection from memory files.",
|
|
5573
|
+
"agents.context.memory.maxChars": "Max characters of memory injected per turn.",
|
|
5574
|
+
"providers.*.apiKey": "API key for this provider.",
|
|
5575
|
+
"providers.*.apiBase": "Override the provider API base URL if needed.",
|
|
5576
|
+
"providers.*.extraHeaders": "Extra headers to send to the provider.",
|
|
5577
|
+
"providers.*.wireApi": "Select API mode (auto/chat/responses) for providers that support it.",
|
|
5578
|
+
"gateway.host": "Bind address for the gateway server.",
|
|
5579
|
+
"gateway.port": "Port for the gateway server.",
|
|
5580
|
+
"ui.enabled": "Enable the built-in UI server.",
|
|
5581
|
+
"ui.host": "Bind address for the UI server.",
|
|
5582
|
+
"ui.port": "Port for the UI server.",
|
|
5583
|
+
"ui.open": "Open the browser when UI starts.",
|
|
5584
|
+
"tools.web.search.apiKey": "API key for the configured web search provider.",
|
|
5585
|
+
"tools.web.search.maxResults": "Default number of search results.",
|
|
5586
|
+
"tools.exec.timeout": "Command execution timeout (seconds).",
|
|
5587
|
+
"tools.restrictToWorkspace": "Restrict tools to the workspace directory.",
|
|
5588
|
+
"channels.whatsapp.bridgeUrl": "WebSocket URL for the WhatsApp bridge.",
|
|
5589
|
+
"channels.telegram.token": "Telegram bot token.",
|
|
5590
|
+
"channels.telegram.proxy": "Optional HTTP proxy for Telegram.",
|
|
5591
|
+
"channels.discord.token": "Discord bot token.",
|
|
5592
|
+
"channels.discord.gatewayUrl": "Override Discord gateway URL.",
|
|
5593
|
+
"channels.discord.intents": "Gateway intents bitmask.",
|
|
5594
|
+
"channels.feishu.appId": "Feishu app ID.",
|
|
5595
|
+
"channels.feishu.appSecret": "Feishu app secret.",
|
|
5596
|
+
"channels.feishu.encryptKey": "Feishu encrypt key (if enabled).",
|
|
5597
|
+
"channels.feishu.verificationToken": "Feishu verification token.",
|
|
5598
|
+
"channels.dingtalk.clientId": "DingTalk client ID.",
|
|
5599
|
+
"channels.dingtalk.clientSecret": "DingTalk client secret.",
|
|
5600
|
+
"channels.mochat.baseUrl": "Base URL for Mochat API.",
|
|
5601
|
+
"channels.mochat.socketUrl": "WebSocket URL for Mochat (optional override).",
|
|
5602
|
+
"channels.mochat.socketPath": "Socket.IO path for Mochat.",
|
|
5603
|
+
"channels.mochat.clawToken": "Mochat claw token.",
|
|
5604
|
+
"channels.mochat.agentUserId": "Mochat agent user id.",
|
|
5605
|
+
"channels.mochat.replyDelayMode": "Reply delay policy for Mochat.",
|
|
5606
|
+
"channels.mochat.replyDelayMs": "Reply delay duration in milliseconds.",
|
|
5607
|
+
"channels.slack.mode": "Slack connection mode (socket or webhook).",
|
|
5608
|
+
"channels.slack.webhookPath": "Slack webhook path when using webhook mode.",
|
|
5609
|
+
"channels.slack.botToken": "Slack bot token.",
|
|
5610
|
+
"channels.slack.appToken": "Slack app-level token.",
|
|
5611
|
+
"channels.slack.groupPolicy": "Group policy for Slack channels.",
|
|
5612
|
+
"channels.slack.dm.policy": "DM policy for Slack.",
|
|
5613
|
+
"channels.email.imapHost": "IMAP server host.",
|
|
5614
|
+
"channels.email.imapPort": "IMAP server port.",
|
|
5615
|
+
"channels.email.imapUsername": "IMAP username.",
|
|
5616
|
+
"channels.email.imapPassword": "IMAP password.",
|
|
5617
|
+
"channels.email.smtpHost": "SMTP server host.",
|
|
5618
|
+
"channels.email.smtpPort": "SMTP server port.",
|
|
5619
|
+
"channels.email.smtpUsername": "SMTP username.",
|
|
5620
|
+
"channels.email.smtpPassword": "SMTP password.",
|
|
5621
|
+
"channels.email.fromAddress": "Default From address for outgoing mail.",
|
|
5622
|
+
"channels.email.pollIntervalSeconds": "Polling interval in seconds.",
|
|
5623
|
+
"channels.email.maxBodyChars": "Max chars to read from incoming emails.",
|
|
5624
|
+
"channels.email.subjectPrefix": "Prefix used for reply subjects.",
|
|
5625
|
+
"channels.qq.appId": "QQ app ID.",
|
|
5626
|
+
"channels.qq.secret": "QQ app secret."
|
|
5627
|
+
};
|
|
5628
|
+
|
|
5629
|
+
// src/config/schema.labels.ts
|
|
5630
|
+
var FIELD_LABELS = {
|
|
5631
|
+
agents: "Agents",
|
|
5632
|
+
"agents.defaults": "Agent Defaults",
|
|
5633
|
+
"agents.defaults.workspace": "Workspace",
|
|
5634
|
+
"agents.defaults.model": "Default Model",
|
|
5635
|
+
"agents.defaults.maxTokens": "Max Tokens",
|
|
5636
|
+
"agents.defaults.temperature": "Temperature",
|
|
5637
|
+
"agents.defaults.maxToolIterations": "Max Tool Iterations",
|
|
5638
|
+
"agents.context": "Context",
|
|
5639
|
+
"agents.context.bootstrap": "Bootstrap Files",
|
|
5640
|
+
"agents.context.bootstrap.files": "Bootstrap Files",
|
|
5641
|
+
"agents.context.bootstrap.minimalFiles": "Minimal Files",
|
|
5642
|
+
"agents.context.bootstrap.heartbeatFiles": "Heartbeat Files",
|
|
5643
|
+
"agents.context.bootstrap.perFileChars": "Max Chars per File",
|
|
5644
|
+
"agents.context.bootstrap.totalChars": "Total Bootstrap Chars",
|
|
5645
|
+
"agents.context.memory": "Memory",
|
|
5646
|
+
"agents.context.memory.enabled": "Enable Memory",
|
|
5647
|
+
"agents.context.memory.maxChars": "Max Memory Chars",
|
|
5648
|
+
providers: "Providers",
|
|
5649
|
+
"providers.*.apiKey": "API Key",
|
|
5650
|
+
"providers.*.apiBase": "API Base URL",
|
|
5651
|
+
"providers.*.extraHeaders": "Extra Headers",
|
|
5652
|
+
"providers.*.wireApi": "Wire API Mode",
|
|
5653
|
+
channels: "Channels",
|
|
5654
|
+
gateway: "Gateway",
|
|
5655
|
+
"gateway.host": "Gateway Host",
|
|
5656
|
+
"gateway.port": "Gateway Port",
|
|
5657
|
+
ui: "UI",
|
|
5658
|
+
"ui.enabled": "Enable UI",
|
|
5659
|
+
"ui.host": "UI Host",
|
|
5660
|
+
"ui.port": "UI Port",
|
|
5661
|
+
"ui.open": "Open Browser",
|
|
5662
|
+
tools: "Tools",
|
|
5663
|
+
"tools.web": "Web Tools",
|
|
5664
|
+
"tools.web.search": "Web Search",
|
|
5665
|
+
"tools.web.search.apiKey": "Search API Key",
|
|
5666
|
+
"tools.web.search.maxResults": "Max Results",
|
|
5667
|
+
"tools.exec": "Command Execution",
|
|
5668
|
+
"tools.exec.timeout": "Exec Timeout (seconds)",
|
|
5669
|
+
"tools.restrictToWorkspace": "Restrict Tools to Workspace",
|
|
5670
|
+
"channels.whatsapp": "WhatsApp",
|
|
5671
|
+
"channels.whatsapp.enabled": "Enabled",
|
|
5672
|
+
"channels.whatsapp.bridgeUrl": "Bridge URL",
|
|
5673
|
+
"channels.whatsapp.allowFrom": "Allow From",
|
|
5674
|
+
"channels.telegram": "Telegram",
|
|
5675
|
+
"channels.telegram.enabled": "Enabled",
|
|
5676
|
+
"channels.telegram.token": "Bot Token",
|
|
5677
|
+
"channels.telegram.allowFrom": "Allow From",
|
|
5678
|
+
"channels.telegram.proxy": "Proxy",
|
|
5679
|
+
"channels.discord": "Discord",
|
|
5680
|
+
"channels.discord.enabled": "Enabled",
|
|
5681
|
+
"channels.discord.token": "Bot Token",
|
|
5682
|
+
"channels.discord.allowFrom": "Allow From",
|
|
5683
|
+
"channels.discord.gatewayUrl": "Gateway URL",
|
|
5684
|
+
"channels.discord.intents": "Gateway Intents",
|
|
5685
|
+
"channels.feishu": "Feishu",
|
|
5686
|
+
"channels.feishu.enabled": "Enabled",
|
|
5687
|
+
"channels.feishu.appId": "App ID",
|
|
5688
|
+
"channels.feishu.appSecret": "App Secret",
|
|
5689
|
+
"channels.feishu.encryptKey": "Encrypt Key",
|
|
5690
|
+
"channels.feishu.verificationToken": "Verification Token",
|
|
5691
|
+
"channels.feishu.allowFrom": "Allow From",
|
|
5692
|
+
"channels.dingtalk": "DingTalk",
|
|
5693
|
+
"channels.dingtalk.enabled": "Enabled",
|
|
5694
|
+
"channels.dingtalk.clientId": "Client ID",
|
|
5695
|
+
"channels.dingtalk.clientSecret": "Client Secret",
|
|
5696
|
+
"channels.dingtalk.allowFrom": "Allow From",
|
|
5697
|
+
"channels.mochat": "Mochat",
|
|
5698
|
+
"channels.mochat.enabled": "Enabled",
|
|
5699
|
+
"channels.mochat.baseUrl": "Base URL",
|
|
5700
|
+
"channels.mochat.socketUrl": "Socket URL",
|
|
5701
|
+
"channels.mochat.socketPath": "Socket Path",
|
|
5702
|
+
"channels.mochat.clawToken": "Claw Token",
|
|
5703
|
+
"channels.mochat.agentUserId": "Agent User ID",
|
|
5704
|
+
"channels.mochat.allowFrom": "Allow From",
|
|
5705
|
+
"channels.mochat.replyDelayMode": "Reply Delay Mode",
|
|
5706
|
+
"channels.mochat.replyDelayMs": "Reply Delay (ms)",
|
|
5707
|
+
"channels.slack": "Slack",
|
|
5708
|
+
"channels.slack.enabled": "Enabled",
|
|
5709
|
+
"channels.slack.mode": "Mode",
|
|
5710
|
+
"channels.slack.webhookPath": "Webhook Path",
|
|
5711
|
+
"channels.slack.botToken": "Bot Token",
|
|
5712
|
+
"channels.slack.appToken": "App Token",
|
|
5713
|
+
"channels.slack.userTokenReadOnly": "User Token Read Only",
|
|
5714
|
+
"channels.slack.groupPolicy": "Group Policy",
|
|
5715
|
+
"channels.slack.groupAllowFrom": "Group Allow From",
|
|
5716
|
+
"channels.slack.dm": "DM",
|
|
5717
|
+
"channels.slack.dm.enabled": "Enabled",
|
|
5718
|
+
"channels.slack.dm.policy": "DM Policy",
|
|
5719
|
+
"channels.slack.dm.allowFrom": "Allow From",
|
|
5720
|
+
"channels.email": "Email",
|
|
5721
|
+
"channels.email.enabled": "Enabled",
|
|
5722
|
+
"channels.email.imapHost": "IMAP Host",
|
|
5723
|
+
"channels.email.imapPort": "IMAP Port",
|
|
5724
|
+
"channels.email.imapUsername": "IMAP Username",
|
|
5725
|
+
"channels.email.imapPassword": "IMAP Password",
|
|
5726
|
+
"channels.email.smtpHost": "SMTP Host",
|
|
5727
|
+
"channels.email.smtpPort": "SMTP Port",
|
|
5728
|
+
"channels.email.smtpUsername": "SMTP Username",
|
|
5729
|
+
"channels.email.smtpPassword": "SMTP Password",
|
|
5730
|
+
"channels.email.fromAddress": "From Address",
|
|
5731
|
+
"channels.email.pollIntervalSeconds": "Poll Interval (seconds)",
|
|
5732
|
+
"channels.email.maxBodyChars": "Max Body Chars",
|
|
5733
|
+
"channels.email.subjectPrefix": "Subject Prefix",
|
|
5734
|
+
"channels.email.allowFrom": "Allow From",
|
|
5735
|
+
"channels.qq": "QQ",
|
|
5736
|
+
"channels.qq.enabled": "Enabled",
|
|
5737
|
+
"channels.qq.appId": "App ID",
|
|
5738
|
+
"channels.qq.secret": "App Secret",
|
|
5739
|
+
"channels.qq.markdownSupport": "Markdown Support",
|
|
5740
|
+
"channels.qq.allowFrom": "Allow From"
|
|
5741
|
+
};
|
|
5742
|
+
|
|
5743
|
+
// src/config/schema.hints.ts
|
|
5744
|
+
var GROUP_LABELS = {
|
|
5745
|
+
agents: "Agents",
|
|
5746
|
+
providers: "Providers",
|
|
5747
|
+
channels: "Channels",
|
|
5748
|
+
tools: "Tools",
|
|
5749
|
+
gateway: "Gateway",
|
|
5750
|
+
ui: "UI"
|
|
5751
|
+
};
|
|
5752
|
+
var GROUP_ORDER = {
|
|
5753
|
+
agents: 20,
|
|
5754
|
+
providers: 30,
|
|
5755
|
+
channels: 40,
|
|
5756
|
+
tools: 50,
|
|
5757
|
+
gateway: 60,
|
|
5758
|
+
ui: 70
|
|
5759
|
+
};
|
|
5760
|
+
var FIELD_PLACEHOLDERS = {
|
|
5761
|
+
"gateway.host": "0.0.0.0",
|
|
5762
|
+
"gateway.port": "18790",
|
|
5763
|
+
"ui.host": "127.0.0.1",
|
|
5764
|
+
"ui.port": "18791",
|
|
5765
|
+
"providers.*.apiBase": "https://api.example.com"
|
|
5766
|
+
};
|
|
5767
|
+
var SENSITIVE_KEY_WHITELIST_SUFFIXES = [
|
|
5768
|
+
"maxtokens",
|
|
5769
|
+
"maxoutputtokens",
|
|
5770
|
+
"maxinputtokens",
|
|
5771
|
+
"maxcompletiontokens",
|
|
5772
|
+
"contexttokens",
|
|
5773
|
+
"totaltokens",
|
|
5774
|
+
"tokencount",
|
|
5775
|
+
"tokenlimit",
|
|
5776
|
+
"tokenbudget"
|
|
5777
|
+
];
|
|
5778
|
+
var NORMALIZED_SENSITIVE_KEY_WHITELIST_SUFFIXES = SENSITIVE_KEY_WHITELIST_SUFFIXES.map(
|
|
5779
|
+
(suffix) => suffix.toLowerCase()
|
|
5780
|
+
);
|
|
5781
|
+
var SENSITIVE_PATTERNS = [/token$/i, /password/i, /secret/i, /api.?key/i];
|
|
5782
|
+
function isWhitelistedSensitivePath(path) {
|
|
5783
|
+
const lowerPath = path.toLowerCase();
|
|
5784
|
+
return NORMALIZED_SENSITIVE_KEY_WHITELIST_SUFFIXES.some((suffix) => lowerPath.endsWith(suffix));
|
|
5785
|
+
}
|
|
5786
|
+
function matchesSensitivePattern(path) {
|
|
5787
|
+
return SENSITIVE_PATTERNS.some((pattern) => pattern.test(path));
|
|
5788
|
+
}
|
|
5789
|
+
function isSensitiveConfigPath(path) {
|
|
5790
|
+
return !isWhitelistedSensitivePath(path) && matchesSensitivePattern(path);
|
|
5791
|
+
}
|
|
5792
|
+
function buildBaseHints() {
|
|
5793
|
+
const hints = {};
|
|
5794
|
+
for (const [group, label] of Object.entries(GROUP_LABELS)) {
|
|
5795
|
+
hints[group] = {
|
|
5796
|
+
label,
|
|
5797
|
+
group: label,
|
|
5798
|
+
order: GROUP_ORDER[group]
|
|
5799
|
+
};
|
|
5800
|
+
}
|
|
5801
|
+
for (const [path, label] of Object.entries(FIELD_LABELS)) {
|
|
5802
|
+
const current = hints[path];
|
|
5803
|
+
hints[path] = current ? { ...current, label } : { label };
|
|
5804
|
+
}
|
|
5805
|
+
for (const [path, help] of Object.entries(FIELD_HELP)) {
|
|
5806
|
+
const current = hints[path];
|
|
5807
|
+
hints[path] = current ? { ...current, help } : { help };
|
|
5808
|
+
}
|
|
5809
|
+
for (const [path, placeholder] of Object.entries(FIELD_PLACEHOLDERS)) {
|
|
5810
|
+
const current = hints[path];
|
|
5811
|
+
hints[path] = current ? { ...current, placeholder } : { placeholder };
|
|
5812
|
+
}
|
|
5813
|
+
return hints;
|
|
5814
|
+
}
|
|
5815
|
+
function applySensitiveHints(hints) {
|
|
5816
|
+
const next = { ...hints };
|
|
5817
|
+
for (const key of Object.keys(next)) {
|
|
5818
|
+
if (next[key]?.sensitive !== void 0) {
|
|
5819
|
+
continue;
|
|
5820
|
+
}
|
|
5821
|
+
if (isSensitiveConfigPath(key)) {
|
|
5822
|
+
next[key] = { ...next[key], sensitive: true };
|
|
5823
|
+
}
|
|
5824
|
+
}
|
|
5825
|
+
return next;
|
|
5826
|
+
}
|
|
5827
|
+
function isUnwrappable(object) {
|
|
5828
|
+
return !!object && typeof object === "object" && "unwrap" in object && typeof object.unwrap === "function" && !(object instanceof z.ZodArray);
|
|
5829
|
+
}
|
|
5830
|
+
function mapSensitivePaths(schema, path, hints) {
|
|
5831
|
+
let next = { ...hints };
|
|
5832
|
+
let currentSchema = schema;
|
|
5833
|
+
while (isUnwrappable(currentSchema)) {
|
|
5834
|
+
currentSchema = currentSchema.unwrap();
|
|
5835
|
+
}
|
|
5836
|
+
if (path && isSensitiveConfigPath(path) && !next[path]?.sensitive) {
|
|
5837
|
+
next[path] = { ...next[path], sensitive: true };
|
|
5838
|
+
}
|
|
5839
|
+
if (currentSchema instanceof z.ZodObject) {
|
|
5840
|
+
const shape = currentSchema.shape;
|
|
5841
|
+
for (const key in shape) {
|
|
5842
|
+
const nextPath = path ? `${path}.${key}` : key;
|
|
5843
|
+
next = mapSensitivePaths(shape[key], nextPath, next);
|
|
5844
|
+
}
|
|
5845
|
+
} else if (currentSchema instanceof z.ZodArray) {
|
|
5846
|
+
const nextPath = path ? `${path}[]` : "[]";
|
|
5847
|
+
next = mapSensitivePaths(currentSchema.element, nextPath, next);
|
|
5848
|
+
} else if (currentSchema instanceof z.ZodRecord) {
|
|
5849
|
+
const nextPath = path ? `${path}.*` : "*";
|
|
5850
|
+
next = mapSensitivePaths(currentSchema._def.valueType, nextPath, next);
|
|
5851
|
+
} else if (currentSchema instanceof z.ZodUnion || currentSchema instanceof z.ZodDiscriminatedUnion) {
|
|
5852
|
+
for (const option of currentSchema.options) {
|
|
5853
|
+
next = mapSensitivePaths(option, path, next);
|
|
5854
|
+
}
|
|
5855
|
+
}
|
|
5856
|
+
return next;
|
|
5857
|
+
}
|
|
5858
|
+
|
|
5544
5859
|
// src/config/schema.ts
|
|
5545
|
-
var allowFrom =
|
|
5546
|
-
var WhatsAppConfigSchema =
|
|
5547
|
-
enabled:
|
|
5548
|
-
bridgeUrl:
|
|
5860
|
+
var allowFrom = z2.array(z2.string()).default([]);
|
|
5861
|
+
var WhatsAppConfigSchema = z2.object({
|
|
5862
|
+
enabled: z2.boolean().default(false),
|
|
5863
|
+
bridgeUrl: z2.string().default("ws://localhost:3001"),
|
|
5549
5864
|
allowFrom
|
|
5550
5865
|
});
|
|
5551
|
-
var TelegramConfigSchema =
|
|
5552
|
-
enabled:
|
|
5553
|
-
token:
|
|
5866
|
+
var TelegramConfigSchema = z2.object({
|
|
5867
|
+
enabled: z2.boolean().default(false),
|
|
5868
|
+
token: z2.string().default(""),
|
|
5554
5869
|
allowFrom,
|
|
5555
|
-
proxy:
|
|
5870
|
+
proxy: z2.string().nullable().default(null)
|
|
5556
5871
|
});
|
|
5557
|
-
var FeishuConfigSchema =
|
|
5558
|
-
enabled:
|
|
5559
|
-
appId:
|
|
5560
|
-
appSecret:
|
|
5561
|
-
encryptKey:
|
|
5562
|
-
verificationToken:
|
|
5872
|
+
var FeishuConfigSchema = z2.object({
|
|
5873
|
+
enabled: z2.boolean().default(false),
|
|
5874
|
+
appId: z2.string().default(""),
|
|
5875
|
+
appSecret: z2.string().default(""),
|
|
5876
|
+
encryptKey: z2.string().default(""),
|
|
5877
|
+
verificationToken: z2.string().default(""),
|
|
5563
5878
|
allowFrom
|
|
5564
5879
|
});
|
|
5565
|
-
var DingTalkConfigSchema =
|
|
5566
|
-
enabled:
|
|
5567
|
-
clientId:
|
|
5568
|
-
clientSecret:
|
|
5880
|
+
var DingTalkConfigSchema = z2.object({
|
|
5881
|
+
enabled: z2.boolean().default(false),
|
|
5882
|
+
clientId: z2.string().default(""),
|
|
5883
|
+
clientSecret: z2.string().default(""),
|
|
5569
5884
|
allowFrom
|
|
5570
5885
|
});
|
|
5571
|
-
var DiscordConfigSchema =
|
|
5572
|
-
enabled:
|
|
5573
|
-
token:
|
|
5886
|
+
var DiscordConfigSchema = z2.object({
|
|
5887
|
+
enabled: z2.boolean().default(false),
|
|
5888
|
+
token: z2.string().default(""),
|
|
5574
5889
|
allowFrom,
|
|
5575
|
-
gatewayUrl:
|
|
5576
|
-
intents:
|
|
5890
|
+
gatewayUrl: z2.string().default("wss://gateway.discord.gg/?v=10&encoding=json"),
|
|
5891
|
+
intents: z2.number().int().default(37377)
|
|
5577
5892
|
});
|
|
5578
|
-
var EmailConfigSchema =
|
|
5579
|
-
enabled:
|
|
5580
|
-
consentGranted:
|
|
5581
|
-
imapHost:
|
|
5582
|
-
imapPort:
|
|
5583
|
-
imapUsername:
|
|
5584
|
-
imapPassword:
|
|
5585
|
-
imapMailbox:
|
|
5586
|
-
imapUseSsl:
|
|
5587
|
-
smtpHost:
|
|
5588
|
-
smtpPort:
|
|
5589
|
-
smtpUsername:
|
|
5590
|
-
smtpPassword:
|
|
5591
|
-
smtpUseTls:
|
|
5592
|
-
smtpUseSsl:
|
|
5593
|
-
fromAddress:
|
|
5594
|
-
autoReplyEnabled:
|
|
5595
|
-
pollIntervalSeconds:
|
|
5596
|
-
markSeen:
|
|
5597
|
-
maxBodyChars:
|
|
5598
|
-
subjectPrefix:
|
|
5893
|
+
var EmailConfigSchema = z2.object({
|
|
5894
|
+
enabled: z2.boolean().default(false),
|
|
5895
|
+
consentGranted: z2.boolean().default(false),
|
|
5896
|
+
imapHost: z2.string().default(""),
|
|
5897
|
+
imapPort: z2.number().int().default(993),
|
|
5898
|
+
imapUsername: z2.string().default(""),
|
|
5899
|
+
imapPassword: z2.string().default(""),
|
|
5900
|
+
imapMailbox: z2.string().default("INBOX"),
|
|
5901
|
+
imapUseSsl: z2.boolean().default(true),
|
|
5902
|
+
smtpHost: z2.string().default(""),
|
|
5903
|
+
smtpPort: z2.number().int().default(587),
|
|
5904
|
+
smtpUsername: z2.string().default(""),
|
|
5905
|
+
smtpPassword: z2.string().default(""),
|
|
5906
|
+
smtpUseTls: z2.boolean().default(true),
|
|
5907
|
+
smtpUseSsl: z2.boolean().default(false),
|
|
5908
|
+
fromAddress: z2.string().default(""),
|
|
5909
|
+
autoReplyEnabled: z2.boolean().default(true),
|
|
5910
|
+
pollIntervalSeconds: z2.number().int().default(30),
|
|
5911
|
+
markSeen: z2.boolean().default(true),
|
|
5912
|
+
maxBodyChars: z2.number().int().default(12e3),
|
|
5913
|
+
subjectPrefix: z2.string().default("Re: "),
|
|
5599
5914
|
allowFrom
|
|
5600
5915
|
});
|
|
5601
|
-
var MochatMentionSchema =
|
|
5602
|
-
requireInGroups:
|
|
5916
|
+
var MochatMentionSchema = z2.object({
|
|
5917
|
+
requireInGroups: z2.boolean().default(false)
|
|
5603
5918
|
});
|
|
5604
|
-
var MochatGroupRuleSchema =
|
|
5605
|
-
requireMention:
|
|
5919
|
+
var MochatGroupRuleSchema = z2.object({
|
|
5920
|
+
requireMention: z2.boolean().default(false)
|
|
5606
5921
|
});
|
|
5607
|
-
var MochatConfigSchema =
|
|
5608
|
-
enabled:
|
|
5609
|
-
baseUrl:
|
|
5610
|
-
socketUrl:
|
|
5611
|
-
socketPath:
|
|
5612
|
-
socketDisableMsgpack:
|
|
5613
|
-
socketReconnectDelayMs:
|
|
5614
|
-
socketMaxReconnectDelayMs:
|
|
5615
|
-
socketConnectTimeoutMs:
|
|
5616
|
-
refreshIntervalMs:
|
|
5617
|
-
watchTimeoutMs:
|
|
5618
|
-
watchLimit:
|
|
5619
|
-
retryDelayMs:
|
|
5620
|
-
maxRetryAttempts:
|
|
5621
|
-
clawToken:
|
|
5622
|
-
agentUserId:
|
|
5623
|
-
sessions:
|
|
5624
|
-
panels:
|
|
5922
|
+
var MochatConfigSchema = z2.object({
|
|
5923
|
+
enabled: z2.boolean().default(false),
|
|
5924
|
+
baseUrl: z2.string().default("https://mochat.io"),
|
|
5925
|
+
socketUrl: z2.string().default(""),
|
|
5926
|
+
socketPath: z2.string().default("/socket.io"),
|
|
5927
|
+
socketDisableMsgpack: z2.boolean().default(false),
|
|
5928
|
+
socketReconnectDelayMs: z2.number().int().default(1e3),
|
|
5929
|
+
socketMaxReconnectDelayMs: z2.number().int().default(1e4),
|
|
5930
|
+
socketConnectTimeoutMs: z2.number().int().default(1e4),
|
|
5931
|
+
refreshIntervalMs: z2.number().int().default(3e4),
|
|
5932
|
+
watchTimeoutMs: z2.number().int().default(25e3),
|
|
5933
|
+
watchLimit: z2.number().int().default(100),
|
|
5934
|
+
retryDelayMs: z2.number().int().default(500),
|
|
5935
|
+
maxRetryAttempts: z2.number().int().default(0),
|
|
5936
|
+
clawToken: z2.string().default(""),
|
|
5937
|
+
agentUserId: z2.string().default(""),
|
|
5938
|
+
sessions: z2.array(z2.string()).default([]),
|
|
5939
|
+
panels: z2.array(z2.string()).default([]),
|
|
5625
5940
|
allowFrom,
|
|
5626
5941
|
mention: MochatMentionSchema.default({}),
|
|
5627
|
-
groups:
|
|
5628
|
-
replyDelayMode:
|
|
5629
|
-
replyDelayMs:
|
|
5942
|
+
groups: z2.record(MochatGroupRuleSchema).default({}),
|
|
5943
|
+
replyDelayMode: z2.string().default("non-mention"),
|
|
5944
|
+
replyDelayMs: z2.number().int().default(12e4)
|
|
5630
5945
|
});
|
|
5631
|
-
var SlackDMSchema =
|
|
5632
|
-
enabled:
|
|
5633
|
-
policy:
|
|
5946
|
+
var SlackDMSchema = z2.object({
|
|
5947
|
+
enabled: z2.boolean().default(true),
|
|
5948
|
+
policy: z2.string().default("open"),
|
|
5634
5949
|
allowFrom
|
|
5635
5950
|
});
|
|
5636
|
-
var SlackConfigSchema =
|
|
5637
|
-
enabled:
|
|
5638
|
-
mode:
|
|
5639
|
-
webhookPath:
|
|
5640
|
-
botToken:
|
|
5641
|
-
appToken:
|
|
5642
|
-
userTokenReadOnly:
|
|
5643
|
-
groupPolicy:
|
|
5951
|
+
var SlackConfigSchema = z2.object({
|
|
5952
|
+
enabled: z2.boolean().default(false),
|
|
5953
|
+
mode: z2.string().default("socket"),
|
|
5954
|
+
webhookPath: z2.string().default("/slack/events"),
|
|
5955
|
+
botToken: z2.string().default(""),
|
|
5956
|
+
appToken: z2.string().default(""),
|
|
5957
|
+
userTokenReadOnly: z2.boolean().default(true),
|
|
5958
|
+
groupPolicy: z2.string().default("mention"),
|
|
5644
5959
|
groupAllowFrom: allowFrom,
|
|
5645
5960
|
dm: SlackDMSchema.default({})
|
|
5646
5961
|
});
|
|
5647
|
-
var QQConfigSchema =
|
|
5648
|
-
enabled:
|
|
5649
|
-
appId:
|
|
5650
|
-
secret:
|
|
5651
|
-
markdownSupport:
|
|
5962
|
+
var QQConfigSchema = z2.object({
|
|
5963
|
+
enabled: z2.boolean().default(false),
|
|
5964
|
+
appId: z2.string().default(""),
|
|
5965
|
+
secret: z2.string().default(""),
|
|
5966
|
+
markdownSupport: z2.boolean().default(false),
|
|
5652
5967
|
allowFrom
|
|
5653
5968
|
});
|
|
5654
|
-
var ChannelsConfigSchema =
|
|
5969
|
+
var ChannelsConfigSchema = z2.object({
|
|
5655
5970
|
whatsapp: WhatsAppConfigSchema.default({}),
|
|
5656
5971
|
telegram: TelegramConfigSchema.default({}),
|
|
5657
5972
|
discord: DiscordConfigSchema.default({}),
|
|
@@ -5662,15 +5977,15 @@ var ChannelsConfigSchema = z.object({
|
|
|
5662
5977
|
slack: SlackConfigSchema.default({}),
|
|
5663
5978
|
qq: QQConfigSchema.default({})
|
|
5664
5979
|
});
|
|
5665
|
-
var AgentDefaultsSchema =
|
|
5666
|
-
workspace:
|
|
5667
|
-
model:
|
|
5668
|
-
maxTokens:
|
|
5669
|
-
temperature:
|
|
5670
|
-
maxToolIterations:
|
|
5980
|
+
var AgentDefaultsSchema = z2.object({
|
|
5981
|
+
workspace: z2.string().default(DEFAULT_WORKSPACE_PATH),
|
|
5982
|
+
model: z2.string().default("anthropic/claude-opus-4-5"),
|
|
5983
|
+
maxTokens: z2.number().int().default(8192),
|
|
5984
|
+
temperature: z2.number().default(0.7),
|
|
5985
|
+
maxToolIterations: z2.number().int().default(20)
|
|
5671
5986
|
});
|
|
5672
|
-
var ContextBootstrapSchema =
|
|
5673
|
-
files:
|
|
5987
|
+
var ContextBootstrapSchema = z2.object({
|
|
5988
|
+
files: z2.array(z2.string()).default([
|
|
5674
5989
|
"AGENTS.md",
|
|
5675
5990
|
"SOUL.md",
|
|
5676
5991
|
"USER.md",
|
|
@@ -5680,30 +5995,30 @@ var ContextBootstrapSchema = z.object({
|
|
|
5680
5995
|
"BOOTSTRAP.md",
|
|
5681
5996
|
"HEARTBEAT.md"
|
|
5682
5997
|
]),
|
|
5683
|
-
minimalFiles:
|
|
5684
|
-
heartbeatFiles:
|
|
5685
|
-
perFileChars:
|
|
5686
|
-
totalChars:
|
|
5998
|
+
minimalFiles: z2.array(z2.string()).default(["AGENTS.md", "SOUL.md", "TOOLS.md", "IDENTITY.md"]),
|
|
5999
|
+
heartbeatFiles: z2.array(z2.string()).default(["HEARTBEAT.md"]),
|
|
6000
|
+
perFileChars: z2.number().int().default(4e3),
|
|
6001
|
+
totalChars: z2.number().int().default(12e3)
|
|
5687
6002
|
});
|
|
5688
|
-
var ContextMemorySchema =
|
|
5689
|
-
enabled:
|
|
5690
|
-
maxChars:
|
|
6003
|
+
var ContextMemorySchema = z2.object({
|
|
6004
|
+
enabled: z2.boolean().default(true),
|
|
6005
|
+
maxChars: z2.number().int().default(8e3)
|
|
5691
6006
|
});
|
|
5692
|
-
var ContextConfigSchema =
|
|
6007
|
+
var ContextConfigSchema = z2.object({
|
|
5693
6008
|
bootstrap: ContextBootstrapSchema.default({}),
|
|
5694
6009
|
memory: ContextMemorySchema.default({})
|
|
5695
6010
|
});
|
|
5696
|
-
var AgentsConfigSchema =
|
|
6011
|
+
var AgentsConfigSchema = z2.object({
|
|
5697
6012
|
defaults: AgentDefaultsSchema.default({}),
|
|
5698
6013
|
context: ContextConfigSchema.default({})
|
|
5699
6014
|
});
|
|
5700
|
-
var ProviderConfigSchema =
|
|
5701
|
-
apiKey:
|
|
5702
|
-
apiBase:
|
|
5703
|
-
extraHeaders:
|
|
5704
|
-
wireApi:
|
|
6015
|
+
var ProviderConfigSchema = z2.object({
|
|
6016
|
+
apiKey: z2.string().default(""),
|
|
6017
|
+
apiBase: z2.string().nullable().default(null),
|
|
6018
|
+
extraHeaders: z2.record(z2.string()).nullable().default(null),
|
|
6019
|
+
wireApi: z2.enum(["auto", "chat", "responses"]).default("auto")
|
|
5705
6020
|
});
|
|
5706
|
-
var ProvidersConfigSchema =
|
|
6021
|
+
var ProvidersConfigSchema = z2.object({
|
|
5707
6022
|
anthropic: ProviderConfigSchema.default({}),
|
|
5708
6023
|
openai: ProviderConfigSchema.default({}),
|
|
5709
6024
|
openrouter: ProviderConfigSchema.default({}),
|
|
@@ -5717,32 +6032,32 @@ var ProvidersConfigSchema = z.object({
|
|
|
5717
6032
|
minimax: ProviderConfigSchema.default({}),
|
|
5718
6033
|
aihubmix: ProviderConfigSchema.default({})
|
|
5719
6034
|
});
|
|
5720
|
-
var GatewayConfigSchema =
|
|
5721
|
-
host:
|
|
5722
|
-
port:
|
|
6035
|
+
var GatewayConfigSchema = z2.object({
|
|
6036
|
+
host: z2.string().default("0.0.0.0"),
|
|
6037
|
+
port: z2.number().int().default(18790)
|
|
5723
6038
|
});
|
|
5724
|
-
var UiConfigSchema =
|
|
5725
|
-
enabled:
|
|
5726
|
-
host:
|
|
5727
|
-
port:
|
|
5728
|
-
open:
|
|
6039
|
+
var UiConfigSchema = z2.object({
|
|
6040
|
+
enabled: z2.boolean().default(false),
|
|
6041
|
+
host: z2.string().default("127.0.0.1"),
|
|
6042
|
+
port: z2.number().int().default(18791),
|
|
6043
|
+
open: z2.boolean().default(false)
|
|
5729
6044
|
});
|
|
5730
|
-
var WebSearchConfigSchema =
|
|
5731
|
-
apiKey:
|
|
5732
|
-
maxResults:
|
|
6045
|
+
var WebSearchConfigSchema = z2.object({
|
|
6046
|
+
apiKey: z2.string().default(""),
|
|
6047
|
+
maxResults: z2.number().int().default(5)
|
|
5733
6048
|
});
|
|
5734
|
-
var WebToolsConfigSchema =
|
|
6049
|
+
var WebToolsConfigSchema = z2.object({
|
|
5735
6050
|
search: WebSearchConfigSchema.default({})
|
|
5736
6051
|
});
|
|
5737
|
-
var ExecToolConfigSchema =
|
|
5738
|
-
timeout:
|
|
6052
|
+
var ExecToolConfigSchema = z2.object({
|
|
6053
|
+
timeout: z2.number().int().default(60)
|
|
5739
6054
|
});
|
|
5740
|
-
var ToolsConfigSchema =
|
|
6055
|
+
var ToolsConfigSchema = z2.object({
|
|
5741
6056
|
web: WebToolsConfigSchema.default({}),
|
|
5742
6057
|
exec: ExecToolConfigSchema.default({}),
|
|
5743
|
-
restrictToWorkspace:
|
|
6058
|
+
restrictToWorkspace: z2.boolean().default(false)
|
|
5744
6059
|
});
|
|
5745
|
-
var ConfigSchema =
|
|
6060
|
+
var ConfigSchema = z2.object({
|
|
5746
6061
|
agents: AgentsConfigSchema.default({}),
|
|
5747
6062
|
channels: ChannelsConfigSchema.default({}),
|
|
5748
6063
|
providers: ProvidersConfigSchema.default({}),
|
|
@@ -5792,6 +6107,22 @@ function getApiBase(config, model) {
|
|
|
5792
6107
|
}
|
|
5793
6108
|
return null;
|
|
5794
6109
|
}
|
|
6110
|
+
function buildConfigSchema(options) {
|
|
6111
|
+
const schema = zodToJsonSchema(ConfigSchema, {
|
|
6112
|
+
name: "NextClawConfig",
|
|
6113
|
+
target: "jsonSchema7"
|
|
6114
|
+
});
|
|
6115
|
+
if (schema && typeof schema === "object") {
|
|
6116
|
+
schema.title = "NextClawConfig";
|
|
6117
|
+
}
|
|
6118
|
+
const hints = mapSensitivePaths(ConfigSchema, "", buildBaseHints());
|
|
6119
|
+
return {
|
|
6120
|
+
schema,
|
|
6121
|
+
uiHints: hints,
|
|
6122
|
+
version: options?.version ?? getPackageVersion(),
|
|
6123
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
6124
|
+
};
|
|
6125
|
+
}
|
|
5795
6126
|
|
|
5796
6127
|
// src/config/loader.ts
|
|
5797
6128
|
function getConfigPath() {
|
|
@@ -5804,12 +6135,12 @@ function loadConfig(configPath) {
|
|
|
5804
6135
|
const path = configPath ?? getConfigPath();
|
|
5805
6136
|
if (existsSync10(path)) {
|
|
5806
6137
|
try {
|
|
5807
|
-
const raw =
|
|
6138
|
+
const raw = readFileSync9(path, "utf-8");
|
|
5808
6139
|
const data = JSON.parse(raw);
|
|
5809
6140
|
const migrated = migrateConfig(data);
|
|
5810
6141
|
return ConfigSchema.parse(migrated);
|
|
5811
6142
|
} catch (err) {
|
|
5812
|
-
const message = err instanceof
|
|
6143
|
+
const message = err instanceof z3.ZodError ? err.message : String(err);
|
|
5813
6144
|
console.warn(`Warning: Failed to load config from ${path}: ${message}`);
|
|
5814
6145
|
}
|
|
5815
6146
|
}
|
|
@@ -5918,8 +6249,66 @@ function buildReloadPlan(changedPaths) {
|
|
|
5918
6249
|
return plan;
|
|
5919
6250
|
}
|
|
5920
6251
|
|
|
6252
|
+
// src/config/redact.ts
|
|
6253
|
+
function matchHint(path, hints) {
|
|
6254
|
+
const direct = hints[path];
|
|
6255
|
+
if (direct) {
|
|
6256
|
+
return direct;
|
|
6257
|
+
}
|
|
6258
|
+
const segments = path.split(".");
|
|
6259
|
+
for (const [hintKey, hint] of Object.entries(hints)) {
|
|
6260
|
+
if (!hintKey.includes("*")) {
|
|
6261
|
+
continue;
|
|
6262
|
+
}
|
|
6263
|
+
const hintSegments = hintKey.split(".");
|
|
6264
|
+
if (hintSegments.length !== segments.length) {
|
|
6265
|
+
continue;
|
|
6266
|
+
}
|
|
6267
|
+
let match = true;
|
|
6268
|
+
for (let i = 0; i < segments.length; i += 1) {
|
|
6269
|
+
if (hintSegments[i] !== "*" && hintSegments[i] !== segments[i]) {
|
|
6270
|
+
match = false;
|
|
6271
|
+
break;
|
|
6272
|
+
}
|
|
6273
|
+
}
|
|
6274
|
+
if (match) {
|
|
6275
|
+
return hint;
|
|
6276
|
+
}
|
|
6277
|
+
}
|
|
6278
|
+
return void 0;
|
|
6279
|
+
}
|
|
6280
|
+
function isSensitivePath(path, hints) {
|
|
6281
|
+
if (hints) {
|
|
6282
|
+
const hint = matchHint(path, hints);
|
|
6283
|
+
if (hint?.sensitive !== void 0) {
|
|
6284
|
+
return Boolean(hint.sensitive);
|
|
6285
|
+
}
|
|
6286
|
+
}
|
|
6287
|
+
return isSensitiveConfigPath(path);
|
|
6288
|
+
}
|
|
6289
|
+
function redactConfigObject(value, hints, prefix = "") {
|
|
6290
|
+
if (Array.isArray(value)) {
|
|
6291
|
+
const nextPath = prefix ? `${prefix}[]` : "[]";
|
|
6292
|
+
return value.map((entry) => redactConfigObject(entry, hints, nextPath));
|
|
6293
|
+
}
|
|
6294
|
+
if (!value || typeof value !== "object") {
|
|
6295
|
+
return value;
|
|
6296
|
+
}
|
|
6297
|
+
const entries = value;
|
|
6298
|
+
const output = {};
|
|
6299
|
+
for (const [key, val] of Object.entries(entries)) {
|
|
6300
|
+
const nextPath = prefix ? `${prefix}.${key}` : key;
|
|
6301
|
+
if (isSensitivePath(nextPath, hints)) {
|
|
6302
|
+
output[key] = val ? "***" : val;
|
|
6303
|
+
continue;
|
|
6304
|
+
}
|
|
6305
|
+
output[key] = redactConfigObject(val, hints, nextPath);
|
|
6306
|
+
}
|
|
6307
|
+
return output;
|
|
6308
|
+
}
|
|
6309
|
+
|
|
5921
6310
|
// src/cron/service.ts
|
|
5922
|
-
import { readFileSync as
|
|
6311
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync7, existsSync as existsSync11, mkdirSync as mkdirSync6 } from "fs";
|
|
5923
6312
|
import { dirname as dirname2 } from "path";
|
|
5924
6313
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
5925
6314
|
import cronParser from "cron-parser";
|
|
@@ -5959,7 +6348,7 @@ var CronService = class {
|
|
|
5959
6348
|
}
|
|
5960
6349
|
if (existsSync11(this.storePath)) {
|
|
5961
6350
|
try {
|
|
5962
|
-
const data = JSON.parse(
|
|
6351
|
+
const data = JSON.parse(readFileSync10(this.storePath, "utf-8"));
|
|
5963
6352
|
const jobs = (data.jobs ?? []).map((job) => ({
|
|
5964
6353
|
id: String(job.id),
|
|
5965
6354
|
name: String(job.name),
|
|
@@ -6162,7 +6551,7 @@ var CronService = class {
|
|
|
6162
6551
|
};
|
|
6163
6552
|
|
|
6164
6553
|
// src/heartbeat/service.ts
|
|
6165
|
-
import { readFileSync as
|
|
6554
|
+
import { readFileSync as readFileSync11, existsSync as existsSync12 } from "fs";
|
|
6166
6555
|
import { join as join9 } from "path";
|
|
6167
6556
|
var DEFAULT_HEARTBEAT_INTERVAL_S = 30 * 60;
|
|
6168
6557
|
var HEARTBEAT_PROMPT = "Read HEARTBEAT.md in your workspace (if it exists).\nFollow any instructions or tasks listed there.\nIf nothing needs attention, reply with just: HEARTBEAT_OK";
|
|
@@ -6196,7 +6585,7 @@ var HeartbeatService = class {
|
|
|
6196
6585
|
readHeartbeatFile() {
|
|
6197
6586
|
if (existsSync12(this.heartbeatFile)) {
|
|
6198
6587
|
try {
|
|
6199
|
-
return
|
|
6588
|
+
return readFileSync11(this.heartbeatFile, "utf-8");
|
|
6200
6589
|
} catch {
|
|
6201
6590
|
return null;
|
|
6202
6591
|
}
|
|
@@ -6639,6 +7028,9 @@ export {
|
|
|
6639
7028
|
WebSearchConfigSchema,
|
|
6640
7029
|
WebToolsConfigSchema,
|
|
6641
7030
|
WhatsAppConfigSchema,
|
|
7031
|
+
applySensitiveHints,
|
|
7032
|
+
buildBaseHints,
|
|
7033
|
+
buildConfigSchema,
|
|
6642
7034
|
buildReloadPlan,
|
|
6643
7035
|
diffConfigPaths,
|
|
6644
7036
|
ensureDir,
|
|
@@ -6652,17 +7044,21 @@ export {
|
|
|
6652
7044
|
getDataDir,
|
|
6653
7045
|
getDataPath,
|
|
6654
7046
|
getMemoryPath,
|
|
7047
|
+
getPackageVersion,
|
|
6655
7048
|
getProvider,
|
|
6656
7049
|
getProviderName,
|
|
6657
7050
|
getSessionsPath,
|
|
6658
7051
|
getSkillsPath,
|
|
6659
7052
|
getWorkspacePath,
|
|
6660
7053
|
getWorkspacePathFromConfig,
|
|
7054
|
+
isSensitiveConfigPath,
|
|
6661
7055
|
loadConfig,
|
|
7056
|
+
mapSensitivePaths,
|
|
6662
7057
|
matchProvider,
|
|
6663
7058
|
parseSessionKey,
|
|
6664
7059
|
probeFeishu,
|
|
6665
7060
|
providerLabel,
|
|
7061
|
+
redactConfigObject,
|
|
6666
7062
|
safeFilename,
|
|
6667
7063
|
saveConfig,
|
|
6668
7064
|
timestamp,
|