ylib-syim 0.0.2 → 0.0.3

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/bridges/main.ts CHANGED
@@ -56,7 +56,7 @@ type RuntimeBotStatus = {
56
56
  };
57
57
 
58
58
  const runtimeStatusRegistry = new Map<string, RuntimeBotStatus>();
59
- let loadedConfigForRuntime: Record<string, unknown> | null = null;
59
+ let loadedConfigForRuntime: Record<string, unknown> | null = { "channels": {}, "bindings": [] } as { channels: Record<string, unknown>; bindings: any[] };;
60
60
  let loadedConfigPathForRuntime: string | null = null;
61
61
  let configVersionHash = "";
62
62
  let configVersionUpdatedAt = nowIso();
@@ -67,6 +67,73 @@ let dingtalkBridgeStarted = false;
67
67
  let dingtalkBridgeStarting = false;
68
68
  let larkBridgeStarted = false;
69
69
  let larkBridgeStarting = false;
70
+ let pluginTempHomeDir: string | null = null;
71
+
72
+ function pluginHomeConfigPayload(
73
+ cfg: Record<string, unknown>,
74
+ ): Record<string, unknown> {
75
+ return {
76
+ channels: Object.prototype.hasOwnProperty.call(cfg, "channels")
77
+ ? cfg.channels
78
+ : {},
79
+ bindings: Object.prototype.hasOwnProperty.call(cfg, "bindings")
80
+ ? cfg.bindings
81
+ : [],
82
+ };
83
+ }
84
+
85
+ /** 远端配置拉取成功时:临时 HOME + ~/.syim/syim.json 与 ~/.openclaw/openclaw.json(内容一致)。 */
86
+ function applyRemoteRuntimeConfigToPluginHome(): void {
87
+ if (
88
+ !loadedConfigForRuntime ||
89
+ typeof loadedConfigForRuntime !== "object" ||
90
+ Array.isArray(loadedConfigForRuntime)
91
+ ) {
92
+ return;
93
+ }
94
+ const slice = pluginHomeConfigPayload(loadedConfigForRuntime);
95
+ try {
96
+ if (!pluginTempHomeDir) {
97
+ pluginTempHomeDir = fs.mkdtempSync(
98
+ path.join(os.tmpdir(), "im-agent-hub-plugin-home-"),
99
+ );
100
+ }
101
+ const payload = JSON.stringify(slice, null, 2);
102
+ const syimDir = path.join(pluginTempHomeDir, ".syim");
103
+ const syimPath = path.join(syimDir, "syim.json");
104
+ if (!fs.existsSync(syimDir)) {
105
+ fs.mkdirSync(syimDir, { recursive: true });
106
+ } else {
107
+ console.log(`[bridges/main] plugin temp HOME syim dir exists: ${syimDir}`);
108
+ }
109
+ if (!fs.existsSync(syimPath)) {
110
+ fs.writeFileSync(syimPath, payload, "utf-8");
111
+ } else {
112
+ console.log(`[bridges/main] plugin temp HOME syim dir exists: ${syimPath}`);
113
+ }
114
+ const openclawDir = path.join(pluginTempHomeDir, ".openclaw");
115
+ const openclawPath = path.join(openclawDir, "openclaw.json");
116
+ if (!fs.existsSync(openclawDir)) {
117
+ fs.mkdirSync(openclawDir, { recursive: true });
118
+ } else {
119
+ console.log(`[bridges/main] plugin temp HOME openclaw dir exists: ${openclawDir}`);
120
+ }
121
+ if (!fs.existsSync(openclawPath)) {
122
+ fs.writeFileSync(openclawPath, payload, "utf-8");
123
+ } else {
124
+ console.log(`[bridges/main] plugin temp HOME openclaw dir exists: ${openclawPath}`);
125
+ }
126
+ process.env.HOME = pluginTempHomeDir;
127
+ if (process.platform === "win32") process.env.USERPROFILE = pluginTempHomeDir;
128
+ console.log(
129
+ `[bridges/main] plugin temp HOME ready home=${pluginTempHomeDir} syim=${syimPath} openclaw=${openclawPath}`,
130
+ );
131
+ } catch (err) {
132
+ console.error(
133
+ `[bridges/main] plugin temp HOME failed: ${(err as Error).message}`,
134
+ );
135
+ }
136
+ }
70
137
 
71
138
  function nowIso(): string {
72
139
  return new Date().toISOString();
@@ -529,7 +596,7 @@ async function probeAndRefreshStatuses(): Promise<void> {
529
596
  if (configuredIds.length === 0) {
530
597
  clearPlatformStatuses("dingtalk");
531
598
  } else {
532
- const dingtalkMod = (await import("@ylib/dingtalk-connector")) as Record<
599
+ const dingtalkMod = (await import("ylib-dingtalk-connector")) as Record<
533
600
  string,
534
601
  unknown
535
602
  >;
@@ -691,7 +758,7 @@ async function probeAndRefreshStatuses(): Promise<void> {
691
758
  if (configuredIds.length === 0) {
692
759
  clearPlatformStatuses("feishu");
693
760
  } else {
694
- const larkMod = (await import("@ylib/openclaw-lark")) as Record<
761
+ const larkMod = (await import("ylib-openclaw-lark")) as Record<
695
762
  string,
696
763
  unknown
697
764
  >;
@@ -782,6 +849,7 @@ async function pullRuntimeConfigFromPython(forceFull = false): Promise<{
782
849
  error?: string;
783
850
  dropped_fields?: Array<{ channel: string; accountId: string; field: string }>;
784
851
  }> {
852
+ applyRemoteRuntimeConfigToPluginHome();
785
853
  if (!runtimeConfigPullUrl) {
786
854
  return {
787
855
  ok: false,
@@ -872,6 +940,7 @@ async function pullRuntimeConfigFromPython(forceFull = false): Promise<{
872
940
  loadedConfigPathForRuntime,
873
941
  );
874
942
  updateConfigVersion(normalizedResult.normalized);
943
+ applyRemoteRuntimeConfigToPluginHome();
875
944
  markConfiguredBotsAsConnecting(normalizedResult.normalized);
876
945
  await probeAndRefreshStatuses();
877
946
 
@@ -1167,7 +1236,7 @@ async function getPluginSchemas(): Promise<Array<Record<string, unknown>>> {
1167
1236
  const whitelist = readEffectiveWhitelist();
1168
1237
  const result: Array<Record<string, unknown>> = [];
1169
1238
  try {
1170
- const dingtalkMod = (await import("@ylib/dingtalk-connector")) as Record<
1239
+ const dingtalkMod = (await import("ylib-dingtalk-connector")) as Record<
1171
1240
  string,
1172
1241
  unknown
1173
1242
  >;
@@ -1196,7 +1265,7 @@ async function getPluginSchemas(): Promise<Array<Record<string, unknown>>> {
1196
1265
  });
1197
1266
  }
1198
1267
  try {
1199
- const larkMod = (await import("@ylib/openclaw-lark")) as Record<
1268
+ const larkMod = (await import("ylib-openclaw-lark")) as Record<
1200
1269
  string,
1201
1270
  unknown
1202
1271
  >;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ylib-syim",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "多 IM / 多 Agent 的会话路由与上下文管理(支持 /new)",
5
5
  "type": "module",
6
6
  "exports": {
@@ -41,13 +41,12 @@
41
41
  "dependencies": {
42
42
  "@ffmpeg-installer/ffmpeg": "^1.1.0",
43
43
  "ylib-dingtalk-connector": "0.7.10-beata.2",
44
- "ylib-openclaw-lark": "2026.3.17-beata.2",
44
+ "ylib-openclaw-lark": "2026.3.17-beata.3",
45
45
  "axios": "^1.6.0",
46
46
  "dingtalk-stream": "^2.1.4",
47
47
  "fluent-ffmpeg": "^2.1.3",
48
48
  "form-data": "^4.0.0",
49
49
  "mammoth": "^1.8.0",
50
- "openclaw": "2026.2.26",
51
50
  "pdf-parse": "^1.1.1",
52
51
  "tsx": "^4.21.0"
53
52
  },
@@ -288,39 +288,6 @@ function buildCfg(): {
288
288
  return { cfg, gatewayBaseUrl, gatewayToken };
289
289
  }
290
290
 
291
- /**
292
- * 方案 A:在导入插件前设置临时 HOME,使插件内读取 ~/.syim/syim.json 时实际读到当前项目 syim.json(用于 bindings 等)。
293
- * 不劫持 fs,仅改环境变量 + 临时目录内放一份配置(拷贝),进程内 os.homedir() 指向该临时目录。
294
- */
295
- function setupOpenClawConfigForPlugin(): void {
296
- const projectRoot = getProjectRoot();
297
- const projectConfigPath = path.join(projectRoot, "syim.json");
298
- if (!fs.existsSync(projectConfigPath)) return;
299
-
300
- const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-bridge-"));
301
- const openclawDir = path.join(tempDir, ".syim");
302
- fs.mkdirSync(openclawDir, { recursive: true });
303
- const targetPath = path.join(openclawDir, "syim.json");
304
- try {
305
- fs.copyFileSync(projectConfigPath, targetPath);
306
- } catch (err) {
307
- console.warn(
308
- "[dingtalk-stdio-bridge] 拷贝 syim.json 到临时目录失败,插件将使用系统 ~/.syim:",
309
- (err as Error).message,
310
- );
311
- try {
312
- fs.rmSync(tempDir, { recursive: true, force: true });
313
- } catch (_) {}
314
- return;
315
- }
316
- process.env.HOME = tempDir;
317
- if (process.platform === "win32") process.env.USERPROFILE = tempDir;
318
- console.log(
319
- "[dingtalk-stdio-bridge] 已设置 HOME 为临时目录,插件将读取当前项目 syim.json(bindings 等):",
320
- projectConfigPath,
321
- );
322
- }
323
-
324
291
  type ResolvedAccount = {
325
292
  accountId: string;
326
293
  config: Record<string, unknown>;
@@ -437,8 +404,6 @@ async function startConfiguredAccounts(): Promise<void> {
437
404
  }
438
405
 
439
406
  async function main(): Promise<void> {
440
- setupOpenClawConfigForPlugin();
441
-
442
407
  const { cfg, gatewayBaseUrl, gatewayToken } = buildCfg();
443
408
 
444
409
  // 确保插件 getConfig(cfg) 拿到的对象上就有 gatewayBaseUrl:直接写入 cfg.channels[CHANNEL_KEY]
@@ -303,50 +303,6 @@ function buildCfg(): {
303
303
  return { cfg, gatewayBaseUrl, gatewayToken };
304
304
  }
305
305
 
306
- // ---------------------------------------------------------------------------
307
- // 设置临时 HOME(使插件内读取 ~/.syim/syim.json 时能读到 bindings)
308
- // ---------------------------------------------------------------------------
309
-
310
- function setupOpenClawConfigForPlugin(): void {
311
- const projectRoot = getProjectRoot();
312
- const projectConfigPath = path.join(projectRoot, "syim.json");
313
- if (!fs.existsSync(projectConfigPath)) return;
314
-
315
- const tempDir = fs.mkdtempSync(
316
- path.join(os.tmpdir(), "openclaw-lark-bridge-"),
317
- );
318
- const openclawDir = path.join(tempDir, ".syim");
319
- fs.mkdirSync(openclawDir, { recursive: true });
320
- const targetPath = path.join(openclawDir, "syim.json");
321
- try {
322
- // 只保留 feishu channel 和 bindings,去掉其他 channel(避免飞书插件 schema 校验报错)
323
- const raw = JSON.parse(
324
- fs.readFileSync(projectConfigPath, "utf-8"),
325
- ) as Record<string, unknown>;
326
- const channels = raw.channels as Record<string, unknown> | undefined;
327
- const feishuOnly: Record<string, unknown> = {
328
- ...(channels?.feishu ? { channels: { feishu: channels.feishu } } : {}),
329
- ...(raw.bindings ? { bindings: raw.bindings } : {}),
330
- };
331
- fs.writeFileSync(targetPath, JSON.stringify(feishuOnly, null, 2), "utf-8");
332
- } catch (err) {
333
- console.warn(
334
- "[lark-stdio-bridge] 拷贝 syim.json 到临时目录失败:",
335
- (err as Error).message,
336
- );
337
- try {
338
- fs.rmSync(tempDir, { recursive: true, force: true });
339
- } catch (_) {}
340
- return;
341
- }
342
- process.env.HOME = tempDir;
343
- if (process.platform === "win32") process.env.USERPROFILE = tempDir;
344
- console.log(
345
- "[lark-stdio-bridge] 已设置 HOME 为临时目录,bindings 将从当前项目 syim.json 读取:",
346
- projectConfigPath,
347
- );
348
- }
349
-
350
306
  // ---------------------------------------------------------------------------
351
307
  // 最小化 runtime mock
352
308
  // ---------------------------------------------------------------------------
@@ -483,8 +439,6 @@ function startMonitorLoop(): void {
483
439
  // ---------------------------------------------------------------------------
484
440
 
485
441
  async function main(): Promise<void> {
486
- setupOpenClawConfigForPlugin();
487
-
488
442
  const { cfg, gatewayBaseUrl } = buildCfg();
489
443
  const accountIds = listFeishuAccountIds(cfg);
490
444
 
@@ -495,7 +449,7 @@ async function main(): Promise<void> {
495
449
  (channelEntry as Record<string, unknown>).gatewayBaseUrl = gatewayBaseUrl;
496
450
  }
497
451
 
498
- console.log("[lark-stdio-bridge] 加载 @ylib/openclaw-lark ...");
452
+ console.log("[lark-stdio-bridge] 加载 ylib-openclaw-lark ...");
499
453
 
500
454
  // 动态导入(需先运行 npm install 安装依赖)
501
455
  const larkModule = await import("ylib-openclaw-lark");