tirtc-devtools-cli 0.0.13 → 0.0.14

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 (137) hide show
  1. package/README.md +42 -46
  2. package/USAGE.md +87 -312
  3. package/dist/cli/src/embedded_paths.d.ts +0 -2
  4. package/dist/cli/src/embedded_paths.js +3 -25
  5. package/dist/cli/src/index.js +82 -584
  6. package/dist/cli/src/role_driver.d.ts +33 -0
  7. package/dist/cli/src/role_driver.js +500 -0
  8. package/dist/cli/src/token_command.js +4 -2
  9. package/dist/cli/src/token_issue.d.ts +9 -0
  10. package/dist/cli/src/token_issue.js +138 -0
  11. package/dist/cli/src/token_tool.d.ts +2 -4
  12. package/dist/cli/src/token_tool.js +12 -186
  13. package/package.json +1 -1
  14. package/vendor/devtools/driver/macos-arm64/devtools_driver_probe +0 -0
  15. package/vendor/devtools/driver/macos-arm64/runtime_validation_client_bin +0 -0
  16. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio.h +56 -2
  17. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io.h +9 -0
  18. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/av.h +52 -0
  19. package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/error.h +11 -0
  20. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_downlink.h +11 -5
  21. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_uplink.h +4 -0
  22. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/transport.h +52 -15
  23. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/trp.h +7 -5
  24. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_codec.h +41 -0
  25. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io.h +7 -0
  26. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_android.h +2 -0
  27. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_audio.a +0 -0
  28. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
  29. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_foundation_http.a +0 -0
  30. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libmatrix_runtime_foundation_logging.a +0 -0
  31. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
  32. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
  33. package/vendor/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
  34. package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/manifest.txt +20 -25
  35. package/vendor/runtime/script/prepare_runtime_media_dataset.sh +308 -12
  36. package/dist/app-server/protocol-client/index.d.ts +0 -25
  37. package/dist/app-server/protocol-client/index.js +0 -114
  38. package/dist/cli/src/bootstrap_flows.d.ts +0 -46
  39. package/dist/cli/src/bootstrap_flows.js +0 -249
  40. package/dist/cli/src/config.d.ts +0 -26
  41. package/dist/cli/src/config.js +0 -62
  42. package/dist/cli/src/facade.d.ts +0 -430
  43. package/dist/cli/src/facade.js +0 -170
  44. package/dist/cli/src/guide.d.ts +0 -1
  45. package/dist/cli/src/guide.js +0 -48
  46. package/dist/cli/src/session_manager.d.ts +0 -25
  47. package/dist/cli/src/session_manager.js +0 -391
  48. package/dist/cli/src/transport.d.ts +0 -30
  49. package/dist/cli/src/transport.js +0 -84
  50. package/vendor/app-server/bin/native/linux-x64/credential_napi.node +0 -0
  51. package/vendor/app-server/bin/native/macos-arm64/credential_napi.node +0 -0
  52. package/vendor/app-server/bin/runtime/linux-x64/include/tirtc/credential.h +0 -34
  53. package/vendor/app-server/bin/runtime/linux-x64/lib/libcrypto.a +0 -0
  54. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_credential.a +0 -0
  55. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_http.a +0 -0
  56. package/vendor/app-server/bin/runtime/linux-x64/lib/libmatrix_runtime_foundation_logging.a +0 -0
  57. package/vendor/app-server/bin/runtime/linux-x64/lib/libssl.a +0 -0
  58. package/vendor/app-server/bin/runtime/linux-x64/lib/libxlog.a +0 -0
  59. package/vendor/app-server/bin/runtime/linux-x64/manifest.txt +0 -4
  60. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/credential.h +0 -34
  61. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/error.h +0 -52
  62. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/foundation/build_info.h +0 -27
  63. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/http.h +0 -57
  64. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/logging.h +0 -55
  65. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_av_sync.h +0 -61
  66. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_fixture_source.h +0 -77
  67. package/vendor/app-server/bin/runtime/macos-arm64/include/tirtc/media_live_source.h +0 -71
  68. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_credential.a +0 -0
  69. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_facade.a +0 -0
  70. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_media.a +0 -0
  71. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_transport.a +0 -0
  72. package/vendor/app-server/bin/runtime/macos-arm64/lib/libmatrix_runtime_video.a +0 -0
  73. package/vendor/app-server/bin/tirtc-devtool-host.js +0 -2
  74. package/vendor/app-server/dist/host/ArtifactManager.d.ts +0 -18
  75. package/vendor/app-server/dist/host/ArtifactManager.js +0 -98
  76. package/vendor/app-server/dist/host/HostCommandCoordinator.d.ts +0 -19
  77. package/vendor/app-server/dist/host/HostCommandCoordinator.js +0 -196
  78. package/vendor/app-server/dist/host/HostProtocol.d.ts +0 -103
  79. package/vendor/app-server/dist/host/HostProtocol.js +0 -239
  80. package/vendor/app-server/dist/host/HostServer.d.ts +0 -52
  81. package/vendor/app-server/dist/host/HostServer.js +0 -727
  82. package/vendor/app-server/dist/host/HostState.d.ts +0 -69
  83. package/vendor/app-server/dist/host/HostState.js +0 -19
  84. package/vendor/app-server/dist/host/RuntimeAdapter.d.ts +0 -95
  85. package/vendor/app-server/dist/host/RuntimeAdapter.js +0 -636
  86. package/vendor/app-server/dist/host/RuntimeReceiveWorker.d.ts +0 -37
  87. package/vendor/app-server/dist/host/RuntimeReceiveWorker.js +0 -186
  88. package/vendor/app-server/dist/host/RuntimeSendWorker.d.ts +0 -58
  89. package/vendor/app-server/dist/host/RuntimeSendWorker.js +0 -438
  90. package/vendor/app-server/dist/host/TokenTool.d.ts +0 -15
  91. package/vendor/app-server/dist/host/TokenTool.js +0 -84
  92. package/vendor/app-server/dist/host/WebPreviewGateway.d.ts +0 -28
  93. package/vendor/app-server/dist/host/WebPreviewGateway.js +0 -815
  94. package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.d.ts +0 -23
  95. package/vendor/app-server/dist/host/native/RuntimeCredentialTokenIssuer.js +0 -115
  96. package/vendor/app-server/dist/host/native/RuntimeHostBridge.d.ts +0 -32
  97. package/vendor/app-server/dist/host/native/RuntimeHostBridge.js +0 -157
  98. package/vendor/app-server/dist/host/runtime_backed_preflight.d.ts +0 -10
  99. package/vendor/app-server/dist/host/runtime_backed_preflight.js +0 -78
  100. package/vendor/app-server/dist/host/tests/helpers/host_socket_client.d.ts +0 -28
  101. package/vendor/app-server/dist/host/tests/helpers/host_socket_client.js +0 -85
  102. package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.d.ts +0 -10
  103. package/vendor/app-server/dist/host/tests/helpers/runtime_e2e_local_config.js +0 -41
  104. package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.d.ts +0 -11
  105. package/vendor/app-server/dist/host/tests/helpers/runtime_test_env.js +0 -32
  106. package/vendor/app-server/dist/protocol/contract.d.ts +0 -1128
  107. package/vendor/app-server/dist/protocol/contract.js +0 -217
  108. package/vendor/app-server/dist/protocol-client/index.d.ts +0 -25
  109. package/vendor/app-server/dist/protocol-client/index.js +0 -114
  110. package/vendor/app-server/dist/src/index.d.ts +0 -1
  111. package/vendor/app-server/dist/src/index.js +0 -294
  112. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_codec.h +0 -0
  113. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_frame.h +0 -0
  114. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_android.h +0 -0
  115. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_apple.h +0 -0
  116. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_harmony.h +0 -0
  117. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_io_windows.h +0 -0
  118. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_processing.h +0 -0
  119. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/audio_sample_rate.h +0 -0
  120. /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/foundation/build_info.h +0 -0
  121. /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/http.h +0 -0
  122. /package/vendor/{app-server/bin/runtime/linux-x64 → runtime/macos-arm64}/include/tirtc/logging.h +0 -0
  123. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/media_codec.h +0 -0
  124. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_frame.h +0 -0
  125. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_apple.h +0 -0
  126. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_harmony.h +0 -0
  127. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_io_windows.h +0 -0
  128. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/include/tirtc/video_processing.h +0 -0
  129. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libTGTRP.a +0 -0
  130. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libTiRTC.a +0 -0
  131. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libcrypto.a +0 -0
  132. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libcrypto.dylib +0 -0
  133. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libssl.a +0 -0
  134. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libssl.dylib +0 -0
  135. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libtgrtc.dylib +0 -0
  136. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libwebrtc_apm.a +0 -0
  137. /package/vendor/{app-server/bin/runtime → runtime}/macos-arm64/lib/libxlog.a +0 -0
@@ -1,23 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const commander_1 = require("commander");
4
- const protocol_client_1 = require("../../app-server/protocol-client");
5
- const bootstrap_flows_1 = require("./bootstrap_flows");
6
- const config_1 = require("./config");
7
- const facade_1 = require("./facade");
8
- const guide_1 = require("./guide");
9
- const session_manager_1 = require("./session_manager");
10
4
  const media_assets_1 = require("./media_assets");
11
5
  const token_command_1 = require("./token_command");
12
- const transport_1 = require("./transport");
13
- const progress_1 = require("./progress");
14
- const CLI_VERSION = '0.0.13';
15
- const HOST_VERSION = '1.0.0';
16
- const PROTOCOL_VERSION = '1.0.0';
6
+ const role_driver_1 = require("./role_driver");
7
+ const cliVersion = '0.0.14';
17
8
  if (process.argv.includes('--version') || process.argv.includes('-V')) {
18
- console.log('CLI Version: ' + CLI_VERSION);
19
- console.log('Host Version: ' + HOST_VERSION);
20
- console.log('Protocol Version: ' + PROTOCOL_VERSION);
9
+ console.log('CLI Version: ' + cliVersion);
10
+ console.log('DevTools Driver Contract: 1');
21
11
  process.exit(0);
22
12
  }
23
13
  const program = new commander_1.Command();
@@ -48,201 +38,26 @@ function normalizeError(error) {
48
38
  data: undefined,
49
39
  };
50
40
  }
51
- function createSessionTransport(sessionId) {
52
- const session = (0, session_manager_1.resolveSession)(sessionId);
53
- return new transport_1.SocketTransport(session.socketPath);
54
- }
55
- function isBootstrapCommand(cmdName) {
56
- return cmdName === 'service start' || cmdName === 'connection connect' || cmdName === 'client start';
57
- }
58
- function resolveSessionForCommand(cmdName, options) {
59
- if (cmdName === 'connection connect' || cmdName === 'client start') {
60
- if (options.session && options.session.trim().length > 0) {
61
- throw new Error(cmdName + ' always creates a new session; do not pass --session');
62
- }
63
- const created = (0, session_manager_1.createSession)({ role: 'client' });
64
- return { sessionId: created.sessionId, created: true };
65
- }
66
- if (cmdName === 'service start') {
67
- if (options.session && options.session.trim().length > 0) {
68
- const existing = (0, session_manager_1.resolveSession)(options.session);
69
- (0, session_manager_1.setSessionRole)(existing.sessionId, 'service');
70
- return { sessionId: existing.sessionId, created: false };
71
- }
72
- const created = (0, session_manager_1.createSession)({ role: 'service' });
73
- return { sessionId: created.sessionId, created: true };
74
- }
75
- if (cmdName === 'debug bootstrap qrcode') {
76
- const existing = (0, session_manager_1.resolveSession)(options.session);
77
- return { sessionId: existing.sessionId, created: false };
78
- }
79
- if (options.session && options.session.trim().length > 0) {
80
- const existing = (0, session_manager_1.resolveSession)(options.session);
81
- return { sessionId: existing.sessionId, created: false };
82
- }
83
- throw new Error(cmdName + ' requires --session <sessionId>');
84
- }
85
- function printSuccess(options, result, session, cmdName) {
86
- const attachSession = isBootstrapCommand(cmdName);
87
- if (options.json) {
88
- const data = attachSession ? { session: { sessionId: session.sessionId, created: session.created }, result } : result;
89
- console.log(JSON.stringify({ code: 0, message: 'OK', data }));
90
- return;
91
- }
92
- if (attachSession) {
93
- const lifecycle = session.created ? 'created' : 'selected';
94
- console.log('Session ' + lifecycle + ': ' + session.sessionId);
95
- }
96
- console.log('Success:', JSON.stringify(result, null, 2));
97
- }
98
- function toResultObject(result) {
99
- if (typeof result === 'object' && result !== null && !Array.isArray(result)) {
100
- return { ...result };
101
- }
102
- return { result };
103
- }
104
- function requireConfigPath(configPath) {
105
- if (!configPath || configPath.trim().length === 0) {
106
- throw new Error('command requires --config <path>');
107
- }
108
- return configPath;
109
- }
110
- function createProgressIndicator(options) {
41
+ function printError(error, options) {
42
+ const normalized = normalizeError(error);
111
43
  if (options.json) {
112
- return undefined;
113
- }
114
- return new progress_1.ProgressIndicator();
115
- }
116
- async function runCommand(cmdName, params, options) {
117
- let transport;
118
- try {
119
- const config = (0, config_1.loadConfig)(options.config);
120
- const session = resolveSessionForCommand(cmdName, options);
121
- transport = createSessionTransport(session.sessionId);
122
- const client = new protocol_client_1.AppServerClient(transport);
123
- await client.initialize({ name: 'tirtc-devtools-cli', version: CLI_VERSION });
124
- const method = facade_1.CommandToHostMethodMapping[cmdName];
125
- if (!method) {
126
- throw new Error('Unknown command mapping for: ' + cmdName);
127
- }
128
- let resultForPrint;
129
- if (cmdName === 'service start') {
130
- const progress = createProgressIndicator(options);
131
- try {
132
- const autoApplied = await (0, bootstrap_flows_1.applyConfiguredServerBootstrap)(client, config, progress);
133
- progress?.update('Starting service session');
134
- const requestParams = {
135
- ...params,
136
- bootstrapSendStreams: autoApplied.bootstrapSendStreams,
137
- };
138
- const result = await client.sendRequest(method, requestParams, 180_000);
139
- progress?.succeed('Service session is ready');
140
- const resultObject = toResultObject(result);
141
- resultForPrint = {
142
- ...resultObject,
143
- autoApplied,
144
- };
145
- printSuccess(options, resultForPrint, session, cmdName);
146
- transport.stop();
147
- return 0;
148
- }
149
- catch (error) {
150
- progress?.fail('Service start failed');
151
- throw error;
152
- }
153
- }
154
- if (cmdName === 'client start') {
155
- const progress = createProgressIndicator(options);
156
- try {
157
- const token = String(params.token ?? '');
158
- const result = await (0, bootstrap_flows_1.applyClientStartBootstrap)(client, config, token, progress);
159
- printSuccess(options, result, session, cmdName);
160
- transport.stop();
161
- return 0;
162
- }
163
- catch (error) {
164
- progress?.fail('Client start failed');
165
- throw error;
166
- }
167
- }
168
- const result = await client.sendRequest(method, params);
169
- resultForPrint = result;
170
- printSuccess(options, resultForPrint, session, cmdName);
171
- transport.stop();
172
- return 0;
173
- }
174
- catch (error) {
175
- const normalized = normalizeError(error);
176
- const reasonCode = normalized.reasonCode;
177
- const exitCode = facade_1.ErrorReasonCodeMapping[reasonCode] ?? 1;
178
- if (options.json) {
179
- console.log(JSON.stringify({
180
- code: exitCode,
181
- message: normalized.message,
182
- data: normalized.data,
183
- }));
184
- }
185
- else {
186
- console.error('Error (' + reasonCode + '): ' + normalized.message);
187
- }
188
- transport?.stop();
189
- return exitCode;
190
- }
191
- }
192
- async function tailEvents(_cmdName, families, options) {
193
- let transport;
194
- try {
195
- if (!options.session || options.session.trim().length === 0) {
196
- throw new Error('events tail requires --session <sessionId>');
197
- }
198
- const session = (0, session_manager_1.resolveSession)(options.session);
199
- transport = new transport_1.SocketTransport(session.socketPath);
200
- const client = new protocol_client_1.AppServerClient(transport);
201
- client.on('event', (event) => {
202
- console.log(JSON.stringify(event));
203
- });
204
- client.on('error', (error) => {
205
- if (!options.json) {
206
- console.error('Client error:', error);
207
- }
208
- transport?.stop();
209
- });
210
- await client.initialize({ name: 'tirtc-devtools-cli', version: CLI_VERSION });
211
- await client.subscribeEvents(families);
212
- await new Promise((resolve) => {
213
- process.on('SIGINT', () => {
214
- transport?.stop();
215
- resolve();
216
- });
217
- transport?.onClose(() => resolve());
218
- });
219
- return 0;
44
+ console.log(JSON.stringify({
45
+ code: 1,
46
+ message: normalized.message,
47
+ data: normalized.data ?? { reason_code: normalized.reasonCode },
48
+ }));
220
49
  }
221
- catch (error) {
222
- const normalized = normalizeError(error);
223
- const reasonCode = normalized.reasonCode;
224
- const exitCode = facade_1.ErrorReasonCodeMapping[reasonCode] ?? 1;
225
- if (options.json) {
226
- console.log(JSON.stringify({
227
- code: exitCode,
228
- message: normalized.message,
229
- data: normalized.data,
230
- }));
231
- }
232
- else {
233
- console.error('Error (' + reasonCode + '): ' + normalized.message);
234
- }
235
- transport?.stop();
236
- return exitCode;
50
+ else {
51
+ console.error('Error (' + normalized.reasonCode + '): ' + normalized.message);
237
52
  }
53
+ return 1;
238
54
  }
239
- async function runMediaAssetsPrepare(source, outputRoot, outputDir, overwrite, options) {
55
+ async function runAssetsPrepare(commandOptions, options) {
240
56
  try {
241
57
  const result = await (0, media_assets_1.prepareMediaAssets)({
242
- source,
243
- outputRoot,
244
- outputDir,
245
- overwrite,
58
+ source: commandOptions.source ?? 'runtime/assets/source.mp4',
59
+ outputRoot: commandOptions.outputRoot ?? 'runtime/assets/.workspace',
60
+ overwrite: false,
246
61
  });
247
62
  if (options.json) {
248
63
  console.log(JSON.stringify({ code: 0, message: 'OK', data: result }));
@@ -253,394 +68,77 @@ async function runMediaAssetsPrepare(source, outputRoot, outputDir, overwrite, o
253
68
  return 0;
254
69
  }
255
70
  catch (error) {
256
- const normalized = normalizeError(error);
257
- const reasonCode = normalized.reasonCode;
258
- const exitCode = facade_1.ErrorReasonCodeMapping[reasonCode] ?? 1;
259
- if (options.json) {
260
- console.log(JSON.stringify({
261
- code: exitCode,
262
- message: normalized.message,
263
- data: normalized.data,
264
- }));
265
- }
266
- else {
267
- console.error('Error (' + reasonCode + '): ' + normalized.message);
268
- }
269
- return exitCode;
71
+ return printError(error, options);
270
72
  }
271
73
  }
272
74
  function runAndExit(promise) {
273
- promise.then((code) => {
274
- process.exit(code);
275
- });
75
+ promise.then((code) => process.exit(code));
276
76
  }
277
77
  program.name('tirtc-devtools-cli')
278
78
  .description('TiRTC DevTools CLI')
279
- .option('--config <path>', '配置文件路径(TOML)')
280
- .option('--json', '以机器可读 JSON 输出(便于脚本集成)')
281
- .option('--session <sessionId>', '指定会话 ID;除 service start / client start / connection connect 外必须传');
282
- const host = program.command('host').description('Host 基础能力(状态、停止)');
283
- host.command('status').description('查看 Host/service/connection/artifact 当前状态').action(() => {
284
- runAndExit(runCommand('host status', {}, getCliOptions()));
285
- });
286
- host.command('stop')
287
- .description('停止 Host 进程(可用 --all 停止所有会话)')
288
- .option('--all', '停止所有会话对应的 Host 进程')
289
- .action(() => {
290
- const options = getCliOptions();
291
- const stopAll = process.argv.includes('--all');
292
- if (!stopAll) {
293
- runAndExit(runCommand('host stop', {}, options));
294
- return;
295
- }
296
- try {
297
- const stopped = (0, session_manager_1.stopAllSessions)();
298
- if (options.json) {
299
- console.log(JSON.stringify({ code: 0, message: 'OK', data: { count: stopped.length, sessions: stopped } }));
300
- return;
301
- }
302
- console.log('Stopped sessions:', stopped.length);
303
- }
304
- catch (error) {
305
- const normalized = normalizeError(error);
306
- const code = facade_1.ErrorReasonCodeMapping[normalized.reasonCode] ?? 1;
307
- if (options.json) {
308
- console.log(JSON.stringify({ code, message: normalized.message, data: normalized.data }));
309
- return;
310
- }
311
- console.error('Error:', normalized.message);
312
- }
313
- });
314
- const hostSession = host.command('session').description('会话管理:start/list/stop(推荐先 start)');
315
- hostSession.command('start').description('创建并启动一个常驻会话,返回 sessionId').action(() => {
316
- try {
317
- const options = getCliOptions();
318
- const created = (0, session_manager_1.createSession)({
319
- role: 'idle',
320
- });
321
- if (options.json) {
322
- console.log(JSON.stringify({ code: 0, message: 'OK', data: created }));
323
- return;
324
- }
325
- console.log('Session started:', created.sessionId);
326
- }
327
- catch (error) {
328
- const normalized = normalizeError(error);
329
- const options = getCliOptions();
330
- const code = facade_1.ErrorReasonCodeMapping[normalized.reasonCode] ?? 1;
331
- if (options.json) {
332
- console.log(JSON.stringify({ code, message: normalized.message }));
333
- return;
334
- }
335
- console.error('Error:', normalized.message);
336
- }
337
- });
338
- hostSession.command('list').description('列出当前所有会话及其状态').action(() => {
339
- try {
340
- const sessions = (0, session_manager_1.listSessions)();
341
- const options = getCliOptions();
342
- if (options.json) {
343
- console.log(JSON.stringify({ code: 0, message: 'OK', data: sessions }));
344
- return;
345
- }
346
- console.log(JSON.stringify(sessions, null, 2));
347
- }
348
- catch (error) {
349
- const normalized = normalizeError(error);
350
- const options = getCliOptions();
351
- const code = facade_1.ErrorReasonCodeMapping[normalized.reasonCode] ?? 1;
352
- if (options.json) {
353
- console.log(JSON.stringify({ code, message: normalized.message }));
354
- return;
355
- }
356
- console.error('Error:', normalized.message);
357
- }
358
- });
359
- hostSession.command('stop <sessionId>')
360
- .description('停止并回收指定会话')
361
- .action((sessionId) => {
362
- try {
363
- const stopped = (0, session_manager_1.stopSession)(sessionId);
364
- const options = getCliOptions();
365
- if (options.json) {
366
- console.log(JSON.stringify({ code: 0, message: 'OK', data: stopped }));
367
- return;
368
- }
369
- console.log('Session stopped:', stopped.sessionId);
370
- }
371
- catch (error) {
372
- const normalized = normalizeError(error);
373
- const options = getCliOptions();
374
- const code = facade_1.ErrorReasonCodeMapping[normalized.reasonCode] ?? 1;
375
- if (options.json) {
376
- console.log(JSON.stringify({ code, message: normalized.message }));
377
- return;
378
- }
379
- console.error('Error:', normalized.message);
380
- }
381
- });
382
- function handleConfigInit(outputPath) {
383
- try {
384
- const written = (0, config_1.writeConfigTemplate)(outputPath);
385
- const options = getCliOptions();
386
- if (options.json) {
387
- console.log(JSON.stringify({ code: 0, message: 'OK', data: { path: written } }));
388
- return;
389
- }
390
- console.log('Config template created:', written);
391
- }
392
- catch (error) {
393
- const normalized = normalizeError(error);
394
- const options = getCliOptions();
395
- const code = facade_1.ErrorReasonCodeMapping[normalized.reasonCode] ?? 1;
396
- if (options.json) {
397
- console.log(JSON.stringify({ code, message: normalized.message }));
398
- return;
399
- }
400
- console.error('Error:', normalized.message);
401
- }
402
- }
403
- const init = program.command('init [outputPath]').description('新手第一步:生成 CLI 配置模板(默认输出到 ./.tmp/tirtc-devtools-cli/config.toml)');
404
- init.action((outputPath) => {
405
- handleConfigInit(outputPath);
406
- });
407
- const media = program.command('media').description('媒体素材辅助:prepare local assets');
408
- const mediaAssets = media.command('assets').description('prepared local assets contract');
409
- mediaAssets.command('prepare')
410
- .description('把 MP4 prepare 为 local_assets 目录')
411
- .requiredOption('--source <path>', '输入 MP4 路径')
412
- .requiredOption('--output-root <dir>', 'prepared assets 输出根目录')
413
- .option('--output-dir <dir>', 'prepared assets 精确输出目录(可选)')
414
- .option('--overwrite', '忽略现有 cache 并重建')
79
+ .option('--json', '以机器可读 JSON 输出(便于脚本集成)');
80
+ (0, token_command_1.registerTokenCommands)(program, getCliOptions, runAndExit);
81
+ const assets = program.command('assets').description('准备 DevTools driver 使用的媒体资产');
82
+ assets.command('prepare')
83
+ .description('准备默认 runtime assets 或把显式 source 写入 output root')
84
+ .option('--source <path>', '输入 MP4 路径;send start 使用输出的 manifest_path')
85
+ .option('--output-root <dir>', 'prepared assets 输出根目录')
86
+ .addHelpText('after', `
87
+ Examples:
88
+ $ tirtc-devtools-cli --json assets prepare --source ./movie.mp4 --output-root .build/tirtc-assets
89
+ $ tirtc-devtools-cli --json send start --source .build/tirtc-assets/manifest.json --video-codec h264
90
+ `)
415
91
  .action((commandOptions) => {
416
- runAndExit(runMediaAssetsPrepare(commandOptions.source, commandOptions.outputRoot, commandOptions.outputDir, commandOptions.overwrite === true, getCliOptions()));
417
- });
418
- const hostConfig = host.command('config').description('配置辅助(兼容别名,推荐用顶层 config)');
419
- hostConfig.command('init [outputPath]').description('生成配置模板(等价于 config init)').action((outputPath) => {
420
- handleConfigInit(outputPath);
421
- });
422
- const service = program.command('service').description('服务端能力:启动/停止服务,等待远端接入');
423
- service.command('start')
424
- .description('启动 server-only 会话(必须显式提供 --config)')
425
- .action(() => {
426
- const options = getCliOptions();
427
- const config = (0, config_1.loadConfig)(requireConfigPath(options.config));
428
- const server = (0, bootstrap_flows_1.validateServerConfig)(config);
429
- runAndExit(runCommand('service start', { serviceEntry: server.serviceEntry, license: server.license, timeoutMs: 5000 }, options));
430
- });
431
- service.command('stop').description('停止服务端监听').action(() => {
432
- runAndExit(runCommand('service stop', {}, getCliOptions()));
433
- });
434
- const client = program.command('client').description('客户端正式入口:连接远端并自动挂载本地 web preview');
435
- client.command('start')
436
- .description('读取 [client] 配置,连接远端并输出 web preview 地址')
437
- .requiredOption('--token <token>', '显式 client token;不支持 auto token')
92
+ runAndExit(runAssetsPrepare(commandOptions, getCliOptions()));
93
+ });
94
+ const send = program.command('send').description('作为标准上行端运行 native DevTools driver');
95
+ send.command('start')
96
+ .description('启动 send role,产出 bootstrap.json 与 summary.json')
97
+ .option('--execution-id <id>', 'runtime validation execution id')
98
+ .option('--case-id <id>', 'runtime validation case id')
99
+ .option('--app-id <id>', 'runtime validation app id')
100
+ .option('--artifact-root <dir>', 'artifact 输出目录')
101
+ .option('--remote-id <id>', 'server remote id;默认读取 TIRTC_DEVICE_ID')
102
+ .option('--source <path>', 'prepared asset root、manifest_path 或 encoded track;MP4 先运行 assets prepare')
103
+ .option('--video-codec <codec>', 'h264|h265|mjpeg', 'h264')
104
+ .option('--duration-ms <ms>', 'role active 时长')
105
+ .option('--connect-timeout-ms <ms>', 'service ready / connect 最大等待')
106
+ .option('--first-packet-timeout-ms <ms>', '首包最大等待')
107
+ .option('--bootstrap-token-json <path>', 'script/issue_devtools_token.sh --json 输出文件')
108
+ .addHelpText('after', `
109
+ Examples:
110
+ $ tirtc-devtools-cli --json assets prepare --source ./movie.mp4 --output-root .build/tirtc-assets
111
+ $ tirtc-devtools-cli --json send start --source .build/tirtc-assets/manifest.json --artifact-root .build/tirtc-send
112
+
113
+ bootstrap.json is a local handoff artifact for receive/sample/validation automation.
114
+ It is not a mobile SDK connection protocol.
115
+ `)
438
116
  .action((commandOptions) => {
439
- const options = getCliOptions();
440
- (0, config_1.loadConfig)(requireConfigPath(options.config));
441
- runAndExit(runCommand('client start', { token: commandOptions.token }, options));
442
- });
443
- const connection = program.command('connection').description('客户端能力:主动连接远端 peer');
444
- connection.command('show').description('查看连接状态').action(() => {
445
- runAndExit(runCommand('connection show', {}, getCliOptions()));
446
- });
447
- connection.command('connect [service_entry] <peer_id> <token>')
448
- .description('作为客户端连接远端(总是新建 session;要求显式 token)')
449
- .action((serviceEntry, peerId, token) => {
450
- const config = (0, config_1.loadConfig)(getCliOptions().config);
451
- const finalServiceEntry = [serviceEntry, config.client?.service_entry, config.server?.service_entry]
452
- .find((value) => typeof value === 'string' && value.trim().length > 0);
453
- const manualToken = token.trim();
454
- if (manualToken.length === 0) {
455
- throw new Error('connection connect requires non-empty token');
456
- }
457
- const params = {
458
- serviceEntry: finalServiceEntry,
459
- peerId,
460
- token: manualToken,
461
- timeoutMs: 5000,
462
- };
463
- runAndExit(runCommand('connection connect', params, getCliOptions()));
464
- });
465
- connection.command('disconnect').description('断开当前连接').action(() => {
466
- runAndExit(runCommand('connection disconnect', {}, getCliOptions()));
467
- });
468
- (0, token_command_1.registerTokenCommands)(program, getCliOptions, runAndExit);
469
- const stream = program.command('stream').description('流控制:发送/接收/消息');
470
- stream.command('list').description('查看流快照列表').action(() => {
471
- runAndExit(runCommand('stream list', {}, getCliOptions()));
472
- });
473
- const streamSend = stream.command('send').description('发送流:绑定 prepared local assets 并发起上行');
474
- streamSend.command('start <streamId> <media> <assets_dir>')
475
- .description('开始发送流(绑定 source.local_assets 并触发上行)')
476
- .action((streamId, media, assetsDir) => {
477
- runAndExit(runCommand('stream send start', {
478
- streamId: Number.parseInt(streamId, 10),
479
- media,
480
- source: {
481
- mode: 'local_assets',
482
- local_assets: {
483
- assets_dir: assetsDir,
484
- },
485
- },
486
- }, getCliOptions()));
487
- });
488
- streamSend.command('stop <streamId>').description('停止发送指定流').action((streamId) => {
489
- runAndExit(runCommand('stream send stop', { streamId: Number.parseInt(streamId, 10) }, getCliOptions()));
490
- });
491
- const streamReceive = stream.command('receive').description('接收流:声明并接收下行');
492
- streamReceive.command('start <streamId> <media>')
493
- .description('开始接收指定流')
494
- .action((streamId, media) => {
495
- runAndExit(runCommand('stream receive start', {
496
- streamId: Number.parseInt(streamId, 10),
497
- media,
498
- }, getCliOptions()));
499
- });
500
- streamReceive.command('stop <streamId>')
501
- .description('停止接收指定流')
502
- .action((streamId) => {
503
- runAndExit(runCommand('stream receive stop', { streamId: Number.parseInt(streamId, 10) }, getCliOptions()));
504
- });
505
- const streamMessage = stream.command('message').description('发送 stream message');
506
- streamMessage.command('send <streamId> <payload>')
507
- .description('发送 UTF-8 字符串型 stream message')
508
- .action((streamId, payload) => {
509
- runAndExit(runCommand('stream message send', { streamId: Number.parseInt(streamId, 10), payload }, getCliOptions()));
510
- });
511
- const output = program.command('output').description('输出挂载:文件等消费者 attach/detach');
512
- output.command('attach <streamId> <consumer> <mediaView> <format> <delivery> [targetPath] [maxFiles]')
513
- .description('挂载输出消费者(如 file_sink)')
514
- .action((streamId, consumer, mediaView, format, delivery, targetPath, maxFiles) => {
515
- const parsed = facade_1.OutputAttachCliParamsSchema.safeParse({
516
- streamId: Number.parseInt(streamId, 10),
517
- consumer,
518
- mediaView,
519
- format,
520
- delivery,
521
- targetPath,
522
- maxFiles: maxFiles ? Number.parseInt(maxFiles, 10) : undefined,
523
- });
524
- if (!parsed.success) {
525
- const msg = parsed.error.issues.map((issue) => issue.message).join('; ');
526
- throw new Error('invalid output attach params: ' + msg);
527
- }
528
- runAndExit(runCommand('output attach', {
529
- streamId: Number.parseInt(streamId, 10),
530
- consumer,
531
- mediaView,
532
- format,
533
- delivery,
534
- targetPath,
535
- maxFiles: maxFiles ? Number.parseInt(maxFiles, 10) : undefined,
536
- }, getCliOptions()));
537
- });
538
- output.command('detach <outputId>').description('卸载输出消费者').action((outputId) => {
539
- runAndExit(runCommand('output detach', { outputId }, getCliOptions()));
540
- });
541
- const command = program.command('command').description('命令通道:发送命令与事件跟踪');
542
- command.command('request <commandId> <payloadEncoding> <payload>')
543
- .description('发送命令请求并等待响应')
544
- .option('--timeout-ms <ms>', '请求超时(毫秒)', '5000')
545
- .action((commandId, payloadEncoding, payload, commandOptions) => {
546
- runAndExit(runCommand('command request', {
547
- commandId: Number.parseInt(commandId, 10),
548
- payloadEncoding,
549
- payload,
550
- timeoutMs: Number.parseInt(commandOptions.timeoutMs, 10),
551
- }, getCliOptions()));
552
- });
553
- command.command('send <commandId> <payloadEncoding> <payload>')
554
- .description('兼容别名:等价于 command request')
555
- .option('--timeout-ms <ms>', '请求超时(毫秒)', '5000')
556
- .action((commandId, payloadEncoding, payload, commandOptions) => {
557
- runAndExit(runCommand('command send', {
558
- commandId: Number.parseInt(commandId, 10),
559
- payloadEncoding,
560
- payload,
561
- timeoutMs: Number.parseInt(commandOptions.timeoutMs, 10),
562
- }, getCliOptions()));
563
- });
564
- const commandPending = command.command('pending').description('查看当前会话内待回复的远端命令请求');
565
- commandPending.command('list')
566
- .description('列出当前待回复的远端命令请求')
567
- .action(() => {
568
- runAndExit(runCommand('command pending list', {}, getCliOptions()));
569
- });
570
- command.command('reply <remoteRequestId> <commandId> <payloadEncoding> <payload>')
571
- .description('按 remoteRequestId 显式回复待处理命令')
572
- .action((remoteRequestId, commandId, payloadEncoding, payload) => {
573
- runAndExit(runCommand('command reply', {
574
- remoteRequestId: Number.parseInt(remoteRequestId, 10),
575
- commandId: Number.parseInt(commandId, 10),
576
- payloadEncoding,
577
- payload,
578
- }, getCliOptions()));
579
- });
580
- command.command('tail').description('持续监听命令相关事件').action(() => {
581
- runAndExit(tailEvents('command tail', ['command'], getCliOptions()));
582
- });
583
- const debug = program.command('debug').description('调试工具:连接 bootstrap 二维码');
584
- const debugBootstrap = debug.command('bootstrap').description('连接 bootstrap(不在 App Server 侧签发 token)');
585
- debugBootstrap.command('qrcode <access_id> <secret_key> <peer_id> [service_entry]')
586
- .description('生成客户端连接 bootstrap 二维码(payload 包含 access_id/secret_key/peer_id)')
587
- .action((accessId, secretKey, peerId, serviceEntry) => {
588
- const payloadObject = {
589
- access_id: accessId,
590
- secret_key: secretKey,
591
- peer_id: peerId,
592
- };
593
- if (serviceEntry && serviceEntry.length > 0) {
594
- payloadObject.service_entry = serviceEntry;
595
- }
596
- const payload = JSON.stringify(payloadObject);
597
- runAndExit(runCommand('debug bootstrap qrcode', { payload, outputStem: 'connect-bootstrap' }, getCliOptions()));
598
- });
599
- debugBootstrap.command('qrcode-from-config')
600
- .description('从 --config 读取 debug.connect_bootstrap 并生成二维码')
601
- .action(() => {
602
- const config = (0, config_1.loadConfig)(getCliOptions().config);
603
- const bootstrap = config.debug?.connect_bootstrap;
604
- if (!bootstrap) {
605
- throw new Error('missing debug.connect_bootstrap in config');
606
- }
607
- if (!bootstrap.access_id || !bootstrap.secret_key || !bootstrap.peer_id) {
608
- throw new Error('debug.connect_bootstrap requires access_id + secret_key + peer_id');
609
- }
610
- const payloadObject = {
611
- access_id: bootstrap.access_id,
612
- secret_key: bootstrap.secret_key,
613
- peer_id: bootstrap.peer_id,
614
- };
615
- if (bootstrap.service_entry && bootstrap.service_entry.length > 0) {
616
- payloadObject.service_entry = bootstrap.service_entry;
617
- }
618
- const payload = JSON.stringify(payloadObject);
619
- runAndExit(runCommand('debug bootstrap qrcode', { payload, outputStem: 'connect-bootstrap' }, getCliOptions()));
620
- });
621
- const events = program.command('events').description('事件订阅:实时观察 Host 事件');
622
- events.command('tail').description('持续监听 Host 事件').action(() => {
623
- runAndExit(tailEvents('events tail', ['service', 'connection', 'stream', 'command', 'operation', 'logs'], getCliOptions()));
624
- });
625
- const logs = program.command('logs').description('日志导出:导出运行日志');
626
- logs.command('export <outputPath>')
627
- .description('导出运行日志到指定路径')
628
- .action((outputPath) => {
629
- runAndExit(runCommand('logs export', { outputPath }, getCliOptions()));
630
- });
631
- const report = program.command('report').description('报告查看/导出:验收证据');
632
- const guide = program.command('guide').description('新手入口:按场景给出可执行步骤');
633
- guide.command('quickstart')
634
- .description('打印服务端启动 -> 安卓扫码连接 的最小闭环步骤')
635
- .action(() => {
636
- (0, guide_1.printQuickstartGuide)();
637
- });
638
- report.command('show').description('查看当前报告内容').action(() => {
639
- runAndExit(runCommand('report show', {}, getCliOptions()));
640
- });
641
- report.command('export <outputPath>')
642
- .description('导出报告到指定路径')
643
- .action((outputPath) => {
644
- runAndExit(runCommand('report export', { outputPath }, getCliOptions()));
117
+ runAndExit((0, role_driver_1.runSendStart)(commandOptions, getCliOptions()));
118
+ });
119
+ const receive = program.command('receive').description('作为标准下行端运行 native DevTools driver');
120
+ receive.command('start')
121
+ .description('启动 receive role,消费 bootstrap 或显式 identity 并产出 frame_dump')
122
+ .option('--artifact-root <dir>', 'artifact 输出目录')
123
+ .option('--bootstrap <path>', 'send role 产出的 bootstrap.json')
124
+ .option('--remote-id <id>', '显式 remote id;优先于 bootstrap')
125
+ .option('--token <token>', '显式 token;优先于 bootstrap')
126
+ .option('--audio-stream-id <id>', '音频 stream id')
127
+ .option('--video-stream-id <id>', '视频 stream id')
128
+ .option('--consumer <consumer>', 'packet_dump|frame_dump', 'frame_dump')
129
+ .option('--frame-limit <count>', 'frame_dump 帧数上限')
130
+ .option('--duration-ms <ms>', 'role active 时长')
131
+ .option('--connect-timeout-ms <ms>', 'connect 最大等待')
132
+ .option('--first-packet-timeout-ms <ms>', '首包最大等待')
133
+ .option('--first-output-timeout-ms <ms>', '首帧输出最大等待')
134
+ .addHelpText('after', `
135
+ Examples:
136
+ $ tirtc-devtools-cli --json receive start --bootstrap .build/tirtc-send/bootstrap.json
137
+
138
+ bootstrap.json is expected to come from a local send start run.
139
+ For mobile device debugging, use token/license QR or a future session QR/deeplink.
140
+ `)
141
+ .action((commandOptions) => {
142
+ runAndExit((0, role_driver_1.runReceiveStart)(commandOptions, getCliOptions()));
645
143
  });
646
144
  program.parse(process.argv);