@caoruhua/open-claude-remote 0.1.0

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 (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +449 -0
  3. package/dist/api/auth-routes.d.ts +4 -0
  4. package/dist/api/auth-routes.d.ts.map +1 -0
  5. package/dist/api/auth-routes.js +7 -0
  6. package/dist/api/auth-routes.js.map +1 -0
  7. package/dist/api/config-routes.d.ts +4 -0
  8. package/dist/api/config-routes.d.ts.map +1 -0
  9. package/dist/api/config-routes.js +180 -0
  10. package/dist/api/config-routes.js.map +1 -0
  11. package/dist/api/health-routes.d.ts +3 -0
  12. package/dist/api/health-routes.d.ts.map +1 -0
  13. package/dist/api/health-routes.js +9 -0
  14. package/dist/api/health-routes.js.map +1 -0
  15. package/dist/api/hook-routes.d.ts +4 -0
  16. package/dist/api/hook-routes.d.ts.map +1 -0
  17. package/dist/api/hook-routes.js +32 -0
  18. package/dist/api/hook-routes.js.map +1 -0
  19. package/dist/api/instance-routes.d.ts +20 -0
  20. package/dist/api/instance-routes.d.ts.map +1 -0
  21. package/dist/api/instance-routes.js +128 -0
  22. package/dist/api/instance-routes.js.map +1 -0
  23. package/dist/api/push-routes.d.ts +5 -0
  24. package/dist/api/push-routes.d.ts.map +1 -0
  25. package/dist/api/push-routes.js +45 -0
  26. package/dist/api/push-routes.js.map +1 -0
  27. package/dist/api/router.d.ts +19 -0
  28. package/dist/api/router.d.ts.map +1 -0
  29. package/dist/api/router.js +37 -0
  30. package/dist/api/router.js.map +1 -0
  31. package/dist/api/status-routes.d.ts +5 -0
  32. package/dist/api/status-routes.d.ts.map +1 -0
  33. package/dist/api/status-routes.js +17 -0
  34. package/dist/api/status-routes.js.map +1 -0
  35. package/dist/attach.d.ts +9 -0
  36. package/dist/attach.d.ts.map +1 -0
  37. package/dist/attach.js +155 -0
  38. package/dist/attach.js.map +1 -0
  39. package/dist/auth/auth-middleware.d.ts +52 -0
  40. package/dist/auth/auth-middleware.d.ts.map +1 -0
  41. package/dist/auth/auth-middleware.js +124 -0
  42. package/dist/auth/auth-middleware.js.map +1 -0
  43. package/dist/auth/rate-limiter.d.ts +37 -0
  44. package/dist/auth/rate-limiter.d.ts.map +1 -0
  45. package/dist/auth/rate-limiter.js +81 -0
  46. package/dist/auth/rate-limiter.js.map +1 -0
  47. package/dist/auth/token-generator.d.ts +9 -0
  48. package/dist/auth/token-generator.d.ts.map +1 -0
  49. package/dist/auth/token-generator.js +15 -0
  50. package/dist/auth/token-generator.js.map +1 -0
  51. package/dist/cli-utils.d.ts +19 -0
  52. package/dist/cli-utils.d.ts.map +1 -0
  53. package/dist/cli-utils.js +132 -0
  54. package/dist/cli-utils.js.map +1 -0
  55. package/dist/cli.d.ts +21 -0
  56. package/dist/cli.d.ts.map +1 -0
  57. package/dist/cli.js +58 -0
  58. package/dist/cli.js.map +1 -0
  59. package/dist/config.d.ts +146 -0
  60. package/dist/config.d.ts.map +1 -0
  61. package/dist/config.js +329 -0
  62. package/dist/config.js.map +1 -0
  63. package/dist/hooks/hook-receiver.d.ts +39 -0
  64. package/dist/hooks/hook-receiver.d.ts.map +1 -0
  65. package/dist/hooks/hook-receiver.js +46 -0
  66. package/dist/hooks/hook-receiver.js.map +1 -0
  67. package/dist/index.d.ts +3 -0
  68. package/dist/index.d.ts.map +1 -0
  69. package/dist/index.js +353 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/logger/logger.d.ts +8 -0
  72. package/dist/logger/logger.d.ts.map +1 -0
  73. package/dist/logger/logger.js +90 -0
  74. package/dist/logger/logger.js.map +1 -0
  75. package/dist/notification/dingtalk-service.d.ts +24 -0
  76. package/dist/notification/dingtalk-service.d.ts.map +1 -0
  77. package/dist/notification/dingtalk-service.js +94 -0
  78. package/dist/notification/dingtalk-service.js.map +1 -0
  79. package/dist/pty/output-buffer.d.ts +25 -0
  80. package/dist/pty/output-buffer.d.ts.map +1 -0
  81. package/dist/pty/output-buffer.js +58 -0
  82. package/dist/pty/output-buffer.js.map +1 -0
  83. package/dist/pty/pty-manager.d.ts +45 -0
  84. package/dist/pty/pty-manager.d.ts.map +1 -0
  85. package/dist/pty/pty-manager.js +108 -0
  86. package/dist/pty/pty-manager.js.map +1 -0
  87. package/dist/pty/types.d.ts +11 -0
  88. package/dist/pty/types.d.ts.map +1 -0
  89. package/dist/pty/types.js +2 -0
  90. package/dist/pty/types.js.map +1 -0
  91. package/dist/pty/virtual-pty.d.ts +37 -0
  92. package/dist/pty/virtual-pty.d.ts.map +1 -0
  93. package/dist/pty/virtual-pty.js +161 -0
  94. package/dist/pty/virtual-pty.js.map +1 -0
  95. package/dist/push/push-service.d.ts +87 -0
  96. package/dist/push/push-service.d.ts.map +1 -0
  97. package/dist/push/push-service.js +301 -0
  98. package/dist/push/push-service.js.map +1 -0
  99. package/dist/registry/instance-registry.d.ts +32 -0
  100. package/dist/registry/instance-registry.d.ts.map +1 -0
  101. package/dist/registry/instance-registry.js +115 -0
  102. package/dist/registry/instance-registry.js.map +1 -0
  103. package/dist/registry/instance-spawner.d.ts +33 -0
  104. package/dist/registry/instance-spawner.d.ts.map +1 -0
  105. package/dist/registry/instance-spawner.js +91 -0
  106. package/dist/registry/instance-spawner.js.map +1 -0
  107. package/dist/registry/port-finder.d.ts +8 -0
  108. package/dist/registry/port-finder.d.ts.map +1 -0
  109. package/dist/registry/port-finder.js +35 -0
  110. package/dist/registry/port-finder.js.map +1 -0
  111. package/dist/registry/shared-token.d.ts +11 -0
  112. package/dist/registry/shared-token.d.ts.map +1 -0
  113. package/dist/registry/shared-token.js +82 -0
  114. package/dist/registry/shared-token.js.map +1 -0
  115. package/dist/registry/stop-instances.d.ts +27 -0
  116. package/dist/registry/stop-instances.d.ts.map +1 -0
  117. package/dist/registry/stop-instances.js +212 -0
  118. package/dist/registry/stop-instances.js.map +1 -0
  119. package/dist/session/session-controller.d.ts +58 -0
  120. package/dist/session/session-controller.d.ts.map +1 -0
  121. package/dist/session/session-controller.js +273 -0
  122. package/dist/session/session-controller.js.map +1 -0
  123. package/dist/terminal/terminal-relay.d.ts +29 -0
  124. package/dist/terminal/terminal-relay.d.ts.map +1 -0
  125. package/dist/terminal/terminal-relay.js +106 -0
  126. package/dist/terminal/terminal-relay.js.map +1 -0
  127. package/dist/utils/ansi-filter.d.ts +41 -0
  128. package/dist/utils/ansi-filter.d.ts.map +1 -0
  129. package/dist/utils/ansi-filter.js +147 -0
  130. package/dist/utils/ansi-filter.js.map +1 -0
  131. package/dist/utils/file-lock.d.ts +23 -0
  132. package/dist/utils/file-lock.d.ts.map +1 -0
  133. package/dist/utils/file-lock.js +125 -0
  134. package/dist/utils/file-lock.js.map +1 -0
  135. package/dist/utils/ip-monitor.d.ts +39 -0
  136. package/dist/utils/ip-monitor.d.ts.map +1 -0
  137. package/dist/utils/ip-monitor.js +114 -0
  138. package/dist/utils/ip-monitor.js.map +1 -0
  139. package/dist/utils/network.d.ts +19 -0
  140. package/dist/utils/network.d.ts.map +1 -0
  141. package/dist/utils/network.js +54 -0
  142. package/dist/utils/network.js.map +1 -0
  143. package/dist/utils/pid-file.d.ts +10 -0
  144. package/dist/utils/pid-file.d.ts.map +1 -0
  145. package/dist/utils/pid-file.js +30 -0
  146. package/dist/utils/pid-file.js.map +1 -0
  147. package/dist/utils/qrcode-banner.d.ts +6 -0
  148. package/dist/utils/qrcode-banner.d.ts.map +1 -0
  149. package/dist/utils/qrcode-banner.js +16 -0
  150. package/dist/utils/qrcode-banner.js.map +1 -0
  151. package/dist/ws/ws-handler.d.ts +10 -0
  152. package/dist/ws/ws-handler.d.ts.map +1 -0
  153. package/dist/ws/ws-handler.js +36 -0
  154. package/dist/ws/ws-handler.js.map +1 -0
  155. package/dist/ws/ws-server.d.ts +78 -0
  156. package/dist/ws/ws-server.d.ts.map +1 -0
  157. package/dist/ws/ws-server.js +223 -0
  158. package/dist/ws/ws-server.js.map +1 -0
  159. package/frontend-dist/assets/index-BKudo1Dw.css +32 -0
  160. package/frontend-dist/assets/index-BqqB1hYe.js +141 -0
  161. package/frontend-dist/index.html +15 -0
  162. package/frontend-dist/sw.js +46 -0
  163. package/package.json +79 -0
  164. package/shared-dist/constants.d.ts +10 -0
  165. package/shared-dist/constants.d.ts.map +1 -0
  166. package/shared-dist/constants.js +10 -0
  167. package/shared-dist/constants.js.map +1 -0
  168. package/shared-dist/defaults.d.ts +30 -0
  169. package/shared-dist/defaults.d.ts.map +1 -0
  170. package/shared-dist/defaults.js +31 -0
  171. package/shared-dist/defaults.js.map +1 -0
  172. package/shared-dist/index.d.ts +5 -0
  173. package/shared-dist/index.d.ts.map +1 -0
  174. package/shared-dist/index.js +5 -0
  175. package/shared-dist/index.js.map +1 -0
  176. package/shared-dist/instance.d.ts +25 -0
  177. package/shared-dist/instance.d.ts.map +1 -0
  178. package/shared-dist/instance.js +7 -0
  179. package/shared-dist/instance.js.map +1 -0
  180. package/shared-dist/question-utils.d.ts +15 -0
  181. package/shared-dist/question-utils.d.ts.map +1 -0
  182. package/shared-dist/question-utils.js +24 -0
  183. package/shared-dist/question-utils.js.map +1 -0
  184. package/shared-dist/ws-protocol.d.ts +60 -0
  185. package/shared-dist/ws-protocol.d.ts.map +1 -0
  186. package/shared-dist/ws-protocol.js +5 -0
  187. package/shared-dist/ws-protocol.js.map +1 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port-finder.js","sourceRoot":"","sources":["../../src/registry/port-finder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C;;GAEG;AACH,SAAS,eAAe,CAAC,IAAY,EAAE,IAAY;IACjD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE;YAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,aAAqB,EACrB,IAAY,EACZ,cAAsB,GAAG;IAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,WAAW,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,aAAa,GAAG,CAAC,CAAC;QAC/B,IAAI,IAAI,GAAG,KAAK;YAAE,MAAM;QAExB,IAAI,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACV,MAAM,CAAC,IAAI,CAAC,EAAE,aAAa,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,4CAA4C,CAAC,CAAC;YACnG,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,yCAAyC,aAAa,UAAU,WAAW,WAAW,CAAC,CAAC;AAC1G,CAAC"}
@@ -0,0 +1,11 @@
1
+ export interface SharedTokenResult {
2
+ token: string;
3
+ source: 'cli' | 'file' | 'generated';
4
+ }
5
+ /**
6
+ * 获取或创建共享 Token。
7
+ * 优先级:CLI 参数 > config.json 中的 token > 自动生成并持久化到 config.json。
8
+ * 支持从旧的 token 文件迁移到 config.json。
9
+ */
10
+ export declare function getOrCreateSharedToken(baseDir: string, cliToken?: string): SharedTokenResult;
11
+ //# sourceMappingURL=shared-token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-token.d.ts","sourceRoot":"","sources":["../../src/registry/shared-token.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,WAAW,CAAC;CACtC;AAyBD;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAqD5F"}
@@ -0,0 +1,82 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync, unlinkSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { generateToken } from '../auth/token-generator.js';
4
+ import { logger } from '../logger/logger.js';
5
+ import { withFileLock } from '../utils/file-lock.js';
6
+ /**
7
+ * 读取 config.json 文件
8
+ */
9
+ function loadConfigFile(configPath) {
10
+ try {
11
+ if (!existsSync(configPath)) {
12
+ return null;
13
+ }
14
+ const content = readFileSync(configPath, 'utf-8');
15
+ return JSON.parse(content);
16
+ }
17
+ catch (err) {
18
+ logger.warn({ err, configPath }, 'Failed to read config.json');
19
+ return null;
20
+ }
21
+ }
22
+ /**
23
+ * 保存 config.json 文件
24
+ */
25
+ function saveConfigFile(configPath, config) {
26
+ writeFileSync(configPath, JSON.stringify(config, null, 2), { mode: 0o600 });
27
+ }
28
+ /**
29
+ * 获取或创建共享 Token。
30
+ * 优先级:CLI 参数 > config.json 中的 token > 自动生成并持久化到 config.json。
31
+ * 支持从旧的 token 文件迁移到 config.json。
32
+ */
33
+ export function getOrCreateSharedToken(baseDir, cliToken) {
34
+ // 1. CLI 参数最高优先级
35
+ if (cliToken) {
36
+ logger.info('Using token from CLI argument');
37
+ return { token: cliToken, source: 'cli' };
38
+ }
39
+ // 确保目录存在
40
+ if (!existsSync(baseDir)) {
41
+ mkdirSync(baseDir, { recursive: true, mode: 0o700 });
42
+ logger.info({ dir: baseDir }, 'Created shared config directory');
43
+ }
44
+ const configPath = join(baseDir, 'config.json');
45
+ const lockPath = configPath + '.lock';
46
+ // 使用文件锁防止多实例并发生成不同 token
47
+ return withFileLock(lockPath, () => {
48
+ // 锁内 double-check:另一个进程可能已写入 token
49
+ let config = loadConfigFile(configPath);
50
+ // 2. 如果 config.json 有有效 token,直接返回
51
+ if (config?.token?.trim()) {
52
+ logger.info('Using token from config.json');
53
+ return { token: config.token.trim(), source: 'file' };
54
+ }
55
+ // 3. 迁移:检查旧 token 文件是否存在
56
+ const oldTokenPath = join(baseDir, 'token');
57
+ if (existsSync(oldTokenPath)) {
58
+ try {
59
+ const oldToken = readFileSync(oldTokenPath, 'utf-8').trim();
60
+ if (oldToken) {
61
+ config = config ?? {};
62
+ config.token = oldToken;
63
+ saveConfigFile(configPath, config);
64
+ unlinkSync(oldTokenPath);
65
+ logger.info({ configPath }, 'Migrated token from old file to config.json');
66
+ return { token: oldToken, source: 'file' };
67
+ }
68
+ }
69
+ catch (err) {
70
+ logger.warn({ err, oldTokenPath }, 'Failed to migrate old token file');
71
+ }
72
+ }
73
+ // 4. 生成新 Token 并写入 config.json
74
+ const newToken = generateToken();
75
+ config = config ?? {};
76
+ config.token = newToken;
77
+ saveConfigFile(configPath, config);
78
+ logger.info({ configPath }, 'Generated and saved new token to config.json');
79
+ return { token: newToken, source: 'generated' };
80
+ });
81
+ }
82
+ //# sourceMappingURL=shared-token.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-token.js","sourceRoot":"","sources":["../../src/registry/shared-token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAQrD;;GAEG;AACH,SAAS,cAAc,CAAC,UAAkB;IACxC,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,OAAO,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAe,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,EAAE,4BAA4B,CAAC,CAAC;QAC/D,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,UAAkB,EAAE,MAAkB;IAC5D,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC9E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,OAAe,EAAE,QAAiB;IACvE,iBAAiB;IACjB,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;QAC7C,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC5C,CAAC;IAED,SAAS;IACT,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACrD,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,iCAAiC,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IAEtC,yBAAyB;IACzB,OAAO,YAAY,CAAC,QAAQ,EAAE,GAAG,EAAE;QACjC,mCAAmC;QACnC,IAAI,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QAExC,mCAAmC;QACnC,IAAI,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAC;YAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAe,EAAE,CAAC;QACjE,CAAC;QAED,yBAAyB;QACzB,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;gBAC5D,IAAI,QAAQ,EAAE,CAAC;oBACb,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;oBACtB,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC;oBACxB,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;oBACnC,UAAU,CAAC,YAAY,CAAC,CAAC;oBACzB,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,EAAE,6CAA6C,CAAC,CAAC;oBAC3E,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAe,EAAE,CAAC;gBACtD,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,kCAAkC,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAED,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;QACjC,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;QACtB,MAAM,CAAC,KAAK,GAAG,QAAQ,CAAC;QACxB,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,EAAE,8CAA8C,CAAC,CAAC;QAC5E,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAoB,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { InstanceInfo } from '@claude-remote/shared';
2
+ import { InstanceRegistryManager } from './instance-registry.js';
3
+ export interface StopFailure {
4
+ instanceId: string;
5
+ name: string;
6
+ port: number;
7
+ pid: number;
8
+ reason: string;
9
+ }
10
+ export interface StopSummary {
11
+ total: number;
12
+ stopped: number;
13
+ failed: number;
14
+ failures: StopFailure[];
15
+ }
16
+ export interface StopInstancesOptions {
17
+ gracePeriodMs?: number;
18
+ pollIntervalMs?: number;
19
+ killSignal?: NodeJS.Signals;
20
+ signalSender?: (pid: number, signal: NodeJS.Signals | 0) => void;
21
+ sleep?: (ms: number) => Promise<void>;
22
+ processVerifier?: (instance: InstanceInfo) => Promise<boolean> | boolean;
23
+ }
24
+ export declare function stopInstances(registry: InstanceRegistryManager, options?: StopInstancesOptions): Promise<StopSummary>;
25
+ export declare function stopAllRegisteredInstances(options?: StopInstancesOptions): Promise<StopSummary>;
26
+ export declare function main(): Promise<void>;
27
+ //# sourceMappingURL=stop-instances.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-instances.d.ts","sourceRoot":"","sources":["../../src/registry/stop-instances.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;IAC5B,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,GAAG,CAAC,KAAK,IAAI,CAAC;IACjE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,eAAe,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAC1E;AAsED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,uBAAuB,EACjC,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,WAAW,CAAC,CAyFtB;AAoED,wBAAsB,0BAA0B,CAAC,OAAO,GAAE,oBAAyB,GAAG,OAAO,CAAC,WAAW,CAAC,CAIzG;AAED,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAmB1C"}
@@ -0,0 +1,212 @@
1
+ import { homedir } from 'node:os';
2
+ import { resolve } from 'node:path';
3
+ import { execFileSync } from 'node:child_process';
4
+ import { CLAUDE_REMOTE_DIR } from '../../shared-dist/index.js';
5
+ import { logger } from '../logger/logger.js';
6
+ import { InstanceRegistryManager } from './instance-registry.js';
7
+ const DEFAULT_GRACE_PERIOD_MS = 5_000;
8
+ const DEFAULT_POLL_INTERVAL_MS = 200;
9
+ function createProcessVerifier(signalSender) {
10
+ return (instance) => {
11
+ // 先确认 PID 仍存在
12
+ try {
13
+ signalSender(instance.pid, 0);
14
+ }
15
+ catch {
16
+ return false;
17
+ }
18
+ // 再确认该 PID 仍在监听注册端口,降低 PID 复用误杀风险
19
+ try {
20
+ const output = execFileSync('lsof', ['-nP', `-iTCP:${instance.port}`, '-sTCP:LISTEN', '-Fp'], {
21
+ encoding: 'utf-8',
22
+ });
23
+ const pids = output
24
+ .split('\n')
25
+ .filter((line) => line.startsWith('p'))
26
+ .map((line) => Number(line.slice(1)))
27
+ .filter((pid) => Number.isInteger(pid));
28
+ return pids.includes(instance.pid);
29
+ }
30
+ catch (err) {
31
+ logger.warn({ err, pid: instance.pid, port: instance.port }, 'Process verification via lsof failed, fallback to PID-only check');
32
+ return true;
33
+ }
34
+ };
35
+ }
36
+ function createSleep() {
37
+ return (ms) => new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
38
+ }
39
+ function createSignalSender() {
40
+ return (pid, signal) => {
41
+ process.kill(pid, signal);
42
+ };
43
+ }
44
+ function createIsAlive(signalSender) {
45
+ return (pid) => {
46
+ try {
47
+ signalSender(pid, 0);
48
+ return true;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ };
54
+ }
55
+ async function waitForExit(pid, timeoutMs, pollIntervalMs, isAlive, sleep) {
56
+ const deadline = Date.now() + timeoutMs;
57
+ while (Date.now() < deadline) {
58
+ if (!isAlive(pid)) {
59
+ return true;
60
+ }
61
+ await sleep(pollIntervalMs);
62
+ }
63
+ return !isAlive(pid);
64
+ }
65
+ export async function stopInstances(registry, options = {}) {
66
+ const gracePeriodMs = options.gracePeriodMs ?? DEFAULT_GRACE_PERIOD_MS;
67
+ const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
68
+ const killSignal = options.killSignal ?? 'SIGKILL';
69
+ const signalSender = options.signalSender ?? createSignalSender();
70
+ const sleep = options.sleep ?? createSleep();
71
+ const isAlive = createIsAlive(signalSender);
72
+ const processVerifier = options.processVerifier ?? createProcessVerifier(signalSender);
73
+ const instances = await registry.list();
74
+ const summary = {
75
+ total: instances.length,
76
+ stopped: 0,
77
+ failed: 0,
78
+ failures: [],
79
+ };
80
+ logger.info({ total: instances.length }, 'Starting multi-instance stop');
81
+ if (instances.length === 0) {
82
+ logger.info('No active instances found, stop is idempotent');
83
+ return summary;
84
+ }
85
+ for (const instance of instances) {
86
+ const verified = await processVerifier(instance);
87
+ if (!verified) {
88
+ summary.failed += 1;
89
+ summary.failures.push({
90
+ instanceId: instance.instanceId,
91
+ name: instance.name,
92
+ port: instance.port,
93
+ pid: instance.pid,
94
+ reason: 'Process verification failed: pid/port mismatch',
95
+ });
96
+ logger.error({
97
+ instanceId: instance.instanceId,
98
+ name: instance.name,
99
+ pid: instance.pid,
100
+ port: instance.port,
101
+ }, 'Skip stopping instance due to process verification failure');
102
+ continue;
103
+ }
104
+ const result = await stopSingleInstance(instance, {
105
+ gracePeriodMs,
106
+ pollIntervalMs,
107
+ killSignal,
108
+ signalSender,
109
+ sleep,
110
+ isAlive,
111
+ });
112
+ if (result.ok) {
113
+ summary.stopped += 1;
114
+ registry.unregister(instance.instanceId);
115
+ logger.info({
116
+ instanceId: instance.instanceId,
117
+ name: instance.name,
118
+ pid: instance.pid,
119
+ port: instance.port,
120
+ }, 'Instance stopped');
121
+ }
122
+ else {
123
+ summary.failed += 1;
124
+ summary.failures.push({
125
+ instanceId: instance.instanceId,
126
+ name: instance.name,
127
+ port: instance.port,
128
+ pid: instance.pid,
129
+ reason: result.reason,
130
+ });
131
+ logger.error({
132
+ instanceId: instance.instanceId,
133
+ name: instance.name,
134
+ pid: instance.pid,
135
+ port: instance.port,
136
+ reason: result.reason,
137
+ }, 'Failed to stop instance');
138
+ }
139
+ }
140
+ logger.info({
141
+ total: summary.total,
142
+ stopped: summary.stopped,
143
+ failed: summary.failed,
144
+ failures: summary.failures,
145
+ }, 'Multi-instance stop summary');
146
+ return summary;
147
+ }
148
+ async function stopSingleInstance(instance, ctx) {
149
+ const { gracePeriodMs, pollIntervalMs, killSignal, signalSender, sleep, isAlive } = ctx;
150
+ try {
151
+ signalSender(instance.pid, 'SIGTERM');
152
+ }
153
+ catch (err) {
154
+ const code = err.code;
155
+ if (code === 'ESRCH') {
156
+ return { ok: true };
157
+ }
158
+ return { ok: false, reason: `SIGTERM failed: ${String(code ?? err)}` };
159
+ }
160
+ const exitedGracefully = await waitForExit(instance.pid, gracePeriodMs, pollIntervalMs, isAlive, sleep);
161
+ if (exitedGracefully) {
162
+ return { ok: true };
163
+ }
164
+ logger.warn({
165
+ instanceId: instance.instanceId,
166
+ pid: instance.pid,
167
+ killSignal,
168
+ }, 'Graceful stop timed out, sending fallback signal');
169
+ try {
170
+ signalSender(instance.pid, killSignal);
171
+ }
172
+ catch (err) {
173
+ const code = err.code;
174
+ if (code === 'ESRCH') {
175
+ return { ok: true };
176
+ }
177
+ return { ok: false, reason: `${killSignal} failed: ${String(code ?? err)}` };
178
+ }
179
+ const exitedAfterKill = await waitForExit(instance.pid, Math.max(pollIntervalMs * 2, 300), pollIntervalMs, isAlive, sleep);
180
+ if (!exitedAfterKill) {
181
+ return { ok: false, reason: `Process still alive after ${killSignal}` };
182
+ }
183
+ return { ok: true };
184
+ }
185
+ export async function stopAllRegisteredInstances(options = {}) {
186
+ const sharedConfigDir = resolve(homedir(), CLAUDE_REMOTE_DIR);
187
+ const registry = new InstanceRegistryManager(sharedConfigDir);
188
+ return stopInstances(registry, options);
189
+ }
190
+ export async function main() {
191
+ try {
192
+ const summary = await stopAllRegisteredInstances();
193
+ if (summary.failed > 0) {
194
+ process.stderr.write(`Failed to stop ${summary.failed}/${summary.total} instance(s).\n`);
195
+ for (const failure of summary.failures) {
196
+ process.stderr.write(`- ${failure.name} (${failure.instanceId}, pid=${failure.pid}, port=${failure.port}): ${failure.reason}\n`);
197
+ }
198
+ process.exit(1);
199
+ }
200
+ process.stderr.write(`Stopped ${summary.stopped} instance(s).\n`);
201
+ process.exit(0);
202
+ }
203
+ catch (err) {
204
+ logger.error({ err }, 'Unexpected error while stopping instances');
205
+ process.stderr.write(`Stop failed: ${String(err)}\n`);
206
+ process.exit(1);
207
+ }
208
+ }
209
+ if (import.meta.url === `file://${process.argv[1]}`) {
210
+ void main();
211
+ }
212
+ //# sourceMappingURL=stop-instances.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop-instances.js","sourceRoot":"","sources":["../../src/registry/stop-instances.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,58 @@
1
+ import type { SessionStatus } from '@claude-remote/shared';
2
+ import { PtyManager } from '../pty/pty-manager.js';
3
+ import { WsServer } from '../ws/ws-server.js';
4
+ import { HookReceiver } from '../hooks/hook-receiver.js';
5
+ import type { PushService } from '../push/push-service.js';
6
+ import type { TerminalRelay } from '../terminal/terminal-relay.js';
7
+ import type { DingtalkService } from '../notification/dingtalk-service.js';
8
+ /**
9
+ * Core coordinator: wires PTY ↔ WebSocket ↔ Terminal ↔ Hooks.
10
+ */
11
+ export declare class SessionController {
12
+ private ptyManager;
13
+ private wsServer;
14
+ private hookReceiver;
15
+ private terminalRelay?;
16
+ private _status;
17
+ private buffer;
18
+ private pushService;
19
+ private dingtalkService;
20
+ private wsPendingChunks;
21
+ private wsPendingBytes;
22
+ private wsFlushTimer;
23
+ private ptyInputBytesTotal;
24
+ private wsFlushCount;
25
+ private wsFlushBytesTotal;
26
+ private wsMaxPendingBytes;
27
+ private wsBackpressureEvents;
28
+ constructor(ptyManager: PtyManager, wsServer: WsServer, hookReceiver: HookReceiver, maxBufferLines: number, terminalRelay?: TerminalRelay | undefined);
29
+ get status(): SessionStatus;
30
+ get connectedClients(): number;
31
+ /**
32
+ * Inject PushService for hook-triggered notifications.
33
+ */
34
+ setPushService(pushService: PushService): void;
35
+ /**
36
+ * Inject DingtalkService for hook-triggered notifications.
37
+ */
38
+ setDingtalkService(dingtalkService: DingtalkService): void;
39
+ /**
40
+ * Wire PTY output → buffer + WS broadcast + process.stdout
41
+ */
42
+ private setupPtyHandlers;
43
+ private enqueueWsOutput;
44
+ private flushPendingWsOutput;
45
+ /**
46
+ * Wire WS messages → PTY input
47
+ */
48
+ private setupWsHandlers;
49
+ /**
50
+ * Wire Hook notifications → status update + Push notification
51
+ */
52
+ private setupHookHandlers;
53
+ /**
54
+ * Update session status.
55
+ */
56
+ setStatus(status: SessionStatus): void;
57
+ }
58
+ //# sourceMappingURL=session-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-controller.d.ts","sourceRoot":"","sources":["../../src/session/session-controller.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAmB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,YAAY,EAAyB,MAAM,2BAA2B,CAAC;AAGhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qCAAqC,CAAC;AAM3E;;GAEG;AACH,qBAAa,iBAAiB;IAiB1B,OAAO,CAAC,UAAU;IAClB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,YAAY;IAEpB,OAAO,CAAC,aAAa,CAAC;IApBxB,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,eAAe,CAAgC;IAEvD,OAAO,CAAC,eAAe,CAAgB;IACvC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,YAAY,CAA+B;IAEnD,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,oBAAoB,CAAK;gBAGvB,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,QAAQ,EAClB,YAAY,EAAE,YAAY,EAClC,cAAc,EAAE,MAAM,EACd,aAAa,CAAC,EAAE,aAAa,YAAA;IAQvC,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAE7B;IAED;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;IAI9C;;OAEG;IACH,kBAAkB,CAAC,eAAe,EAAE,eAAe,GAAG,IAAI;IAI1D;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqDxB,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,oBAAoB;IAiC5B;;OAEG;IACH,OAAO,CAAC,eAAe;IAkFvB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAqCzB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI;CAIvC"}