@ganglion/xacpx 0.9.0 → 0.9.2

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.
@@ -8,4 +8,4 @@ export interface CommandHint {
8
8
  * 从 HELP_TOPICS 派生输入框命令提示(单一真源,与 /help 同源不漂移)。
9
9
  * 额外置顶 /help。
10
10
  */
11
- export declare function listWeacpxCommandHints(): CommandHint[];
11
+ export declare function listXacpxCommandHints(): CommandHint[];
@@ -1,3 +1,3 @@
1
- export declare const WEACPX_KNOWN_COMMAND_PREFIXES: readonly ["/help", "/agents", "/workspaces", "/sessions", "/tasks", "/status", "/cancel", "/stop", "/clear", "/mode", "/replymode", "/config", "/permission", "/pm", "/session", "/ss", "/ssn", "/workspace", "/ws", "/use", "/agent", "/delegate", "/dg", "/group", "/groups", "/task", "/later", "/lt"];
2
- export declare function isKnownWeacpxCommandPrefix(prefix: string): boolean;
3
- export declare function isKnownWeacpxCommandText(text: string): boolean;
1
+ export declare const XACPX_KNOWN_COMMAND_PREFIXES: readonly ["/help", "/agents", "/workspaces", "/sessions", "/tasks", "/status", "/cancel", "/stop", "/clear", "/mode", "/replymode", "/config", "/permission", "/pm", "/session", "/ss", "/ssn", "/workspace", "/ws", "/use", "/agent", "/delegate", "/dg", "/group", "/groups", "/task", "/later", "/lt"];
2
+ export declare function isKnownXacpxCommandPrefix(prefix: string): boolean;
3
+ export declare function isKnownXacpxCommandText(text: string): boolean;
@@ -0,0 +1,13 @@
1
+ import type { AppConfig, ReplyMode } from "../../config/types";
2
+ /**
3
+ * The per-channel default reply mode declared on `channels[].replyMode`, or
4
+ * `undefined` when the channel does not set one (so callers fall through to the
5
+ * global default). The channel is derived from the chatKey the same way the rest
6
+ * of the system scopes sessions.
7
+ */
8
+ export declare function resolveChannelDefaultReplyMode(config: AppConfig | undefined, chatKey: string): ReplyMode | undefined;
9
+ /**
10
+ * Effective reply mode precedence:
11
+ * session override → per-channel default → global channel.replyMode → "verbose".
12
+ */
13
+ export declare function resolveEffectiveReplyMode(config: AppConfig | undefined, chatKey: string, sessionOverride: ReplyMode | undefined): ReplyMode;
@@ -66,6 +66,7 @@ export interface ChannelRuntimeConfig {
66
66
  id: string;
67
67
  type: string;
68
68
  enabled: boolean;
69
+ replyMode?: ReplyMode;
69
70
  options?: Record<string, unknown>;
70
71
  }
71
72
  export interface PluginConfig {
@@ -3,4 +3,5 @@ export declare function isLocale(value: unknown): value is Locale;
3
3
  export declare function resolveLocale(input?: {
4
4
  configLanguage?: string;
5
5
  env?: NodeJS.ProcessEnv;
6
+ systemLocale?: string;
6
7
  }): Locale;
@@ -27,10 +27,11 @@ export interface SessionMessages {
27
27
  replyModeHeader: string;
28
28
  replyModeSessionLabel: (alias: string) => string;
29
29
  replyModeGlobalDefault: (value: string) => string;
30
+ replyModeChannelDefault: (value: string) => string;
30
31
  replyModeSessionOverride: (value: string) => string;
31
32
  replyModeEffective: (value: string) => string;
32
33
  replyModeSet: (replyMode: string) => string;
33
- replyModeReset: (globalDefault: string) => string;
34
+ replyModeReset: (effective: string) => string;
34
35
  statusHeader: string;
35
36
  statusNameLabel: (alias: string) => string;
36
37
  statusAgentLabel: (agent: string) => string;
@@ -503,6 +504,8 @@ export interface ConfigMessages {
503
504
  mustBePositiveNumber: (path: string) => string;
504
505
  channelTypeDisabled: string;
505
506
  channelReplyModeInvalid: string;
507
+ channelRuntimeNotFound: (id: string) => string;
508
+ channelRuntimeReplyModeInvalid: (id: string) => string;
506
509
  wechatReplyModeInvalid: string;
507
510
  wechatReplyModeMapped: (value: string) => string;
508
511
  agentNotFound: (name: string) => string;
@@ -658,6 +661,8 @@ export interface ChannelCliMessages {
658
661
  channelRemoved: (id: string) => string;
659
662
  cannotDisableLastEnabled: string;
660
663
  channelEnabledToggled: (id: string, enabled: boolean) => string;
664
+ channelReplyModeSet: (id: string, mode: string) => string;
665
+ channelReplyModeInvalid: (mode: string) => string;
661
666
  channelAccountAlreadyExists: (type: string, accountId: string) => string;
662
667
  channelAccountAdded: (type: string, accountId: string) => string;
663
668
  channelReEnabled: (type: string) => string;
@@ -6,7 +6,7 @@ export type { ChannelRuntimeConfig } from "./config/types.js";
6
6
  export type { CommandHint } from "./commands/command-hints.js";
7
7
  export type { AppLogger } from "./logging/app-logger.js";
8
8
  export type { WeacpxPlugin, XacpxPlugin } from "./plugins/types.js";
9
- export { WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION, } from "./plugins/types.js";
9
+ export { XACPX_PLUGIN_API_VERSION, XACPX_PLUGIN_API_SUPPORTED_VERSIONS, XACPX_PLUGIN_MIN_CORE_VERSION, WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION, } from "./plugins/types.js";
10
10
  export { createConversationExecutor } from "./runtime/conversation-executor.js";
11
11
  export type { ConversationExecutor, ConversationExecutorLane } from "./runtime/conversation-executor.js";
12
12
  export { resolveTurnLane } from "./runtime/turn-lane.js";
@@ -88,10 +88,11 @@ var init_session = __esm(() => {
88
88
  replyModeHeader: "Current reply mode:",
89
89
  replyModeSessionLabel: (alias) => `- Session: ${alias}`,
90
90
  replyModeGlobalDefault: (value) => `- Global default: ${value}`,
91
+ replyModeChannelDefault: (value) => `- Channel default: ${value}`,
91
92
  replyModeSessionOverride: (value) => `- Session override: ${value}`,
92
93
  replyModeEffective: (value) => `- Effective: ${value}`,
93
94
  replyModeSet: (replyMode) => `Current session reply mode set to: ${replyMode}`,
94
- replyModeReset: (globalDefault) => `Session reply mode reset. Falling back to global default: ${globalDefault}`,
95
+ replyModeReset: (effective) => `Session reply mode reset. Now effective: ${effective}`,
95
96
  statusHeader: "Current session:",
96
97
  statusNameLabel: (alias) => `- Name: ${alias}`,
97
98
  statusAgentLabel: (agent) => `- Agent: ${agent}`,
@@ -634,6 +635,8 @@ var init_config = __esm(() => {
634
635
  mustBePositiveNumber: (path) => `${path} must be a positive number.`,
635
636
  channelTypeDisabled: "channel.type is a legacy single-channel field; /config set writes are disabled. Use `xacpx channel ...` to manage channels[], then restart xacpx.",
636
637
  channelReplyModeInvalid: "channel.replyMode only supports: stream, final, verbose",
638
+ channelRuntimeNotFound: (id) => `Channel "${id}" does not exist; add it first with \`xacpx channel add ${id}\`.`,
639
+ channelRuntimeReplyModeInvalid: (id) => `channels.${id}.replyMode only supports: stream, final, verbose`,
637
640
  wechatReplyModeInvalid: "wechat.replyMode only supports: stream, final, verbose",
638
641
  wechatReplyModeMapped: (value) => `${value} (mapped to channel.replyMode)`,
639
642
  agentNotFound: (name) => `Agent "${name}" does not exist. Create it first.`,
@@ -854,6 +857,8 @@ var init_channel_cli = __esm(() => {
854
857
  channelRemoved: (id) => `Channel ${id} removed`,
855
858
  cannotDisableLastEnabled: "Cannot disable the last enabled channel.",
856
859
  channelEnabledToggled: (id, enabled) => `Channel ${id} ${enabled ? "enabled" : "disabled"}`,
860
+ channelReplyModeSet: (id, mode) => `Channel ${id} default reply mode set to: ${mode}`,
861
+ channelReplyModeInvalid: (mode) => `reply mode must be stream / final / verbose, got: ${mode}`,
857
862
  channelAccountAlreadyExists: (type, accountId) => `Account ${accountId} already exists on channel ${type}; run xacpx channel rm ${type} --account ${accountId} first`,
858
863
  channelAccountAdded: (type, accountId) => `Channel ${type} account ${accountId} added`,
859
864
  channelReEnabled: (type) => `Channel ${type} was disabled; it has been automatically re-enabled.`,
@@ -1154,10 +1159,11 @@ var init_session2 = __esm(() => {
1154
1159
  replyModeHeader: "当前 reply mode:",
1155
1160
  replyModeSessionLabel: (alias) => `- 会话:${alias}`,
1156
1161
  replyModeGlobalDefault: (value) => `- 全局默认:${value}`,
1162
+ replyModeChannelDefault: (value) => `- 频道默认:${value}`,
1157
1163
  replyModeSessionOverride: (value) => `- 当前会话覆盖:${value}`,
1158
1164
  replyModeEffective: (value) => `- 当前生效:${value}`,
1159
1165
  replyModeSet: (replyMode) => `已设置当前会话 reply mode:${replyMode}`,
1160
- replyModeReset: (globalDefault) => `已重置当前会话 reply mode,当前回退到全局默认:${globalDefault}`,
1166
+ replyModeReset: (effective) => `已重置当前会话 reply mode,当前生效:${effective}`,
1161
1167
  statusHeader: "当前会话:",
1162
1168
  statusNameLabel: (alias) => `- 名称:${alias}`,
1163
1169
  statusAgentLabel: (agent2) => `- Agent:${agent2}`,
@@ -1700,6 +1706,8 @@ var init_config2 = __esm(() => {
1700
1706
  mustBePositiveNumber: (path) => `${path} 必须是正数。`,
1701
1707
  channelTypeDisabled: "channel.type 是旧单频道字段,/config set 已禁用写入;请使用 `xacpx channel ...` 管理 channels[],然后重启 xacpx。",
1702
1708
  channelReplyModeInvalid: "channel.replyMode 只支持:stream、final、verbose",
1709
+ channelRuntimeNotFound: (id) => `频道「${id}」不存在;请先用 \`xacpx channel add ${id}\` 添加。`,
1710
+ channelRuntimeReplyModeInvalid: (id) => `channels.${id}.replyMode 只支持:stream、final、verbose`,
1703
1711
  wechatReplyModeInvalid: "wechat.replyMode 只支持:stream、final、verbose",
1704
1712
  wechatReplyModeMapped: (value) => `${value}(已映射到 channel.replyMode)`,
1705
1713
  agentNotFound: (name) => `Agent「${name}」不存在,请先创建。`,
@@ -1920,6 +1928,8 @@ var init_channel_cli2 = __esm(() => {
1920
1928
  channelRemoved: (id) => `频道 ${id} 已删除`,
1921
1929
  cannotDisableLastEnabled: "不能禁用最后一个启用的频道。",
1922
1930
  channelEnabledToggled: (id, enabled) => `频道 ${id} 已${enabled ? "启用" : "禁用"}`,
1931
+ channelReplyModeSet: (id, mode) => `频道 ${id} 的默认 reply mode 已设置为:${mode}`,
1932
+ channelReplyModeInvalid: (mode) => `reply mode 只支持 stream / final / verbose,收到:${mode}`,
1923
1933
  channelAccountAlreadyExists: (type, accountId) => `频道 ${type} 的账号 ${accountId} 已存在;先 xacpx channel rm ${type} --account ${accountId}`,
1924
1934
  channelAccountAdded: (type, accountId) => `频道 ${type} 账号 ${accountId} 已添加`,
1925
1935
  channelReEnabled: (type) => `频道 ${type} 此前是 disabled 状态,已自动启用。`,
@@ -2184,12 +2194,22 @@ var init_zh = __esm(() => {
2184
2194
  function isLocale(value) {
2185
2195
  return typeof value === "string" && VALID.includes(value);
2186
2196
  }
2197
+ function detectSystemLocale() {
2198
+ try {
2199
+ return Intl.DateTimeFormat().resolvedOptions().locale || "";
2200
+ } catch {
2201
+ return "";
2202
+ }
2203
+ }
2187
2204
  function resolveLocale(input = {}) {
2188
2205
  const { configLanguage, env = process.env } = input;
2189
2206
  if (isLocale(configLanguage))
2190
2207
  return configLanguage;
2191
2208
  const raw = env.LC_ALL || env.LC_MESSAGES || env.LANG || "";
2192
- return /^zh/i.test(raw) ? "zh" : "en";
2209
+ if (raw)
2210
+ return /^zh/i.test(raw) ? "zh" : "en";
2211
+ const systemLocale = input.systemLocale ?? detectSystemLocale();
2212
+ return /^zh/i.test(systemLocale) ? "zh" : "en";
2193
2213
  }
2194
2214
  var VALID;
2195
2215
  var init_resolve_locale = __esm(() => {
@@ -2285,19 +2305,19 @@ function cmpTuple(a, b) {
2285
2305
  return 0;
2286
2306
  }
2287
2307
  function validatePluginCompatibility(metadata, context) {
2288
- const { packageName, currentWeacpxVersion } = context;
2308
+ const { packageName, currentXacpxVersion } = context;
2289
2309
  const apiVersion = metadata.apiVersion;
2290
2310
  if (typeof apiVersion !== "number") {
2291
2311
  throw new Error(t().pluginCli.compatMissingApiVersion(packageName));
2292
2312
  }
2293
- if (!WEACPX_PLUGIN_API_SUPPORTED_VERSIONS.includes(apiVersion)) {
2294
- const supported = WEACPX_PLUGIN_API_SUPPORTED_VERSIONS.join(", ");
2313
+ if (!XACPX_PLUGIN_API_SUPPORTED_VERSIONS.includes(apiVersion)) {
2314
+ const supported = XACPX_PLUGIN_API_SUPPORTED_VERSIONS.join(", ");
2295
2315
  throw new Error(t().pluginCli.compatUnsupportedApiVersion(packageName, apiVersion, supported));
2296
2316
  }
2297
- if (!currentWeacpxVersion || currentWeacpxVersion === "unknown") {
2317
+ if (!currentXacpxVersion || currentXacpxVersion === "unknown") {
2298
2318
  return;
2299
2319
  }
2300
- const normalizedCurrent = normalizeCoreVersionForCompat(currentWeacpxVersion);
2320
+ const normalizedCurrent = normalizeCoreVersionForCompat(currentXacpxVersion);
2301
2321
  const minVersion = metadata.minXacpxVersion ?? metadata.minWeacpxVersion;
2302
2322
  const minVersionField = metadata.minXacpxVersion !== undefined ? "minXacpxVersion" : "minWeacpxVersion";
2303
2323
  if (minVersion !== undefined) {
@@ -2312,7 +2332,7 @@ function validatePluginCompatibility(metadata, context) {
2312
2332
  throw new Error(t().pluginCli.compatInvalidMinVersionDetail(packageName, minVersionField, detail));
2313
2333
  }
2314
2334
  if (!satisfied) {
2315
- throw new Error(t().pluginCli.compatMinVersionNotSatisfied(packageName, minVersion, currentWeacpxVersion));
2335
+ throw new Error(t().pluginCli.compatMinVersionNotSatisfied(packageName, minVersion, currentXacpxVersion));
2316
2336
  }
2317
2337
  }
2318
2338
  const compatibleVersions = metadata.compatibleXacpxVersions ?? metadata.compatibleWeacpxVersions;
@@ -2329,14 +2349,17 @@ function validatePluginCompatibility(metadata, context) {
2329
2349
  throw new Error(t().pluginCli.compatInvalidCompatibleVersionsDetail(packageName, compatibleField, detail));
2330
2350
  }
2331
2351
  if (!satisfied) {
2332
- throw new Error(t().pluginCli.compatCompatibleVersionsNotSatisfied(packageName, compatibleVersions, currentWeacpxVersion));
2352
+ throw new Error(t().pluginCli.compatCompatibleVersionsNotSatisfied(packageName, compatibleVersions, currentXacpxVersion));
2333
2353
  }
2334
2354
  }
2335
2355
  }
2336
- var WEACPX_PLUGIN_API_VERSION = 1, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION = "0.5.0", SEMVER_RE;
2356
+ var XACPX_PLUGIN_API_VERSION = 1, XACPX_PLUGIN_API_SUPPORTED_VERSIONS, XACPX_PLUGIN_MIN_CORE_VERSION = "0.5.0", WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION, SEMVER_RE;
2337
2357
  var init_compatibility = __esm(() => {
2338
2358
  init_i18n();
2339
- WEACPX_PLUGIN_API_SUPPORTED_VERSIONS = [1];
2359
+ XACPX_PLUGIN_API_SUPPORTED_VERSIONS = [1];
2360
+ WEACPX_PLUGIN_API_VERSION = XACPX_PLUGIN_API_VERSION;
2361
+ WEACPX_PLUGIN_API_SUPPORTED_VERSIONS = XACPX_PLUGIN_API_SUPPORTED_VERSIONS;
2362
+ WEACPX_PLUGIN_MIN_CORE_VERSION = XACPX_PLUGIN_MIN_CORE_VERSION;
2340
2363
  SEMVER_RE = /^(\d+)\.(\d+)\.(\d+)$/;
2341
2364
  });
2342
2365
 
@@ -2507,6 +2530,9 @@ export {
2507
2530
  getLocale,
2508
2531
  createConversationExecutor,
2509
2532
  createActiveTurnRegistry,
2533
+ XACPX_PLUGIN_MIN_CORE_VERSION,
2534
+ XACPX_PLUGIN_API_VERSION,
2535
+ XACPX_PLUGIN_API_SUPPORTED_VERSIONS,
2510
2536
  WEACPX_PLUGIN_MIN_CORE_VERSION,
2511
2537
  WEACPX_PLUGIN_API_VERSION,
2512
2538
  WEACPX_PLUGIN_API_SUPPORTED_VERSIONS
@@ -1,3 +1,6 @@
1
+ export declare const XACPX_PLUGIN_API_VERSION: 1;
2
+ export declare const XACPX_PLUGIN_API_SUPPORTED_VERSIONS: readonly number[];
3
+ export declare const XACPX_PLUGIN_MIN_CORE_VERSION: "0.5.0";
1
4
  export declare const WEACPX_PLUGIN_API_VERSION: 1;
2
5
  export declare const WEACPX_PLUGIN_API_SUPPORTED_VERSIONS: readonly number[];
3
6
  export declare const WEACPX_PLUGIN_MIN_CORE_VERSION: "0.5.0";
@@ -13,6 +16,6 @@ export interface PluginCompatibilityMetadata {
13
16
  }
14
17
  export interface PluginCompatibilityContext {
15
18
  packageName: string;
16
- currentWeacpxVersion: string;
19
+ currentXacpxVersion: string;
17
20
  }
18
21
  export declare function validatePluginCompatibility(metadata: PluginCompatibilityMetadata, context: PluginCompatibilityContext): void;
@@ -1,6 +1,6 @@
1
1
  import type { ChannelPluginDefinition } from "../channels/plugin.js";
2
- import { WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION } from "./compatibility.js";
3
- export { WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION, };
2
+ import { XACPX_PLUGIN_API_VERSION, XACPX_PLUGIN_API_SUPPORTED_VERSIONS, XACPX_PLUGIN_MIN_CORE_VERSION, WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION } from "./compatibility.js";
3
+ export { XACPX_PLUGIN_API_VERSION, XACPX_PLUGIN_API_SUPPORTED_VERSIONS, XACPX_PLUGIN_MIN_CORE_VERSION, WEACPX_PLUGIN_API_VERSION, WEACPX_PLUGIN_API_SUPPORTED_VERSIONS, WEACPX_PLUGIN_MIN_CORE_VERSION, };
4
4
  export interface WeacpxPlugin {
5
5
  apiVersion: 1;
6
6
  name?: string;
@@ -1,6 +1,6 @@
1
1
  import { type OrchestrationState } from "../orchestration/orchestration-types";
2
2
  import type { ScheduledTaskRecord } from "../scheduled/scheduled-types";
3
- export type LogicalSessionSource = "weacpx" | "agent-side";
3
+ export type LogicalSessionSource = "xacpx" | "agent-side";
4
4
  export interface NativeSessionCacheEntry {
5
5
  session_id: string;
6
6
  cwd?: string;
@@ -24,7 +24,7 @@ export interface ResolvedSession {
24
24
  agentCommand?: string;
25
25
  workspace: string;
26
26
  transportSession: string;
27
- source?: "weacpx" | "agent-side";
27
+ source?: "xacpx" | "agent-side";
28
28
  agentSessionId?: string;
29
29
  agentSessionTitle?: string;
30
30
  agentSessionUpdatedAt?: string;
@@ -124,6 +124,14 @@ export interface SessionTransport {
124
124
  listAgentSessions?(query: AgentSessionListQuery): Promise<AgentSessionListResult | undefined>;
125
125
  resumeAgentSession?(session: ResolvedSession, agentSessionId: string): Promise<void>;
126
126
  removeSession?(session: ResolvedSession): Promise<void>;
127
+ /**
128
+ * Read the underlying agent-native session id for an existing transport
129
+ * session. Used by `/clear` to keep a native session native: the fresh
130
+ * post-clear session is itself backed by a new agent rollout, and this
131
+ * returns that rollout's resumable id. Returns undefined when the agent did
132
+ * not advertise one. Optional: transports that can't resolve it omit it.
133
+ */
134
+ getAgentSessionId?(session: ResolvedSession): Promise<string | undefined>;
127
135
  updatePermissionPolicy?(policy: PermissionPolicy): Promise<void>;
128
136
  dispose?(): Promise<void>;
129
137
  }
package/dist/version.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export declare function readVersion(moduleUrl?: string): string;
2
- /** weacpx 核心版本,派生自 package.json(经 readVersion 动态读取,无硬编码漂移)。 */
3
- export declare const WEACPX_CORE_VERSION: string;
2
+ /** xacpx 核心版本,派生自 package.json(经 readVersion 动态读取,无硬编码漂移)。 */
3
+ export declare const XACPX_CORE_VERSION: string;
@@ -62,7 +62,7 @@ export interface ChatRequestMetadata {
62
62
  senderName?: string;
63
63
  groupId?: string;
64
64
  isOwner?: boolean;
65
- /** Internal weacpx session alias to use for non-interactive scheduled prompts. */
65
+ /** Internal xacpx session alias to use for non-interactive scheduled prompts. */
66
66
  scheduledSessionAlias?: string;
67
67
  /** Transient session descriptor for temp-mode scheduled prompts (no persisted alias). */
68
68
  scheduledSessionDescriptor?: ScheduledSessionDescriptor;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ganglion/xacpx",
3
- "version": "0.9.0",
3
+ "version": "0.9.2",
4
4
  "description": "随时随地通过聊天频道(微信 / 飞书 / 元宝等)远程控制 `acpx` 上的 Claude Code、Codex 等 Agents。",
5
5
  "keywords": [
6
6
  "acpx",