@ganglion/xacpx 0.8.1 → 0.8.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/dist/cli.js CHANGED
@@ -2023,7 +2023,7 @@ var require_lib = __commonJS((exports, module) => {
2023
2023
 
2024
2024
  // src/util/private-file.ts
2025
2025
  import { chmod, mkdir, writeFile } from "node:fs/promises";
2026
- import { chmodSync, mkdirSync, writeFileSync } from "node:fs";
2026
+ import { chmodSync, mkdirSync as mkdirSync2, writeFileSync } from "node:fs";
2027
2027
  import { dirname } from "node:path";
2028
2028
  async function writePrivateFileAtomic(path, content) {
2029
2029
  await mkdir(dirname(path), { recursive: true });
@@ -2057,7 +2057,7 @@ async function writePrivateFileAtomic(path, content) {
2057
2057
  }
2058
2058
  }
2059
2059
  function writePrivateFileSync(path, content, deps = {}) {
2060
- mkdirSync(dirname(path), { recursive: true });
2060
+ mkdirSync2(dirname(path), { recursive: true });
2061
2061
  const platform = deps.platform ?? process.platform;
2062
2062
  const atomicWrite = deps.atomicWrite ?? ((p, c) => import_write_file_atomic.default.sync(p, c, { mode: PRIVATE_FILE_MODE, encoding: "utf8", fsync: true }));
2063
2063
  try {
@@ -2174,6 +2174,21 @@ var init_workspace_path = __esm(() => {
2174
2174
  init_path();
2175
2175
  });
2176
2176
 
2177
+ // src/plugins/plugin-renames.ts
2178
+ function normalizePluginPackageName(packageName) {
2179
+ return LEGACY_PLUGIN_PACKAGE_RENAMES.get(packageName) ?? packageName;
2180
+ }
2181
+ function isLegacyPluginPackageName(packageName) {
2182
+ return LEGACY_PLUGIN_PACKAGE_RENAMES.has(packageName);
2183
+ }
2184
+ var LEGACY_PLUGIN_PACKAGE_RENAMES;
2185
+ var init_plugin_renames = __esm(() => {
2186
+ LEGACY_PLUGIN_PACKAGE_RENAMES = new Map([
2187
+ ["@ganglion/weacpx-channel-feishu", "@ganglion/xacpx-channel-feishu"],
2188
+ ["@ganglion/weacpx-channel-yuanbao", "@ganglion/xacpx-channel-yuanbao"]
2189
+ ]);
2190
+ });
2191
+
2177
2192
  // src/config/resolve-agent-command.ts
2178
2193
  function resolveAgentCommand(driver, command) {
2179
2194
  if (!command) {
@@ -2395,7 +2410,8 @@ function parsePluginConfig(raw, index) {
2395
2410
  if (!isRecord(raw)) {
2396
2411
  throw new Error(`plugins[${index}] must be an object`);
2397
2412
  }
2398
- const name = typeof raw.name === "string" ? raw.name.trim() : "";
2413
+ const rawName = typeof raw.name === "string" ? raw.name.trim() : "";
2414
+ const name = normalizePluginPackageName(rawName);
2399
2415
  if (!name) {
2400
2416
  throw new Error(`plugins[${index}].name must be a non-empty string`);
2401
2417
  }
@@ -2417,15 +2433,26 @@ function parsePlugins(rawPlugins) {
2417
2433
  if (!Array.isArray(rawPlugins)) {
2418
2434
  throw new Error("plugins must be an array");
2419
2435
  }
2420
- const parsed = rawPlugins.map((entry, index) => parsePluginConfig(entry, index));
2421
- const names = new Set;
2436
+ const parsed = rawPlugins.map((entry, index) => ({
2437
+ plugin: parsePluginConfig(entry, index),
2438
+ originalName: isRecord(entry) && typeof entry.name === "string" ? entry.name.trim() : ""
2439
+ }));
2440
+ const pluginsByName = new Map;
2422
2441
  for (const entry of parsed) {
2423
- if (names.has(entry.name)) {
2442
+ const existing = pluginsByName.get(entry.plugin.name);
2443
+ if (!existing) {
2444
+ pluginsByName.set(entry.plugin.name, entry);
2445
+ continue;
2446
+ }
2447
+ const hasLegacyName = isLegacyPluginPackageName(existing.originalName) || isLegacyPluginPackageName(entry.originalName);
2448
+ if (!hasLegacyName) {
2424
2449
  throw new Error("plugins names must be unique");
2425
2450
  }
2426
- names.add(entry.name);
2451
+ if (isLegacyPluginPackageName(existing.originalName) && !isLegacyPluginPackageName(entry.originalName)) {
2452
+ pluginsByName.set(entry.plugin.name, entry);
2453
+ }
2427
2454
  }
2428
- return parsed;
2455
+ return Array.from(pluginsByName.values()).map((entry) => entry.plugin);
2429
2456
  }
2430
2457
  function parseRuntimeChannelConfig(raw, index) {
2431
2458
  if (!isRecord(raw)) {
@@ -2500,6 +2527,7 @@ function parseOrchestrationConfig(raw) {
2500
2527
  var DEFAULT_PERF_LOG_CONFIG, DEFAULT_LOGGING_CONFIG, DEFAULT_PERMISSION_MODE = "approve-all", DEFAULT_NON_INTERACTIVE_PERMISSIONS = "deny", DEFAULT_QUEUE_OWNER_TTL_SECONDS = 1800, DEFAULT_CHANNEL_CONFIG, DEFAULT_ORCHESTRATION_CONFIG, DEFAULT_LATER_CONFIG;
2501
2528
  var init_load_config = __esm(() => {
2502
2529
  init_workspace_path();
2530
+ init_plugin_renames();
2503
2531
  DEFAULT_PERF_LOG_CONFIG = {
2504
2532
  enabled: false,
2505
2533
  maxSizeBytes: 5 * 1024 * 1024,
@@ -31114,24 +31142,24 @@ import { fileURLToPath as fileURLToPath7 } from "node:url";
31114
31142
 
31115
31143
  // src/runtime/migrate-core-home.ts
31116
31144
  init_core_home();
31117
- import { cpSync, existsSync as existsSync2, readFileSync } from "node:fs";
31145
+ import { copyFileSync, cpSync, existsSync as existsSync2, mkdirSync, readFileSync } from "node:fs";
31118
31146
  import { join as join2 } from "node:path";
31119
31147
  function migrateCoreHome(home, deps = {}) {
31120
31148
  const log = deps.log ?? ((message) => console.error(message));
31121
31149
  const isProcessAlive = deps.isProcessAlive ?? defaultIsProcessAlive;
31122
31150
  const primary = join2(home, CORE_HOME_DIR_NAME);
31123
- if (existsSync2(primary)) {
31124
- return { migrated: false, reason: "already-current" };
31125
- }
31126
31151
  const legacy = join2(home, CORE_HOME_LEGACY_DIR_NAME);
31127
31152
  if (!existsSync2(legacy)) {
31128
- return { migrated: false, reason: "no-legacy" };
31153
+ return existsSync2(primary) ? { migrated: false, reason: "already-current" } : { migrated: false, reason: "no-legacy" };
31129
31154
  }
31130
31155
  const legacyPid = readLegacyDaemonPid(legacy);
31131
31156
  if (legacyPid !== null && isProcessAlive(legacyPid)) {
31132
31157
  log(`检测到运行中的旧守护进程 (pid ${legacyPid}),暂不迁移 ${legacy} → ${primary};` + `请先停止守护进程(weacpx stop / xacpx stop)后重试,期间仍使用旧目录。`);
31133
31158
  return { migrated: false, reason: "daemon-running", from: legacy };
31134
31159
  }
31160
+ if (existsSync2(primary)) {
31161
+ return supplementMissingCoreFiles({ legacy, primary, log });
31162
+ }
31135
31163
  try {
31136
31164
  cpSync(legacy, primary, { recursive: true });
31137
31165
  log(`已将状态目录从 ${legacy} 复制到 ${primary}(旧目录保留为备份,可手动删除)。`);
@@ -31142,6 +31170,28 @@ function migrateCoreHome(home, deps = {}) {
31142
31170
  return { migrated: false, reason: "failed", from: legacy };
31143
31171
  }
31144
31172
  }
31173
+ function supplementMissingCoreFiles(input) {
31174
+ const copied = [];
31175
+ for (const fileName of ["config.json", "state.json"]) {
31176
+ const from = join2(input.legacy, fileName);
31177
+ const to = join2(input.primary, fileName);
31178
+ if (!existsSync2(from) || existsSync2(to))
31179
+ continue;
31180
+ try {
31181
+ mkdirSync(input.primary, { recursive: true });
31182
+ copyFileSync(from, to);
31183
+ copied.push(fileName);
31184
+ } catch (error) {
31185
+ const detail = error instanceof Error ? error.message : String(error);
31186
+ input.log(`补迁移 ${from} → ${to} 失败,已跳过:${detail}`);
31187
+ }
31188
+ }
31189
+ if (copied.length === 0) {
31190
+ return { migrated: false, reason: "already-current" };
31191
+ }
31192
+ input.log(`已从旧目录补迁移 ${copied.join(", ")} 到 ${input.primary}(未覆盖任何现有文件)。`);
31193
+ return { migrated: true, reason: "supplemented", from: input.legacy, to: input.primary };
31194
+ }
31145
31195
  function readLegacyDaemonPid(legacyHome) {
31146
31196
  try {
31147
31197
  const content = readFileSync(join2(legacyHome, "runtime", "daemon.pid"), "utf8");
@@ -46175,6 +46225,7 @@ async function inspectPlugins(input) {
46175
46225
 
46176
46226
  // src/plugins/plugin-cli.ts
46177
46227
  init_known_plugins();
46228
+ init_plugin_renames();
46178
46229
  function looksLikePath(spec) {
46179
46230
  return spec === "." || spec.startsWith("./") || spec.startsWith("../") || spec.startsWith("/") || spec.startsWith(".\\") || spec.startsWith("..\\") || spec.startsWith("\\") || /^[a-zA-Z]:[\\/]/.test(spec) || isAbsolute(spec);
46180
46231
  }
@@ -46276,7 +46327,8 @@ function parseRestartAndVersionFlags(args) {
46276
46327
  return { ok: true, rest, restart: restart ? "restart" : noRestart ? "no-restart" : "ask", ...version2 ? { version: version2 } : {} };
46277
46328
  }
46278
46329
  function findPlugin(plugins, name) {
46279
- return plugins.find((plugin) => plugin.name === name);
46330
+ const normalizedName = normalizePluginPackageName(name);
46331
+ return plugins.find((plugin) => normalizePluginPackageName(plugin.name) === normalizedName);
46280
46332
  }
46281
46333
  async function validateInstalledPluginDefault(packageName, pluginHome) {
46282
46334
  const moduleValue = await importPluginFromHome(packageName, pluginHome);
@@ -46363,7 +46415,7 @@ async function addPlugin(packageSpec, rawArgs, deps) {
46363
46415
  deps.print(`插件 ${packageSpec} 安装失败:${describeError(error2)}`);
46364
46416
  return 1;
46365
46417
  }
46366
- const recordedName = looksLikePath(packageSpec) ? await resolveLocalPluginName(installSpec, pluginHome, namesBeforeInstall) : packageSpec;
46418
+ const recordedName = normalizePluginPackageName(looksLikePath(packageSpec) ? await resolveLocalPluginName(installSpec, pluginHome, namesBeforeInstall) : packageSpec);
46367
46419
  const validate = deps.validateInstalledPlugin ?? ((name) => validateInstalledPluginDefault(name, pluginHome));
46368
46420
  let summary;
46369
46421
  try {
@@ -46381,7 +46433,7 @@ async function addPlugin(packageSpec, rawArgs, deps) {
46381
46433
  enabled: true
46382
46434
  };
46383
46435
  if (existing) {
46384
- config2.plugins = config2.plugins.map((entry) => entry.name === recordedName ? next : entry);
46436
+ config2.plugins = config2.plugins.filter((entry) => normalizePluginPackageName(entry.name) !== recordedName).concat(next);
46385
46437
  } else {
46386
46438
  config2.plugins = [...config2.plugins, next];
46387
46439
  }
@@ -0,0 +1,2 @@
1
+ export declare function normalizePluginPackageName(packageName: string): string;
2
+ export declare function isLegacyPluginPackageName(packageName: string): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ganglion/xacpx",
3
- "version": "0.8.1",
3
+ "version": "0.8.3",
4
4
  "description": "随时随地通过聊天频道(微信 / 飞书 / 元宝等)远程控制 `acpx` 上的 Claude Code、Codex 等 Agents。",
5
5
  "keywords": [
6
6
  "acpx",