@chenacc/agentbridge 0.2.2 → 0.2.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/cli.js +56 -8
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chenacc/agentbridge",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "Control local coding agents from a phone through a secure WeChat QR web console.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from "node:crypto";
2
2
  import { spawn } from "node:child_process";
3
- import { mkdir, writeFile } from "node:fs/promises";
3
+ import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
4
4
  import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { fileURLToPath } from "node:url";
@@ -52,23 +52,37 @@ Tell the user to scan the QR with WeChat. While the phone controls this session,
52
52
  `;
53
53
  }
54
54
 
55
+ /**
56
+ * The Codex skill is named `phone-codex`, not `phone`.
57
+ *
58
+ * `~/.agents/skills` is shared: Codex reads it, and so does DSH Desktop. A skill
59
+ * called `phone` therefore shadows the DSH plugin's `/phone` command, and typing
60
+ * `/phone` in DSH Desktop runs `phone --agent codex` — pairing a Codex
61
+ * conversation instead of the one on screen. One name per client: the plugin owns
62
+ * `/phone`, this skill answers `/phone-codex`.
63
+ */
64
+ export const CODEX_SKILL_NAME = "phone-codex";
65
+ const CODEX_SKILL_MARKER = "# Send a Codex project to AgentBridge";
66
+
55
67
  export function renderCodexPhoneSkill(entryPath = cliEntry) {
56
68
  const portableEntry = entryPath.replaceAll("\\", "/").replaceAll('"', '\\"');
57
69
  return `---
58
- name: phone
59
- description: Generate a one-time WeChat QR code for a Codex project conversation. Use only when the user explicitly invokes /phone.
70
+ name: ${CODEX_SKILL_NAME}
71
+ description: Generate a one-time WeChat QR code for a Codex project conversation. Use only when the user explicitly invokes /${CODEX_SKILL_NAME}.
60
72
  disable-model-invocation: true
61
73
  ---
62
74
 
63
- # Send a Codex project to AgentBridge
75
+ ${CODEX_SKILL_MARKER}
64
76
 
65
- When the user invokes \`/phone\`, you must immediately execute the following command in the terminal from the current project directory. Do not merely describe the command or ask the user to run it:
77
+ When the user invokes \`/${CODEX_SKILL_NAME}\`, you must immediately execute the following command in the terminal from the current project directory. Do not merely describe the command or ask the user to run it:
66
78
 
67
79
  \`node "${portableEntry}" phone --agent codex --cwd .\`
68
80
 
69
81
  After a successful command, reply with the exact QR image Markdown emitted by the command (for example, \`![微信扫码二维码](<temporary QR image URL>)\`) so Codex Desktop renders a scannable image. The temporary QR image URL and pairing URL must be shown as clickable links; then tell the user to scan the 微信扫码二维码 with WeChat. Do not invent or alter either URL. If the command fails, show its exact safe error and do not claim that a QR code was generated.
70
82
 
71
83
  If the user supplies a known persisted Codex thread ID, append \`--session <thread-id>\` to resume that exact thread. Do not claim that the command attached the current desktop conversation when no thread ID was supplied: Codex does not expose a documented current-thread substitution to this local skill.
84
+
85
+ > Named \`${CODEX_SKILL_NAME}\` on purpose: DSH Desktop reads the same skills folder and owns \`/phone\` for the conversation on screen. Running \`/phone\` here would pair the wrong Agent.
72
86
  `;
73
87
  }
74
88
 
@@ -271,17 +285,51 @@ async function installClaudeSkill(options) {
271
285
  return target;
272
286
  }
273
287
 
288
+ /**
289
+ * Remove a `phone` skill this installer used to create.
290
+ *
291
+ * Earlier releases wrote the Codex skill as `phone`, which shadowed the DSH
292
+ * plugin's `/phone` in DSH Desktop because both clients read `~/.agents/skills`.
293
+ * Re-running the installer has to clean that up, or the wrong pairing keeps
294
+ * happening after an upgrade. Only a file carrying our own marker is touched —
295
+ * a hand-written `phone` skill belongs to whoever wrote it.
296
+ */
297
+ async function removeLegacyCodexSkill(root) {
298
+ const legacy = path.join(root, "phone", "SKILL.md");
299
+ let content;
300
+ try {
301
+ content = await readFile(legacy, "utf8");
302
+ } catch {
303
+ return null;
304
+ }
305
+ if (!content.includes(CODEX_SKILL_MARKER)) return null;
306
+ try {
307
+ await rm(path.join(root, "phone"), { recursive: true, force: true });
308
+ return legacy;
309
+ } catch {
310
+ return null;
311
+ }
312
+ }
313
+
274
314
  async function installCodexSkill(options) {
275
315
  if (options.user && options.project) throw new Error("Choose only one of --user or --project");
276
316
  const projectCwd = path.resolve(options.cwd ?? process.cwd());
277
317
  const root = options.project
278
318
  ? path.join(projectCwd, ".agents", "skills")
279
319
  : path.join(os.homedir(), ".agents", "skills");
280
- const target = path.join(root, "phone", "SKILL.md");
320
+
321
+ const removed = await removeLegacyCodexSkill(root);
322
+ if (removed) {
323
+ console.log(`已移除会抢占 /phone 的旧技能: ${removed}`);
324
+ console.log("(DSH Desktop 也读这个目录,旧的 phone 技能会让 /phone 绑到 Codex 会话。)");
325
+ }
326
+
327
+ const target = path.join(root, CODEX_SKILL_NAME, "SKILL.md");
281
328
  await mkdir(path.dirname(target), { recursive: true });
282
329
  await writeFile(target, renderCodexPhoneSkill(), { encoding: "utf8", flag: "w" });
283
- console.log(`Codex /phone 已安装到: ${target}`);
284
- console.log("重新打开 Codex 桌面项目后,在斜杠命令列表选择 /phone。未提供 thread ID 时,它会创建新的项目会话并清楚标注。");
330
+ console.log(`Codex /${CODEX_SKILL_NAME} 已安装到: ${target}`);
331
+ console.log(`重新打开 Codex 桌面项目后,在斜杠命令列表选择 /${CODEX_SKILL_NAME}。未提供 thread ID 时,它会创建新的项目会话并清楚标注。`);
332
+ console.log("DSH Desktop 里的 /phone 保持归插件所有,绑定的就是屏幕上那条会话。");
285
333
  return target;
286
334
  }
287
335