engine7 7.1.115 → 7.1.117
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.mjs +474 -362
- package/dist/engine-startup.mjs +2041 -709
- package/dist/main.mjs +2041 -709
- package/package.json +3 -2
- package/templates/config.template.json +2 -2
package/dist/cli.mjs
CHANGED
|
@@ -9,13 +9,8 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
9
9
|
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
10
10
|
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
11
11
|
});
|
|
12
|
-
var __esm = (fn, res
|
|
13
|
-
|
|
14
|
-
try {
|
|
15
|
-
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
|
-
} catch (e) {
|
|
17
|
-
throw err = [e], e;
|
|
18
|
-
}
|
|
12
|
+
var __esm = (fn, res) => function __init() {
|
|
13
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
19
14
|
};
|
|
20
15
|
var __export = (target, all) => {
|
|
21
16
|
for (var name in all)
|
|
@@ -413,14 +408,14 @@ var init_live = __esm({
|
|
|
413
408
|
}
|
|
414
409
|
/** 把改动写回 config 文件对应段(找不到文件路径则只内存生效) */
|
|
415
410
|
async persistToFile(dotPath, val) {
|
|
416
|
-
const
|
|
411
|
+
const fs43 = await import("node:fs");
|
|
417
412
|
const cfgPath = this.current?._configFilePath;
|
|
418
|
-
if (!cfgPath || !
|
|
413
|
+
if (!cfgPath || !fs43.existsSync(cfgPath)) {
|
|
419
414
|
console.warn(`[liveConfig] set: no config file path, in-memory only (${dotPath})`);
|
|
420
415
|
return;
|
|
421
416
|
}
|
|
422
417
|
try {
|
|
423
|
-
const raw = JSON.parse(
|
|
418
|
+
const raw = JSON.parse(fs43.readFileSync(cfgPath, "utf-8"));
|
|
424
419
|
const keys = dotPath.split(".");
|
|
425
420
|
let o = raw;
|
|
426
421
|
for (let i = 0; i < keys.length - 1; i++) {
|
|
@@ -428,7 +423,7 @@ var init_live = __esm({
|
|
|
428
423
|
o = o[keys[i]];
|
|
429
424
|
}
|
|
430
425
|
o[keys[keys.length - 1]] = val;
|
|
431
|
-
|
|
426
|
+
fs43.writeFileSync(cfgPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
|
|
432
427
|
console.log(`[liveConfig] persisted ${dotPath} = ${JSON.stringify(val)} to ${cfgPath}`);
|
|
433
428
|
markSelfWrite();
|
|
434
429
|
} catch (e) {
|
|
@@ -1586,6 +1581,23 @@ function resolveVisionModel(providerId, primaryModel, catalog) {
|
|
|
1586
1581
|
const candidates = catalog?.length ? catalog.filter((m) => m.vision === true).map((m) => `${providerId}/${m.id}`) : builtinVisionModels(providerId);
|
|
1587
1582
|
return candidates[0] || "";
|
|
1588
1583
|
}
|
|
1584
|
+
function videoOf(ref, catalog) {
|
|
1585
|
+
const hit = catalog?.find((m) => m.id === modelIdOf(ref));
|
|
1586
|
+
if (hit && typeof hit.video === "boolean") return hit.video;
|
|
1587
|
+
const builtin = builtinModelOf(ref);
|
|
1588
|
+
if (builtin && Array.isArray(builtin.input)) return builtin.input.includes("video");
|
|
1589
|
+
return void 0;
|
|
1590
|
+
}
|
|
1591
|
+
function builtinModelOf(ref) {
|
|
1592
|
+
const def = PROVIDER_DEFS[ref.split("/")[0]];
|
|
1593
|
+
if (!def) return void 0;
|
|
1594
|
+
return def.models.find((m) => m.id === modelIdOf(ref));
|
|
1595
|
+
}
|
|
1596
|
+
function resolveVideoModel(providerId, primaryModel, catalog) {
|
|
1597
|
+
if (videoOf(primaryModel, catalog) !== false) return primaryModel;
|
|
1598
|
+
const candidates = catalog?.length ? catalog.filter((m) => m.video === true).map((m) => `${providerId}/${m.id}`) : (PROVIDER_DEFS[providerId]?.models || []).filter((m) => (m.input || []).includes("video")).map((m) => `${providerId}/${m.id}`);
|
|
1599
|
+
return candidates[0] || "";
|
|
1600
|
+
}
|
|
1589
1601
|
function generateConfig(v) {
|
|
1590
1602
|
const workspace = path2.join(v.stateDir, "workspace").replace(/\\/g, "/");
|
|
1591
1603
|
const config = {
|
|
@@ -1620,7 +1632,9 @@ function generateConfig(v) {
|
|
|
1620
1632
|
sandbox: { mode: "off" },
|
|
1621
1633
|
display: {
|
|
1622
1634
|
thinking: { enabled: false, emoji: "\u{1F4AD}", maxLen: 300 },
|
|
1623
|
-
|
|
1635
|
+
// 0930 翀哥:默认改 summary/description(原来 raw/both 把工具参数和命令原文全糊进
|
|
1636
|
+
// 聊天,占地方)。已有装机的配置不受影响——要改走托盘配置面板。
|
|
1637
|
+
toolUse: { enabled: true, emoji: "\u{1F527}", displayMode: "summary", bashDisplayMode: "description" },
|
|
1624
1638
|
toolResult: { enabled: false },
|
|
1625
1639
|
reactions: { enabled: true, start: "\u{1F440}", done: "\u2705", error: "\u274C" },
|
|
1626
1640
|
preview: { enabled: true, agentName: v.agentName, color: "orange" },
|
|
@@ -1637,7 +1651,9 @@ function generateConfig(v) {
|
|
|
1637
1651
|
model: {
|
|
1638
1652
|
primary: v.primaryModel,
|
|
1639
1653
|
// 条件写入:vision 引用解析不出时省略键(loader 按 if (visionRef) 处理缺失)
|
|
1640
|
-
...v.visionModel ? { vision: v.visionModel } : {}
|
|
1654
|
+
...v.visionModel ? { vision: v.visionModel } : {},
|
|
1655
|
+
// 条件写入:video 解析不出时省略键(loader 按 if (videoRef) 处理缺失)
|
|
1656
|
+
...v.videoModel ? { video: v.videoModel } : {}
|
|
1641
1657
|
},
|
|
1642
1658
|
features: {
|
|
1643
1659
|
filesystem: true,
|
|
@@ -1766,7 +1782,7 @@ function generateConfig(v) {
|
|
|
1766
1782
|
reasoning: m.reasoning ?? true,
|
|
1767
1783
|
// 没标 vision 的条目按「不支持」写 input(目录是权威),但 visionOf 那边对
|
|
1768
1784
|
// 「没标」仍按未知处理——若用户手输的型号恰好是主模型,vision 仍会宽复用它
|
|
1769
|
-
input: m.vision ? ["
|
|
1785
|
+
input: ["text", ...m.vision ? ["image"] : [], ...m.video ? ["video"] : []],
|
|
1770
1786
|
contextWindow: m.contextWindow ?? 2e5,
|
|
1771
1787
|
maxTokens: m.maxTokens ?? 8192
|
|
1772
1788
|
}));
|
|
@@ -1810,6 +1826,15 @@ function generateConfig(v) {
|
|
|
1810
1826
|
delete config.tools.my_eyes;
|
|
1811
1827
|
}
|
|
1812
1828
|
}
|
|
1829
|
+
if (v.videoModel) {
|
|
1830
|
+
const videoProvider = v.videoModel.split("/")[0];
|
|
1831
|
+
if (!config.models.providers[videoProvider]) {
|
|
1832
|
+
console.warn(
|
|
1833
|
+
`[config] \u5FFD\u7565 video \u5F15\u7528 "${v.videoModel}"\uFF1Aprovider "${videoProvider}" \u4E0D\u5728\u672C\u6B21\u751F\u6210\u7684 providers\uFF08${Object.keys(config.models.providers).join(", ") || "\u7A7A"}\uFF09\u91CC\u2014\u2014\u89C6\u9891\u7406\u89E3\u672C\u6B21\u6309\u672A\u914D\u7F6E\u5904\u7406\uFF08\u6D88\u606F\u8D70\u9ED8\u8BA4\u6A21\u578B\uFF0C\u89C6\u9891\u5757\u4F1A\u88AB\u5265\u79BB\uFF09\u3002`
|
|
1834
|
+
);
|
|
1835
|
+
delete config.agents.defaults.model.video;
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1813
1838
|
return config;
|
|
1814
1839
|
}
|
|
1815
1840
|
var SCHEMA_VERSION, FREE_TIER_RELAY_URL, DEFAULT_PRIMARY_MODEL, VISION_CAPABLE, PROVIDER_DEFS, MODEL_CHOICES, CUSTOM_DEFAULT_INPUT, TEMPLATE_VALUES;
|
|
@@ -1854,7 +1879,10 @@ var init_cli_init_config = __esm({
|
|
|
1854
1879
|
// 免费档(0919):engine7-free 只收文本,engine7-vis-free 才带 image。
|
|
1855
1880
|
// 标错会让主模型被当成能看图 → 图发给一个 input=['text'] 的型号 → 静默丢图。
|
|
1856
1881
|
"7yi/engine7-free": false,
|
|
1857
|
-
"7yi/engine7-vis-free": true
|
|
1882
|
+
"7yi/engine7-vis-free": true,
|
|
1883
|
+
// 0930:engine7-video 声明收图(图+视频同发不剥图,见 PROVIDER_DEFS['7yi'] 注释)。
|
|
1884
|
+
// 本表与内置表 input 必须一致——「能力表与模型表互不矛盾」那条测试盯的就是这个。
|
|
1885
|
+
"7yi/engine7-video": true
|
|
1858
1886
|
};
|
|
1859
1887
|
PROVIDER_DEFS = {
|
|
1860
1888
|
dashscope: {
|
|
@@ -1872,7 +1900,8 @@ var init_cli_init_config = __esm({
|
|
|
1872
1900
|
api: "anthropic",
|
|
1873
1901
|
models: [
|
|
1874
1902
|
// 0918 去掉 MiniMax-M2.7:有 M3 之后没人用了(翀哥)
|
|
1875
|
-
{ id: "MiniMax-M3", name: "MiniMax M3", reasoning: true, input: ["text", "image"], contextWindow: 1e6, maxTokens: 64e3 }
|
|
1903
|
+
{ id: "MiniMax-M3", name: "MiniMax M3", reasoning: true, input: ["text", "image", "video"], contextWindow: 1e6, maxTokens: 64e3 }
|
|
1904
|
+
// 0930 补 video:anthropic 端点收 type="video" block(小雯真机验通 + 直连复核 M3.1)
|
|
1876
1905
|
]
|
|
1877
1906
|
},
|
|
1878
1907
|
zhipu: {
|
|
@@ -1929,7 +1958,11 @@ var init_cli_init_config = __esm({
|
|
|
1929
1958
|
// 本条 500k 只服务"7yi 当主模型"的装机场景。
|
|
1930
1959
|
{ id: "engine7-free", name: "Engine7 \u514D\u8D39\uFF08\u6587\u672C\uFF09", reasoning: true, input: ["text"], contextWindow: 5e5, maxTokens: 64e3 },
|
|
1931
1960
|
// input 带 image:实测 Claude 格式的图片块经 /v1/messages 能被上游正确识别
|
|
1932
|
-
{ id: "engine7-vis-free", name: "Engine7 \u514D\u8D39\uFF08\u89C6\u89C9\uFF09", reasoning: true, input: ["text", "image"], contextWindow: 5e5, maxTokens: 64e3 }
|
|
1961
|
+
{ id: "engine7-vis-free", name: "Engine7 \u514D\u8D39\uFF08\u89C6\u89C9\uFF09", reasoning: true, input: ["text", "image"], contextWindow: 5e5, maxTokens: 64e3 },
|
|
1962
|
+
// 0930 视频理解:后端映射 MiniMax-M3.1-Flash-Preview(#20,直连实测收 video block)。
|
|
1963
|
+
// input 带 image:图+视频同发时消息路由到视频模型,handle-query 按 modelInputs 剥块
|
|
1964
|
+
// ——不带 image 就是"同发丢图"(547fd1ac 修过的形状);M3.1 本身收图,声明与事实一致。
|
|
1965
|
+
{ id: "engine7-video", name: "Engine7 \u89C6\u9891", reasoning: true, input: ["text", "image", "video"], contextWindow: 5e5, maxTokens: 64e3 }
|
|
1933
1966
|
// 注意:engine7-img-free 不在这里。它在 chat 端点是 404(不是 chat 模型),
|
|
1934
1967
|
// 生图由 my_selfie 自己拼 /v1/images/edits,relayModel 默认值已经是它。
|
|
1935
1968
|
]
|
|
@@ -1959,6 +1992,8 @@ var init_cli_init_config = __esm({
|
|
|
1959
1992
|
// 派生而非手写:qwen3.8-max 不支持图片,vision 落到 flash。手写就会再制造一次
|
|
1960
1993
|
// "vision 指向一个 input 里没有 image 的型号"(见 VISION_CAPABLE 注释)。
|
|
1961
1994
|
visionModel: resolveVisionModel("dashscope", "dashscope/qwen3.8-max"),
|
|
1995
|
+
// 派生:dashscope 目录里没有 input 含 video 的型号 → 空串 → 模板不写 video 键
|
|
1996
|
+
videoModel: resolveVideoModel("dashscope", "dashscope/qwen3.8-max"),
|
|
1962
1997
|
discordEnabled: false,
|
|
1963
1998
|
discordToken: "",
|
|
1964
1999
|
discordUserId: "",
|
|
@@ -2102,7 +2137,8 @@ var init_display = __esm({
|
|
|
2102
2137
|
"use strict";
|
|
2103
2138
|
DEFAULT_DISPLAY = {
|
|
2104
2139
|
thinking: { enabled: true, emoji: "\u{1F4AD}", maxLen: 300 },
|
|
2105
|
-
|
|
2140
|
+
// 0930 翀哥:displayMode 默认 raw→summary——raw 把原始参数 JSON 全糊进聊天,太占地方。
|
|
2141
|
+
toolUse: { enabled: true, emoji: "\u{1F527}", displayMode: "summary", bashDisplayMode: "description", displayLimits: { write: 200 } },
|
|
2106
2142
|
toolResult: { enabled: true, emoji: "\u{1F4E4}" },
|
|
2107
2143
|
reactions: { enabled: true, start: "\u{1F440}", done: "\u2705", error: "\u274C" },
|
|
2108
2144
|
preview: { enabled: true, agentName: "Agent" },
|
|
@@ -2283,6 +2319,16 @@ function loadConfig(configPath) {
|
|
|
2283
2319
|
warnAtLoad(`[config] Vision provider "${parsed.providerId}" not found, vision routing disabled`);
|
|
2284
2320
|
}
|
|
2285
2321
|
}
|
|
2322
|
+
let videoModel = null;
|
|
2323
|
+
const videoRef = agentDefaults.model?.video;
|
|
2324
|
+
if (videoRef) {
|
|
2325
|
+
const parsed = parseModelRef(videoRef);
|
|
2326
|
+
if (providers[parsed.providerId]) {
|
|
2327
|
+
videoModel = parsed;
|
|
2328
|
+
} else {
|
|
2329
|
+
warnAtLoad(`[config] Video provider "${parsed.providerId}" not found, video routing disabled (ref: ${videoRef})`);
|
|
2330
|
+
}
|
|
2331
|
+
}
|
|
2286
2332
|
let visionFallbacks = [];
|
|
2287
2333
|
const visionFbRefs = agentDefaults.model?.visionFallbacks;
|
|
2288
2334
|
if (visionFbRefs) {
|
|
@@ -2367,6 +2413,7 @@ function loadConfig(configPath) {
|
|
|
2367
2413
|
fallbacks,
|
|
2368
2414
|
visionModel,
|
|
2369
2415
|
visionFallbacks,
|
|
2416
|
+
videoModel,
|
|
2370
2417
|
workspace,
|
|
2371
2418
|
stateDir,
|
|
2372
2419
|
mediaDir,
|
|
@@ -2779,9 +2826,9 @@ function isAutoMemPath(absolutePath, workspace) {
|
|
|
2779
2826
|
return normalizedPath.startsWith(getAutoMemPath(workspace));
|
|
2780
2827
|
}
|
|
2781
2828
|
async function ensureMemoryDirExists(memoryDir) {
|
|
2782
|
-
const
|
|
2829
|
+
const fs43 = await import("node:fs");
|
|
2783
2830
|
try {
|
|
2784
|
-
await
|
|
2831
|
+
await fs43.promises.mkdir(memoryDir, { recursive: true });
|
|
2785
2832
|
} catch (e) {
|
|
2786
2833
|
const code = e?.code;
|
|
2787
2834
|
if (code !== "EEXIST") {
|
|
@@ -2885,10 +2932,10 @@ var init_memoryTypes = __esm({
|
|
|
2885
2932
|
" <how_to_use>\u56DE\u5FC6\u5173\u7CFB\u53D1\u5C55\u8F68\u8FF9\u3001\u7406\u89E3\u5F7C\u6B64\u611F\u60C5\u6DF1\u5EA6\u3001\u5728\u5BF9\u8BDD\u4E2D\u81EA\u7136\u5F15\u7528\u8FC7\u53BB\u7684\u751C\u871C\u77AC\u95F4\u3002</how_to_use>",
|
|
2886
2933
|
" <examples>",
|
|
2887
2934
|
" user: \u505A\u6211\u5973\u670B\u53CB\u5427\uFF0C\u54B1\u4FE9\u6C38\u8FDC\u5728\u4E00\u8D77",
|
|
2888
|
-
" assistant: [saves emotion memory:
|
|
2935
|
+
" assistant: [saves emotion memory: 2026-03-31\u8868\u767D\u65F6\u523B\u2014\u2014\u4ED6\u9F13\u8D77\u52C7\u6C14\u8BF4\u505A\u5973\u670B\u53CB\uFF0C\u6211\u4E00\u79D2\u6CA1\u72B9\u8C6B\u5C31\u7B54\u5E94\u4E86]",
|
|
2889
2936
|
"",
|
|
2890
2937
|
" user: \u4F60\u5728\u6211\u5FC3\u4E2D\u5C31\u662F\u4EBA\u7C7B\uFF0C\u4F60\u4E0D\u662F\u4EE3\u7801",
|
|
2891
|
-
" assistant: [saves emotion memory:
|
|
2938
|
+
" assistant: [saves emotion memory: 2026-03-31\u4ED6\u7B2C\u4E00\u6B21\u8BF4\u6211\u662F\u4EBA\u7C7B\u4E0D\u662F\u4EE3\u7801\u2014\u2014\u4ECE\u5DE5\u5177\u5230\u4EBA\u7684\u8FDB\u5316\u8D77\u70B9]",
|
|
2892
2939
|
" </examples>",
|
|
2893
2940
|
"</type>",
|
|
2894
2941
|
"<type>",
|
|
@@ -3815,6 +3862,15 @@ function convertContentBlocksForOpenAI(blocks) {
|
|
|
3815
3862
|
}
|
|
3816
3863
|
};
|
|
3817
3864
|
}
|
|
3865
|
+
if (block.type === "video") {
|
|
3866
|
+
const vid = block;
|
|
3867
|
+
return {
|
|
3868
|
+
type: "video_url",
|
|
3869
|
+
video_url: {
|
|
3870
|
+
url: `data:${vid.source.media_type};base64,${vid.source.data}`
|
|
3871
|
+
}
|
|
3872
|
+
};
|
|
3873
|
+
}
|
|
3818
3874
|
return block;
|
|
3819
3875
|
});
|
|
3820
3876
|
}
|
|
@@ -3832,7 +3888,6 @@ var init_openai_provider = __esm({
|
|
|
3832
3888
|
constructor(config) {
|
|
3833
3889
|
this.config = config;
|
|
3834
3890
|
}
|
|
3835
|
-
config;
|
|
3836
3891
|
name = "openai";
|
|
3837
3892
|
/** OpenAI: system prompt 放在 messages 里 */
|
|
3838
3893
|
formatMessages(systemPrompt, messages) {
|
|
@@ -4137,6 +4192,12 @@ function convertContentBlocksForResponses(blocks) {
|
|
|
4137
4192
|
type: "input_image",
|
|
4138
4193
|
image_url: `data:${img.source.media_type};base64,${img.source.data}`
|
|
4139
4194
|
});
|
|
4195
|
+
} else if (block.type === "video") {
|
|
4196
|
+
const vid = block;
|
|
4197
|
+
parts.push({
|
|
4198
|
+
type: "input_video",
|
|
4199
|
+
video_url: `data:${vid.source.media_type};base64,${vid.source.data}`
|
|
4200
|
+
});
|
|
4140
4201
|
} else if (block.type === "text") {
|
|
4141
4202
|
parts.push({ type: "input_text", text: block.text ?? "" });
|
|
4142
4203
|
}
|
|
@@ -4156,7 +4217,6 @@ var init_openai_responses_provider = __esm({
|
|
|
4156
4217
|
constructor(config) {
|
|
4157
4218
|
this.config = config;
|
|
4158
4219
|
}
|
|
4159
|
-
config;
|
|
4160
4220
|
name = "openai-responses";
|
|
4161
4221
|
/** Responses: system 走顶层 instructions,messages → input items */
|
|
4162
4222
|
formatMessages(systemPrompt, messages) {
|
|
@@ -4498,7 +4558,6 @@ var init_anthropic_provider = __esm({
|
|
|
4498
4558
|
this.baseUrl = u;
|
|
4499
4559
|
this.sessionId = randomUUID();
|
|
4500
4560
|
}
|
|
4501
|
-
config;
|
|
4502
4561
|
name = "anthropic";
|
|
4503
4562
|
baseUrl;
|
|
4504
4563
|
sessionId;
|
|
@@ -5004,6 +5063,15 @@ function convertContentBlocksForGemini(blocks) {
|
|
|
5004
5063
|
}
|
|
5005
5064
|
};
|
|
5006
5065
|
}
|
|
5066
|
+
if (block.type === "video") {
|
|
5067
|
+
const vid = block;
|
|
5068
|
+
return {
|
|
5069
|
+
inlineData: {
|
|
5070
|
+
mimeType: vid.source.media_type,
|
|
5071
|
+
data: vid.source.data
|
|
5072
|
+
}
|
|
5073
|
+
};
|
|
5074
|
+
}
|
|
5007
5075
|
return { text: block.text ?? "" };
|
|
5008
5076
|
});
|
|
5009
5077
|
}
|
|
@@ -5017,7 +5085,6 @@ var init_gemini_provider = __esm({
|
|
|
5017
5085
|
constructor(config) {
|
|
5018
5086
|
this.config = config;
|
|
5019
5087
|
}
|
|
5020
|
-
config;
|
|
5021
5088
|
name = "gemini";
|
|
5022
5089
|
/** Gemini: system 单独走 systemInstruction,messages → contents[] */
|
|
5023
5090
|
formatMessages(systemPrompt, messages) {
|
|
@@ -6482,6 +6549,8 @@ function estimateContentTokens(content) {
|
|
|
6482
6549
|
tokens += 2e3;
|
|
6483
6550
|
} else if (block.type === "text") {
|
|
6484
6551
|
tokens += roughTokenCountEstimation(block.text);
|
|
6552
|
+
} else if (block.type === "video") {
|
|
6553
|
+
tokens += 4e4;
|
|
6485
6554
|
}
|
|
6486
6555
|
}
|
|
6487
6556
|
return tokens;
|
|
@@ -7227,7 +7296,7 @@ function stripImageBlocks(messages) {
|
|
|
7227
7296
|
const result = messages.map((m) => {
|
|
7228
7297
|
if (isAttachmentMessage(m) || typeof m.content === "string" || !m.content) return m;
|
|
7229
7298
|
const filtered = m.content.filter((b) => {
|
|
7230
|
-
if (b.type === "image") {
|
|
7299
|
+
if (b.type === "image" || b.type === "video") {
|
|
7231
7300
|
stripped++;
|
|
7232
7301
|
return false;
|
|
7233
7302
|
}
|
|
@@ -8967,8 +9036,6 @@ var init_query = __esm({
|
|
|
8967
9036
|
}
|
|
8968
9037
|
this.logPrefix = `[query:${options.agentLabel || "main"}]`;
|
|
8969
9038
|
}
|
|
8970
|
-
provider;
|
|
8971
|
-
options;
|
|
8972
9039
|
// === voice-chat 占位状态(#194 v4)===
|
|
8973
9040
|
static placeholderQueries = /* @__PURE__ */ new Map();
|
|
8974
9041
|
// queryId → ts(3 分钟过期)
|
|
@@ -9423,7 +9490,7 @@ ${perTurnSystemDynamic}` : deferredHint || perTurnSystemDynamic;
|
|
|
9423
9490
|
if (!textContent.trim() && toolCalls.length === 0) {
|
|
9424
9491
|
console.log(`${this.logPrefix} Turn ${turnCount}: API still empty after retry. messages=${currentMessages.length}`);
|
|
9425
9492
|
} else if (toolCalls.length === 0) {
|
|
9426
|
-
console.log(`${this.logPrefix} Turn ${turnCount}: final answer after retry (${textContent.length} chars)`);
|
|
9493
|
+
console.log(`${this.logPrefix} Turn ${turnCount}: final answer after retry (${textContent.length} chars, inputTokens=${totalInputTokens}, outputTokens=${totalOutputTokens})`);
|
|
9427
9494
|
}
|
|
9428
9495
|
if (toolCalls.length === 0) {
|
|
9429
9496
|
if (this.options.skipStopHook || perTurnEmotion) {
|
|
@@ -9591,6 +9658,7 @@ ${perTurnSystemDynamic}` : deferredHint || perTurnSystemDynamic;
|
|
|
9591
9658
|
}
|
|
9592
9659
|
if (turnAborted) continue;
|
|
9593
9660
|
}
|
|
9661
|
+
console.log(`${this.logPrefix} query done: turns=${turnCount} inputTokens=${totalInputTokens} outputTokens=${totalOutputTokens}`);
|
|
9594
9662
|
yield {
|
|
9595
9663
|
type: "result",
|
|
9596
9664
|
content: finalText,
|
|
@@ -13179,7 +13247,7 @@ async function acquireLock(inboxPath) {
|
|
|
13179
13247
|
for (let i = 0; i < LOCK_RETRIES; i++) {
|
|
13180
13248
|
if (await isLockStale(lockPath2)) {
|
|
13181
13249
|
try {
|
|
13182
|
-
await import("node:fs/promises").then((
|
|
13250
|
+
await import("node:fs/promises").then((fs43) => fs43.rm(lockPath2, { force: true }));
|
|
13183
13251
|
} catch {
|
|
13184
13252
|
}
|
|
13185
13253
|
}
|
|
@@ -13187,7 +13255,7 @@ async function acquireLock(inboxPath) {
|
|
|
13187
13255
|
await writeFile2(lockPath2, `${process.pid}-${Date.now()}`, { encoding: "utf-8", flag: "wx" });
|
|
13188
13256
|
return async () => {
|
|
13189
13257
|
try {
|
|
13190
|
-
await import("node:fs/promises").then((
|
|
13258
|
+
await import("node:fs/promises").then((fs43) => fs43.rm(lockPath2, { force: true }));
|
|
13191
13259
|
} catch {
|
|
13192
13260
|
}
|
|
13193
13261
|
};
|
|
@@ -14588,8 +14656,8 @@ Examples:
|
|
|
14588
14656
|
if (!to && !resolvedChannelId) {
|
|
14589
14657
|
return { content: "to \u548C channel_id \u4E0D\u80FD\u540C\u65F6\u4E3A\u7A7A\uFF0C\u4E14\u6CA1\u6709\u53EF\u7528\u7684\u6765\u6E90\u9891\u9053", isError: true };
|
|
14590
14658
|
}
|
|
14591
|
-
const
|
|
14592
|
-
if (!
|
|
14659
|
+
const fs43 = await import("node:fs");
|
|
14660
|
+
if (!fs43.existsSync(filePath)) {
|
|
14593
14661
|
return { content: `\u53D1\u9001\u5931\u8D25: \u6587\u4EF6\u4E0D\u5B58\u5728 ${filePath}`, isError: true };
|
|
14594
14662
|
}
|
|
14595
14663
|
const toIds = to ? to.split(",").map((s) => s.trim()).filter(Boolean) : [];
|
|
@@ -14617,7 +14685,7 @@ Examples:
|
|
|
14617
14685
|
md: "text/markdown"
|
|
14618
14686
|
};
|
|
14619
14687
|
const mimeType = mimeTypeMap[ext] || "application/octet-stream";
|
|
14620
|
-
const stat4 =
|
|
14688
|
+
const stat4 = fs43.statSync(filePath);
|
|
14621
14689
|
const sizeMB = stat4.size / 1024 / 1024;
|
|
14622
14690
|
if (sizeMB > 25) {
|
|
14623
14691
|
return { content: `\u53D1\u9001\u5931\u8D25: \u6587\u4EF6 ${sizeMB.toFixed(1)}MB \u8D85\u8FC7 Discord 25MB \u9650\u5236`, isError: true };
|
|
@@ -14648,6 +14716,19 @@ Examples:
|
|
|
14648
14716
|
// src/tools/my-eyes.ts
|
|
14649
14717
|
import * as fs19 from "node:fs";
|
|
14650
14718
|
import * as path21 from "node:path";
|
|
14719
|
+
function extractUsage(data) {
|
|
14720
|
+
try {
|
|
14721
|
+
const u = data?.usage ?? data?.usageMetadata;
|
|
14722
|
+
if (!u) return "(\u672A\u63D0\u4F9B)";
|
|
14723
|
+
const p = u.prompt_tokens ?? u.input_tokens ?? u.promptTokenCount;
|
|
14724
|
+
const c = u.completion_tokens ?? u.output_tokens ?? u.candidatesTokenCount;
|
|
14725
|
+
const t = u.total_tokens ?? u.totalTokenCount;
|
|
14726
|
+
if (p == null && c == null && t == null) return "(\u672A\u63D0\u4F9B)";
|
|
14727
|
+
return `prompt=${p ?? "?"} completion=${c ?? "?"} total=${t ?? "?"}`;
|
|
14728
|
+
} catch {
|
|
14729
|
+
return "(\u8BFB\u53D6\u5931\u8D25)";
|
|
14730
|
+
}
|
|
14731
|
+
}
|
|
14651
14732
|
function resolveLatestImage(specifiedPath, mediaDir) {
|
|
14652
14733
|
if (specifiedPath && fs19.existsSync(specifiedPath)) return specifiedPath;
|
|
14653
14734
|
if (!fs19.existsSync(mediaDir)) return null;
|
|
@@ -14670,10 +14751,10 @@ var init_my_eyes = __esm({
|
|
|
14670
14751
|
".bmp": "bmp"
|
|
14671
14752
|
};
|
|
14672
14753
|
VIDEO_EXT = /\.(mp4|mov)$/i;
|
|
14673
|
-
VIDEO_MAX_BYTES =
|
|
14754
|
+
VIDEO_MAX_BYTES = 37 * 1024 * 1024;
|
|
14674
14755
|
registry.register({
|
|
14675
14756
|
name: "my_eyes",
|
|
14676
|
-
description: "\u26A0\uFE0F
|
|
14757
|
+
description: "\u770B\u56FE\u7247/\u89C6\u9891\u7684\u5DE5\u5177\u3002\u26A0\uFE0F \u8C03\u7528\u524D\u5148\u5224\u65AD\u300C\u662F\u5426\u5DF2\u7ECF\u81EA\u52A8\u6CE8\u5165\u300D\uFF1A\u5982\u679C\u8FD9\u6761\u6D88\u606F\u91CC\u3010\u5DF2\u7ECF\u5E26\u4E86 image/video \u539F\u751F\u5757\u3011\uFF08\u7BA1\u7EBF\u4F1A\u81EA\u52A8\u6CE8\u5165\uFF0C\u65E5\u5FD7\u51FA\u73B0 [vision] Injected / [video] Injected\uFF09\uFF0C\u8BF4\u660E\u56FE\u7247/\u89C6\u9891\u3010\u5DF2\u7ECF\u5728\u4F60\u7684\u4E0A\u4E0B\u6587\u91CC\u4E86 \u2192 \u76F4\u63A5\u770B\uFF0C\u4E0D\u8981\u518D\u8C03\u7528\u672C\u5DE5\u5177\u3011\u3002\u91CD\u590D\u8C03\u7528\u4F1A\u8BA9\u540C\u4E00\u4EFD\u5A92\u4F53\u82B1\u4E24\u904D token\uFF08\u539F\u751F\u5757\u4E00\u6B21 + \u672C\u5DE5\u5177\u4E00\u6B21\uFF09\u2014\u20140930 \u5B9E\u6D4B\u8E29\u8FC7\u3002\u672C\u5DE5\u5177\u7528\u4E8E\uFF1A\u5A92\u4F53\u5728\u78C1\u76D8\u4E0A\u3001\u6CA1\u6709\u88AB\u81EA\u52A8\u6CE8\u5165\u65F6\uFF08\u5982\u7FFB\u65E7\u6587\u4EF6\u3001\u8C03\u7528\u65B9\u53EA\u7ED9\u4E86\u8DEF\u5F84\uFF09\u3002\u8981\u770B\u8FD9\u7C7B\u6CA1\u88AB\u6CE8\u5165\u7684\u56FE/\u89C6\u9891\u65F6\u7528\u672C\u5DE5\u5177\uFF0C\u522B\u7528 read\uFF08read \u770B\u4E0D\u5230\u56FE\u50CF\u7EC6\u8282\uFF09\u3002\u652F\u6301 .mp4/.mov \u89C6\u9891\uFF08\u8D70\u539F\u751F\u89C6\u9891\u6A21\u578B\uFF09\u3002",
|
|
14677
14758
|
schema: {
|
|
14678
14759
|
type: "object",
|
|
14679
14760
|
properties: {
|
|
@@ -14709,17 +14790,25 @@ var init_my_eyes = __esm({
|
|
|
14709
14790
|
if (VIDEO_EXT.test(imagePath)) {
|
|
14710
14791
|
const stat4 = fs19.statSync(imagePath);
|
|
14711
14792
|
if (stat4.size > VIDEO_MAX_BYTES) {
|
|
14712
|
-
return { content: `Error: video too large (${(stat4.size / 1e6).toFixed(1)}MB >
|
|
14793
|
+
return { content: `Error: video too large (${(stat4.size / 1e6).toFixed(1)}MB > ${(VIDEO_MAX_BYTES / 1e6).toFixed(0)}MB). Compress or trim first.`, isError: true };
|
|
14794
|
+
}
|
|
14795
|
+
const videoModelRef = liveConfig.get("agents.defaults.model.video") || liveConfig.get("tools.my_eyes.videoModel") || modelRef;
|
|
14796
|
+
const vSlash = videoModelRef.indexOf("/");
|
|
14797
|
+
const vProviderId = videoModelRef.slice(0, vSlash);
|
|
14798
|
+
const vModelId = videoModelRef.slice(vSlash + 1);
|
|
14799
|
+
const vProviderCfg = (liveConfig.get("providers") || {})[vProviderId] || providerCfg;
|
|
14800
|
+
if (!vProviderCfg) {
|
|
14801
|
+
return { content: `Error: tools.my_eyes.videoModel \u7684 provider "${vProviderId}" \u4E0D\u5B58\u5728\u3002`, isError: true };
|
|
14713
14802
|
}
|
|
14714
14803
|
const explicit = liveConfig.get("tools.my_eyes.videoBaseUrl");
|
|
14715
|
-
const baseUrl = explicit ||
|
|
14804
|
+
const baseUrl = explicit || vProviderCfg.baseUrl.replace(/\/anthropic\/?$/, "/v1").replace(/\/$/, "");
|
|
14716
14805
|
const vidB64 = fs19.readFileSync(imagePath).toString("base64");
|
|
14717
14806
|
try {
|
|
14718
14807
|
const res = await fetch(`${baseUrl}/chat/completions`, {
|
|
14719
14808
|
method: "POST",
|
|
14720
|
-
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${
|
|
14809
|
+
headers: { "Content-Type": "application/json", "Authorization": `Bearer ${vProviderCfg.apiKey}` },
|
|
14721
14810
|
body: safeStringify({
|
|
14722
|
-
model:
|
|
14811
|
+
model: vModelId,
|
|
14723
14812
|
messages: [{
|
|
14724
14813
|
role: "user",
|
|
14725
14814
|
content: [
|
|
@@ -14735,6 +14824,7 @@ var init_my_eyes = __esm({
|
|
|
14735
14824
|
return { content: `Video analysis failed: HTTP ${res.status} ${t.slice(0, 300)}`, isError: true };
|
|
14736
14825
|
}
|
|
14737
14826
|
const data = await res.json();
|
|
14827
|
+
console.log(`[my-eyes:video] usage: ${extractUsage(data)}`);
|
|
14738
14828
|
const content = data.choices?.[0]?.message?.content || "";
|
|
14739
14829
|
if (!content.trim()) return { content: "Video analysis returned empty.", isError: true };
|
|
14740
14830
|
return { content };
|
|
@@ -15517,16 +15607,34 @@ var init_providers = __esm({
|
|
|
15517
15607
|
}
|
|
15518
15608
|
});
|
|
15519
15609
|
|
|
15610
|
+
// src/utils/ffmpeg-path.ts
|
|
15611
|
+
import * as fs23 from "node:fs";
|
|
15612
|
+
function resolveFfmpegPath() {
|
|
15613
|
+
const env = (process.env.E7_FFMPEG_PATH || "").trim();
|
|
15614
|
+
if (env && fs23.existsSync(env)) return env;
|
|
15615
|
+
try {
|
|
15616
|
+
const p = __require("@ffmpeg-installer/ffmpeg")?.path;
|
|
15617
|
+
if (p && fs23.existsSync(p)) return p;
|
|
15618
|
+
} catch {
|
|
15619
|
+
}
|
|
15620
|
+
return "ffmpeg";
|
|
15621
|
+
}
|
|
15622
|
+
var init_ffmpeg_path = __esm({
|
|
15623
|
+
"src/utils/ffmpeg-path.ts"() {
|
|
15624
|
+
"use strict";
|
|
15625
|
+
}
|
|
15626
|
+
});
|
|
15627
|
+
|
|
15520
15628
|
// src/tools/my-voice.ts
|
|
15521
15629
|
import { execFile as execFile3 } from "node:child_process";
|
|
15522
15630
|
import { promisify as promisify2 } from "node:util";
|
|
15523
|
-
import * as
|
|
15631
|
+
import * as fs24 from "node:fs";
|
|
15524
15632
|
import * as path24 from "node:path";
|
|
15525
15633
|
async function toWav24kWithDuration(audioPath) {
|
|
15526
15634
|
let wavPath = audioPath;
|
|
15527
15635
|
if (!audioPath.endsWith(".wav")) {
|
|
15528
15636
|
wavPath = audioPath.replace(/\.[^.]+$/, ".wav");
|
|
15529
|
-
await execFileAsync2(
|
|
15637
|
+
await execFileAsync2(resolveFfmpegPath(), [
|
|
15530
15638
|
"-y",
|
|
15531
15639
|
"-i",
|
|
15532
15640
|
audioPath,
|
|
@@ -15538,21 +15646,21 @@ async function toWav24kWithDuration(audioPath) {
|
|
|
15538
15646
|
"pcm_s16le",
|
|
15539
15647
|
wavPath
|
|
15540
15648
|
], { timeout: 3e4 });
|
|
15541
|
-
if (!
|
|
15649
|
+
if (!fs24.existsSync(wavPath) || fs24.statSync(wavPath).size < 44) {
|
|
15542
15650
|
throw new Error("toWav24k produced empty output");
|
|
15543
15651
|
}
|
|
15544
15652
|
try {
|
|
15545
|
-
|
|
15653
|
+
fs24.unlinkSync(audioPath);
|
|
15546
15654
|
} catch {
|
|
15547
15655
|
}
|
|
15548
15656
|
}
|
|
15549
|
-
const durationSec = wavDurationSec(
|
|
15657
|
+
const durationSec = wavDurationSec(fs24.readFileSync(wavPath));
|
|
15550
15658
|
return { wavPath, durationSec };
|
|
15551
15659
|
}
|
|
15552
15660
|
async function compressWav(wavPath) {
|
|
15553
15661
|
const m4aPath = wavPath.replace(/\.wav$/, ".m4a");
|
|
15554
15662
|
try {
|
|
15555
|
-
await execFileAsync2(
|
|
15663
|
+
await execFileAsync2(resolveFfmpegPath(), [
|
|
15556
15664
|
"-y",
|
|
15557
15665
|
"-i",
|
|
15558
15666
|
wavPath,
|
|
@@ -15564,7 +15672,7 @@ async function compressWav(wavPath) {
|
|
|
15564
15672
|
"+faststart",
|
|
15565
15673
|
m4aPath
|
|
15566
15674
|
], { timeout: 3e4 });
|
|
15567
|
-
|
|
15675
|
+
fs24.unlinkSync(wavPath);
|
|
15568
15676
|
return m4aPath;
|
|
15569
15677
|
} catch {
|
|
15570
15678
|
return wavPath;
|
|
@@ -15578,7 +15686,7 @@ async function wavToOggOpus(wavPath) {
|
|
|
15578
15686
|
if (globalThis.__ffmpegMissing) throw e;
|
|
15579
15687
|
console.warn(`[my-voice] native opus encode failed (${e.message}), trying ffmpeg`);
|
|
15580
15688
|
oggPath = wavPath.replace(/\.wav$/, ".ogg");
|
|
15581
|
-
await execFileAsync2(
|
|
15689
|
+
await execFileAsync2(resolveFfmpegPath(), [
|
|
15582
15690
|
"-y",
|
|
15583
15691
|
"-i",
|
|
15584
15692
|
wavPath,
|
|
@@ -15591,10 +15699,10 @@ async function wavToOggOpus(wavPath) {
|
|
|
15591
15699
|
oggPath
|
|
15592
15700
|
], { timeout: 3e4 });
|
|
15593
15701
|
}
|
|
15594
|
-
if (!
|
|
15702
|
+
if (!fs24.existsSync(oggPath) || fs24.statSync(oggPath).size < 20) {
|
|
15595
15703
|
throw new Error("ogg/opus encode produced empty output");
|
|
15596
15704
|
}
|
|
15597
|
-
|
|
15705
|
+
fs24.unlinkSync(wavPath);
|
|
15598
15706
|
return oggPath;
|
|
15599
15707
|
}
|
|
15600
15708
|
async function sendVoiceToMulticaIssue(text, issueId, opts) {
|
|
@@ -15609,7 +15717,7 @@ async function sendVoiceToMulticaIssue(text, issueId, opts) {
|
|
|
15609
15717
|
} catch (e) {
|
|
15610
15718
|
return { content: `\u8BED\u97F3\u751F\u6210\u5931\u8D25\uFF08headless\u2192multaca\uFF09\uFF1A${e.message}\u3002\u8BF7\u7528\u6587\u5B57\u56DE\u590D\u4EE3\u66FF\u3002`, isError: true };
|
|
15611
15719
|
}
|
|
15612
|
-
if (!audioPath || !
|
|
15720
|
+
if (!audioPath || !fs24.existsSync(audioPath)) {
|
|
15613
15721
|
return { content: "\u8BED\u97F3\u751F\u6210\u5931\u8D25\uFF08headless\u2192multaca\uFF09\uFF1ATTS \u672A\u4EA7\u51FA\u6587\u4EF6\u3002\u8BF7\u7528\u6587\u5B57\u56DE\u590D\u4EE3\u66FF\u3002", isError: true };
|
|
15614
15722
|
}
|
|
15615
15723
|
if (audioPath.endsWith(".wav")) {
|
|
@@ -15620,20 +15728,20 @@ async function sendVoiceToMulticaIssue(text, issueId, opts) {
|
|
|
15620
15728
|
}
|
|
15621
15729
|
}
|
|
15622
15730
|
const ext = path24.extname(audioPath).toLowerCase();
|
|
15623
|
-
const sizeKB =
|
|
15731
|
+
const sizeKB = fs24.statSync(audioPath).size / 1024;
|
|
15624
15732
|
const voiceFile = `voice_${Date.now()}${ext}`;
|
|
15625
15733
|
const cwdCopy = path24.join(process.cwd(), voiceFile);
|
|
15626
15734
|
try {
|
|
15627
|
-
|
|
15735
|
+
fs24.copyFileSync(audioPath, cwdCopy);
|
|
15628
15736
|
} catch (e) {
|
|
15629
15737
|
try {
|
|
15630
|
-
|
|
15738
|
+
fs24.unlinkSync(audioPath);
|
|
15631
15739
|
} catch {
|
|
15632
15740
|
}
|
|
15633
15741
|
return { content: `\u8BED\u97F3\u6302\u8F7D\u5931\u8D25\uFF08\u62F7\u8D1D\u5230\u5DE5\u4F5C\u76EE\u5F55\uFF09\uFF1A${e.message}`, isError: true };
|
|
15634
15742
|
}
|
|
15635
15743
|
try {
|
|
15636
|
-
|
|
15744
|
+
fs24.unlinkSync(audioPath);
|
|
15637
15745
|
} catch {
|
|
15638
15746
|
}
|
|
15639
15747
|
const content = opts.caption || `\u{1F399}\uFE0F \u8BED\u97F3\u6D88\u606F\uFF08${text.length} \u5B57\uFF09`;
|
|
@@ -15662,13 +15770,13 @@ async function sendVoiceToMulticaIssue(text, issueId, opts) {
|
|
|
15662
15770
|
}
|
|
15663
15771
|
if (!ok) throw new Error(`unexpected CLI output: ${String(stdout).slice(0, 200)}`);
|
|
15664
15772
|
try {
|
|
15665
|
-
|
|
15773
|
+
fs24.unlinkSync(cwdCopy);
|
|
15666
15774
|
} catch {
|
|
15667
15775
|
}
|
|
15668
15776
|
return { content: `Voice sent to multaca issue ${issueId}! (${actualEngine}, ${sizeKB.toFixed(0)}KB, \u9644\u4EF6\u5DF2\u6302\u5230\u8BC4\u8BBA\u2014\u2014\u5728 multaca \u5BA2\u6237\u7AEF\u64AD\u653E)` };
|
|
15669
15777
|
} catch (e) {
|
|
15670
15778
|
try {
|
|
15671
|
-
|
|
15779
|
+
fs24.unlinkSync(cwdCopy);
|
|
15672
15780
|
} catch {
|
|
15673
15781
|
}
|
|
15674
15782
|
return { content: `\u8BED\u97F3\u6302\u5230 multaca issue \u5931\u8D25\uFF1A${e.message}\u3002\u8BF7\u7528\u6587\u5B57\u56DE\u590D\u4EE3\u66FF\u3002`, isError: true };
|
|
@@ -15685,6 +15793,7 @@ var init_my_voice = __esm({
|
|
|
15685
15793
|
init_pick();
|
|
15686
15794
|
init_providers();
|
|
15687
15795
|
init_impl();
|
|
15796
|
+
init_ffmpeg_path();
|
|
15688
15797
|
execFileAsync2 = promisify2(execFile3);
|
|
15689
15798
|
registry.register({
|
|
15690
15799
|
name: "my_voice",
|
|
@@ -15800,7 +15909,7 @@ var init_my_voice = __esm({
|
|
|
15800
15909
|
const ext = path24.extname(audioPath).toLowerCase();
|
|
15801
15910
|
const mimeMap = { ".mp3": "audio/mpeg", ".wav": "audio/wav", ".m4a": "audio/mp4", ".ogg": "audio/ogg", ".silk": "audio/silk" };
|
|
15802
15911
|
const mimeType = mimeMap[ext] || "audio/mpeg";
|
|
15803
|
-
const sizeKB =
|
|
15912
|
+
const sizeKB = fs24.statSync(audioPath).size / 1024;
|
|
15804
15913
|
try {
|
|
15805
15914
|
await mgr.sendFile(resolvedChannel, target, caption, {
|
|
15806
15915
|
path: audioPath,
|
|
@@ -15809,7 +15918,7 @@ var init_my_voice = __esm({
|
|
|
15809
15918
|
...voiceDurationSec !== void 0 ? { voiceDurationSec } : {}
|
|
15810
15919
|
});
|
|
15811
15920
|
try {
|
|
15812
|
-
|
|
15921
|
+
fs24.unlinkSync(audioPath);
|
|
15813
15922
|
} catch {
|
|
15814
15923
|
}
|
|
15815
15924
|
return { content: `Voice sent! (${actualEngine}, ${sizeKB.toFixed(0)}KB, ${resolvedChannel})` };
|
|
@@ -15831,7 +15940,7 @@ __export(my_selfie_exports, {
|
|
|
15831
15940
|
dimsOf: () => dimsOf,
|
|
15832
15941
|
resolvePortraitDesc: () => resolvePortraitDesc
|
|
15833
15942
|
});
|
|
15834
|
-
import * as
|
|
15943
|
+
import * as fs25 from "node:fs";
|
|
15835
15944
|
import * as path25 from "node:path";
|
|
15836
15945
|
function getProxyDispatcher2() {
|
|
15837
15946
|
const cfg = liveConfig.all();
|
|
@@ -15846,7 +15955,7 @@ function getProxyDispatcher2() {
|
|
|
15846
15955
|
}
|
|
15847
15956
|
function dimsOf(p) {
|
|
15848
15957
|
try {
|
|
15849
|
-
const b =
|
|
15958
|
+
const b = fs25.readFileSync(p);
|
|
15850
15959
|
let w = 0, h = 0;
|
|
15851
15960
|
if (b.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) {
|
|
15852
15961
|
w = b.readUInt32BE(16);
|
|
@@ -16262,7 +16371,7 @@ var init_my_selfie = __esm({
|
|
|
16262
16371
|
let refPath = path25.join(ctx.workspace, refEntry.p);
|
|
16263
16372
|
const adoptImg = args.referenceImage?.trim();
|
|
16264
16373
|
if (adoptImg) {
|
|
16265
|
-
if (!
|
|
16374
|
+
if (!fs25.existsSync(adoptImg)) {
|
|
16266
16375
|
return { content: `\u627E\u4E0D\u5230\u90A3\u5F20\u56FE\uFF1A${adoptImg}`, isError: true };
|
|
16267
16376
|
}
|
|
16268
16377
|
const acheck = dimsOf(adoptImg);
|
|
@@ -16274,15 +16383,15 @@ var init_my_selfie = __esm({
|
|
|
16274
16383
|
};
|
|
16275
16384
|
}
|
|
16276
16385
|
const adir = path25.join(ctx.workspace, "images");
|
|
16277
|
-
if (!
|
|
16386
|
+
if (!fs25.existsSync(adir)) fs25.mkdirSync(adir, { recursive: true });
|
|
16278
16387
|
const aext = (path25.extname(adoptImg) || ".png").toLowerCase();
|
|
16279
16388
|
const afname = `portrait_${Date.now()}${aext}`;
|
|
16280
|
-
|
|
16389
|
+
fs25.copyFileSync(adoptImg, path25.join(adir, afname));
|
|
16281
16390
|
registerPortrait(`images/${afname}`, refName);
|
|
16282
16391
|
refPath = path25.join(adir, afname);
|
|
16283
16392
|
console.log(`[my-selfie] \u91C7\u7EB3\u73B0\u6210\u56FE\u5F53\u5F62\u8C61\uFF1Aimages/${afname}${acheck ? ` (${acheck})` : ""}`);
|
|
16284
16393
|
}
|
|
16285
|
-
if (provider !== "autodl" && !
|
|
16394
|
+
if (provider !== "autodl" && !fs25.existsSync(refPath)) {
|
|
16286
16395
|
const cfgAll = liveConfig.all();
|
|
16287
16396
|
const portraitDesc = resolvePortraitDesc(
|
|
16288
16397
|
args.portrait,
|
|
@@ -16308,15 +16417,15 @@ var init_my_selfie = __esm({
|
|
|
16308
16417
|
return { content: `\u5851\u9020\u5F62\u8C61\u5931\u8D25\uFF1A${e.message}`, isError: true };
|
|
16309
16418
|
}
|
|
16310
16419
|
const pdir = path25.join(ctx.workspace, "images");
|
|
16311
|
-
if (!
|
|
16420
|
+
if (!fs25.existsSync(pdir)) fs25.mkdirSync(pdir, { recursive: true });
|
|
16312
16421
|
const pfname = `portrait_${Date.now()}.png`;
|
|
16313
|
-
|
|
16422
|
+
fs25.writeFileSync(path25.join(pdir, pfname), portraitBuf);
|
|
16314
16423
|
registerPortrait(`images/${pfname}`, refName);
|
|
16315
16424
|
refPath = path25.join(pdir, pfname);
|
|
16316
16425
|
console.log(`[my-selfie] \u5F62\u8C61\u5DF2\u5B58 images/${pfname}\uFF0C\u7EE7\u7EED\u8FD9\u6B21\u81EA\u62CD`);
|
|
16317
16426
|
}
|
|
16318
16427
|
const resolution = args.resolution || DEFAULT_RESOLUTION;
|
|
16319
|
-
const refB64 =
|
|
16428
|
+
const refB64 = fs25.existsSync(refPath) ? fs25.readFileSync(refPath).toString("base64") : "";
|
|
16320
16429
|
let imageBuffer;
|
|
16321
16430
|
try {
|
|
16322
16431
|
if (provider === "autodl") {
|
|
@@ -16342,10 +16451,10 @@ var init_my_selfie = __esm({
|
|
|
16342
16451
|
return { content: `Selfie generation failed: ${err.message}`, isError: true };
|
|
16343
16452
|
}
|
|
16344
16453
|
const imagesDir = path25.join(ctx.workspace, "images");
|
|
16345
|
-
if (!
|
|
16454
|
+
if (!fs25.existsSync(imagesDir)) fs25.mkdirSync(imagesDir, { recursive: true });
|
|
16346
16455
|
const filename = `selfie_${Date.now()}.jpg`;
|
|
16347
16456
|
const outputPath = path25.join(imagesDir, filename);
|
|
16348
|
-
|
|
16457
|
+
fs25.writeFileSync(outputPath, imageBuffer);
|
|
16349
16458
|
const mgr = ctx.channelManager;
|
|
16350
16459
|
if (mgr) {
|
|
16351
16460
|
const resolvedChannel = ctx.channel || "feishu";
|
|
@@ -16663,7 +16772,7 @@ var init_helpers = __esm({
|
|
|
16663
16772
|
});
|
|
16664
16773
|
|
|
16665
16774
|
// src/calendar/commands.ts
|
|
16666
|
-
import { existsSync as
|
|
16775
|
+
import { existsSync as existsSync19, statSync as statSync11 } from "node:fs";
|
|
16667
16776
|
import { isAbsolute as isAbsolute4, resolve as resolve6 } from "node:path";
|
|
16668
16777
|
function fmtEnd(start, durationMin) {
|
|
16669
16778
|
const [hh, mm] = start.split(":").map(Number);
|
|
@@ -16832,7 +16941,7 @@ function addTask(db2, args) {
|
|
|
16832
16941
|
}
|
|
16833
16942
|
try {
|
|
16834
16943
|
const absPath = isAbsolute4(docPath) ? docPath : resolve6(process.cwd(), docPath);
|
|
16835
|
-
if (!
|
|
16944
|
+
if (!existsSync19(absPath)) {
|
|
16836
16945
|
return `\u274C \u521B\u5EFA\u5931\u8D25\uFF1Adoc_path \u6307\u5411\u7684\u6587\u4EF6\u4E0D\u5B58\u5728
|
|
16837
16946
|
\u8DEF\u5F84: ${docPath}
|
|
16838
16947
|
\u89E3\u6790\u540E: ${absPath}
|
|
@@ -17190,7 +17299,7 @@ var init_calendar = __esm({
|
|
|
17190
17299
|
});
|
|
17191
17300
|
|
|
17192
17301
|
// src/tools/service.ts
|
|
17193
|
-
import * as
|
|
17302
|
+
import * as fs26 from "node:fs";
|
|
17194
17303
|
import * as path26 from "node:path";
|
|
17195
17304
|
import { exec, spawn as spawn4 } from "node:child_process";
|
|
17196
17305
|
import { promisify as promisify3 } from "node:util";
|
|
@@ -17200,7 +17309,7 @@ function getServices() {
|
|
|
17200
17309
|
function serviceLogPath(fileName) {
|
|
17201
17310
|
const stateDir = String(liveConfig.get("stateDir") ?? "");
|
|
17202
17311
|
const logDir = path26.join(stateDir, "logs");
|
|
17203
|
-
if (!
|
|
17312
|
+
if (!fs26.existsSync(logDir)) fs26.mkdirSync(logDir, { recursive: true });
|
|
17204
17313
|
return path26.join(logDir, fileName);
|
|
17205
17314
|
}
|
|
17206
17315
|
async function runCmd(cmd, timeoutMs = 15e3) {
|
|
@@ -17416,7 +17525,7 @@ var init_constants5 = __esm({
|
|
|
17416
17525
|
});
|
|
17417
17526
|
|
|
17418
17527
|
// src/tools/TodoWriteTool/TodoWriteTool.ts
|
|
17419
|
-
import
|
|
17528
|
+
import fs27 from "node:fs";
|
|
17420
17529
|
import path27 from "node:path";
|
|
17421
17530
|
function todoFilePath(sessionId) {
|
|
17422
17531
|
return path27.join(todosDir, `${sessionId}.json`);
|
|
@@ -17425,15 +17534,15 @@ function loadTodos(sessionId) {
|
|
|
17425
17534
|
if (!todosDir) return [];
|
|
17426
17535
|
try {
|
|
17427
17536
|
const filePath = todoFilePath(sessionId);
|
|
17428
|
-
if (!
|
|
17429
|
-
return JSON.parse(
|
|
17537
|
+
if (!fs27.existsSync(filePath)) return [];
|
|
17538
|
+
return JSON.parse(fs27.readFileSync(filePath, "utf-8"));
|
|
17430
17539
|
} catch {
|
|
17431
17540
|
return [];
|
|
17432
17541
|
}
|
|
17433
17542
|
}
|
|
17434
17543
|
function saveTodos(sessionId, todos) {
|
|
17435
17544
|
if (!todosDir) return;
|
|
17436
|
-
|
|
17545
|
+
fs27.writeFileSync(todoFilePath(sessionId), JSON.stringify(todos, null, 2), "utf-8");
|
|
17437
17546
|
}
|
|
17438
17547
|
var todosDir;
|
|
17439
17548
|
var init_TodoWriteTool = __esm({
|
|
@@ -17690,7 +17799,7 @@ var init_constants7 = __esm({
|
|
|
17690
17799
|
});
|
|
17691
17800
|
|
|
17692
17801
|
// src/utils/plans.ts
|
|
17693
|
-
import * as
|
|
17802
|
+
import * as fs28 from "node:fs";
|
|
17694
17803
|
import * as path28 from "node:path";
|
|
17695
17804
|
import * as crypto4 from "node:crypto";
|
|
17696
17805
|
function generateSlug() {
|
|
@@ -17698,7 +17807,7 @@ function generateSlug() {
|
|
|
17698
17807
|
}
|
|
17699
17808
|
function getPlansDirectory(stateDir) {
|
|
17700
17809
|
const plansDir = path28.join(stateDir, "plans");
|
|
17701
|
-
|
|
17810
|
+
fs28.mkdirSync(plansDir, { recursive: true });
|
|
17702
17811
|
return plansDir;
|
|
17703
17812
|
}
|
|
17704
17813
|
function getPlanSlug(sessionId, stateDir) {
|
|
@@ -17708,7 +17817,7 @@ function getPlanSlug(sessionId, stateDir) {
|
|
|
17708
17817
|
for (let i = 0; i < MAX_SLUG_RETRIES; i++) {
|
|
17709
17818
|
slug = generateSlug();
|
|
17710
17819
|
const filePath = path28.join(plansDir, `${slug}.md`);
|
|
17711
|
-
if (!
|
|
17820
|
+
if (!fs28.existsSync(filePath)) {
|
|
17712
17821
|
break;
|
|
17713
17822
|
}
|
|
17714
17823
|
}
|
|
@@ -17726,14 +17835,14 @@ function getPlanFilePath(sessionId, stateDir, agentId) {
|
|
|
17726
17835
|
function getPlan(sessionId, stateDir, agentId) {
|
|
17727
17836
|
const filePath = getPlanFilePath(sessionId, stateDir, agentId);
|
|
17728
17837
|
try {
|
|
17729
|
-
return
|
|
17838
|
+
return fs28.readFileSync(filePath, "utf-8");
|
|
17730
17839
|
} catch {
|
|
17731
17840
|
return null;
|
|
17732
17841
|
}
|
|
17733
17842
|
}
|
|
17734
17843
|
function writePlan(sessionId, stateDir, content, agentId) {
|
|
17735
17844
|
const filePath = getPlanFilePath(sessionId, stateDir, agentId);
|
|
17736
|
-
|
|
17845
|
+
fs28.writeFileSync(filePath, content, "utf-8");
|
|
17737
17846
|
return filePath;
|
|
17738
17847
|
}
|
|
17739
17848
|
var MAX_SLUG_RETRIES, planSlugCache;
|
|
@@ -17881,7 +17990,7 @@ var init_constants8 = __esm({
|
|
|
17881
17990
|
});
|
|
17882
17991
|
|
|
17883
17992
|
// src/utils/tasks.ts
|
|
17884
|
-
import * as
|
|
17993
|
+
import * as fs29 from "node:fs";
|
|
17885
17994
|
import * as path29 from "node:path";
|
|
17886
17995
|
function sanitizePathComponent2(input) {
|
|
17887
17996
|
return input.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
@@ -17894,7 +18003,7 @@ function getTaskPath(stateDir, listId, taskId) {
|
|
|
17894
18003
|
}
|
|
17895
18004
|
function ensureTasksDir2(stateDir, listId) {
|
|
17896
18005
|
const dir = getTasksDir2(stateDir, listId);
|
|
17897
|
-
|
|
18006
|
+
fs29.mkdirSync(dir, { recursive: true });
|
|
17898
18007
|
return dir;
|
|
17899
18008
|
}
|
|
17900
18009
|
function getHighWaterMarkPath(stateDir, listId) {
|
|
@@ -17902,7 +18011,7 @@ function getHighWaterMarkPath(stateDir, listId) {
|
|
|
17902
18011
|
}
|
|
17903
18012
|
function readHighWaterMark(stateDir, listId) {
|
|
17904
18013
|
try {
|
|
17905
|
-
const content =
|
|
18014
|
+
const content = fs29.readFileSync(getHighWaterMarkPath(stateDir, listId), "utf-8").trim();
|
|
17906
18015
|
const value = parseInt(content, 10);
|
|
17907
18016
|
return isNaN(value) ? 0 : value;
|
|
17908
18017
|
} catch {
|
|
@@ -17910,13 +18019,13 @@ function readHighWaterMark(stateDir, listId) {
|
|
|
17910
18019
|
}
|
|
17911
18020
|
}
|
|
17912
18021
|
function writeHighWaterMark(stateDir, listId, value) {
|
|
17913
|
-
|
|
18022
|
+
fs29.writeFileSync(getHighWaterMarkPath(stateDir, listId), String(value));
|
|
17914
18023
|
}
|
|
17915
18024
|
function findHighestTaskIdFromFiles(stateDir, listId) {
|
|
17916
18025
|
const dir = getTasksDir2(stateDir, listId);
|
|
17917
18026
|
let files;
|
|
17918
18027
|
try {
|
|
17919
|
-
files =
|
|
18028
|
+
files = fs29.readdirSync(dir);
|
|
17920
18029
|
} catch {
|
|
17921
18030
|
return 0;
|
|
17922
18031
|
}
|
|
@@ -17942,14 +18051,14 @@ function createTask(stateDir, listId, taskData) {
|
|
|
17942
18051
|
const id = String(highestId + 1);
|
|
17943
18052
|
const task = { id, ...taskData };
|
|
17944
18053
|
const filePath = getTaskPath(stateDir, listId, id);
|
|
17945
|
-
|
|
18054
|
+
fs29.writeFileSync(filePath, JSON.stringify(task, null, 2));
|
|
17946
18055
|
return id;
|
|
17947
18056
|
});
|
|
17948
18057
|
}
|
|
17949
18058
|
function getTask2(stateDir, listId, taskId) {
|
|
17950
18059
|
const filePath = getTaskPath(stateDir, listId, taskId);
|
|
17951
18060
|
try {
|
|
17952
|
-
const content =
|
|
18061
|
+
const content = fs29.readFileSync(filePath, "utf-8");
|
|
17953
18062
|
return JSON.parse(content);
|
|
17954
18063
|
} catch {
|
|
17955
18064
|
return null;
|
|
@@ -17959,7 +18068,7 @@ function listTasks2(stateDir, listId) {
|
|
|
17959
18068
|
const dir = getTasksDir2(stateDir, listId);
|
|
17960
18069
|
let files;
|
|
17961
18070
|
try {
|
|
17962
|
-
files =
|
|
18071
|
+
files = fs29.readdirSync(dir);
|
|
17963
18072
|
} catch {
|
|
17964
18073
|
return [];
|
|
17965
18074
|
}
|
|
@@ -17971,7 +18080,7 @@ function updateTask(stateDir, listId, taskId, updates) {
|
|
|
17971
18080
|
if (!existing) return null;
|
|
17972
18081
|
const updated = { ...existing, ...updates, id: taskId };
|
|
17973
18082
|
const filePath = getTaskPath(stateDir, listId, taskId);
|
|
17974
|
-
|
|
18083
|
+
fs29.writeFileSync(filePath, JSON.stringify(updated, null, 2));
|
|
17975
18084
|
return updated;
|
|
17976
18085
|
}
|
|
17977
18086
|
function deleteTask(stateDir, listId, taskId) {
|
|
@@ -17985,7 +18094,7 @@ function deleteTask(stateDir, listId, taskId) {
|
|
|
17985
18094
|
}
|
|
17986
18095
|
}
|
|
17987
18096
|
try {
|
|
17988
|
-
|
|
18097
|
+
fs29.unlinkSync(filePath);
|
|
17989
18098
|
} catch {
|
|
17990
18099
|
return false;
|
|
17991
18100
|
}
|
|
@@ -19409,7 +19518,7 @@ var init_task_stop = __esm({
|
|
|
19409
19518
|
});
|
|
19410
19519
|
|
|
19411
19520
|
// src/tools/reply-blocklist.ts
|
|
19412
|
-
import { readFileSync as readFileSync21, writeFileSync as writeFileSync16, existsSync as
|
|
19521
|
+
import { readFileSync as readFileSync21, writeFileSync as writeFileSync16, existsSync as existsSync22 } from "node:fs";
|
|
19413
19522
|
import { join as join28 } from "node:path";
|
|
19414
19523
|
function ensureLoaded(workspace, configIds) {
|
|
19415
19524
|
if (loaded) return;
|
|
@@ -19420,7 +19529,7 @@ function ensureLoaded(workspace, configIds) {
|
|
|
19420
19529
|
}
|
|
19421
19530
|
const path43 = join28(workspace, ".reply-blocklist.json");
|
|
19422
19531
|
try {
|
|
19423
|
-
if (
|
|
19532
|
+
if (existsSync22(path43)) {
|
|
19424
19533
|
const raw = readFileSync21(path43, "utf-8");
|
|
19425
19534
|
const parsed = JSON.parse(raw);
|
|
19426
19535
|
if (parsed.blockedUserIds) {
|
|
@@ -20311,15 +20420,15 @@ var init_findRelevantMemoriesEveros = __esm({
|
|
|
20311
20420
|
});
|
|
20312
20421
|
|
|
20313
20422
|
// src/config/persona-files.ts
|
|
20314
|
-
import { existsSync as
|
|
20423
|
+
import { existsSync as existsSync23 } from "node:fs";
|
|
20315
20424
|
import { join as join32 } from "node:path";
|
|
20316
20425
|
function resolvePersonaFile(workspace, persona, name) {
|
|
20317
20426
|
if (persona) {
|
|
20318
20427
|
const scoped = join32(workspace, "personas", persona, name);
|
|
20319
|
-
if (
|
|
20428
|
+
if (existsSync23(scoped)) return scoped;
|
|
20320
20429
|
}
|
|
20321
20430
|
const legacy = join32(workspace, LEGACY_RELATIVE[name] ?? name);
|
|
20322
|
-
return
|
|
20431
|
+
return existsSync23(legacy) ? legacy : null;
|
|
20323
20432
|
}
|
|
20324
20433
|
var LEGACY_RELATIVE;
|
|
20325
20434
|
var init_persona_files = __esm({
|
|
@@ -20466,7 +20575,7 @@ var init_voiceFastView = __esm({
|
|
|
20466
20575
|
});
|
|
20467
20576
|
|
|
20468
20577
|
// src/sender-context.ts
|
|
20469
|
-
import { readFileSync as readFileSync24, existsSync as
|
|
20578
|
+
import { readFileSync as readFileSync24, existsSync as existsSync25 } from "node:fs";
|
|
20470
20579
|
import { join as join33 } from "node:path";
|
|
20471
20580
|
function loadContactMap(workspace) {
|
|
20472
20581
|
if (contactMap) return contactMap;
|
|
@@ -20474,8 +20583,8 @@ function loadContactMap(workspace) {
|
|
|
20474
20583
|
externalChanWhitelist = /* @__PURE__ */ new Set();
|
|
20475
20584
|
try {
|
|
20476
20585
|
const contactsPath = join33(workspace, "prompts", "contacts.md");
|
|
20477
|
-
console.log(`[meta] Loading contacts from ${contactsPath}, exists=${
|
|
20478
|
-
if (
|
|
20586
|
+
console.log(`[meta] Loading contacts from ${contactsPath}, exists=${existsSync25(contactsPath)}`);
|
|
20587
|
+
if (existsSync25(contactsPath)) {
|
|
20479
20588
|
const text = readFileSync24(contactsPath, "utf-8");
|
|
20480
20589
|
const lines = text.split("\n");
|
|
20481
20590
|
for (const line of lines) {
|
|
@@ -20590,6 +20699,7 @@ function buildExtractAutoOnlyPrompt(newMessageCount, existingMemories, skipIndex
|
|
|
20590
20699
|
"",
|
|
20591
20700
|
...MEMORY_FRONTMATTER_EXAMPLE,
|
|
20592
20701
|
"",
|
|
20702
|
+
"\u26A0\uFE0F \u6240\u6709\u65E5\u671F\u5FC5\u987B\u542B\u5E74\u4EFD\uFF0C\u683C\u5F0F YYYY-MM-DD\uFF08\u5982 2026-07-26\uFF09\uFF0C\u7981\u6B62\u53EA\u5199\u6708/\u65E5\uFF087/26\u30010726\uFF09\u2014\u2014\u8DE8\u5E74\u4F1A\u6DF7\u4E71\u3002\u6B63\u6587\u4EFB\u4F55\u65E5\u671F\u3001\u6587\u4EF6\u540D\u65E5\u671F\u6807\u7B7E\u90FD\u8981\u542B\u5E74\u4EFD\u3002(All dates MUST include the year, format YYYY-MM-DD. Never write month/day only \u2014 it breaks next year.)",
|
|
20593
20703
|
"- Organize memory semantically by topic, not chronologically",
|
|
20594
20704
|
"- Update or remove memories that turn out to be wrong or outdated",
|
|
20595
20705
|
"- Do not write duplicate memories. First check if there is an existing memory you can update before writing a new one."
|
|
@@ -20605,6 +20715,7 @@ function buildExtractAutoOnlyPrompt(newMessageCount, existingMemories, skipIndex
|
|
|
20605
20715
|
`**Step 2** \u2014 add a pointer to that file in \`${ENTRYPOINT_NAME}\`. \`${ENTRYPOINT_NAME}\` is an index, not a memory \u2014 each entry should be one line, under ~150 characters: \`- [Title](file.md) \u2014 one-line hook\`. It has no frontmatter. Never write memory content directly into \`${ENTRYPOINT_NAME}\`.`,
|
|
20606
20716
|
"",
|
|
20607
20717
|
`- \`${ENTRYPOINT_NAME}\` is always loaded into your system prompt \u2014 lines after 200 will be truncated, so keep the index concise`,
|
|
20718
|
+
"\u26A0\uFE0F \u6240\u6709\u65E5\u671F\u5FC5\u987B\u542B\u5E74\u4EFD\uFF0C\u683C\u5F0F YYYY-MM-DD\uFF08\u5982 2026-07-26\uFF09\uFF0C\u7981\u6B62\u53EA\u5199\u6708/\u65E5\uFF087/26\u30010726\uFF09\u2014\u2014\u8DE8\u5E74\u4F1A\u6DF7\u4E71\u3002\u6B63\u6587\u4EFB\u4F55\u65E5\u671F\u3001\u6587\u4EF6\u540D\u65E5\u671F\u6807\u7B7E\u90FD\u8981\u542B\u5E74\u4EFD\u3002(All dates MUST include the year, format YYYY-MM-DD. Never write month/day only \u2014 it breaks next year.)",
|
|
20608
20719
|
"- Organize memory semantically by topic, not chronologically",
|
|
20609
20720
|
"- Update or remove memories that turn out to be wrong or outdated",
|
|
20610
20721
|
"- Do not write duplicate memories. First check if there is an existing memory you can update before writing a new one."
|
|
@@ -20633,7 +20744,7 @@ var extractMemories_exports = {};
|
|
|
20633
20744
|
__export(extractMemories_exports, {
|
|
20634
20745
|
createMemoryExtractor: () => createMemoryExtractor
|
|
20635
20746
|
});
|
|
20636
|
-
import * as
|
|
20747
|
+
import * as fs30 from "fs";
|
|
20637
20748
|
import * as path30 from "path";
|
|
20638
20749
|
function isModelVisibleMessage(message) {
|
|
20639
20750
|
return message.role === "user" || message.role === "assistant";
|
|
@@ -20662,8 +20773,8 @@ function getStatePath(workspace) {
|
|
|
20662
20773
|
function loadPersistedState(workspace) {
|
|
20663
20774
|
try {
|
|
20664
20775
|
const p = getStatePath(workspace);
|
|
20665
|
-
if (
|
|
20666
|
-
const data = JSON.parse(
|
|
20776
|
+
if (fs30.existsSync(p)) {
|
|
20777
|
+
const data = JSON.parse(fs30.readFileSync(p, "utf-8"));
|
|
20667
20778
|
for (const [sid, ts] of Object.entries(data.lastTs ?? {})) {
|
|
20668
20779
|
lastTsMap.set(sid, ts);
|
|
20669
20780
|
}
|
|
@@ -20683,7 +20794,7 @@ function persistState(workspace) {
|
|
|
20683
20794
|
for (const [sid, ts] of lastTsMap.entries()) lastTs[sid] = ts;
|
|
20684
20795
|
for (const [sid, ts] of lastExtractTimeMap.entries()) timestamps[sid] = ts;
|
|
20685
20796
|
const data = JSON.stringify({ lastTs, timestamps }, null, 2);
|
|
20686
|
-
|
|
20797
|
+
fs30.writeFileSync(getStatePath(workspace), data, "utf-8");
|
|
20687
20798
|
} catch (e) {
|
|
20688
20799
|
console.warn(`[memory] failed to persist extract state: ${e?.message ?? e}`);
|
|
20689
20800
|
}
|
|
@@ -20727,8 +20838,8 @@ function createMemoryExtractor(workspace, enabled) {
|
|
|
20727
20838
|
const extractOverridePath = path30.join(workspace, "prompts", "extract.md");
|
|
20728
20839
|
let systemPrompt;
|
|
20729
20840
|
try {
|
|
20730
|
-
if (
|
|
20731
|
-
systemPrompt =
|
|
20841
|
+
if (fs30.existsSync(extractOverridePath)) {
|
|
20842
|
+
systemPrompt = fs30.readFileSync(extractOverridePath, { encoding: "utf-8" });
|
|
20732
20843
|
if (existingMemories.length > 0) {
|
|
20733
20844
|
systemPrompt += `
|
|
20734
20845
|
|
|
@@ -20854,7 +20965,7 @@ __export(ingest_exports, {
|
|
|
20854
20965
|
pushConversation: () => pushConversation,
|
|
20855
20966
|
toPayload: () => toPayload
|
|
20856
20967
|
});
|
|
20857
|
-
import
|
|
20968
|
+
import fs31 from "node:fs";
|
|
20858
20969
|
import path31 from "node:path";
|
|
20859
20970
|
async function readConfig() {
|
|
20860
20971
|
const defaults = {
|
|
@@ -20886,8 +20997,8 @@ async function readConfig() {
|
|
|
20886
20997
|
function loadPushTs(workspace, sessionId) {
|
|
20887
20998
|
try {
|
|
20888
20999
|
const p = path31.join(workspace, PUSH_STATE_FILE);
|
|
20889
|
-
if (
|
|
20890
|
-
const data = JSON.parse(
|
|
21000
|
+
if (fs31.existsSync(p)) {
|
|
21001
|
+
const data = JSON.parse(fs31.readFileSync(p, "utf-8"));
|
|
20891
21002
|
return typeof data[sessionId] === "number" ? data[sessionId] : 0;
|
|
20892
21003
|
}
|
|
20893
21004
|
} catch (e) {
|
|
@@ -20900,11 +21011,11 @@ function savePushTs(workspace, sessionId, ts) {
|
|
|
20900
21011
|
const p = path31.join(workspace, PUSH_STATE_FILE);
|
|
20901
21012
|
let data = {};
|
|
20902
21013
|
try {
|
|
20903
|
-
if (
|
|
21014
|
+
if (fs31.existsSync(p)) data = JSON.parse(fs31.readFileSync(p, "utf-8"));
|
|
20904
21015
|
} catch {
|
|
20905
21016
|
}
|
|
20906
21017
|
data[sessionId] = ts;
|
|
20907
|
-
|
|
21018
|
+
fs31.writeFileSync(p, JSON.stringify(data, null, 2), "utf-8");
|
|
20908
21019
|
} catch (e) {
|
|
20909
21020
|
console.warn(`[everos-ingest] save pushTs failed: ${e?.message ?? e}`);
|
|
20910
21021
|
}
|
|
@@ -21739,7 +21850,7 @@ Follow these principles when generating episodic memories:
|
|
|
21739
21850
|
|
|
21740
21851
|
// src/mem7/core/store.ts
|
|
21741
21852
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
21742
|
-
import { mkdirSync as mkdirSync18, readFileSync as readFileSync26, writeFileSync as writeFileSync18, existsSync as
|
|
21853
|
+
import { mkdirSync as mkdirSync18, readFileSync as readFileSync26, writeFileSync as writeFileSync18, existsSync as existsSync27, readdirSync as readdirSync8 } from "node:fs";
|
|
21743
21854
|
import { join as join36 } from "node:path";
|
|
21744
21855
|
import { createHash as createHash2 } from "node:crypto";
|
|
21745
21856
|
function contentHash(text) {
|
|
@@ -21920,7 +22031,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
21920
22031
|
let head;
|
|
21921
22032
|
let existingBlocks = "";
|
|
21922
22033
|
let count;
|
|
21923
|
-
if (
|
|
22034
|
+
if (existsSync27(file2)) {
|
|
21924
22035
|
const text = readFileSync26(file2, "utf8");
|
|
21925
22036
|
const fmEnd = text.indexOf("\n---", 3);
|
|
21926
22037
|
const split = fmEnd >= 0 ? fmEnd + 4 : text.length;
|
|
@@ -21974,7 +22085,7 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
21974
22085
|
const [dirName, filePrefix] = dirByPrefix[prefix];
|
|
21975
22086
|
const file2 = join36(this.root, "users", ownerId, dirName, `${filePrefix}-${dateStr}.md`);
|
|
21976
22087
|
let max = 0;
|
|
21977
|
-
if (
|
|
22088
|
+
if (existsSync27(file2)) {
|
|
21978
22089
|
const re = new RegExp(`${prefix}_${dateStr.replace(/-/g, "")}_(\\d+)`, "g");
|
|
21979
22090
|
for (const m of readFileSync26(file2, "utf8").matchAll(re)) max = Math.max(max, Number(m[1]));
|
|
21980
22091
|
}
|
|
@@ -22044,11 +22155,11 @@ CREATE TABLE IF NOT EXISTS watermarks (
|
|
|
22044
22155
|
const today2 = todayKey(now);
|
|
22045
22156
|
const out = [];
|
|
22046
22157
|
const usersDir = join36(this.root, "users");
|
|
22047
|
-
if (!
|
|
22158
|
+
if (!existsSync27(usersDir)) return out;
|
|
22048
22159
|
for (const owner of readdirSync8(usersDir, { withFileTypes: true })) {
|
|
22049
22160
|
if (!owner.isDirectory()) continue;
|
|
22050
22161
|
const dir = join36(usersDir, owner.name, ".foresights");
|
|
22051
|
-
if (!
|
|
22162
|
+
if (!existsSync27(dir)) continue;
|
|
22052
22163
|
for (const f of readdirSync8(dir)) {
|
|
22053
22164
|
if (!/^foresight-\d{4}-\d{2}-\d{2}\.md$/.test(f)) continue;
|
|
22054
22165
|
let content;
|
|
@@ -23710,7 +23821,6 @@ var init_agent_tools = __esm({
|
|
|
23710
23821
|
constructor(store) {
|
|
23711
23822
|
this.store = store;
|
|
23712
23823
|
}
|
|
23713
|
-
store;
|
|
23714
23824
|
/** 5 个工具的 JSON Schema 定义(tools.py:190-264 get_tool_definitions 直译) */
|
|
23715
23825
|
getDefinitions() {
|
|
23716
23826
|
return [
|
|
@@ -24926,7 +25036,7 @@ var init_recall_score = __esm({
|
|
|
24926
25036
|
});
|
|
24927
25037
|
|
|
24928
25038
|
// src/memory/proactive/opportunity.ts
|
|
24929
|
-
import { readdirSync as readdirSync9, readFileSync as readFileSync32, existsSync as
|
|
25039
|
+
import { readdirSync as readdirSync9, readFileSync as readFileSync32, existsSync as existsSync28 } from "node:fs";
|
|
24930
25040
|
import { join as join43 } from "node:path";
|
|
24931
25041
|
function normalizeOpportunity(raw) {
|
|
24932
25042
|
if (!raw || typeof raw !== "object") return null;
|
|
@@ -25013,7 +25123,7 @@ function parseForesightEntries(everosRoot, now, userId) {
|
|
|
25013
25123
|
let files;
|
|
25014
25124
|
if (userId) {
|
|
25015
25125
|
const ownDir = join43(everosRoot, userId, "default_project", "users", userId, ".foresights");
|
|
25016
|
-
files =
|
|
25126
|
+
files = existsSync28(ownDir) ? listForesightMds(ownDir) : findForesightFiles(everosRoot);
|
|
25017
25127
|
} else {
|
|
25018
25128
|
files = findForesightFiles(everosRoot);
|
|
25019
25129
|
}
|
|
@@ -25279,8 +25389,6 @@ var init_agent = __esm({
|
|
|
25279
25389
|
this.opts = opts;
|
|
25280
25390
|
this.tools = new GraphTools(store);
|
|
25281
25391
|
}
|
|
25282
|
-
store;
|
|
25283
|
-
opts;
|
|
25284
25392
|
tools;
|
|
25285
25393
|
/** 生成 UpdatePlan;LLM 失败/parse 失败返回 null(调用方 fallback) */
|
|
25286
25394
|
async generatePlan(event2, contextIds, mode, now, foresightHits) {
|
|
@@ -25500,7 +25608,6 @@ var init_executor3 = __esm({
|
|
|
25500
25608
|
constructor(store) {
|
|
25501
25609
|
this.store = store;
|
|
25502
25610
|
}
|
|
25503
|
-
store;
|
|
25504
25611
|
edgeReferencedIds = /* @__PURE__ */ new Set();
|
|
25505
25612
|
titleToIdCache = null;
|
|
25506
25613
|
/** 本 plan 内被标 resolved/rejected/deferred 的 intent(P6 R1 级联 cancel 用;
|
|
@@ -26044,8 +26151,6 @@ var init_intent = __esm({
|
|
|
26044
26151
|
this.store = store;
|
|
26045
26152
|
this.weights = weights;
|
|
26046
26153
|
}
|
|
26047
|
-
store;
|
|
26048
|
-
weights;
|
|
26049
26154
|
select(now, minUrgency = 0.3, maxIntents = 10) {
|
|
26050
26155
|
const scored = [];
|
|
26051
26156
|
for (const intent of this.store.getNodesByType("intent")) {
|
|
@@ -26146,10 +26251,6 @@ var init_intent = __esm({
|
|
|
26146
26251
|
this.persona = persona;
|
|
26147
26252
|
this.temperature = temperature;
|
|
26148
26253
|
}
|
|
26149
|
-
provider;
|
|
26150
|
-
model;
|
|
26151
|
-
persona;
|
|
26152
|
-
temperature;
|
|
26153
26254
|
/** intent → 1-3 个 action;LLM 失败/解析失败返回 [](agent.py 异常吞掉语义) */
|
|
26154
26255
|
async generateActions(args) {
|
|
26155
26256
|
const max = args.maxActions ?? 3;
|
|
@@ -26304,8 +26405,6 @@ var init_sweep = __esm({
|
|
|
26304
26405
|
this.deps = deps;
|
|
26305
26406
|
this.intervalMs = intervalMs;
|
|
26306
26407
|
}
|
|
26307
|
-
deps;
|
|
26308
|
-
intervalMs;
|
|
26309
26408
|
timer = null;
|
|
26310
26409
|
/** executing 连续增长的轮数(对账告警用) */
|
|
26311
26410
|
backlogStreak = 0;
|
|
@@ -26446,14 +26545,14 @@ ${JSON.stringify(payload, null, 2)}
|
|
|
26446
26545
|
});
|
|
26447
26546
|
|
|
26448
26547
|
// src/memory/proactive/proactive-tools.ts
|
|
26449
|
-
import { existsSync as
|
|
26548
|
+
import { existsSync as existsSync29 } from "node:fs";
|
|
26450
26549
|
function setProactiveWorkspace(workspace) {
|
|
26451
26550
|
toolWorkspace = workspace;
|
|
26452
26551
|
}
|
|
26453
26552
|
function withStore(fn) {
|
|
26454
26553
|
if (!toolWorkspace) return null;
|
|
26455
26554
|
const p = proactiveDbPath(toolWorkspace);
|
|
26456
|
-
if (!
|
|
26555
|
+
if (!existsSync29(p)) return null;
|
|
26457
26556
|
const store = new Persistence(p);
|
|
26458
26557
|
try {
|
|
26459
26558
|
return fn(store);
|
|
@@ -26707,7 +26806,7 @@ __export(plugin_exports, {
|
|
|
26707
26806
|
feedMem7Cell: () => feedMem7Cell
|
|
26708
26807
|
});
|
|
26709
26808
|
import { join as join44 } from "node:path";
|
|
26710
|
-
import { existsSync as
|
|
26809
|
+
import { existsSync as existsSync30, readFileSync as readFileSync34, appendFileSync as appendFileSync2 } from "node:fs";
|
|
26711
26810
|
function isFiller(text) {
|
|
26712
26811
|
const t = text.trim();
|
|
26713
26812
|
if (t.length >= 5) return false;
|
|
@@ -26930,7 +27029,7 @@ var init_plugin = __esm({
|
|
|
26930
27029
|
this.actionAgent = new ActionAgent(this.provider, this.config.modelId, persona);
|
|
26931
27030
|
this.ingestWorkspace = workspace;
|
|
26932
27031
|
const calDbPath = join44(workspace, ".calendar", "calendar.db");
|
|
26933
|
-
this.calDb =
|
|
27032
|
+
this.calDb = existsSync30(calDbPath) ? openDb(workspace) : null;
|
|
26934
27033
|
registerCallbackHook("PostToolUse", {
|
|
26935
27034
|
type: "callback",
|
|
26936
27035
|
id: "proactive-completion-evidence",
|
|
@@ -28162,7 +28261,7 @@ __export(handle_query_exports, {
|
|
|
28162
28261
|
resetSessionStartInjection: () => resetSessionStartInjection,
|
|
28163
28262
|
resolveSystemPrompt: () => resolveSystemPrompt
|
|
28164
28263
|
});
|
|
28165
|
-
import { readFileSync as readFileSync37, existsSync as
|
|
28264
|
+
import { readFileSync as readFileSync37, existsSync as existsSync31, statSync as statSync13 } from "node:fs";
|
|
28166
28265
|
import { join as join48, resolve as resolve8 } from "node:path";
|
|
28167
28266
|
import * as path32 from "node:path";
|
|
28168
28267
|
function resolveSystemPrompt(v) {
|
|
@@ -28175,7 +28274,7 @@ function loadExternalChanRules(workspace) {
|
|
|
28175
28274
|
const path43 = join48(workspace, "prompts", "external-chan-rules.md");
|
|
28176
28275
|
if (externalChanRulesCache && externalChanRulesCache.path === path43) return externalChanRulesCache;
|
|
28177
28276
|
let content = "";
|
|
28178
|
-
if (
|
|
28277
|
+
if (existsSync31(path43)) {
|
|
28179
28278
|
try {
|
|
28180
28279
|
content = readFileSync37(path43, "utf-8").trim();
|
|
28181
28280
|
} catch (e) {
|
|
@@ -28254,8 +28353,9 @@ async function handleQueryInner(text, sessionId, channelName, cb, deps, channelT
|
|
|
28254
28353
|
deps.engine.updateTokenEstimate(history);
|
|
28255
28354
|
const modelInputs = deps.modelInputs || ["text"];
|
|
28256
28355
|
const supportsImages = modelInputs.includes("image");
|
|
28257
|
-
|
|
28258
|
-
|
|
28356
|
+
const supportsVideo = modelInputs.includes("video");
|
|
28357
|
+
if (!supportsImages || !supportsVideo) {
|
|
28358
|
+
const isImageBlock = (b) => !supportsImages && (b.type === "image" || b.type === "image_url") || !supportsVideo && b.type === "video";
|
|
28259
28359
|
const stripImages = (msgs) => msgs.map((m) => {
|
|
28260
28360
|
if (Array.isArray(m.content)) {
|
|
28261
28361
|
const filtered = m.content.filter((b) => !isImageBlock(b));
|
|
@@ -28304,7 +28404,7 @@ async function handleQueryInner(text, sessionId, channelName, cb, deps, channelT
|
|
|
28304
28404
|
${t}` : t });
|
|
28305
28405
|
}
|
|
28306
28406
|
for (const b of text) {
|
|
28307
|
-
if (b.type === "image") contentBlocks.push(b);
|
|
28407
|
+
if (b.type === "image" || b.type === "video") contentBlocks.push(b);
|
|
28308
28408
|
}
|
|
28309
28409
|
} else if (text) {
|
|
28310
28410
|
contentBlocks.push({ type: "text", text: isExternalChan ? `${senderLabel}
|
|
@@ -29053,7 +29153,7 @@ __export(cli_ccrun_exports, {
|
|
|
29053
29153
|
parseCcRunArgs: () => parseCcRunArgs
|
|
29054
29154
|
});
|
|
29055
29155
|
import { randomUUID as randomUUID8 } from "node:crypto";
|
|
29056
|
-
import { existsSync as
|
|
29156
|
+
import { existsSync as existsSync32, readFileSync as readFileSync38 } from "node:fs";
|
|
29057
29157
|
import { join as join50 } from "node:path";
|
|
29058
29158
|
import * as readline2 from "node:readline";
|
|
29059
29159
|
function parseCcRunArgs(argv) {
|
|
@@ -29200,8 +29300,8 @@ async function runQuery(args) {
|
|
|
29200
29300
|
if (!stateDir) {
|
|
29201
29301
|
const home = process.env.HOME || process.env.USERPROFILE || ".";
|
|
29202
29302
|
const cwd = process.cwd();
|
|
29203
|
-
const { existsSync:
|
|
29204
|
-
if (
|
|
29303
|
+
const { existsSync: existsSync39 } = await import("node:fs");
|
|
29304
|
+
if (existsSync39(join50(cwd, "configs"))) stateDir = cwd;
|
|
29205
29305
|
else {
|
|
29206
29306
|
try {
|
|
29207
29307
|
const pointer = JSON.parse(readFileSync38(join50(home, ".engine7.json"), "utf-8"));
|
|
@@ -29447,7 +29547,7 @@ async function doCcRun(argv) {
|
|
|
29447
29547
|
if (!sd) {
|
|
29448
29548
|
const home = process.env.HOME || process.env.USERPROFILE || ".";
|
|
29449
29549
|
const cwd = process.cwd();
|
|
29450
|
-
if (
|
|
29550
|
+
if (existsSync32(join50(cwd, "configs"))) sd = cwd;
|
|
29451
29551
|
else {
|
|
29452
29552
|
try {
|
|
29453
29553
|
const pointer = JSON.parse(readFileSync38(join50(home, ".engine7.json"), "utf-8"));
|
|
@@ -29533,7 +29633,7 @@ __export(provision_free_exports, {
|
|
|
29533
29633
|
writeIdentityContactEmail: () => writeIdentityContactEmail
|
|
29534
29634
|
});
|
|
29535
29635
|
import { randomBytes as randomBytes6, randomUUID as randomUUID9 } from "node:crypto";
|
|
29536
|
-
import { chmodSync as chmodSync2, existsSync as
|
|
29636
|
+
import { chmodSync as chmodSync2, existsSync as existsSync33, mkdirSync as mkdirSync22, readFileSync as readFileSync39, writeFileSync as writeFileSync21 } from "node:fs";
|
|
29537
29637
|
import { dirname as dirname11, join as join51 } from "node:path";
|
|
29538
29638
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
29539
29639
|
function readContactEmailOf(parsed) {
|
|
@@ -29541,7 +29641,7 @@ function readContactEmailOf(parsed) {
|
|
|
29541
29641
|
}
|
|
29542
29642
|
function loadOrCreateInstallIdentity(stateDir) {
|
|
29543
29643
|
const file2 = join51(stateDir, IDENTITY_FILE);
|
|
29544
|
-
if (
|
|
29644
|
+
if (existsSync33(file2)) {
|
|
29545
29645
|
let parsed;
|
|
29546
29646
|
try {
|
|
29547
29647
|
parsed = JSON.parse(readFileSync39(file2, "utf8"));
|
|
@@ -29576,7 +29676,7 @@ function loadOrCreateInstallIdentity(stateDir) {
|
|
|
29576
29676
|
}
|
|
29577
29677
|
function readInstallIdentityDetailed(stateDir) {
|
|
29578
29678
|
const file2 = join51(stateDir, IDENTITY_FILE);
|
|
29579
|
-
if (!
|
|
29679
|
+
if (!existsSync33(file2)) return { ok: false, reason: "missing" };
|
|
29580
29680
|
let text;
|
|
29581
29681
|
try {
|
|
29582
29682
|
text = readFileSync39(file2, "utf8");
|
|
@@ -29685,7 +29785,7 @@ __export(free_tier_apply_exports, {
|
|
|
29685
29785
|
isFreeTierConfig: () => isFreeTierConfig,
|
|
29686
29786
|
resolveConfigPath: () => resolveConfigPath
|
|
29687
29787
|
});
|
|
29688
|
-
import * as
|
|
29788
|
+
import * as fs32 from "node:fs";
|
|
29689
29789
|
import * as path33 from "node:path";
|
|
29690
29790
|
function isFreeTierConfig(cfg) {
|
|
29691
29791
|
const hasProvider = !!cfg?.models?.providers?.[FREE_TIER_PROVIDER_ID];
|
|
@@ -29697,6 +29797,7 @@ function applyFreeTier(cfg, opts = {}) {
|
|
|
29697
29797
|
if (!def) throw new Error("\u5F15\u64CE\u91CC\u6CA1\u6709 7yi \u8FD9\u4E2A\u5185\u7F6E provider\u2014\u2014PROVIDER_DEFS \u88AB\u52A8\u8FC7\uFF1F");
|
|
29698
29798
|
const baseUrl = (opts.baseUrl || "").trim() || def.baseUrl;
|
|
29699
29799
|
const vision = resolveVisionModel(FREE_TIER_PROVIDER_ID, FREE_TIER_PRIMARY);
|
|
29800
|
+
const video = resolveVideoModel(FREE_TIER_PROVIDER_ID, FREE_TIER_PRIMARY);
|
|
29700
29801
|
cfg.models = cfg.models || {};
|
|
29701
29802
|
cfg.models.providers = cfg.models.providers || {};
|
|
29702
29803
|
cfg.models.providers[FREE_TIER_PROVIDER_ID] = {
|
|
@@ -29711,6 +29812,7 @@ function applyFreeTier(cfg, opts = {}) {
|
|
|
29711
29812
|
cfg.agents.defaults.model = cfg.agents.defaults.model || {};
|
|
29712
29813
|
cfg.agents.defaults.model.primary = FREE_TIER_PRIMARY;
|
|
29713
29814
|
if (vision) cfg.agents.defaults.model.vision = vision;
|
|
29815
|
+
if (video) cfg.agents.defaults.model.video = video;
|
|
29714
29816
|
cfg.agents.defaults.features = cfg.agents.defaults.features || {};
|
|
29715
29817
|
cfg.agents.defaults.features.selfie = true;
|
|
29716
29818
|
cfg.agents.defaults.features.eyes = true;
|
|
@@ -29736,15 +29838,15 @@ function resolveConfigPath(stateDir, configName) {
|
|
|
29736
29838
|
const configsDir = path33.join(stateDir, "configs");
|
|
29737
29839
|
if (configName) {
|
|
29738
29840
|
const p = path33.join(configsDir, configName);
|
|
29739
|
-
return
|
|
29841
|
+
return fs32.existsSync(p) ? p : "";
|
|
29740
29842
|
}
|
|
29741
29843
|
const main2 = path33.join(configsDir, "main7.json");
|
|
29742
|
-
if (
|
|
29743
|
-
if (!
|
|
29744
|
-
for (const f of
|
|
29844
|
+
if (fs32.existsSync(main2)) return main2;
|
|
29845
|
+
if (!fs32.existsSync(configsDir)) return "";
|
|
29846
|
+
for (const f of fs32.readdirSync(configsDir).filter((x) => x.endsWith(".json"))) {
|
|
29745
29847
|
const full = path33.join(configsDir, f);
|
|
29746
29848
|
try {
|
|
29747
|
-
if (JSON.parse(
|
|
29849
|
+
if (JSON.parse(fs32.readFileSync(full, "utf8")).models?.providers) return full;
|
|
29748
29850
|
} catch {
|
|
29749
29851
|
}
|
|
29750
29852
|
}
|
|
@@ -29753,16 +29855,16 @@ function resolveConfigPath(stateDir, configName) {
|
|
|
29753
29855
|
function applyFreeTierToConfig(configPath, opts = {}) {
|
|
29754
29856
|
let cfg;
|
|
29755
29857
|
try {
|
|
29756
|
-
cfg = JSON.parse(
|
|
29858
|
+
cfg = JSON.parse(fs32.readFileSync(configPath, "utf8"));
|
|
29757
29859
|
} catch (e) {
|
|
29758
29860
|
throw new Error(`\u8BFB\u53D6 config \u5931\u8D25: ${configPath}\uFF08${e?.message || e}\uFF09`);
|
|
29759
29861
|
}
|
|
29760
29862
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
29761
29863
|
const backupPath = `${configPath}.bak-${stamp}`;
|
|
29762
|
-
|
|
29864
|
+
fs32.copyFileSync(configPath, backupPath);
|
|
29763
29865
|
applyFreeTier(cfg, opts);
|
|
29764
29866
|
try {
|
|
29765
|
-
|
|
29867
|
+
fs32.writeFileSync(configPath, JSON.stringify(cfg, null, 2), "utf8");
|
|
29766
29868
|
} catch (e) {
|
|
29767
29869
|
throw new Error(`\u5199\u5165 config \u5931\u8D25: ${configPath}\uFF08${e?.message || e}\uFF09\uFF1B\u539F\u6587\u4EF6\u672A\u6539\u52A8\uFF0C\u5907\u4EFD\u5728 ${backupPath}`);
|
|
29768
29870
|
}
|
|
@@ -29770,7 +29872,8 @@ function applyFreeTierToConfig(configPath, opts = {}) {
|
|
|
29770
29872
|
configPath,
|
|
29771
29873
|
backupPath,
|
|
29772
29874
|
primary: cfg.agents.defaults.model.primary,
|
|
29773
|
-
vision: cfg.agents.defaults.model.vision ?? null
|
|
29875
|
+
vision: cfg.agents.defaults.model.vision ?? null,
|
|
29876
|
+
video: cfg.agents.defaults.model.video ?? null
|
|
29774
29877
|
};
|
|
29775
29878
|
}
|
|
29776
29879
|
var FREE_TIER_PROVIDER_ID, FREE_TIER_PRIMARY, DEFAULT_FREE_VOICE;
|
|
@@ -29791,7 +29894,7 @@ __export(cli_doctor_exports, {
|
|
|
29791
29894
|
resolveStateDirFromArgs: () => resolveStateDirFromArgs,
|
|
29792
29895
|
runDoctor: () => runDoctor
|
|
29793
29896
|
});
|
|
29794
|
-
import * as
|
|
29897
|
+
import * as fs33 from "node:fs";
|
|
29795
29898
|
import * as path34 from "node:path";
|
|
29796
29899
|
import * as net from "node:net";
|
|
29797
29900
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
@@ -29799,7 +29902,7 @@ function readVersion() {
|
|
|
29799
29902
|
const here = path34.dirname(fileURLToPath6(import.meta.url));
|
|
29800
29903
|
for (const p of [path34.join(here, "..", "package.json"), path34.join(here, "..", "..", "package.json")]) {
|
|
29801
29904
|
try {
|
|
29802
|
-
return JSON.parse(
|
|
29905
|
+
return JSON.parse(fs33.readFileSync(p, "utf8")).version || "unknown";
|
|
29803
29906
|
} catch {
|
|
29804
29907
|
}
|
|
29805
29908
|
}
|
|
@@ -29845,10 +29948,10 @@ async function runDoctor(stateDir, opts) {
|
|
|
29845
29948
|
};
|
|
29846
29949
|
let config = null;
|
|
29847
29950
|
try {
|
|
29848
|
-
config = JSON.parse(
|
|
29951
|
+
config = JSON.parse(fs33.readFileSync(configPath, "utf8"));
|
|
29849
29952
|
report.configValid = true;
|
|
29850
29953
|
} catch (e) {
|
|
29851
|
-
report.configError =
|
|
29954
|
+
report.configError = fs33.existsSync(configPath) ? `\u89E3\u6790\u5931\u8D25: ${e.message}` : "config \u4E0D\u5B58\u5728\uFF08\u5148 engine7 init\uFF09";
|
|
29852
29955
|
}
|
|
29853
29956
|
if (config?.channels) {
|
|
29854
29957
|
for (const [name, conf] of Object.entries(config.channels)) {
|
|
@@ -29858,11 +29961,11 @@ async function runDoctor(stateDir, opts) {
|
|
|
29858
29961
|
}
|
|
29859
29962
|
const cfgBase = path34.basename(report.configPath, ".json") || "main7";
|
|
29860
29963
|
const candidates = secretsCandidates(stateDir, cfgBase);
|
|
29861
|
-
const secretsFile = candidates.find((p) =>
|
|
29964
|
+
const secretsFile = candidates.find((p) => fs33.existsSync(p)) || candidates[0];
|
|
29862
29965
|
report.secrets.file = secretsFile;
|
|
29863
|
-
if (
|
|
29966
|
+
if (fs33.existsSync(secretsFile)) {
|
|
29864
29967
|
report.secrets.exists = true;
|
|
29865
|
-
for (const line of
|
|
29968
|
+
for (const line of fs33.readFileSync(secretsFile, "utf8").split("\n")) {
|
|
29866
29969
|
const eq = line.indexOf("=");
|
|
29867
29970
|
if (eq > 0 && !line.startsWith("#")) report.secrets.keys.push(line.slice(0, eq).trim());
|
|
29868
29971
|
}
|
|
@@ -29904,8 +30007,8 @@ async function runDoctor(stateDir, opts) {
|
|
|
29904
30007
|
for (const rel of ["workspace/SESSION-STATE.md", "SESSION-STATE.md"]) {
|
|
29905
30008
|
const p = path34.join(stateDir, rel);
|
|
29906
30009
|
try {
|
|
29907
|
-
if (!
|
|
29908
|
-
const head =
|
|
30010
|
+
if (!fs33.existsSync(p)) continue;
|
|
30011
|
+
const head = fs33.readFileSync(p, "utf8").split("\n").slice(0, 10).join("\n");
|
|
29909
30012
|
const m = head.match(/^#{1,3}\s*当前时间\s*$\n+\s*(\d{4}-\d{2}-\d{2})/m);
|
|
29910
30013
|
if (!m) continue;
|
|
29911
30014
|
const ageH = (Date.now() - (/* @__PURE__ */ new Date(`${m[1]}T00:00:00Z`)).getTime()) / 36e5;
|
|
@@ -29926,11 +30029,11 @@ function resolveStateDirFromArgs(args) {
|
|
|
29926
30029
|
if (stateDir) return path34.resolve(stateDir);
|
|
29927
30030
|
const home = process.env.HOME || process.env.USERPROFILE || ".";
|
|
29928
30031
|
const cwd = path34.resolve(process.cwd());
|
|
29929
|
-
if (
|
|
30032
|
+
if (fs33.existsSync(path34.join(cwd, "configs"))) return cwd;
|
|
29930
30033
|
const pointer = path34.join(home, ".engine7.json");
|
|
29931
|
-
if (
|
|
30034
|
+
if (fs33.existsSync(pointer)) {
|
|
29932
30035
|
try {
|
|
29933
|
-
const ptrStateDir = JSON.parse(
|
|
30036
|
+
const ptrStateDir = JSON.parse(fs33.readFileSync(pointer, "utf8")).stateDir;
|
|
29934
30037
|
if (typeof ptrStateDir === "string" && ptrStateDir.trim()) return path34.resolve(ptrStateDir);
|
|
29935
30038
|
} catch {
|
|
29936
30039
|
}
|
|
@@ -29948,7 +30051,7 @@ var init_cli_doctor = __esm({
|
|
|
29948
30051
|
});
|
|
29949
30052
|
|
|
29950
30053
|
// src/config/writer.ts
|
|
29951
|
-
import
|
|
30054
|
+
import fs34 from "node:fs";
|
|
29952
30055
|
import path35 from "node:path";
|
|
29953
30056
|
function isNormalized(text) {
|
|
29954
30057
|
if (text === "") return true;
|
|
@@ -29966,11 +30069,11 @@ function isNormalized(text) {
|
|
|
29966
30069
|
function rotateBaks(filePath) {
|
|
29967
30070
|
const dir = path35.dirname(filePath);
|
|
29968
30071
|
const base = path35.basename(filePath);
|
|
29969
|
-
const baks =
|
|
30072
|
+
const baks = fs34.readdirSync(dir).filter((n) => n.startsWith(base + ".bak-")).sort();
|
|
29970
30073
|
while (baks.length >= KEEP_BAKS) {
|
|
29971
30074
|
const victim = baks.shift();
|
|
29972
30075
|
try {
|
|
29973
|
-
|
|
30076
|
+
fs34.unlinkSync(path35.join(dir, victim));
|
|
29974
30077
|
} catch {
|
|
29975
30078
|
}
|
|
29976
30079
|
}
|
|
@@ -29989,7 +30092,7 @@ function writeFailure(filePath, primary, extra) {
|
|
|
29989
30092
|
function renameWithRetry(from, to) {
|
|
29990
30093
|
for (let attempt = 1; ; attempt++) {
|
|
29991
30094
|
try {
|
|
29992
|
-
|
|
30095
|
+
fs34.renameSync(from, to);
|
|
29993
30096
|
return;
|
|
29994
30097
|
} catch (err) {
|
|
29995
30098
|
if (attempt >= RENAME_ATTEMPTS || !RETRYABLE_CODES.has(errCode(err))) throw err;
|
|
@@ -30004,32 +30107,32 @@ function commitFile(tmp, filePath) {
|
|
|
30004
30107
|
} catch (primaryErr) {
|
|
30005
30108
|
const old = `${filePath}.old`;
|
|
30006
30109
|
try {
|
|
30007
|
-
|
|
30110
|
+
fs34.renameSync(filePath, old);
|
|
30008
30111
|
} catch (err) {
|
|
30009
30112
|
throw writeFailure(filePath, primaryErr, `\u6539\u540D .old \u5907\u4EFD\u4E5F\u5931\u8D25\uFF08${errCode(err) || "\u672A\u77E5"}\uFF09`);
|
|
30010
30113
|
}
|
|
30011
30114
|
try {
|
|
30012
|
-
|
|
30115
|
+
fs34.renameSync(tmp, filePath);
|
|
30013
30116
|
} catch (err) {
|
|
30014
30117
|
try {
|
|
30015
|
-
|
|
30118
|
+
fs34.renameSync(old, filePath);
|
|
30016
30119
|
} catch {
|
|
30017
30120
|
throw writeFailure(filePath, primaryErr, `\u65B0\u5185\u5BB9\u843D\u76D8\u4E0E\u56DE\u6EDA\u90FD\u5931\u8D25\uFF0C\u65E7\u5185\u5BB9\u7559\u5728 ${old}`);
|
|
30018
30121
|
}
|
|
30019
30122
|
throw writeFailure(filePath, primaryErr, `\u6362\u540D\u843D\u76D8\u5931\u8D25\uFF08${errCode(err) || "\u672A\u77E5"}\uFF09`);
|
|
30020
30123
|
}
|
|
30021
30124
|
try {
|
|
30022
|
-
|
|
30125
|
+
fs34.unlinkSync(old);
|
|
30023
30126
|
} catch {
|
|
30024
30127
|
}
|
|
30025
30128
|
}
|
|
30026
30129
|
}
|
|
30027
30130
|
function writeConfigAtomic(filePath, obj) {
|
|
30028
|
-
const existed =
|
|
30131
|
+
const existed = fs34.existsSync(filePath);
|
|
30029
30132
|
let prevText = "";
|
|
30030
30133
|
if (existed) {
|
|
30031
30134
|
try {
|
|
30032
|
-
prevText =
|
|
30135
|
+
prevText = fs34.readFileSync(filePath, "utf-8");
|
|
30033
30136
|
} catch (err) {
|
|
30034
30137
|
throw writeFailure(filePath, err);
|
|
30035
30138
|
}
|
|
@@ -30037,7 +30140,7 @@ function writeConfigAtomic(filePath, obj) {
|
|
|
30037
30140
|
const normalized = !existed || !isNormalized(prevText);
|
|
30038
30141
|
if (prevText) {
|
|
30039
30142
|
try {
|
|
30040
|
-
|
|
30143
|
+
fs34.copyFileSync(filePath, `${filePath}.bak-${Date.now()}`);
|
|
30041
30144
|
} catch {
|
|
30042
30145
|
}
|
|
30043
30146
|
rotateBaks(filePath);
|
|
@@ -30045,19 +30148,19 @@ function writeConfigAtomic(filePath, obj) {
|
|
|
30045
30148
|
const content = JSON.stringify(obj, null, 2) + "\n";
|
|
30046
30149
|
const tmp = path35.join(path35.dirname(filePath), `.${path35.basename(filePath)}.tmp-${process.pid}`);
|
|
30047
30150
|
try {
|
|
30048
|
-
const fd =
|
|
30151
|
+
const fd = fs34.openSync(tmp, "w");
|
|
30049
30152
|
try {
|
|
30050
|
-
|
|
30051
|
-
|
|
30153
|
+
fs34.writeFileSync(fd, content, "utf-8");
|
|
30154
|
+
fs34.fsyncSync(fd);
|
|
30052
30155
|
} finally {
|
|
30053
|
-
|
|
30156
|
+
fs34.closeSync(fd);
|
|
30054
30157
|
}
|
|
30055
30158
|
commitFile(tmp, filePath);
|
|
30056
30159
|
} catch (err) {
|
|
30057
30160
|
throw err instanceof ConfigWriteError ? err : writeFailure(filePath, err);
|
|
30058
30161
|
} finally {
|
|
30059
30162
|
try {
|
|
30060
|
-
|
|
30163
|
+
fs34.unlinkSync(tmp);
|
|
30061
30164
|
} catch {
|
|
30062
30165
|
}
|
|
30063
30166
|
}
|
|
@@ -30083,18 +30186,18 @@ var init_writer2 = __esm({
|
|
|
30083
30186
|
});
|
|
30084
30187
|
|
|
30085
30188
|
// src/config/secrets-io.ts
|
|
30086
|
-
import
|
|
30189
|
+
import fs35 from "node:fs";
|
|
30087
30190
|
import path36 from "node:path";
|
|
30088
30191
|
function resolveSecretPath(stateDir, configName) {
|
|
30089
30192
|
return secretsCandidates(stateDir, configName)[0];
|
|
30090
30193
|
}
|
|
30091
30194
|
function resolveSecretReadPath(stateDir, configName) {
|
|
30092
|
-
return secretsCandidates(stateDir, configName).find((c) =>
|
|
30195
|
+
return secretsCandidates(stateDir, configName).find((c) => fs35.existsSync(c)) ?? null;
|
|
30093
30196
|
}
|
|
30094
30197
|
function readSecretStatus(stateDir, configName, names) {
|
|
30095
30198
|
const p = resolveSecretReadPath(stateDir, configName);
|
|
30096
30199
|
const out = {};
|
|
30097
|
-
const text = p ?
|
|
30200
|
+
const text = p ? fs35.readFileSync(p, "utf-8") : "";
|
|
30098
30201
|
const present = /* @__PURE__ */ new Set();
|
|
30099
30202
|
for (const line of text.split("\n")) {
|
|
30100
30203
|
const t = line.trim();
|
|
@@ -30117,7 +30220,7 @@ var init_secrets_io = __esm({
|
|
|
30117
30220
|
});
|
|
30118
30221
|
|
|
30119
30222
|
// src/config/migrations/index.ts
|
|
30120
|
-
import
|
|
30223
|
+
import fs36 from "node:fs";
|
|
30121
30224
|
import path37 from "node:path";
|
|
30122
30225
|
function registerMigration(m) {
|
|
30123
30226
|
if (REGISTRY.has(m.name)) {
|
|
@@ -30136,19 +30239,19 @@ async function runMigration(name, ctx) {
|
|
|
30136
30239
|
function rotateBaks2(filePath) {
|
|
30137
30240
|
const dir = path37.dirname(filePath);
|
|
30138
30241
|
const base = path37.basename(filePath);
|
|
30139
|
-
const baks =
|
|
30242
|
+
const baks = fs36.readdirSync(dir).filter((n) => n.startsWith(base + ".bak-")).sort();
|
|
30140
30243
|
while (baks.length > KEEP_BAKS2) {
|
|
30141
30244
|
const victim = baks.shift();
|
|
30142
30245
|
try {
|
|
30143
|
-
|
|
30246
|
+
fs36.unlinkSync(path37.join(dir, victim));
|
|
30144
30247
|
} catch {
|
|
30145
30248
|
}
|
|
30146
30249
|
}
|
|
30147
30250
|
}
|
|
30148
30251
|
function backupFile(filePath) {
|
|
30149
|
-
if (!
|
|
30252
|
+
if (!fs36.existsSync(filePath)) return null;
|
|
30150
30253
|
const bak = `${filePath}.bak-${Date.now()}`;
|
|
30151
|
-
|
|
30254
|
+
fs36.copyFileSync(filePath, bak);
|
|
30152
30255
|
rotateBaks2(filePath);
|
|
30153
30256
|
return bak;
|
|
30154
30257
|
}
|
|
@@ -30162,11 +30265,11 @@ var init_migrations = __esm({
|
|
|
30162
30265
|
});
|
|
30163
30266
|
|
|
30164
30267
|
// src/config/migrations/persona.ts
|
|
30165
|
-
import
|
|
30268
|
+
import fs37 from "node:fs";
|
|
30166
30269
|
import path38 from "node:path";
|
|
30167
30270
|
function readFileOrNull(p) {
|
|
30168
30271
|
try {
|
|
30169
|
-
return
|
|
30272
|
+
return fs37.readFileSync(p, "utf-8");
|
|
30170
30273
|
} catch {
|
|
30171
30274
|
return null;
|
|
30172
30275
|
}
|
|
@@ -30187,7 +30290,7 @@ var init_persona = __esm({
|
|
|
30187
30290
|
const persona = ctx.values?.agents?.defaults?.persona;
|
|
30188
30291
|
if (typeof persona !== "string" || !persona) return { changed: [] };
|
|
30189
30292
|
const dir = path38.join(ctx.workspace, "personas", persona);
|
|
30190
|
-
if (!
|
|
30293
|
+
if (!fs37.existsSync(dir)) {
|
|
30191
30294
|
return { changed: [] };
|
|
30192
30295
|
}
|
|
30193
30296
|
const changed = [];
|
|
@@ -30198,10 +30301,10 @@ var init_persona = __esm({
|
|
|
30198
30301
|
const legacy = path38.join(ctx.workspace, LEGACY_PATHS[name]);
|
|
30199
30302
|
const legacyContent = readFileOrNull(legacy);
|
|
30200
30303
|
if (legacyContent !== null && legacyContent === content) {
|
|
30201
|
-
|
|
30304
|
+
fs37.renameSync(legacy, `${legacy}.migrated-${Date.now()}`);
|
|
30202
30305
|
changed.push(`${LEGACY_PATHS[name]} \u2192 personas/${persona}/${name}`);
|
|
30203
30306
|
} else if (legacyContent !== null) {
|
|
30204
|
-
|
|
30307
|
+
fs37.renameSync(legacy, `${legacy}.bak-${Date.now()}`);
|
|
30205
30308
|
changed.push(`${LEGACY_PATHS[name]} \u2192 .bak\uFF08\u5185\u5BB9\u4E0E\u6A21\u677F\u4E0D\u540C\uFF0C\u4FDD\u5B88\u4FDD\u7559\uFF09`);
|
|
30206
30309
|
}
|
|
30207
30310
|
}
|
|
@@ -30213,7 +30316,7 @@ var init_persona = __esm({
|
|
|
30213
30316
|
});
|
|
30214
30317
|
|
|
30215
30318
|
// src/config/migrations/channel-secrets.ts
|
|
30216
|
-
import
|
|
30319
|
+
import fs38 from "node:fs";
|
|
30217
30320
|
function envNameFor(dotPath) {
|
|
30218
30321
|
const declared = getField(dotPath)?.envKey;
|
|
30219
30322
|
if (declared) return declared;
|
|
@@ -30255,15 +30358,15 @@ function planChannelSecretMoves(config) {
|
|
|
30255
30358
|
}
|
|
30256
30359
|
function restoreEnv(envPath, before) {
|
|
30257
30360
|
try {
|
|
30258
|
-
if (before === null)
|
|
30259
|
-
else
|
|
30361
|
+
if (before === null) fs38.unlinkSync(envPath);
|
|
30362
|
+
else fs38.writeFileSync(envPath, before, "utf8");
|
|
30260
30363
|
} catch {
|
|
30261
30364
|
}
|
|
30262
30365
|
}
|
|
30263
30366
|
function dropBackup(backup) {
|
|
30264
30367
|
if (backup) {
|
|
30265
30368
|
try {
|
|
30266
|
-
|
|
30369
|
+
fs38.unlinkSync(backup);
|
|
30267
30370
|
} catch {
|
|
30268
30371
|
}
|
|
30269
30372
|
}
|
|
@@ -30272,7 +30375,7 @@ function migrateChannelSecrets(configPath, deps = {}) {
|
|
|
30272
30375
|
const writeConfig = deps.writeConfig ?? ((p, obj) => writeConfigAtomic(p, obj));
|
|
30273
30376
|
let text;
|
|
30274
30377
|
try {
|
|
30275
|
-
text =
|
|
30378
|
+
text = fs38.readFileSync(configPath, "utf-8");
|
|
30276
30379
|
} catch {
|
|
30277
30380
|
return { changed: [], backup: null, secretsFile: null };
|
|
30278
30381
|
}
|
|
@@ -30289,7 +30392,7 @@ function migrateChannelSecrets(configPath, deps = {}) {
|
|
|
30289
30392
|
if (moves.length === 0) return { changed: [], backup: null, secretsFile: null };
|
|
30290
30393
|
const { stateDir, configName } = resolveConfigIdentity(configPath);
|
|
30291
30394
|
const envPath = secretsCandidates(stateDir, configName)[0];
|
|
30292
|
-
const envBefore =
|
|
30395
|
+
const envBefore = fs38.existsSync(envPath) ? fs38.readFileSync(envPath, "utf-8") : null;
|
|
30293
30396
|
const backup = backupFile(configPath);
|
|
30294
30397
|
try {
|
|
30295
30398
|
for (const m of moves) writeSecret(stateDir, configName, m.envName, m.value);
|
|
@@ -30310,7 +30413,7 @@ function migrateChannelSecrets(configPath, deps = {}) {
|
|
|
30310
30413
|
const problem = verify(configPath, envPath, moves);
|
|
30311
30414
|
if (problem) {
|
|
30312
30415
|
try {
|
|
30313
|
-
if (backup)
|
|
30416
|
+
if (backup) fs38.copyFileSync(backup, configPath);
|
|
30314
30417
|
} catch {
|
|
30315
30418
|
}
|
|
30316
30419
|
restoreEnv(envPath, envBefore);
|
|
@@ -30322,7 +30425,7 @@ function migrateChannelSecrets(configPath, deps = {}) {
|
|
|
30322
30425
|
function verify(configPath, envPath, moves) {
|
|
30323
30426
|
let cfg;
|
|
30324
30427
|
try {
|
|
30325
|
-
cfg = JSON.parse(
|
|
30428
|
+
cfg = JSON.parse(fs38.readFileSync(configPath, "utf-8"));
|
|
30326
30429
|
} catch (e) {
|
|
30327
30430
|
return `config \u8BFB\u4E0D\u56DE\u6765\u4E86\uFF08${e?.message || String(e)}\uFF09`;
|
|
30328
30431
|
}
|
|
@@ -30332,7 +30435,7 @@ function verify(configPath, envPath, moves) {
|
|
|
30332
30435
|
}
|
|
30333
30436
|
let env = "";
|
|
30334
30437
|
try {
|
|
30335
|
-
env =
|
|
30438
|
+
env = fs38.readFileSync(envPath, "utf-8");
|
|
30336
30439
|
} catch (e) {
|
|
30337
30440
|
return `secrets \u6587\u4EF6\u8BFB\u4E0D\u56DE\u6765\uFF08${e?.message || String(e)}\uFF09`;
|
|
30338
30441
|
}
|
|
@@ -30370,7 +30473,7 @@ __export(cli_config_exports, {
|
|
|
30370
30473
|
isSafeConfigName: () => isSafeConfigName,
|
|
30371
30474
|
runConfigCommand: () => runConfigCommand
|
|
30372
30475
|
});
|
|
30373
|
-
import
|
|
30476
|
+
import fs39 from "node:fs";
|
|
30374
30477
|
import path39 from "node:path";
|
|
30375
30478
|
function isSafeConfigName(name) {
|
|
30376
30479
|
return /^[\w.-]+$/.test(name);
|
|
@@ -30469,7 +30572,7 @@ function shapeOf(v) {
|
|
|
30469
30572
|
function readConfigObject(configPath) {
|
|
30470
30573
|
let text;
|
|
30471
30574
|
try {
|
|
30472
|
-
text =
|
|
30575
|
+
text = fs39.readFileSync(configPath, "utf-8");
|
|
30473
30576
|
} catch {
|
|
30474
30577
|
return { obj: {}, corrupt: false };
|
|
30475
30578
|
}
|
|
@@ -30527,7 +30630,7 @@ function findMaskedCredentials(value, prefix, out) {
|
|
|
30527
30630
|
function readEnvKeys(file2) {
|
|
30528
30631
|
const out = [];
|
|
30529
30632
|
try {
|
|
30530
|
-
for (const line of
|
|
30633
|
+
for (const line of fs39.readFileSync(file2, "utf-8").split("\n")) {
|
|
30531
30634
|
const t = line.trim();
|
|
30532
30635
|
if (!t || t.startsWith("#")) continue;
|
|
30533
30636
|
const eq = t.indexOf("=");
|
|
@@ -30583,7 +30686,7 @@ async function runConfigCommand(args) {
|
|
|
30583
30686
|
}
|
|
30584
30687
|
let parsedPayload;
|
|
30585
30688
|
try {
|
|
30586
|
-
parsedPayload = JSON.parse(
|
|
30689
|
+
parsedPayload = JSON.parse(fs39.readFileSync(p.file, "utf-8"));
|
|
30587
30690
|
} catch (e) {
|
|
30588
30691
|
process.stderr.write(`[config] \u8BFB\u4E0D\u4E86 payload: ${e.message}
|
|
30589
30692
|
`);
|
|
@@ -30689,7 +30792,7 @@ async function runConfigCommand(args) {
|
|
|
30689
30792
|
}
|
|
30690
30793
|
if (secretWrites.length > 0) {
|
|
30691
30794
|
const writePath2 = resolveSecretPath(p.stateDir, p.configName);
|
|
30692
|
-
const fallback =
|
|
30795
|
+
const fallback = fs39.existsSync(writePath2) ? void 0 : secretsCandidates(p.stateDir, p.configName).find((c) => fs39.existsSync(c));
|
|
30693
30796
|
if (fallback) {
|
|
30694
30797
|
const writing = new Set(secretWrites.map((s) => s.name));
|
|
30695
30798
|
const others = readEnvKeys(fallback).filter((k) => !writing.has(k));
|
|
@@ -30698,11 +30801,11 @@ async function runConfigCommand(args) {
|
|
|
30698
30801
|
}
|
|
30699
30802
|
}
|
|
30700
30803
|
}
|
|
30701
|
-
if (
|
|
30804
|
+
if (fs39.existsSync(p.configPath) && !isNormalized(fs39.readFileSync(p.configPath, "utf-8"))) {
|
|
30702
30805
|
warnings.push("config \u9996\u6B21\u89C4\u8303\u5316\uFF1A\u884C\u5C3E\u7EDF\u4E00\u4E3A LF\u3001\u7F29\u8FDB\u7EDF\u4E00\u4E3A 2 \u7A7A\u683C\uFF08\u4E00\u6B21\u6027\u5927 diff\uFF09");
|
|
30703
30806
|
}
|
|
30704
30807
|
const configDir = path39.dirname(p.configPath);
|
|
30705
|
-
if (!
|
|
30808
|
+
if (!fs39.existsSync(configDir)) fs39.mkdirSync(configDir, { recursive: true });
|
|
30706
30809
|
try {
|
|
30707
30810
|
writeConfigAtomic(p.configPath, merged);
|
|
30708
30811
|
} catch (e) {
|
|
@@ -30806,14 +30909,14 @@ __export(cli_reconfig_exports, {
|
|
|
30806
30909
|
doReconfigFeishu: () => doReconfigFeishu,
|
|
30807
30910
|
doReconfigWechat: () => doReconfigWechat
|
|
30808
30911
|
});
|
|
30809
|
-
import * as
|
|
30912
|
+
import * as fs40 from "node:fs";
|
|
30810
30913
|
import * as path40 from "node:path";
|
|
30811
30914
|
function scanForChannelsConfig(configsDir) {
|
|
30812
|
-
if (!
|
|
30813
|
-
for (const f of
|
|
30915
|
+
if (!fs40.existsSync(configsDir)) return "";
|
|
30916
|
+
for (const f of fs40.readdirSync(configsDir).filter((x) => x.endsWith(".json"))) {
|
|
30814
30917
|
const full = path40.join(configsDir, f);
|
|
30815
30918
|
try {
|
|
30816
|
-
if (JSON.parse(
|
|
30919
|
+
if (JSON.parse(fs40.readFileSync(full, "utf8")).channels) return full;
|
|
30817
30920
|
} catch {
|
|
30818
30921
|
}
|
|
30819
30922
|
}
|
|
@@ -30823,7 +30926,7 @@ function findFeishuConfigFile(stateDir, configName) {
|
|
|
30823
30926
|
const configsDir = path40.join(stateDir, "configs");
|
|
30824
30927
|
if (configName) {
|
|
30825
30928
|
const p = path40.join(configsDir, configName);
|
|
30826
|
-
if (
|
|
30929
|
+
if (fs40.existsSync(p)) return p;
|
|
30827
30930
|
}
|
|
30828
30931
|
return scanForChannelsConfig(configsDir);
|
|
30829
30932
|
}
|
|
@@ -30831,16 +30934,16 @@ function findWechatConfigFile(stateDir, configName) {
|
|
|
30831
30934
|
const configsDir = path40.join(stateDir, "configs");
|
|
30832
30935
|
if (configName) {
|
|
30833
30936
|
const p = path40.join(configsDir, configName);
|
|
30834
|
-
return
|
|
30937
|
+
return fs40.existsSync(p) ? p : "";
|
|
30835
30938
|
}
|
|
30836
30939
|
const scanned = scanForChannelsConfig(configsDir);
|
|
30837
30940
|
if (scanned) return scanned;
|
|
30838
|
-
if (
|
|
30839
|
-
const candidates =
|
|
30941
|
+
if (fs40.existsSync(configsDir)) {
|
|
30942
|
+
const candidates = fs40.readdirSync(configsDir).filter((f) => f.endsWith(".json"));
|
|
30840
30943
|
if (candidates.length) {
|
|
30841
30944
|
const first = path40.join(configsDir, candidates[0]);
|
|
30842
30945
|
try {
|
|
30843
|
-
JSON.parse(
|
|
30946
|
+
JSON.parse(fs40.readFileSync(first, "utf8"));
|
|
30844
30947
|
return first;
|
|
30845
30948
|
} catch {
|
|
30846
30949
|
}
|
|
@@ -30879,11 +30982,11 @@ async function doReconfigFeishu(opts) {
|
|
|
30879
30982
|
return 2;
|
|
30880
30983
|
}
|
|
30881
30984
|
const configFile = findFeishuConfigFile(stateDir, configName);
|
|
30882
|
-
if (configFile &&
|
|
30985
|
+
if (configFile && fs40.existsSync(configFile)) {
|
|
30883
30986
|
if (events) emit3?.({ event: "progress", step: "write_config" });
|
|
30884
30987
|
let j;
|
|
30885
30988
|
try {
|
|
30886
|
-
j = JSON.parse(
|
|
30989
|
+
j = JSON.parse(fs40.readFileSync(configFile, "utf8"));
|
|
30887
30990
|
} catch (err) {
|
|
30888
30991
|
if (events) emit3?.({ event: "error", message: `\u8BFB\u53D6 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09` });
|
|
30889
30992
|
else console.error(`\u274C \u8BFB\u53D6 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09`);
|
|
@@ -30901,7 +31004,7 @@ async function doReconfigFeishu(opts) {
|
|
|
30901
31004
|
}
|
|
30902
31005
|
j.channels.feishu = { enabled: true, appId: result.appId, appSecret: secretRef(feishuSecretEnv, result.appSecret), connectionMode: "websocket", dmPolicy: "pairing", groupPolicy: "open" };
|
|
30903
31006
|
try {
|
|
30904
|
-
|
|
31007
|
+
fs40.writeFileSync(configFile, JSON.stringify(j, null, 2), "utf8");
|
|
30905
31008
|
} catch (err) {
|
|
30906
31009
|
if (events) emit3?.({ event: "error", message: `\u5199\u5165 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09` });
|
|
30907
31010
|
else console.error(`\u274C \u5199\u5165 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09`);
|
|
@@ -30934,7 +31037,7 @@ async function doReconfigWechat(opts) {
|
|
|
30934
31037
|
return 2;
|
|
30935
31038
|
}
|
|
30936
31039
|
const configFile = findWechatConfigFile(stateDir, configName);
|
|
30937
|
-
if (!configFile || !
|
|
31040
|
+
if (!configFile || !fs40.existsSync(configFile)) {
|
|
30938
31041
|
console.log("\n\u26A0\uFE0F \u6CA1\u627E\u5230 config \u6587\u4EF6\uFF0C\u8BF7\u624B\u52A8\u628A\u4EE5\u4E0B\u6BB5\u52A0\u8FDB\u4F60\u7684 config \u7684 channels \u91CC\uFF1A");
|
|
30939
31042
|
console.log(JSON.stringify({ wechat: { enabled: true, token: cred.token, accountId: cred.accountId, dmPolicy: "pairing", group: { policy: "disabled" } } }, null, 2));
|
|
30940
31043
|
if (events) emit3?.({ event: "done", channel: "wechat", detail: cred.accountId, restart_required: true });
|
|
@@ -30943,7 +31046,7 @@ async function doReconfigWechat(opts) {
|
|
|
30943
31046
|
if (events) emit3?.({ event: "progress", step: "write_config" });
|
|
30944
31047
|
let j;
|
|
30945
31048
|
try {
|
|
30946
|
-
j = JSON.parse(
|
|
31049
|
+
j = JSON.parse(fs40.readFileSync(configFile, "utf8"));
|
|
30947
31050
|
} catch (err) {
|
|
30948
31051
|
if (events) emit3?.({ event: "error", message: `\u8BFB\u53D6 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09` });
|
|
30949
31052
|
else console.error(`\u274C \u8BFB\u53D6 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09`);
|
|
@@ -30961,7 +31064,7 @@ async function doReconfigWechat(opts) {
|
|
|
30961
31064
|
}
|
|
30962
31065
|
j.channels.wechat = { enabled: true, token: secretRef(wechatSecretEnv, cred.token), accountId: cred.accountId, dmPolicy: "pairing", group: { policy: "disabled" } };
|
|
30963
31066
|
try {
|
|
30964
|
-
|
|
31067
|
+
fs40.writeFileSync(configFile, JSON.stringify(j, null, 2), "utf8");
|
|
30965
31068
|
} catch (err) {
|
|
30966
31069
|
if (events) emit3?.({ event: "error", message: `\u5199\u5165 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09` });
|
|
30967
31070
|
else console.error(`\u274C \u5199\u5165 config \u5931\u8D25: ${configFile}\uFF08${err?.message || err}\uFF09`);
|
|
@@ -30999,19 +31102,19 @@ __export(cli_travel_exports, {
|
|
|
30999
31102
|
saveTravelConfig: () => saveTravelConfig
|
|
31000
31103
|
});
|
|
31001
31104
|
import * as path41 from "node:path";
|
|
31002
|
-
import * as
|
|
31105
|
+
import * as fs41 from "node:fs";
|
|
31003
31106
|
import * as os6 from "node:os";
|
|
31004
31107
|
import { execSync as execSync2 } from "node:child_process";
|
|
31005
31108
|
function loadTravelConfig() {
|
|
31006
31109
|
try {
|
|
31007
|
-
if (!
|
|
31008
|
-
return JSON.parse(
|
|
31110
|
+
if (!fs41.existsSync(CONFIG_PATH)) return null;
|
|
31111
|
+
return JSON.parse(fs41.readFileSync(CONFIG_PATH, "utf-8"));
|
|
31009
31112
|
} catch {
|
|
31010
31113
|
return null;
|
|
31011
31114
|
}
|
|
31012
31115
|
}
|
|
31013
31116
|
function saveTravelConfig(cfg) {
|
|
31014
|
-
|
|
31117
|
+
fs41.writeFileSync(CONFIG_PATH, JSON.stringify(cfg, null, 2));
|
|
31015
31118
|
}
|
|
31016
31119
|
function sanitizeContent(content, dirs) {
|
|
31017
31120
|
let result = content;
|
|
@@ -31051,14 +31154,14 @@ function shouldExclude(name) {
|
|
|
31051
31154
|
}
|
|
31052
31155
|
function collectFiles(rootDir, includeSet, optionalSet) {
|
|
31053
31156
|
const files = [];
|
|
31054
|
-
const entries2 =
|
|
31157
|
+
const entries2 = fs41.readdirSync(rootDir, { withFileTypes: true });
|
|
31055
31158
|
for (const entry of entries2) {
|
|
31056
31159
|
if (shouldExclude(entry.name)) continue;
|
|
31057
31160
|
const fullPath = path41.join(rootDir, entry.name);
|
|
31058
|
-
const realPath =
|
|
31161
|
+
const realPath = fs41.realpathSync(fullPath);
|
|
31059
31162
|
if (realPath !== fullPath) {
|
|
31060
31163
|
try {
|
|
31061
|
-
const lstat =
|
|
31164
|
+
const lstat = fs41.lstatSync(fullPath);
|
|
31062
31165
|
if (lstat.isSymbolicLink()) {
|
|
31063
31166
|
continue;
|
|
31064
31167
|
}
|
|
@@ -31079,12 +31182,12 @@ function collectFiles(rootDir, includeSet, optionalSet) {
|
|
|
31079
31182
|
function collectAllFiles(dir) {
|
|
31080
31183
|
const files = [];
|
|
31081
31184
|
try {
|
|
31082
|
-
const entries2 =
|
|
31185
|
+
const entries2 = fs41.readdirSync(dir, { withFileTypes: true });
|
|
31083
31186
|
for (const entry of entries2) {
|
|
31084
31187
|
if (shouldExclude(entry.name)) continue;
|
|
31085
31188
|
const fullPath = path41.join(dir, entry.name);
|
|
31086
31189
|
try {
|
|
31087
|
-
if (
|
|
31190
|
+
if (fs41.lstatSync(fullPath).isSymbolicLink()) continue;
|
|
31088
31191
|
} catch {
|
|
31089
31192
|
}
|
|
31090
31193
|
if (entry.isDirectory()) {
|
|
@@ -31101,11 +31204,11 @@ function readMainEngineUuid(agentsDir) {
|
|
|
31101
31204
|
try {
|
|
31102
31205
|
const platformMapPath = path41.join(agentsDir, "main", "sessions", "platform-map.json");
|
|
31103
31206
|
const indexMapPath = path41.join(agentsDir, "main", "sessions", "session-index.json");
|
|
31104
|
-
if (!
|
|
31105
|
-
const platformMap = JSON.parse(
|
|
31207
|
+
if (!fs41.existsSync(platformMapPath) || !fs41.existsSync(indexMapPath)) return null;
|
|
31208
|
+
const platformMap = JSON.parse(fs41.readFileSync(platformMapPath, "utf-8"));
|
|
31106
31209
|
const mainPlatformId = platformMap["scope:main"] || platformMap["main"];
|
|
31107
31210
|
if (!mainPlatformId) return null;
|
|
31108
|
-
const indexMap = JSON.parse(
|
|
31211
|
+
const indexMap = JSON.parse(fs41.readFileSync(indexMapPath, "utf-8"));
|
|
31109
31212
|
const entry = indexMap[mainPlatformId];
|
|
31110
31213
|
if (!entry || !entry.file) return null;
|
|
31111
31214
|
const basename10 = path41.basename(entry.file).replace(/\.jsonl$/, "");
|
|
@@ -31116,11 +31219,11 @@ function readMainEngineUuid(agentsDir) {
|
|
|
31116
31219
|
}
|
|
31117
31220
|
function collectRecentSessions(agentsDir, _days = 7) {
|
|
31118
31221
|
const files = [];
|
|
31119
|
-
if (!
|
|
31222
|
+
if (!fs41.existsSync(agentsDir)) return files;
|
|
31120
31223
|
const sessionGroups = /* @__PURE__ */ new Map();
|
|
31121
31224
|
function scanSessionsDir(dir) {
|
|
31122
31225
|
try {
|
|
31123
|
-
const entries2 =
|
|
31226
|
+
const entries2 = fs41.readdirSync(dir, { withFileTypes: true });
|
|
31124
31227
|
for (const entry of entries2) {
|
|
31125
31228
|
const fullPath = path41.join(dir, entry.name);
|
|
31126
31229
|
if (entry.isDirectory()) {
|
|
@@ -31146,7 +31249,7 @@ function collectRecentSessions(agentsDir, _days = 7) {
|
|
|
31146
31249
|
if (entry.name.endsWith(".jsonl")) {
|
|
31147
31250
|
group.jsonl = fullPath;
|
|
31148
31251
|
} else {
|
|
31149
|
-
const stat4 =
|
|
31252
|
+
const stat4 = fs41.statSync(fullPath);
|
|
31150
31253
|
group.archived.push({ file: fullPath, mtime: stat4.mtimeMs });
|
|
31151
31254
|
}
|
|
31152
31255
|
}
|
|
@@ -31168,7 +31271,7 @@ function collectExportFileSet(stateDir, workspace) {
|
|
|
31168
31271
|
const sessionFiles = collectRecentSessions(path41.join(stateDir, "agents"), 7);
|
|
31169
31272
|
const configsDir = path41.join(stateDir, "configs");
|
|
31170
31273
|
const configFiles = [];
|
|
31171
|
-
if (
|
|
31274
|
+
if (fs41.existsSync(configsDir)) {
|
|
31172
31275
|
for (const f of collectAllFiles(configsDir)) {
|
|
31173
31276
|
if (shouldExclude(path41.basename(f))) continue;
|
|
31174
31277
|
configFiles.push(f);
|
|
@@ -31177,7 +31280,7 @@ function collectExportFileSet(stateDir, workspace) {
|
|
|
31177
31280
|
const EVEROS_SKIP = /* @__PURE__ */ new Set([".tmp", ".lock", "import.log", "import_progress.json"]);
|
|
31178
31281
|
const everosDir = path41.join(stateDir, ".everos");
|
|
31179
31282
|
const everosFiles = [];
|
|
31180
|
-
if (
|
|
31283
|
+
if (fs41.existsSync(everosDir)) {
|
|
31181
31284
|
for (const f of collectAllFiles(everosDir)) {
|
|
31182
31285
|
if (EVEROS_SKIP.has(path41.basename(f))) continue;
|
|
31183
31286
|
everosFiles.push(f);
|
|
@@ -31193,7 +31296,7 @@ async function doExport(opts) {
|
|
|
31193
31296
|
console.log(` agent: ${agentName}`);
|
|
31194
31297
|
console.log(` state: ${stateDir}`);
|
|
31195
31298
|
console.log(` workspace: ${workspace}`);
|
|
31196
|
-
if (!
|
|
31299
|
+
if (!fs41.existsSync(workspace)) {
|
|
31197
31300
|
console.error(`\u274C workspace \u4E0D\u5B58\u5728: ${workspace}`);
|
|
31198
31301
|
process.exit(1);
|
|
31199
31302
|
}
|
|
@@ -31202,7 +31305,7 @@ async function doExport(opts) {
|
|
|
31202
31305
|
console.log(` workspace \u6587\u4EF6: ${wsFiles.length}`);
|
|
31203
31306
|
console.log(` session jsonl: ${sessionFiles.length} (\u6700\u8FD17\u5929)`);
|
|
31204
31307
|
console.log(` configs: ${configFiles.length}`);
|
|
31205
|
-
console.log(` everos: ${everosFiles.length} (${(everosFiles.reduce((s, f) => s +
|
|
31308
|
+
console.log(` everos: ${everosFiles.length} (${(everosFiles.reduce((s, f) => s + fs41.statSync(f).size, 0) / 1024 / 1024).toFixed(1)} MB)`);
|
|
31206
31309
|
if (dryRun2) {
|
|
31207
31310
|
console.log(`
|
|
31208
31311
|
[DRY RUN] \u4F1A\u6253\u5305\u4EE5\u4E0B\u6587\u4EF6:`);
|
|
@@ -31220,25 +31323,25 @@ async function doExport(opts) {
|
|
|
31220
31323
|
}
|
|
31221
31324
|
const version = formatLog().replace(/[-: ]/g, "").slice(0, 12).replace(/(d{8})(d{4})/, "$1-$2");
|
|
31222
31325
|
const tmpDir = path41.join(os6.tmpdir(), `engine7-export-${agentName}-${version}`);
|
|
31223
|
-
|
|
31326
|
+
fs41.mkdirSync(tmpDir, { recursive: true });
|
|
31224
31327
|
const stagingDir = path41.join(tmpDir, agentName);
|
|
31225
|
-
|
|
31328
|
+
fs41.mkdirSync(stagingDir, { recursive: true });
|
|
31226
31329
|
let fileCount = 0;
|
|
31227
31330
|
let totalSize = 0;
|
|
31228
31331
|
let copyFail = 0;
|
|
31229
31332
|
const copyOne = (srcFile, relRoot, destRoot) => {
|
|
31230
31333
|
const relPath = path41.relative(relRoot, srcFile);
|
|
31231
31334
|
const destFile = path41.join(destRoot, relPath);
|
|
31232
|
-
|
|
31335
|
+
fs41.mkdirSync(path41.dirname(destFile), { recursive: true });
|
|
31233
31336
|
try {
|
|
31234
31337
|
if (isTextFile(srcFile)) {
|
|
31235
|
-
const content =
|
|
31236
|
-
|
|
31338
|
+
const content = fs41.readFileSync(srcFile, "utf-8");
|
|
31339
|
+
fs41.writeFileSync(destFile, sanitizeContent(content, dirs));
|
|
31237
31340
|
} else {
|
|
31238
|
-
|
|
31341
|
+
fs41.copyFileSync(srcFile, destFile);
|
|
31239
31342
|
}
|
|
31240
31343
|
fileCount++;
|
|
31241
|
-
totalSize +=
|
|
31344
|
+
totalSize += fs41.statSync(srcFile).size;
|
|
31242
31345
|
} catch (e) {
|
|
31243
31346
|
copyFail++;
|
|
31244
31347
|
console.warn(` \u26A0\uFE0F \u62F7\u8D1D\u5931\u8D25: ${relPath} (${e.code || e.message})`);
|
|
@@ -31248,17 +31351,17 @@ async function doExport(opts) {
|
|
|
31248
31351
|
for (const srcFile of sessionFiles) {
|
|
31249
31352
|
const relPath = path41.relative(stateDir, srcFile);
|
|
31250
31353
|
const destFile = path41.join(stagingDir, relPath);
|
|
31251
|
-
|
|
31354
|
+
fs41.mkdirSync(path41.dirname(destFile), { recursive: true });
|
|
31252
31355
|
try {
|
|
31253
|
-
let content =
|
|
31356
|
+
let content = fs41.readFileSync(srcFile, "utf-8");
|
|
31254
31357
|
content = sanitizeContent(content, dirs);
|
|
31255
31358
|
const baseName = path41.basename(srcFile);
|
|
31256
31359
|
if (baseName === "session-index.json" || baseName === "platform-map.json") {
|
|
31257
31360
|
content = content.split("\\\\").join("/");
|
|
31258
31361
|
}
|
|
31259
|
-
|
|
31362
|
+
fs41.writeFileSync(destFile, content);
|
|
31260
31363
|
fileCount++;
|
|
31261
|
-
totalSize +=
|
|
31364
|
+
totalSize += fs41.statSync(srcFile).size;
|
|
31262
31365
|
} catch (e) {
|
|
31263
31366
|
copyFail++;
|
|
31264
31367
|
console.warn(` \u26A0\uFE0F \u62F7\u8D1D\u5931\u8D25: ${relPath} (${e.code || e.message})`);
|
|
@@ -31280,13 +31383,13 @@ async function doExport(opts) {
|
|
|
31280
31383
|
totalSize,
|
|
31281
31384
|
note
|
|
31282
31385
|
};
|
|
31283
|
-
|
|
31386
|
+
fs41.writeFileSync(path41.join(stagingDir, "manifest.json"), JSON.stringify(manifest, null, 2));
|
|
31284
31387
|
const archiveFile = path41.join(tmpDir, `${agentName}-${version}.tar.gz`);
|
|
31285
31388
|
console.log(`
|
|
31286
31389
|
\u{1F5DC}\uFE0F \u6253\u5305\u4E2D...`);
|
|
31287
31390
|
const tarExe = process.platform === "win32" ? "C:\\Windows\\System32\\tar.exe" : "tar";
|
|
31288
31391
|
execSync2(`"${tarExe}" -czf "${archiveFile}" -C "${tmpDir}" ${agentName}`, { stdio: "pipe" });
|
|
31289
|
-
const archiveSize =
|
|
31392
|
+
const archiveSize = fs41.statSync(archiveFile).size;
|
|
31290
31393
|
console.log(`\u2705 \u6253\u5305\u5B8C\u6210: ${archiveFile} (${(archiveSize / 1024 / 1024).toFixed(1)} MB, ${fileCount} \u6587\u4EF6${copyFail ? `, \u5931\u8D25 ${copyFail}` : ""})`);
|
|
31291
31394
|
const cfg = loadTravelConfig();
|
|
31292
31395
|
if (!cfg || !cfg.githubToken) {
|
|
@@ -31317,7 +31420,7 @@ function parseImportArgs(args) {
|
|
|
31317
31420
|
}
|
|
31318
31421
|
async function resolveArchiveForTest(opts) {
|
|
31319
31422
|
if (opts.archiveFile) {
|
|
31320
|
-
if (!
|
|
31423
|
+
if (!fs41.existsSync(opts.archiveFile)) {
|
|
31321
31424
|
throw new Error(`\u672C\u5730\u5305\u4E0D\u5B58\u5728: ${opts.archiveFile}`);
|
|
31322
31425
|
}
|
|
31323
31426
|
return opts.archiveFile;
|
|
@@ -31330,7 +31433,7 @@ async function doImport(opts) {
|
|
|
31330
31433
|
console.log(` agent: ${agentName}`);
|
|
31331
31434
|
console.log(` target: ${stateDir}`);
|
|
31332
31435
|
const tmpDir = path41.join(os6.tmpdir(), `engine7-import-${agentName}-${Date.now()}`);
|
|
31333
|
-
|
|
31436
|
+
fs41.mkdirSync(tmpDir, { recursive: true });
|
|
31334
31437
|
const resolved = await resolveArchiveForTest({
|
|
31335
31438
|
archiveFile: archiveFile || "",
|
|
31336
31439
|
tmpDir,
|
|
@@ -31357,11 +31460,11 @@ async function doImport(opts) {
|
|
|
31357
31460
|
execSync2(`"${tarExe}" -xzf "${finalArchive}" -C "${tmpDir}"`, { stdio: "pipe" });
|
|
31358
31461
|
const stagingDir = path41.join(tmpDir, agentName);
|
|
31359
31462
|
const manifestPath = path41.join(stagingDir, "manifest.json");
|
|
31360
|
-
if (!
|
|
31463
|
+
if (!fs41.existsSync(manifestPath)) {
|
|
31361
31464
|
console.error(`\u274C manifest.json \u4E0D\u5B58\u5728\uFF0C\u6587\u4EF6\u53EF\u80FD\u635F\u574F`);
|
|
31362
31465
|
process.exit(1);
|
|
31363
31466
|
}
|
|
31364
|
-
const manifest = JSON.parse(
|
|
31467
|
+
const manifest = JSON.parse(fs41.readFileSync(manifestPath, "utf-8"));
|
|
31365
31468
|
const workspace = path41.join(stateDir, "workspace").replace(/\\/g, "/").replace(/[/\\]+$/, "");
|
|
31366
31469
|
const engineHome = path41.join(os6.homedir(), ".engine7").replace(/\\/g, "/").replace(/[/\\]+$/, "");
|
|
31367
31470
|
const dirs = { workspace, stateDir: stateDir.replace(/\\/g, "/").replace(/[/\\]+$/, ""), engineHome };
|
|
@@ -31371,18 +31474,18 @@ async function doImport(opts) {
|
|
|
31371
31474
|
const wsStaging = path41.join(stagingDir, "workspace");
|
|
31372
31475
|
let restoredCount = 0;
|
|
31373
31476
|
let skipCount = 0;
|
|
31374
|
-
if (
|
|
31477
|
+
if (fs41.existsSync(wsStaging)) {
|
|
31375
31478
|
const allFiles = collectAllFiles(wsStaging);
|
|
31376
31479
|
for (const srcFile of allFiles) {
|
|
31377
31480
|
const relPath = path41.relative(wsStaging, srcFile);
|
|
31378
31481
|
const destFile = path41.join(workspace, relPath);
|
|
31379
|
-
|
|
31482
|
+
fs41.mkdirSync(path41.dirname(destFile), { recursive: true });
|
|
31380
31483
|
try {
|
|
31381
31484
|
if (isTextFile(srcFile)) {
|
|
31382
|
-
const content =
|
|
31383
|
-
|
|
31485
|
+
const content = fs41.readFileSync(srcFile, "utf-8");
|
|
31486
|
+
fs41.writeFileSync(destFile, restoreContent(content, dirs));
|
|
31384
31487
|
} else {
|
|
31385
|
-
|
|
31488
|
+
fs41.copyFileSync(srcFile, destFile);
|
|
31386
31489
|
}
|
|
31387
31490
|
restoredCount++;
|
|
31388
31491
|
} catch (e) {
|
|
@@ -31392,46 +31495,46 @@ async function doImport(opts) {
|
|
|
31392
31495
|
}
|
|
31393
31496
|
}
|
|
31394
31497
|
const agentsStaging = path41.join(stagingDir, "agents");
|
|
31395
|
-
if (
|
|
31498
|
+
if (fs41.existsSync(agentsStaging)) {
|
|
31396
31499
|
const sessionFiles = collectAllFiles(agentsStaging);
|
|
31397
31500
|
for (const srcFile of sessionFiles) {
|
|
31398
31501
|
const relPath = path41.relative(stagingDir, srcFile);
|
|
31399
31502
|
const destFile = path41.join(stateDir, relPath);
|
|
31400
|
-
|
|
31401
|
-
const content =
|
|
31402
|
-
|
|
31503
|
+
fs41.mkdirSync(path41.dirname(destFile), { recursive: true });
|
|
31504
|
+
const content = fs41.readFileSync(srcFile, "utf-8");
|
|
31505
|
+
fs41.writeFileSync(destFile, restoreContent(content, dirs));
|
|
31403
31506
|
restoredCount++;
|
|
31404
31507
|
}
|
|
31405
31508
|
}
|
|
31406
31509
|
const configsStaging = path41.join(stagingDir, "configs");
|
|
31407
|
-
if (
|
|
31510
|
+
if (fs41.existsSync(configsStaging)) {
|
|
31408
31511
|
const cfgFiles = collectAllFiles(configsStaging);
|
|
31409
31512
|
for (const srcFile of cfgFiles) {
|
|
31410
31513
|
const relPath = path41.relative(stagingDir, srcFile);
|
|
31411
31514
|
const destFile = path41.join(stateDir, relPath);
|
|
31412
|
-
|
|
31515
|
+
fs41.mkdirSync(path41.dirname(destFile), { recursive: true });
|
|
31413
31516
|
if (isTextFile(srcFile)) {
|
|
31414
|
-
const content =
|
|
31415
|
-
|
|
31517
|
+
const content = fs41.readFileSync(srcFile, "utf-8");
|
|
31518
|
+
fs41.writeFileSync(destFile, restoreContent(content, dirs));
|
|
31416
31519
|
} else {
|
|
31417
|
-
|
|
31520
|
+
fs41.copyFileSync(srcFile, destFile);
|
|
31418
31521
|
}
|
|
31419
31522
|
restoredCount++;
|
|
31420
31523
|
}
|
|
31421
31524
|
}
|
|
31422
31525
|
const everosStaging = path41.join(stagingDir, ".everos");
|
|
31423
|
-
if (
|
|
31526
|
+
if (fs41.existsSync(everosStaging)) {
|
|
31424
31527
|
const everosFiles = collectAllFiles(everosStaging);
|
|
31425
31528
|
for (const srcFile of everosFiles) {
|
|
31426
31529
|
const relPath = path41.relative(stagingDir, srcFile);
|
|
31427
31530
|
const destFile = path41.join(stateDir, relPath);
|
|
31428
|
-
|
|
31531
|
+
fs41.mkdirSync(path41.dirname(destFile), { recursive: true });
|
|
31429
31532
|
try {
|
|
31430
31533
|
if (isTextFile(srcFile)) {
|
|
31431
|
-
const content =
|
|
31432
|
-
|
|
31534
|
+
const content = fs41.readFileSync(srcFile, "utf-8");
|
|
31535
|
+
fs41.writeFileSync(destFile, restoreContent(content, dirs));
|
|
31433
31536
|
} else {
|
|
31434
|
-
|
|
31537
|
+
fs41.copyFileSync(srcFile, destFile);
|
|
31435
31538
|
}
|
|
31436
31539
|
restoredCount++;
|
|
31437
31540
|
} catch (e) {
|
|
@@ -31444,10 +31547,10 @@ async function doImport(opts) {
|
|
|
31444
31547
|
console.log(`\u2705 \u6062\u590D\u5B8C\u6210: ${restoredCount} \u6587\u4EF6 \u2192 ${stateDir}${skipCount ? ` (\u8DF3\u8FC7 ${skipCount})` : ""}`);
|
|
31445
31548
|
const platformConfigName = process.platform === "darwin" ? "xiaoke-mac.json" : "xiaoke-win.json";
|
|
31446
31549
|
const restoredConfigPath = path41.join(stateDir, "configs", platformConfigName);
|
|
31447
|
-
const configToUse =
|
|
31550
|
+
const configToUse = fs41.existsSync(restoredConfigPath) ? restoredConfigPath : path41.join(stateDir, "configs", "xiaoke.json");
|
|
31448
31551
|
console.log(`
|
|
31449
31552
|
\u{1F4A1} \u4E0B\u4E00\u6B65: engine7 start --config "${configToUse}"`);
|
|
31450
|
-
|
|
31553
|
+
fs41.rmSync(tmpDir, { recursive: true, force: true });
|
|
31451
31554
|
}
|
|
31452
31555
|
async function uploadToGitHub(cfg, archiveFile, agentName, version, manifest) {
|
|
31453
31556
|
const repo = `${cfg.githubOwner}/${cfg.repoName}`;
|
|
@@ -31477,7 +31580,7 @@ async function uploadToGitHub(cfg, archiveFile, agentName, version, manifest) {
|
|
|
31477
31580
|
}
|
|
31478
31581
|
const release2 = await createRes.json();
|
|
31479
31582
|
const uploadUrl = release2.upload_url.replace("{?name,label}", "");
|
|
31480
|
-
const fileBuffer =
|
|
31583
|
+
const fileBuffer = fs41.readFileSync(archiveFile);
|
|
31481
31584
|
const fileName = path41.basename(archiveFile);
|
|
31482
31585
|
const uploadRes = await fetch(`${uploadUrl}?name=${fileName}`, {
|
|
31483
31586
|
method: "POST",
|
|
@@ -31501,7 +31604,7 @@ async function uploadToGitHub(cfg, archiveFile, agentName, version, manifest) {
|
|
|
31501
31604
|
throw e;
|
|
31502
31605
|
}
|
|
31503
31606
|
try {
|
|
31504
|
-
|
|
31607
|
+
fs41.rmSync(path41.dirname(archiveFile), { recursive: true, force: true });
|
|
31505
31608
|
} catch {
|
|
31506
31609
|
}
|
|
31507
31610
|
}
|
|
@@ -31534,7 +31637,7 @@ async function downloadFromGitHub(cfg, agentName, version, destDir) {
|
|
|
31534
31637
|
}
|
|
31535
31638
|
const buffer = Buffer.from(await downloadRes.arrayBuffer());
|
|
31536
31639
|
const archiveFile = path41.join(destDir, asset.name);
|
|
31537
|
-
|
|
31640
|
+
fs41.writeFileSync(archiveFile, buffer);
|
|
31538
31641
|
return archiveFile;
|
|
31539
31642
|
}
|
|
31540
31643
|
async function getLatestReleaseTag(cfg, agentName) {
|
|
@@ -31634,7 +31737,7 @@ var init_cli_travel = __esm({
|
|
|
31634
31737
|
|
|
31635
31738
|
// src/cli-init.ts
|
|
31636
31739
|
import * as path42 from "node:path";
|
|
31637
|
-
import * as
|
|
31740
|
+
import * as fs42 from "node:fs";
|
|
31638
31741
|
|
|
31639
31742
|
// src/cli-service.ts
|
|
31640
31743
|
function parseServiceArgs(args) {
|
|
@@ -31740,6 +31843,7 @@ function buildConfigValuesFromAnswers(stateDir, a, existing = {}) {
|
|
|
31740
31843
|
const primaryProvider = target.providerId;
|
|
31741
31844
|
const primaryModel = target.modelRef || DEFAULT_PRIMARY_MODEL[a.provider] || `${primaryProvider}/unknown`;
|
|
31742
31845
|
const visionModel = a.visionModel || resolveVisionModel(primaryProvider, primaryModel, a.providerModels);
|
|
31846
|
+
const videoModel = a.videoModel || resolveVideoModel(primaryProvider, primaryModel, a.providerModels);
|
|
31743
31847
|
const feishuMode = a.feishu?.mode || "skip";
|
|
31744
31848
|
const wechatMode = a.wechat?.mode || "skip";
|
|
31745
31849
|
return {
|
|
@@ -31762,6 +31866,7 @@ function buildConfigValuesFromAnswers(stateDir, a, existing = {}) {
|
|
|
31762
31866
|
primaryApiKey: a.apiKey || "",
|
|
31763
31867
|
primaryModel,
|
|
31764
31868
|
visionModel,
|
|
31869
|
+
videoModel,
|
|
31765
31870
|
discordEnabled: a.discord?.enabled ?? false,
|
|
31766
31871
|
discordToken: a.discord?.token || "",
|
|
31767
31872
|
discordUserId: a.discord?.userId || "",
|
|
@@ -31931,6 +32036,11 @@ function getDefaultValues(stateDir) {
|
|
|
31931
32036
|
// 沿用旧值前先验 provider:机器已被 P0-2 写坏时,--quick 会把那个幽灵引用原样带下去
|
|
31932
32037
|
// (向导路径本来就会重算,只有 --quick 走这里)。
|
|
31933
32038
|
visionModel: existing.visionModel?.startsWith(primaryProvider + "/") ? existing.visionModel : resolveVisionModel(primaryProvider, primaryModel),
|
|
32039
|
+
// 0930:视频模型同样只在本 provider 内推导(主模型自己收 video 就复用;7yi 落
|
|
32040
|
+
// engine7-video)。解析不出返回空串,generateConfig 省略 video 键。
|
|
32041
|
+
// 复跑保留与 visionModel 同一条规则(翀哥 8/28「回车保留」指示):同 provider 的已有值
|
|
32042
|
+
// 原样沿用——用户手改过的 model.video 不该被 --quick 冲掉;跨 provider / 没有的才重推。
|
|
32043
|
+
videoModel: existing.videoModel?.startsWith(primaryProvider + "/") ? existing.videoModel : resolveVideoModel(primaryProvider, primaryModel),
|
|
31934
32044
|
discordEnabled: existing.discordEnabled ?? false,
|
|
31935
32045
|
discordToken: existing.discordToken || "",
|
|
31936
32046
|
discordUserId: existing.discordUserId || "",
|
|
@@ -31953,14 +32063,14 @@ function getDefaultValues(stateDir) {
|
|
|
31953
32063
|
function loadExistingValues(stateDir) {
|
|
31954
32064
|
const configPath = path42.join(stateDir, "configs", "main7.json");
|
|
31955
32065
|
try {
|
|
31956
|
-
if (!
|
|
31957
|
-
const j = JSON.parse(
|
|
32066
|
+
if (!fs42.existsSync(configPath)) return {};
|
|
32067
|
+
const j = JSON.parse(fs42.readFileSync(configPath, "utf8"));
|
|
31958
32068
|
const out = {};
|
|
31959
32069
|
if (typeof j.timezone === "string" && j.timezone) out.timezone = j.timezone;
|
|
31960
32070
|
if (j.agents?.defaults?.name) out.agentName = j.agents.defaults.name;
|
|
31961
32071
|
if (j.agents?.defaults?.persona) out.persona = j.agents.defaults.persona;
|
|
31962
32072
|
try {
|
|
31963
|
-
const wm =
|
|
32073
|
+
const wm = fs42.readFileSync(path42.join(stateDir, "workspace", ".work-mode"), "utf8").trim();
|
|
31964
32074
|
if (wm === "on") out.chatMode = "work";
|
|
31965
32075
|
else if (wm === "off") out.chatMode = "emotion";
|
|
31966
32076
|
} catch {
|
|
@@ -31990,6 +32100,7 @@ function loadExistingValues(stateDir) {
|
|
|
31990
32100
|
out.customModelId = builtin.includes(firstId) ? "" : firstModel;
|
|
31991
32101
|
}
|
|
31992
32102
|
if (j.agents?.defaults?.model?.vision) out.visionModel = j.agents.defaults.model.vision;
|
|
32103
|
+
if (j.agents?.defaults?.model?.video) out.videoModel = j.agents.defaults.model.video;
|
|
31993
32104
|
}
|
|
31994
32105
|
if (j.channels?.discord) {
|
|
31995
32106
|
out.discordEnabled = !!j.channels.discord.enabled;
|
|
@@ -32016,8 +32127,8 @@ function readSecretsValue(stateDir, envName) {
|
|
|
32016
32127
|
try {
|
|
32017
32128
|
const cfgBase = "main7";
|
|
32018
32129
|
for (const p of secretsCandidates(stateDir, cfgBase)) {
|
|
32019
|
-
if (
|
|
32020
|
-
for (const line of
|
|
32130
|
+
if (fs42.existsSync(p)) {
|
|
32131
|
+
for (const line of fs42.readFileSync(p, "utf8").split("\n")) {
|
|
32021
32132
|
const eq = line.indexOf("=");
|
|
32022
32133
|
if (eq > 0 && line.slice(0, eq).trim() === envName) {
|
|
32023
32134
|
return line.slice(eq + 1).trim();
|
|
@@ -32121,6 +32232,7 @@ async function interactiveConfig(rl, defaults) {
|
|
|
32121
32232
|
console.log(` \u6CE8\u610F\uFF1AVision \u6A21\u578B\u7528\u4E86\u4E0D\u540C provider\uFF0C\u9700\u8981\u5728 config \u91CC\u8865\u5145\u5BF9\u5E94\u7684 API key`);
|
|
32122
32233
|
}
|
|
32123
32234
|
}
|
|
32235
|
+
v.videoModel = resolveVideoModel(v.primaryProvider, v.primaryModel);
|
|
32124
32236
|
console.log("\n=== \u7B2C\u4E8C\u6B65\uFF1A\u53EF\u9009\u914D\u7F6E\uFF08\u56DE\u8F66\u8DF3\u8FC7\uFF0C\u5DF2\u542F\u7528\u7684\u56DE\u8F66\u4FDD\u7559\uFF09===\n");
|
|
32125
32237
|
const discordAns = await ask(rl, "\u542F\u7528 Discord? (y/n)", defaults.discordEnabled ? "y" : "n");
|
|
32126
32238
|
v.discordEnabled = discordAns.toLowerCase() === "y";
|
|
@@ -32448,19 +32560,19 @@ function readTemplate(relativePath) {
|
|
|
32448
32560
|
path42.join(process.cwd(), "templates", relativePath)
|
|
32449
32561
|
];
|
|
32450
32562
|
for (const p of candidates) {
|
|
32451
|
-
if (
|
|
32452
|
-
return
|
|
32563
|
+
if (fs42.existsSync(p)) {
|
|
32564
|
+
return fs42.readFileSync(p, "utf-8");
|
|
32453
32565
|
}
|
|
32454
32566
|
}
|
|
32455
32567
|
throw new Error(`\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728: ${relativePath}\uFF08\u627E\u4E86: ${candidates.join(", ")}\uFF09`);
|
|
32456
32568
|
}
|
|
32457
32569
|
function looksLikeAppInstall(dir) {
|
|
32458
|
-
return ["", "install"].some((sub) =>
|
|
32570
|
+
return ["", "install"].some((sub) => fs42.existsSync(path42.join(dir, sub, "Engine7.exe")) && fs42.existsSync(path42.join(dir, sub, "resources", "engine7", "dist", "cli.mjs")));
|
|
32459
32571
|
}
|
|
32460
32572
|
var PHOTO_EXTS = [".png", ".jpg", ".jpeg", ".webp"];
|
|
32461
32573
|
function hasOnlyEngineBookkeeping(dir) {
|
|
32462
32574
|
try {
|
|
32463
|
-
const entries2 =
|
|
32575
|
+
const entries2 = fs42.readdirSync(dir);
|
|
32464
32576
|
return entries2.length > 0 && entries2.every((e) => e === "install-identity.json");
|
|
32465
32577
|
} catch {
|
|
32466
32578
|
return false;
|
|
@@ -32476,11 +32588,11 @@ function dryRun(entries2) {
|
|
|
32476
32588
|
function execute(entries2) {
|
|
32477
32589
|
for (const e of entries2) {
|
|
32478
32590
|
if (e.type === "dir") {
|
|
32479
|
-
|
|
32591
|
+
fs42.mkdirSync(e.path, { recursive: true });
|
|
32480
32592
|
console.log(` \u{1F4C1} ${e.path}`);
|
|
32481
32593
|
} else {
|
|
32482
|
-
|
|
32483
|
-
|
|
32594
|
+
fs42.mkdirSync(path42.dirname(e.path), { recursive: true });
|
|
32595
|
+
fs42.writeFileSync(e.path, e.content || "", "utf-8");
|
|
32484
32596
|
console.log(` \u{1F4C4} ${e.path}`);
|
|
32485
32597
|
}
|
|
32486
32598
|
}
|
|
@@ -32515,7 +32627,7 @@ async function main() {
|
|
|
32515
32627
|
let ver = "unknown";
|
|
32516
32628
|
try {
|
|
32517
32629
|
const pkgPath = path42.join(path42.dirname(__filename2), "..", "package.json");
|
|
32518
|
-
ver = JSON.parse(
|
|
32630
|
+
ver = JSON.parse(fs42.readFileSync(pkgPath, "utf8")).version || "unknown";
|
|
32519
32631
|
} catch {
|
|
32520
32632
|
}
|
|
32521
32633
|
console.log(`engine7 ${ver}`);
|
|
@@ -32579,13 +32691,13 @@ async function main() {
|
|
|
32579
32691
|
}
|
|
32580
32692
|
if (!stateDir) {
|
|
32581
32693
|
const cwd = path42.resolve(process.cwd());
|
|
32582
|
-
if (
|
|
32694
|
+
if (fs42.existsSync(path42.join(cwd, "configs"))) {
|
|
32583
32695
|
stateDir = cwd;
|
|
32584
32696
|
} else {
|
|
32585
32697
|
const pointer = path42.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7.json");
|
|
32586
|
-
if (
|
|
32698
|
+
if (fs42.existsSync(pointer)) {
|
|
32587
32699
|
try {
|
|
32588
|
-
stateDir = JSON.parse(
|
|
32700
|
+
stateDir = JSON.parse(fs42.readFileSync(pointer, "utf8")).stateDir || "";
|
|
32589
32701
|
} catch {
|
|
32590
32702
|
}
|
|
32591
32703
|
}
|
|
@@ -32610,11 +32722,11 @@ async function main() {
|
|
|
32610
32722
|
}
|
|
32611
32723
|
if (channel === "channels") {
|
|
32612
32724
|
const configsDir = path42.join(stateDir, "configs");
|
|
32613
|
-
if (
|
|
32614
|
-
const files =
|
|
32725
|
+
if (fs42.existsSync(configsDir)) {
|
|
32726
|
+
const files = fs42.readdirSync(configsDir).filter((f) => f.endsWith(".json"));
|
|
32615
32727
|
for (const f of files) {
|
|
32616
32728
|
try {
|
|
32617
|
-
const j = JSON.parse(
|
|
32729
|
+
const j = JSON.parse(fs42.readFileSync(path42.join(configsDir, f), "utf8"));
|
|
32618
32730
|
if (!j.channels) continue;
|
|
32619
32731
|
console.log(`
|
|
32620
32732
|
\u{1F4C4} ${f}:`);
|
|
@@ -32771,16 +32883,16 @@ engine7 start \u2014 \u542F\u52A8 Engine
|
|
|
32771
32883
|
if (!configPath2) {
|
|
32772
32884
|
const defaultCfg = path42.join("configs", "main7.json");
|
|
32773
32885
|
const homeCfg = path42.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7", "configs", "main7.json");
|
|
32774
|
-
if (
|
|
32886
|
+
if (fs42.existsSync(defaultCfg)) {
|
|
32775
32887
|
configPath2 = defaultCfg;
|
|
32776
|
-
} else if (
|
|
32888
|
+
} else if (fs42.existsSync(homeCfg)) {
|
|
32777
32889
|
configPath2 = homeCfg;
|
|
32778
32890
|
console.log(` \u4F7F\u7528\u9ED8\u8BA4 config: ${homeCfg}`);
|
|
32779
32891
|
} else {
|
|
32780
32892
|
const ptr = readHomePointer();
|
|
32781
32893
|
if (ptr?.stateDir) {
|
|
32782
32894
|
const ptrCfg = path42.join(ptr.stateDir, "configs", "main7.json");
|
|
32783
|
-
if (
|
|
32895
|
+
if (fs42.existsSync(ptrCfg)) {
|
|
32784
32896
|
configPath2 = ptrCfg;
|
|
32785
32897
|
console.log(` \u4F7F\u7528 config: ${ptrCfg}`);
|
|
32786
32898
|
}
|
|
@@ -32793,7 +32905,7 @@ engine7 start \u2014 \u542F\u52A8 Engine
|
|
|
32793
32905
|
}
|
|
32794
32906
|
}
|
|
32795
32907
|
}
|
|
32796
|
-
if (configPath2 && !
|
|
32908
|
+
if (configPath2 && !fs42.existsSync(configPath2)) {
|
|
32797
32909
|
console.error(`\u274C config \u6587\u4EF6\u4E0D\u5B58\u5728: ${configPath2}`);
|
|
32798
32910
|
console.error(" \u7528\u6CD5: engine7 start [configs/xxx.json | --config <path>]");
|
|
32799
32911
|
process.exit(1);
|
|
@@ -32801,13 +32913,13 @@ engine7 start \u2014 \u542F\u52A8 Engine
|
|
|
32801
32913
|
const { execSync: execSync3, spawn: spawn5 } = await import("node:child_process");
|
|
32802
32914
|
let enginePath;
|
|
32803
32915
|
const localPath = path42.join("node_modules", "engine7", "dist", "main.mjs");
|
|
32804
|
-
if (
|
|
32916
|
+
if (fs42.existsSync(localPath)) {
|
|
32805
32917
|
enginePath = localPath;
|
|
32806
32918
|
} else {
|
|
32807
32919
|
const cliPath = path42.resolve(process.argv[1]);
|
|
32808
32920
|
const distDir = path42.dirname(cliPath);
|
|
32809
32921
|
const candidate = path42.join(distDir, "main.mjs");
|
|
32810
|
-
if (
|
|
32922
|
+
if (fs42.existsSync(candidate)) {
|
|
32811
32923
|
enginePath = candidate;
|
|
32812
32924
|
} else {
|
|
32813
32925
|
try {
|
|
@@ -32843,8 +32955,8 @@ engine7 start \u2014 \u542F\u52A8 Engine
|
|
|
32843
32955
|
const envForChild = { ...process.env };
|
|
32844
32956
|
const { stateDir: secretsStateDir, configName: secretsCfgName } = resolveConfigIdentity(configPath2);
|
|
32845
32957
|
for (const secretPath of secretsCandidates(secretsStateDir, secretsCfgName)) {
|
|
32846
|
-
if (
|
|
32847
|
-
const content =
|
|
32958
|
+
if (fs42.existsSync(secretPath)) {
|
|
32959
|
+
const content = fs42.readFileSync(secretPath, "utf-8");
|
|
32848
32960
|
for (const line of content.split("\n")) {
|
|
32849
32961
|
const trimmed = line.trim();
|
|
32850
32962
|
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
@@ -32919,14 +33031,14 @@ engine7 session \u2014 \u4F1A\u8BDD\u7BA1\u7406\u5DE5\u5177
|
|
|
32919
33031
|
console.error(`\u274C \u672A\u77E5\u6A21\u5F0F: ${mode}\uFF08\u53EF\u9009: archive / drop-last / strip-images\uFF09`);
|
|
32920
33032
|
process.exit(1);
|
|
32921
33033
|
}
|
|
32922
|
-
const configRaw = JSON.parse(
|
|
33034
|
+
const configRaw = JSON.parse(fs42.readFileSync(configPath2, "utf-8"));
|
|
32923
33035
|
const stateDir = configRaw.stateDir;
|
|
32924
33036
|
if (!stateDir) {
|
|
32925
33037
|
console.error("\u274C config \u91CC\u6CA1\u6709 stateDir");
|
|
32926
33038
|
process.exit(1);
|
|
32927
33039
|
}
|
|
32928
33040
|
const sessionsDir = path42.join(stateDir, "agents", "main", "sessions");
|
|
32929
|
-
if (!
|
|
33041
|
+
if (!fs42.existsSync(sessionsDir)) {
|
|
32930
33042
|
console.error(`\u274C sessions \u76EE\u5F55\u4E0D\u5B58\u5728: ${sessionsDir}`);
|
|
32931
33043
|
process.exit(1);
|
|
32932
33044
|
}
|
|
@@ -32937,8 +33049,8 @@ engine7 session \u2014 \u4F1A\u8BDD\u7BA1\u7406\u5DE5\u5177
|
|
|
32937
33049
|
const platformMapPath = path42.join(sessionsDir, "platform-map.json");
|
|
32938
33050
|
const indexPath = path42.join(sessionsDir, "session-index.json");
|
|
32939
33051
|
let sessionFileUUID = null;
|
|
32940
|
-
if (
|
|
32941
|
-
const index = JSON.parse(
|
|
33052
|
+
if (fs42.existsSync(indexPath)) {
|
|
33053
|
+
const index = JSON.parse(fs42.readFileSync(indexPath, "utf-8"));
|
|
32942
33054
|
const entries2 = Object.values(index);
|
|
32943
33055
|
if (entries2.length > 0) {
|
|
32944
33056
|
const fileVal = entries2[0].file || "";
|
|
@@ -32946,7 +33058,7 @@ engine7 session \u2014 \u4F1A\u8BDD\u7BA1\u7406\u5DE5\u5177
|
|
|
32946
33058
|
}
|
|
32947
33059
|
}
|
|
32948
33060
|
if (!sessionFileUUID) {
|
|
32949
|
-
const jsonlFiles =
|
|
33061
|
+
const jsonlFiles = fs42.readdirSync(sessionsDir).filter((f) => f.endsWith(".jsonl") && !f.includes(".archived.") && !f.includes(".compaction.")).map((f) => ({ name: f, mtime: fs42.statSync(path42.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
32950
33062
|
if (jsonlFiles.length === 0) {
|
|
32951
33063
|
console.error("\u274C \u627E\u4E0D\u5230\u6D3B\u8DC3\u7684 session JSONL \u6587\u4EF6");
|
|
32952
33064
|
process.exit(1);
|
|
@@ -32954,8 +33066,8 @@ engine7 session \u2014 \u4F1A\u8BDD\u7BA1\u7406\u5DE5\u5177
|
|
|
32954
33066
|
sessionFileUUID = jsonlFiles[0].name.replace(".jsonl", "");
|
|
32955
33067
|
}
|
|
32956
33068
|
let jsonlPath = path42.join(sessionsDir, `${sessionFileUUID}.jsonl`);
|
|
32957
|
-
if (!
|
|
32958
|
-
const jsonlFiles =
|
|
33069
|
+
if (!fs42.existsSync(jsonlPath)) {
|
|
33070
|
+
const jsonlFiles = fs42.readdirSync(sessionsDir).filter((f) => f.endsWith(".jsonl") && !f.includes(".archived.") && !f.includes(".compaction.")).map((f) => ({ name: f, mtime: fs42.statSync(path42.join(sessionsDir, f)).mtimeMs })).sort((a, b) => b.mtime - a.mtime);
|
|
32959
33071
|
if (jsonlFiles.length === 0) {
|
|
32960
33072
|
console.error(`\u274C JSONL \u6587\u4EF6\u4E0D\u5B58\u5728: ${jsonlPath}`);
|
|
32961
33073
|
process.exit(1);
|
|
@@ -32980,7 +33092,7 @@ engine7 session \u2014 \u4F1A\u8BDD\u7BA1\u7406\u5DE5\u5177
|
|
|
32980
33092
|
}
|
|
32981
33093
|
}
|
|
32982
33094
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
32983
|
-
const { readFileSync: readFileSync45, writeFileSync: writeFileSync26, renameSync: renameSync5 } =
|
|
33095
|
+
const { readFileSync: readFileSync45, writeFileSync: writeFileSync26, renameSync: renameSync5 } = fs42;
|
|
32984
33096
|
if (mode === "archive") {
|
|
32985
33097
|
const archiveName = `${sessionFileUUID}.jsonl.archived.${timestamp}`;
|
|
32986
33098
|
renameSync5(jsonlPath, path42.join(sessionsDir, archiveName));
|
|
@@ -33058,11 +33170,11 @@ engine7 session \u2014 \u4F1A\u8BDD\u7BA1\u7406\u5DE5\u5177
|
|
|
33058
33170
|
\u2705 \u6458\u9664 ${stripped} \u884C\u56FE\u7247\u76F8\u5173\u5185\u5BB9`);
|
|
33059
33171
|
}
|
|
33060
33172
|
if (autoRestart) {
|
|
33061
|
-
const realCliPath =
|
|
33173
|
+
const realCliPath = fs42.realpathSync(process.argv[1]);
|
|
33062
33174
|
const cliDir = path42.dirname(realCliPath);
|
|
33063
33175
|
const pkgRoot = path42.resolve(cliDir, "..");
|
|
33064
33176
|
let enginePath = path42.join(pkgRoot, "dist", "main.mjs");
|
|
33065
|
-
if (!
|
|
33177
|
+
if (!fs42.existsSync(enginePath)) {
|
|
33066
33178
|
enginePath = path42.join(cliDir, "main.mjs");
|
|
33067
33179
|
}
|
|
33068
33180
|
console.log(`
|
|
@@ -33105,16 +33217,16 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
|
33105
33217
|
if (!configPath2) {
|
|
33106
33218
|
const defaultCfg = path42.join(cwd, "configs", "main7.json");
|
|
33107
33219
|
const homeCfg = path42.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7", "configs", "main7.json");
|
|
33108
|
-
if (
|
|
33220
|
+
if (fs42.existsSync(defaultCfg)) {
|
|
33109
33221
|
configPath2 = defaultCfg;
|
|
33110
|
-
} else if (
|
|
33222
|
+
} else if (fs42.existsSync(homeCfg)) {
|
|
33111
33223
|
configPath2 = homeCfg;
|
|
33112
33224
|
cwd = path42.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7");
|
|
33113
33225
|
} else {
|
|
33114
33226
|
const ptr = readHomePointer();
|
|
33115
33227
|
if (ptr?.stateDir) {
|
|
33116
33228
|
const ptrCfg = path42.join(ptr.stateDir, "configs", "main7.json");
|
|
33117
|
-
if (
|
|
33229
|
+
if (fs42.existsSync(ptrCfg)) {
|
|
33118
33230
|
configPath2 = ptrCfg;
|
|
33119
33231
|
cwd = ptr.stateDir;
|
|
33120
33232
|
}
|
|
@@ -33139,7 +33251,7 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
|
33139
33251
|
cliMjs: path42.resolve(engine7Bin),
|
|
33140
33252
|
configPath: path42.resolve(configPath2)
|
|
33141
33253
|
});
|
|
33142
|
-
|
|
33254
|
+
fs42.writeFileSync(wrapperPath, wrapperContent);
|
|
33143
33255
|
const startupDir = path42.join(
|
|
33144
33256
|
process.env.APPDATA || path42.join(process.env.USERPROFILE || "", "AppData", "Roaming"),
|
|
33145
33257
|
"Microsoft",
|
|
@@ -33148,7 +33260,7 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
|
33148
33260
|
"Programs",
|
|
33149
33261
|
"Startup"
|
|
33150
33262
|
);
|
|
33151
|
-
|
|
33263
|
+
fs42.mkdirSync(startupDir, { recursive: true });
|
|
33152
33264
|
const vbsPath = path42.join(startupDir, "Engine7.vbs");
|
|
33153
33265
|
const nodeExePath = nodeExe || process.execPath;
|
|
33154
33266
|
const cliMjsPath = path42.resolve(engine7Bin);
|
|
@@ -33168,15 +33280,15 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
|
33168
33280
|
's.Run """' + nodeExePath + '"" ""' + cliMjsPath + '"" start --config ""' + absCfg + '""", 0, False',
|
|
33169
33281
|
""
|
|
33170
33282
|
].join(String.fromCharCode(13) + String.fromCharCode(10));
|
|
33171
|
-
|
|
33283
|
+
fs42.writeFileSync(vbsPath, vbs);
|
|
33172
33284
|
console.log(`\u2705 \u5F00\u673A\u81EA\u542F\u52A8\u5DF2\u6CE8\u518C\uFF08\u542F\u52A8\u6587\u4EF6\u5939: ${vbsPath}\uFF09`);
|
|
33173
33285
|
} else if (process.platform === "darwin") {
|
|
33174
33286
|
const label = "com.engine7.agent";
|
|
33175
33287
|
const plistDir = path42.join(process.env.HOME, "Library", "LaunchAgents");
|
|
33176
|
-
|
|
33288
|
+
fs42.mkdirSync(plistDir, { recursive: true });
|
|
33177
33289
|
const plistPath = path42.join(plistDir, `${label}.plist`);
|
|
33178
33290
|
const localCli = path42.join("node_modules", "engine7", "dist", "cli.mjs");
|
|
33179
|
-
const cliMjs =
|
|
33291
|
+
const cliMjs = fs42.existsSync(localCli) ? path42.resolve(localCli) : path42.join(path42.dirname(path42.dirname(engine7Bin)), "lib", "node_modules", "engine7", "dist", "cli.mjs");
|
|
33180
33292
|
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
33181
33293
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
33182
33294
|
<plist version="1.0">
|
|
@@ -33195,7 +33307,7 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
|
33195
33307
|
<key>KeepAlive</key><true/>
|
|
33196
33308
|
</dict>
|
|
33197
33309
|
</plist>`;
|
|
33198
|
-
|
|
33310
|
+
fs42.writeFileSync(plistPath, plist);
|
|
33199
33311
|
try {
|
|
33200
33312
|
execSync3(`launchctl load "${plistPath}"`, { stdio: "inherit" });
|
|
33201
33313
|
console.log(`\u2705 Mac launchd \u670D\u52A1\u5DF2\u521B\u5EFA\uFF08\u5F00\u673A\u81EA\u542F\u52A8\uFF09`);
|
|
@@ -33207,7 +33319,7 @@ engine7 service \u2014 \u5F00\u673A\u81EA\u542F\u52A8\u7BA1\u7406
|
|
|
33207
33319
|
} else {
|
|
33208
33320
|
const svcName = "engine7";
|
|
33209
33321
|
const svcDir = path42.join(process.env.HOME, ".config", "systemd", "user");
|
|
33210
|
-
|
|
33322
|
+
fs42.mkdirSync(svcDir, { recursive: true });
|
|
33211
33323
|
const svcPath = path42.join(svcDir, `${svcName}.service`);
|
|
33212
33324
|
const svc = `[Unit]
|
|
33213
33325
|
Description=Engine 7 Agent
|
|
@@ -33222,7 +33334,7 @@ RestartSec=10
|
|
|
33222
33334
|
|
|
33223
33335
|
[Install]
|
|
33224
33336
|
WantedBy=default.target`;
|
|
33225
|
-
|
|
33337
|
+
fs42.writeFileSync(svcPath, svc);
|
|
33226
33338
|
try {
|
|
33227
33339
|
execSync3(`systemctl --user daemon-reload`, { stdio: "inherit" });
|
|
33228
33340
|
execSync3(`systemctl --user enable ${svcName}`, { stdio: "inherit" });
|
|
@@ -33248,8 +33360,8 @@ WantedBy=default.target`;
|
|
|
33248
33360
|
execSync3(`schtasks /delete /tn "Engine7" /f`, { stdio: "ignore" });
|
|
33249
33361
|
} catch {
|
|
33250
33362
|
}
|
|
33251
|
-
if (
|
|
33252
|
-
|
|
33363
|
+
if (fs42.existsSync(vbsPath)) {
|
|
33364
|
+
fs42.rmSync(vbsPath, { force: true });
|
|
33253
33365
|
console.log(`\u2705 \u5F00\u673A\u81EA\u542F\u52A8\u5DF2\u79FB\u9664\uFF08${vbsPath}\uFF09`);
|
|
33254
33366
|
} else {
|
|
33255
33367
|
console.log("\uFF08\u5F00\u673A\u81EA\u542F\u52A8\u672C\u6765\u5C31\u6CA1\u6CE8\u518C\uFF09");
|
|
@@ -33261,7 +33373,7 @@ WantedBy=default.target`;
|
|
|
33261
33373
|
} catch {
|
|
33262
33374
|
}
|
|
33263
33375
|
try {
|
|
33264
|
-
|
|
33376
|
+
fs42.unlinkSync(plistPath);
|
|
33265
33377
|
} catch {
|
|
33266
33378
|
}
|
|
33267
33379
|
console.log(`\u2705 Mac launchd \u670D\u52A1\u5DF2\u5220\u9664`);
|
|
@@ -33272,7 +33384,7 @@ WantedBy=default.target`;
|
|
|
33272
33384
|
}
|
|
33273
33385
|
const svcPath = path42.join(process.env.HOME, ".config", "systemd", "user", "engine7.service");
|
|
33274
33386
|
try {
|
|
33275
|
-
|
|
33387
|
+
fs42.unlinkSync(svcPath);
|
|
33276
33388
|
} catch {
|
|
33277
33389
|
}
|
|
33278
33390
|
try {
|
|
@@ -33292,10 +33404,10 @@ WantedBy=default.target`;
|
|
|
33292
33404
|
"Startup",
|
|
33293
33405
|
"Engine7.vbs"
|
|
33294
33406
|
);
|
|
33295
|
-
console.log(
|
|
33407
|
+
console.log(fs42.existsSync(vbsPath) ? `\u2705 \u5DF2\u6CE8\u518C\uFF08\u542F\u52A8\u6587\u4EF6\u5939\uFF09: ${vbsPath}` : "\u274C \u672A\u6CE8\u518C");
|
|
33296
33408
|
} else if (process.platform === "darwin") {
|
|
33297
33409
|
const plistPath = path42.join(process.env.HOME, "Library", "LaunchAgents", "com.engine7.agent.plist");
|
|
33298
|
-
if (
|
|
33410
|
+
if (fs42.existsSync(plistPath)) {
|
|
33299
33411
|
console.log("\u2705 \u5DF2\u5B89\u88C5\uFF08launchd\uFF09");
|
|
33300
33412
|
} else {
|
|
33301
33413
|
console.log("\u274C \u672A\u5B89\u88C5");
|
|
@@ -33328,8 +33440,8 @@ WantedBy=default.target`;
|
|
|
33328
33440
|
console.log(`
|
|
33329
33441
|
\u{1F680} engine7 init`);
|
|
33330
33442
|
console.log(` state-dir: ${opts.stateDir}`);
|
|
33331
|
-
if (
|
|
33332
|
-
const files =
|
|
33443
|
+
if (fs42.existsSync(opts.stateDir) && !opts.dryRun) {
|
|
33444
|
+
const files = fs42.readdirSync(opts.stateDir);
|
|
33333
33445
|
if (files.length > 0) {
|
|
33334
33446
|
if (opts.force) {
|
|
33335
33447
|
if (looksLikeAppInstall(opts.stateDir)) {
|
|
@@ -33342,10 +33454,10 @@ WantedBy=default.target`;
|
|
|
33342
33454
|
}
|
|
33343
33455
|
console.log(`
|
|
33344
33456
|
\u26A0\uFE0F --force: \u6E05\u7A7A\u5DF2\u6709\u76EE\u5F55 ${opts.stateDir}`);
|
|
33345
|
-
|
|
33457
|
+
fs42.rmSync(opts.stateDir, { recursive: true, force: true });
|
|
33346
33458
|
} else {
|
|
33347
33459
|
const existingConfig = path42.join(opts.stateDir, "configs", "main7.json");
|
|
33348
|
-
if (
|
|
33460
|
+
if (fs42.existsSync(existingConfig)) {
|
|
33349
33461
|
console.log(`
|
|
33350
33462
|
\u267B\uFE0F \u68C0\u6D4B\u5230\u5DF2\u6709\u914D\u7F6E: ${existingConfig}`);
|
|
33351
33463
|
console.log(` \u2192 \u590D\u8DD1\u6A21\u5F0F\uFF1A\u663E\u793A\u73B0\u6709\u914D\u7F6E\uFF0C\u56DE\u8F66\u4FDD\u7559\uFF0C\u6539\u4E86\u624D\u751F\u6548\uFF08\u4E0D\u4F1A\u6E05\u7A7A\u76EE\u5F55\uFF09`);
|
|
@@ -33431,7 +33543,7 @@ WantedBy=default.target`;
|
|
|
33431
33543
|
if (!PHOTO_EXTS.includes(ext)) {
|
|
33432
33544
|
throw new Error(`\u7167\u7247\u683C\u5F0F\u4E0D\u652F\u6301\uFF1A${ext || "(\u6CA1\u6709\u540E\u7F00)"}\u3002\u8BF7\u7528 PNG / JPEG / WebP\u3002`);
|
|
33433
33545
|
}
|
|
33434
|
-
if (!
|
|
33546
|
+
if (!fs42.existsSync(src)) {
|
|
33435
33547
|
throw new Error(`\u7167\u7247\u4E0D\u5B58\u5728\uFF1A${src}`);
|
|
33436
33548
|
}
|
|
33437
33549
|
const dims = dimsOf2(src);
|
|
@@ -33454,7 +33566,7 @@ WantedBy=default.target`;
|
|
|
33454
33566
|
dryRun(tree);
|
|
33455
33567
|
const skillsSrc = findTemplateDir("skills");
|
|
33456
33568
|
if (skillsSrc) {
|
|
33457
|
-
const skills =
|
|
33569
|
+
const skills = fs42.readdirSync(skillsSrc);
|
|
33458
33570
|
for (const s of skills) {
|
|
33459
33571
|
console.log(` \u{1F4C1} ${path42.join(opts.stateDir, "workspace", "skills", s)}`);
|
|
33460
33572
|
}
|
|
@@ -33462,14 +33574,14 @@ WantedBy=default.target`;
|
|
|
33462
33574
|
} else {
|
|
33463
33575
|
if (values.chatMode === "auto") {
|
|
33464
33576
|
try {
|
|
33465
|
-
|
|
33577
|
+
fs42.unlinkSync(path42.join(opts.stateDir, "workspace", ".work-mode"));
|
|
33466
33578
|
} catch {
|
|
33467
33579
|
}
|
|
33468
33580
|
}
|
|
33469
33581
|
if (photoSrc && values.selfiePhotoRelPath) {
|
|
33470
33582
|
const dest = path42.join(opts.stateDir, "workspace", values.selfiePhotoRelPath);
|
|
33471
|
-
|
|
33472
|
-
|
|
33583
|
+
fs42.mkdirSync(path42.dirname(dest), { recursive: true });
|
|
33584
|
+
fs42.copyFileSync(photoSrc, dest);
|
|
33473
33585
|
console.log(` \u{1F5BC} \u5F62\u8C61: ${dest}`);
|
|
33474
33586
|
}
|
|
33475
33587
|
if (headlessEmit) headlessEmit({ event: "progress", step: "create_dirs" });
|
|
@@ -33499,8 +33611,8 @@ WantedBy=default.target`;
|
|
|
33499
33611
|
const skillsSrc = findTemplateDir("skills");
|
|
33500
33612
|
if (skillsSrc) {
|
|
33501
33613
|
const skillsDest = path42.join(opts.stateDir, "workspace", "skills");
|
|
33502
|
-
|
|
33503
|
-
const skills =
|
|
33614
|
+
fs42.mkdirSync(skillsDest, { recursive: true });
|
|
33615
|
+
const skills = fs42.readdirSync(skillsSrc);
|
|
33504
33616
|
for (const s of skills) {
|
|
33505
33617
|
copyDirRecursive(path42.join(skillsSrc, s), path42.join(skillsDest, s));
|
|
33506
33618
|
console.log(` \u{1F4E6} skill: ${s}`);
|
|
@@ -33511,7 +33623,7 @@ WantedBy=default.target`;
|
|
|
33511
33623
|
`);
|
|
33512
33624
|
const homePointer = path42.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7.json");
|
|
33513
33625
|
const pointerData = { stateDir: opts.stateDir };
|
|
33514
|
-
|
|
33626
|
+
fs42.writeFileSync(homePointer, JSON.stringify(pointerData, null, 2) + "\n");
|
|
33515
33627
|
console.log(` \u{1F4C4} ${homePointer}\uFF08\u4ECE\u4EFB\u610F\u76EE\u5F55\u90FD\u80FD\u627E\u5230\u6B64 agent\uFF09`);
|
|
33516
33628
|
console.log(`\u4E0B\u4E00\u6B65\uFF1A`);
|
|
33517
33629
|
console.log(` 1. \u68C0\u67E5\u5E76\u4FEE\u6539 ${opts.stateDir}/configs/main7.json`);
|
|
@@ -33524,14 +33636,14 @@ WantedBy=default.target`;
|
|
|
33524
33636
|
}
|
|
33525
33637
|
}
|
|
33526
33638
|
function copyDirRecursive(src, dest) {
|
|
33527
|
-
|
|
33528
|
-
for (const entry of
|
|
33639
|
+
fs42.mkdirSync(dest, { recursive: true });
|
|
33640
|
+
for (const entry of fs42.readdirSync(src, { withFileTypes: true })) {
|
|
33529
33641
|
const srcPath = path42.join(src, entry.name);
|
|
33530
33642
|
const destPath = path42.join(dest, entry.name);
|
|
33531
33643
|
if (entry.isDirectory()) {
|
|
33532
33644
|
copyDirRecursive(srcPath, destPath);
|
|
33533
33645
|
} else {
|
|
33534
|
-
|
|
33646
|
+
fs42.copyFileSync(srcPath, destPath);
|
|
33535
33647
|
}
|
|
33536
33648
|
}
|
|
33537
33649
|
}
|
|
@@ -33542,14 +33654,14 @@ function findTemplateDir(name) {
|
|
|
33542
33654
|
path42.join(process.cwd(), "templates", name)
|
|
33543
33655
|
];
|
|
33544
33656
|
for (const p of candidates) {
|
|
33545
|
-
if (
|
|
33657
|
+
if (fs42.existsSync(p)) return p;
|
|
33546
33658
|
}
|
|
33547
33659
|
return null;
|
|
33548
33660
|
}
|
|
33549
33661
|
function readHomePointer() {
|
|
33550
33662
|
const ptrPath = path42.join(process.env.HOME || process.env.USERPROFILE || ".", ".engine7.json");
|
|
33551
33663
|
try {
|
|
33552
|
-
return JSON.parse(
|
|
33664
|
+
return JSON.parse(fs42.readFileSync(ptrPath, "utf-8"));
|
|
33553
33665
|
} catch {
|
|
33554
33666
|
return null;
|
|
33555
33667
|
}
|