lark-remote 0.1.13 → 0.2.1

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 (132) hide show
  1. package/CHANGELOG.md +36 -3
  2. package/README.en.md +7 -11
  3. package/README.md +7 -11
  4. package/dist/bridge/final-usage.d.ts +24 -0
  5. package/dist/bridge/final-usage.js +55 -0
  6. package/dist/bridge/index.d.ts +0 -7
  7. package/dist/bridge/index.js +22 -64
  8. package/dist/bridge/queue-manager.js +4 -3
  9. package/dist/card/approval-render.js +39 -94
  10. package/dist/card/bash-renderer.js +12 -21
  11. package/dist/card/card-shared.d.ts +13 -1
  12. package/dist/card/card-shared.js +21 -30
  13. package/dist/card/run-renderer.d.ts +0 -22
  14. package/dist/card/run-renderer.js +206 -153
  15. package/dist/card/run-state.d.ts +29 -1
  16. package/dist/card/run-state.js +172 -84
  17. package/dist/card/text-truncate.d.ts +0 -9
  18. package/dist/card/text-truncate.js +0 -9
  19. package/dist/card/tool-render.d.ts +4 -1
  20. package/dist/card/tool-render.js +76 -32
  21. package/dist/cli.js +2 -2
  22. package/dist/common/fs.d.ts +14 -0
  23. package/dist/common/fs.js +57 -3
  24. package/dist/config/codex-config.js +2 -0
  25. package/dist/config/index.d.ts +0 -5
  26. package/dist/config/index.js +0 -11
  27. package/dist/config/kimi-config.js +1 -0
  28. package/dist/config/opencode-config.js +13 -2
  29. package/dist/config/qr.d.ts +36 -0
  30. package/dist/config/qr.js +124 -0
  31. package/dist/config/wizard.js +69 -27
  32. package/dist/connector/index.d.ts +3 -2
  33. package/dist/connector/index.js +5 -4
  34. package/dist/index.js +15 -42
  35. package/dist/instance-lock.js +7 -0
  36. package/dist/persistence/atomic-write.d.ts +2 -0
  37. package/dist/persistence/atomic-write.js +20 -5
  38. package/dist/persistence/load-json-file.d.ts +1 -2
  39. package/dist/persistence/load-json-file.js +2 -3
  40. package/dist/platform/agent-stopper.d.ts +22 -0
  41. package/dist/platform/agent-stopper.js +19 -0
  42. package/dist/platform/command.d.ts +11 -0
  43. package/dist/platform/command.js +107 -0
  44. package/dist/platform/identity.d.ts +33 -0
  45. package/dist/platform/identity.js +187 -0
  46. package/dist/platform/path.d.ts +24 -0
  47. package/dist/platform/path.js +110 -0
  48. package/dist/platform/select.d.ts +9 -0
  49. package/dist/platform/select.js +12 -0
  50. package/dist/platform/shell.d.ts +51 -0
  51. package/dist/platform/shell.js +75 -0
  52. package/dist/platform/spawn.d.ts +41 -0
  53. package/dist/platform/spawn.js +77 -0
  54. package/dist/platform/terminator-posix.d.ts +38 -0
  55. package/dist/platform/terminator-posix.js +103 -0
  56. package/dist/platform/terminator-win32.d.ts +21 -0
  57. package/dist/platform/terminator-win32.js +110 -0
  58. package/dist/platform/terminator.d.ts +44 -0
  59. package/dist/platform/terminator.js +24 -0
  60. package/dist/platform/types.d.ts +23 -0
  61. package/dist/platform/types.js +5 -0
  62. package/dist/restart.js +4 -2
  63. package/dist/router/card-helpers.d.ts +33 -6
  64. package/dist/router/card-helpers.js +67 -11
  65. package/dist/router/config/common/render.d.ts +1 -1
  66. package/dist/router/config/common/render.js +1 -1
  67. package/dist/router/config-diff.d.ts +4 -0
  68. package/dist/router/config-diff.js +70 -0
  69. package/dist/router/index.d.ts +66 -6
  70. package/dist/router/index.js +451 -316
  71. package/dist/router/utils.d.ts +6 -0
  72. package/dist/router/utils.js +12 -0
  73. package/dist/runner/bash/runner.d.ts +9 -2
  74. package/dist/runner/bash/runner.js +45 -20
  75. package/dist/runner/claude/session.d.ts +4 -1
  76. package/dist/runner/claude/session.js +18 -4
  77. package/dist/runner/codex/app-server/protocol-types.d.ts +35 -1
  78. package/dist/runner/codex/app-server/translator.d.ts +18 -0
  79. package/dist/runner/codex/app-server/translator.js +146 -0
  80. package/dist/runner/common/acp/base-acp-runner.d.ts +116 -0
  81. package/dist/runner/common/acp/base-acp-runner.js +248 -0
  82. package/dist/runner/common/acp/base-translator.d.ts +141 -0
  83. package/dist/runner/common/acp/base-translator.js +271 -0
  84. package/dist/runner/common/acp/protocol-helpers.d.ts +39 -0
  85. package/dist/runner/common/acp/protocol-helpers.js +34 -0
  86. package/dist/runner/common/jsonrpc/transport.d.ts +2 -0
  87. package/dist/runner/common/jsonrpc/transport.js +25 -5
  88. package/dist/runner/common/process-stopper.d.ts +4 -26
  89. package/dist/runner/common/process-stopper.js +4 -76
  90. package/dist/runner/common/runner-utils.d.ts +0 -5
  91. package/dist/runner/common/runner-utils.js +0 -7
  92. package/dist/runner/common/spawning-runner.d.ts +42 -132
  93. package/dist/runner/common/spawning-runner.js +52 -271
  94. package/dist/runner/common/usage.d.ts +2 -0
  95. package/dist/runner/common/usage.js +2 -0
  96. package/dist/runner/index.d.ts +1 -1
  97. package/dist/runner/kimi/acp/runner.d.ts +45 -42
  98. package/dist/runner/kimi/acp/runner.js +140 -293
  99. package/dist/runner/kimi/acp/translator.d.ts +18 -100
  100. package/dist/runner/kimi/acp/translator.js +56 -242
  101. package/dist/runner/opencode/acp/runner.d.ts +22 -46
  102. package/dist/runner/opencode/acp/runner.js +73 -256
  103. package/dist/runner/opencode/acp/translator.d.ts +28 -103
  104. package/dist/runner/opencode/acp/translator.js +51 -236
  105. package/dist/runner/pi/rpc/translator.d.ts +3 -0
  106. package/dist/runner/pi/rpc/translator.js +47 -9
  107. package/dist/runner/probe.d.ts +8 -11
  108. package/dist/runner/probe.js +17 -21
  109. package/dist/runner/registry.d.ts +4 -4
  110. package/dist/runner/registry.js +4 -4
  111. package/dist/runner/types.d.ts +38 -1
  112. package/dist/session/claude/sessions.js +35 -58
  113. package/dist/session/codex/rollout-reader.d.ts +10 -0
  114. package/dist/session/codex/rollout-reader.js +123 -41
  115. package/dist/session/common/constants.d.ts +7 -0
  116. package/dist/session/common/constants.js +9 -0
  117. package/dist/session/common/two-pass.d.ts +22 -0
  118. package/dist/session/common/two-pass.js +70 -0
  119. package/dist/session/dsh/sessions.js +7 -6
  120. package/dist/session/kimi/sessions.d.ts +6 -0
  121. package/dist/session/kimi/sessions.js +50 -73
  122. package/dist/session/opencode/sessions.js +26 -8
  123. package/dist/session/pi/sessions.js +54 -73
  124. package/dist/update/index.d.ts +1 -2
  125. package/dist/update/index.js +1 -2
  126. package/dist/update/install.d.ts +2 -1
  127. package/dist/update/install.js +58 -9
  128. package/dist/update/version-check.d.ts +5 -0
  129. package/dist/update/version-check.js +9 -0
  130. package/package.json +9 -6
  131. package/dist/update/startup-hint.d.ts +0 -5
  132. package/dist/update/startup-hint.js +0 -11
@@ -1,6 +1,53 @@
1
- import { execFile, execFileSync } from 'node:child_process';
2
1
  import fs from 'node:fs';
3
2
  import { getLogger } from '../logger/index.js';
3
+ import { resolveExecutable } from '../platform/command.js';
4
+ import { currentPlatform, isWin32 } from '../platform/select.js';
5
+ import { spawnProcess, spawnProcessSync } from '../platform/spawn.js';
6
+ /**
7
+ * execFile 回调风格适配 cross-spawn(platform/spawn.ts)。
8
+ *
9
+ * npm/pnpm 在 Windows 是 .cmd 垫片,execFile 不经 shell 无法执行——Node 自
10
+ * CVE-2024-27980 收紧后对无 shell 启动 .cmd 直接抛错,win32 上 /update 会
11
+ * 永远失败。执行统一走 spawnProcess(cross-spawn 处理 PATHEXT + .cmd 经
12
+ * cmd.exe 受控执行),错误/退出码语义对齐 execFile:
13
+ * - 非 0 退出 → err.message 为 execFile 同款 "Command failed: ..." 形态
14
+ * (含 stderr 首段,EACCES 提示逻辑依赖它);
15
+ * - 'error' 事件(ENOENT 等)→ 原样回调。
16
+ */
17
+ function execViaSpawnProcess(file, args, options, callback) {
18
+ const proc = spawnProcess(file, args, {
19
+ timeout: options.timeout,
20
+ stdio: ['ignore', 'pipe', 'pipe'],
21
+ windowsHide: true,
22
+ });
23
+ let stdout = '';
24
+ let stderr = '';
25
+ let settled = false;
26
+ const finish = (error) => {
27
+ if (settled)
28
+ return;
29
+ settled = true;
30
+ callback(error, stdout, stderr);
31
+ };
32
+ proc.stdout?.setEncoding('utf8');
33
+ proc.stdout?.on('data', (chunk) => {
34
+ stdout += chunk;
35
+ });
36
+ proc.stderr?.setEncoding('utf8');
37
+ proc.stderr?.on('data', (chunk) => {
38
+ stderr += chunk;
39
+ });
40
+ proc.on('error', (err) => finish(err));
41
+ proc.on('close', (code, signal) => {
42
+ if (code === 0) {
43
+ finish(null);
44
+ return;
45
+ }
46
+ const detail = stderr.trim() || stdout.trim();
47
+ const how = signal ? ` terminated with ${signal}` : ` with exit code ${code ?? 'unknown'}`;
48
+ finish(new Error(`Command failed: ${file} ${args.join(' ')}${how}${detail ? `\n${detail}` : ''}`));
49
+ });
50
+ }
4
51
  /**
5
52
  * Infer the installing package manager from the real path of the running
6
53
  * script (e.g. `.../node_modules/lark-remote/dist/index.js`).
@@ -54,15 +101,16 @@ export function detectPackageManager(scriptPath) {
54
101
  if (inferred)
55
102
  return inferred;
56
103
  }
57
- // 3. which availability fallback
104
+ // 3. availability fallback: 纯 Node PATH 解析(win32 PATHEXT),不再依赖外部 which
105
+ // (Windows 无 which);win32 再用 where.exe 兜底罕见的解析失败场景(v2 §4.3)
58
106
  const candidates = ['npm', 'bun', 'pnpm'];
59
107
  for (const cmd of candidates) {
60
- try {
61
- execFileSync('which', [cmd], { stdio: 'pipe', timeout: 3000 });
108
+ if (resolveExecutable(cmd))
62
109
  return cmd;
63
- }
64
- catch {
65
- // Not found, try next
110
+ if (isWin32(currentPlatform)) {
111
+ const res = spawnProcessSync('where.exe', [cmd], { stdio: 'pipe', timeout: 3000 });
112
+ if (!res.error && res.status === 0)
113
+ return cmd;
66
114
  }
67
115
  }
68
116
  return null;
@@ -82,7 +130,8 @@ function getInstallCommand(pm) {
82
130
  * Run the global install command to upgrade lark-remote to the latest version.
83
131
  *
84
132
  * @param opts.packageManager - Override detected package manager
85
- * @param opts.execFn - Override execFile for testing
133
+ * @param opts.execFn - Override exec for testing; default routes through
134
+ * platform/spawn.ts (cross-spawn, win32 .cmd shim safe)
86
135
  */
87
136
  export function runInstallLatest(opts) {
88
137
  // If packageManager is explicitly null, skip detection and fail immediately.
@@ -104,7 +153,7 @@ export function runInstallLatest(opts) {
104
153
  });
105
154
  }
106
155
  const { cmd, args } = getInstallCommand(pm);
107
- const execFn = opts?.execFn ?? ((...args) => execFile(...args));
156
+ const execFn = opts?.execFn ?? execViaSpawnProcess;
108
157
  const logger = getLogger();
109
158
  logger.info(`[update] running: ${cmd} ${args.join(' ')}`);
110
159
  return new Promise((resolve) => {
@@ -29,3 +29,8 @@ export declare function checkLatestVersion(opts?: {
29
29
  bypassCache?: boolean;
30
30
  registryUrl?: string;
31
31
  }): Promise<VersionCheckResult>;
32
+ /**
33
+ * Format an update hint string for the startup notification.
34
+ * Returns null if no newer version is available.
35
+ */
36
+ export declare function formatUpdateHint(current: string, latest: string): string | null;
@@ -146,4 +146,13 @@ export async function checkLatestVersion(opts) {
146
146
  }
147
147
  return { current, latest };
148
148
  }
149
+ /**
150
+ * Format an update hint string for the startup notification.
151
+ * Returns null if no newer version is available.
152
+ */
153
+ export function formatUpdateHint(current, latest) {
154
+ if (!isNewer(current, latest))
155
+ return null;
156
+ return `📦 有新版本 ${latest} 可用(当前 ${current}),发送 /update 升级`;
157
+ }
149
158
  //# sourceMappingURL=version-check.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lark-remote",
3
- "version": "0.1.13",
3
+ "version": "0.2.1",
4
4
  "description": "Feishu (Lark) private-chat bridge to local coding agents — Claude Code / Codex / opencode / pi / kimi, with live-streaming CardKit 2.0 cards",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -25,8 +25,9 @@
25
25
  ],
26
26
  "scripts": {
27
27
  "dev": "bun src/index.ts",
28
- "build": "rm -rf dist && tsc && chmod +x dist/index.js dist/cli.js",
29
- "typecheck": "tsc --noEmit",
28
+ "build": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\" && tsc && node -e \"if(process.platform!=='win32'){const fs=require('fs');for(const f of ['dist/index.js','dist/cli.js'])fs.chmodSync(f,0o755)}\"",
29
+ "typecheck": "tsc --noEmit && tsc -p tsconfig.test-infra.json",
30
+ "typecheck:test-infra": "tsc -p tsconfig.test-infra.json",
30
31
  "lint": "eslint src tests",
31
32
  "lint:fix": "eslint src tests --fix",
32
33
  "format": "prettier --write 'src/**/*.ts' 'tests/**/*.ts'",
@@ -42,6 +43,7 @@
42
43
  "test:config": "vitest run --project infra-config",
43
44
  "test:order": "vitest run --project infra-order",
44
45
  "test:misc": "vitest run --project infra-misc",
46
+ "test:platform": "vitest run --project infra-platform",
45
47
  "test:claude": "vitest run --project agent-claude",
46
48
  "test:codex": "vitest run --project agent-codex",
47
49
  "test:opencode": "vitest run --project agent-opencode",
@@ -57,7 +59,7 @@
57
59
  "test:pi-full": "vitest run --project agent-pi --project infra-runner --project infra-session",
58
60
  "test:kimi-full": "vitest run --project agent-kimi --project infra-runner --project infra-session",
59
61
  "test:live": "vitest run --project live",
60
- "prepublishOnly": "tsc --noEmit && vitest run && rm -rf dist && tsc && chmod +x dist/index.js dist/cli.js",
62
+ "prepublishOnly": "npm run typecheck && vitest run && npm run build",
61
63
  "prepack": "node -e \"const fs=require('fs');if(!fs.existsSync('dist/cli.js')){console.error('dist/ missing — run bun run build first');process.exit(1)}\""
62
64
  },
63
65
  "publishConfig": {
@@ -94,15 +96,16 @@
94
96
  "@iarna/toml": "^2.2.5",
95
97
  "@larksuite/channel": "^0.3.0",
96
98
  "axios": "^1.18.0",
99
+ "cross-spawn": "^7.0.6",
97
100
  "form-data": "^4.0.6",
98
- "qrcode-terminal": "^0.12.0",
101
+ "qrcode-generator": "^2.0.4",
99
102
  "yaml": "^2.9.0",
100
103
  "zod": "^4.4.3"
101
104
  },
102
105
  "devDependencies": {
103
106
  "@eslint/js": "^10.0.1",
107
+ "@types/cross-spawn": "^6.0.6",
104
108
  "@types/node": "^26.1.2",
105
- "@types/qrcode-terminal": "^0.12.2",
106
109
  "@vitest/coverage-v8": "4.1.10",
107
110
  "eslint": "^10.7.0",
108
111
  "eslint-config-prettier": "^10.1.8",
@@ -1,5 +0,0 @@
1
- /**
2
- * Format an update hint string for the startup notification.
3
- * Returns null if no newer version is available.
4
- */
5
- export declare function formatUpdateHint(current: string, latest: string): string | null;
@@ -1,11 +0,0 @@
1
- import { isNewer } from './version-check.js';
2
- /**
3
- * Format an update hint string for the startup notification.
4
- * Returns null if no newer version is available.
5
- */
6
- export function formatUpdateHint(current, latest) {
7
- if (!isNewer(current, latest))
8
- return null;
9
- return `📦 有新版本 ${latest} 可用(当前 ${current}),发送 /update 升级`;
10
- }
11
- //# sourceMappingURL=startup-hint.js.map