weacpx 0.4.8 → 0.4.10

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/README.md CHANGED
@@ -180,7 +180,7 @@ weacpx restart
180
180
  | `weacpx agent add <name>` | 从内置模板添加 agent;已存在且配置不同的同名 agent 不会被覆盖 |
181
181
  | `weacpx agent rm <name>` | 删除 agent |
182
182
  | `weacpx workspace list` | 查看本机已注册的 workspace |
183
- | `weacpx workspace add [name]` | 把当前目录注册成 workspace;不传 `name` 时使用当前目录名 |
183
+ | `weacpx workspace add [name] [--raw]` | 把当前目录注册成 workspace;不传 `name` 时使用当前目录名,含特殊字符的名称会被自动规范化 |
184
184
  | `weacpx workspace rm <name>` | 删除 workspace |
185
185
 
186
186
  首次运行 `weacpx start` 或 `weacpx run` 时,如果没有会话、workspace 和插件,CLI 会询问是否把当前目录创建为 workspace,并选择一个内置 agent 模板;服务启动后会通过正常会话创建流程创建初始 acpx 会话。
@@ -200,8 +200,9 @@ weacpx ws rm backend
200
200
  | 命令 | 说明 |
201
201
  |------|------|
202
202
  | `weacpx workspace list` | 列出已注册的 workspace 及其路径 |
203
- | `weacpx workspace add` | 把当前目录注册为 workspace,名称默认取当前目录名 |
204
- | `weacpx workspace add <name>` | 把当前目录注册为指定名称 |
203
+ | `weacpx workspace add` | 把当前目录注册为 workspace,名称默认取当前目录名(自动规范化) |
204
+ | `weacpx workspace add <name>` | 把当前目录注册为指定名称(含特殊字符时自动规范化) |
205
+ | `weacpx workspace add [name] --raw` | 保留原始名称(含空格等),后续命令需要用引号引用 |
205
206
  | `weacpx workspace rm <name>` | 删除指定 workspace |
206
207
 
207
208
  常见用法:
@@ -224,7 +225,7 @@ weacpx ws rm frontend
224
225
  /ss new claude --ws frontend
225
226
  ```
226
227
 
227
- 注意:`workspace add` 总是注册**当前终端所在目录**;如果不传名称,会用当前目录名作为 workspace 名称。
228
+ 注意:`workspace add` 总是注册**当前终端所在目录**。如果不传名称,会用当前目录名作为 workspace 名称。含空格、中文等字符的名称会被自动规范化为 `[a-zA-Z0-9._-]+`(例如目录 `My Project` 会保存为 `My-Project`),重名时追加 `-2`、`-3`。如需保留原始名称,加 `--raw`;之后 `weacpx workspace rm`、`/ws rm`、`--ws <name>` 都需要用引号引用,例如 `weacpx workspace rm "My Project"`。
228
229
 
229
230
  ### `agent` CLI 怎么用
230
231
 
@@ -292,7 +293,7 @@ opencode, qoder, qwen, trae
292
293
  | 命令 | 说明 |
293
294
  |------|------|
294
295
  | `/workspaces` / `/workspace` / `/ws` | 查看 workspace 列表 |
295
- | `/ws new <name> -d <path>` | 添加 workspace,`path` 是电脑上的绝对路径,Windows 不用区分正反斜杠 |
296
+ | `/ws new <name> -d <path> [--raw]` | 添加 workspace,`path` 是电脑上的绝对路径,Windows 不用区分正反斜杠;含空格/中文等特殊字符的名称会被自动规范化,--raw 保留原名 |
296
297
  | `/workspace rm <name>` | 删除 workspace |
297
298
 
298
299
  ### Session 会话
@@ -1042,6 +1042,13 @@ function normalizeBridgePermissionMode(value) {
1042
1042
  function normalizeBridgeNonInteractivePermissions(value) {
1043
1043
  return value === "deny" || value === "fail" ? value : "deny";
1044
1044
  }
1045
+ function normalizeBridgeQueueOwnerTtlSeconds(value) {
1046
+ if (value === undefined) {
1047
+ return;
1048
+ }
1049
+ const parsed = Number(value);
1050
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;
1051
+ }
1045
1052
 
1046
1053
  // src/bridge/bridge-server.ts
1047
1054
  init_prompt_output();
@@ -1125,7 +1132,8 @@ class BridgeRuntime {
1125
1132
  queueOwnerLauncher;
1126
1133
  acpxVerboseSupported = undefined;
1127
1134
  constructor(command = "acpx", run = defaultRunner, runSessionCreate = shellSessionCreateRunner, options = {}, runPromptCommand = defaultPromptRunner, repairSessionIndex = tryRepairAcpxSessionIndex, queueOwnerLauncher = new AcpxQueueOwnerLauncher({
1128
- acpxCommand: command
1135
+ acpxCommand: command,
1136
+ ...typeof options.queueOwnerTtlSeconds === "number" && Number.isFinite(options.queueOwnerTtlSeconds) ? { ttlMs: options.queueOwnerTtlSeconds * 1000 } : {}
1129
1137
  })) {
1130
1138
  this.command = command;
1131
1139
  this.run = run;
@@ -1381,13 +1389,21 @@ class BridgeRuntime {
1381
1389
  "--json-strict",
1382
1390
  "--cwd",
1383
1391
  input.cwd,
1384
- ...this.buildPermissionArgs()
1392
+ ...this.buildPermissionArgs(),
1393
+ ...this.buildQueueOwnerTtlArgs()
1385
1394
  ];
1386
1395
  if (input.agentCommand) {
1387
1396
  return [...prefix, "--agent", input.agentCommand, ...tail];
1388
1397
  }
1389
1398
  return [...prefix, input.agent, ...tail];
1390
1399
  }
1400
+ buildQueueOwnerTtlArgs() {
1401
+ const ttl = this.options.queueOwnerTtlSeconds;
1402
+ if (typeof ttl !== "number" || !Number.isFinite(ttl)) {
1403
+ return [];
1404
+ }
1405
+ return ["--ttl", String(ttl)];
1406
+ }
1391
1407
  buildPermissionArgs() {
1392
1408
  const permissionMode = this.options.permissionMode ?? "approve-all";
1393
1409
  const nonInteractivePermissions = this.options.nonInteractivePermissions ?? "deny";
@@ -1924,7 +1940,8 @@ async function processBridgeInput(options) {
1924
1940
  async function runBridgeMain() {
1925
1941
  const server = new BridgeServer(new BridgeRuntime(process.env.WEACPX_BRIDGE_ACPX_COMMAND ?? "acpx", undefined, undefined, {
1926
1942
  permissionMode: normalizeBridgePermissionMode(process.env.WEACPX_BRIDGE_PERMISSION_MODE),
1927
- nonInteractivePermissions: normalizeBridgeNonInteractivePermissions(process.env.WEACPX_BRIDGE_NON_INTERACTIVE_PERMISSIONS)
1943
+ nonInteractivePermissions: normalizeBridgeNonInteractivePermissions(process.env.WEACPX_BRIDGE_NON_INTERACTIVE_PERMISSIONS),
1944
+ queueOwnerTtlSeconds: normalizeBridgeQueueOwnerTtlSeconds(process.env.WEACPX_BRIDGE_QUEUE_OWNER_TTL_SECONDS)
1928
1945
  }));
1929
1946
  const input = createInterface({
1930
1947
  input: process.stdin,