@calltelemetry/cli 0.15.1 → 1.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 (46) hide show
  1. package/README.md +47 -0
  2. package/dist/commands/cube.d.ts.map +1 -1
  3. package/dist/commands/cube.js +68 -0
  4. package/dist/commands/cube.js.map +1 -1
  5. package/dist/commands/sftp.d.ts +3 -0
  6. package/dist/commands/sftp.d.ts.map +1 -0
  7. package/dist/commands/sftp.js +1586 -0
  8. package/dist/commands/sftp.js.map +1 -0
  9. package/dist/index.js +9 -4
  10. package/dist/index.js.map +1 -1
  11. package/dist/lib/appliance-api.d.ts +149 -0
  12. package/dist/lib/appliance-api.d.ts.map +1 -0
  13. package/dist/lib/appliance-api.js +492 -0
  14. package/dist/lib/appliance-api.js.map +1 -0
  15. package/dist/lib/cube-diag.d.ts +6 -0
  16. package/dist/lib/cube-diag.d.ts.map +1 -1
  17. package/dist/lib/cube-diag.js +9 -0
  18. package/dist/lib/cube-diag.js.map +1 -1
  19. package/dist/lib/cube-doctor.d.ts +107 -0
  20. package/dist/lib/cube-doctor.d.ts.map +1 -0
  21. package/dist/lib/cube-doctor.js +426 -0
  22. package/dist/lib/cube-doctor.js.map +1 -0
  23. package/dist/lib/openapi.d.ts +129 -0
  24. package/dist/lib/openapi.d.ts.map +1 -0
  25. package/dist/lib/openapi.js +325 -0
  26. package/dist/lib/openapi.js.map +1 -0
  27. package/dist/lib/sftp.d.ts +231 -0
  28. package/dist/lib/sftp.d.ts.map +1 -0
  29. package/dist/lib/sftp.js +439 -0
  30. package/dist/lib/sftp.js.map +1 -0
  31. package/dist/lib/version.d.ts +1 -1
  32. package/dist/lib/version.d.ts.map +1 -1
  33. package/dist/lib/version.js +1 -1
  34. package/dist/lib/version.js.map +1 -1
  35. package/dist/program.d.ts.map +1 -1
  36. package/dist/program.js +2 -0
  37. package/dist/program.js.map +1 -1
  38. package/dist/utils/prompt.d.ts +14 -0
  39. package/dist/utils/prompt.d.ts.map +1 -1
  40. package/dist/utils/prompt.js +28 -0
  41. package/dist/utils/prompt.js.map +1 -1
  42. package/dist/utils/table.d.ts +18 -0
  43. package/dist/utils/table.d.ts.map +1 -0
  44. package/dist/utils/table.js +97 -0
  45. package/dist/utils/table.js.map +1 -0
  46. package/package.json +1 -1
@@ -0,0 +1,492 @@
1
+ /**
2
+ * Appliance REST API client.
3
+ *
4
+ * Uses the appliance's own OpenAPI document (`/api/openapi`) to stay aligned
5
+ * with the installed release.
6
+ *
7
+ * Human invocations authenticate interactively as an appliance admin and use
8
+ * the short-lived session JWT returned by `POST /api/session`. The JWT lives
9
+ * only in this process; nothing is written to disk. Automation can supply
10
+ * `CT_API_TOKEN` (machine API key) or `CT_API_EMAIL` + `CT_API_PASSWORD`
11
+ * instead of prompting.
12
+ */
13
+ import { request as httpRequest } from 'node:http';
14
+ import { request as httpsRequest } from 'node:https';
15
+ import { createWriteStream, readFileSync } from 'node:fs';
16
+ import { randomBytes } from 'node:crypto';
17
+ import { password as promptPassword, text as promptText } from '../utils/prompt.js';
18
+ export const DEFAULT_API_URL = 'https://127.0.0.1';
19
+ export const DEFAULT_TIMEOUT_MS = 30_000;
20
+ export class ApplianceApiError extends Error {
21
+ status;
22
+ code;
23
+ method;
24
+ url;
25
+ body;
26
+ constructor(message, opts = {}) {
27
+ super(message);
28
+ this.name = 'ApplianceApiError';
29
+ this.status = opts.status;
30
+ this.code = opts.code;
31
+ this.method = opts.method;
32
+ this.url = opts.url;
33
+ this.body = opts.body;
34
+ }
35
+ }
36
+ export function normalizeBaseUrl(value) {
37
+ const raw = (value ?? process.env.CT_API_URL ?? DEFAULT_API_URL).trim();
38
+ if (!raw)
39
+ return DEFAULT_API_URL;
40
+ const withProtocol = /^[a-z][a-z0-9+.-]*:\/\//i.test(raw) ? raw : `https://${raw}`;
41
+ return withProtocol.replace(/\/+$/, '');
42
+ }
43
+ export function isLocalBaseUrl(baseUrl) {
44
+ try {
45
+ const host = new URL(baseUrl).hostname.toLowerCase();
46
+ return host === '127.0.0.1' || host === 'localhost' || host === '::1' || host === '[::1]';
47
+ }
48
+ catch {
49
+ return false;
50
+ }
51
+ }
52
+ export function authHeaderValue(token) {
53
+ const trimmed = token.trim();
54
+ if (/^Bearer\s+/i.test(trimmed))
55
+ return trimmed;
56
+ // JWTs are accepted with the standard Bearer prefix. Appliance API keys are
57
+ // sent raw, matching the api_key_auth security scheme.
58
+ if (trimmed.startsWith('eyJ'))
59
+ return `Bearer ${trimmed}`;
60
+ return trimmed;
61
+ }
62
+ export function parsePositiveInt(value, label) {
63
+ if (value === undefined || value === '')
64
+ return undefined;
65
+ const parsed = typeof value === 'number' ? value : Number(value);
66
+ if (!Number.isInteger(parsed) || parsed <= 0) {
67
+ throw new ApplianceApiError(`${label} must be a positive integer`);
68
+ }
69
+ return parsed;
70
+ }
71
+ export async function resolveOrgId(explicit) {
72
+ if (explicit !== undefined)
73
+ return explicit;
74
+ const envValue = process.env.CT_ORG_ID;
75
+ if (envValue) {
76
+ return parsePositiveInt(envValue, 'CT_ORG_ID');
77
+ }
78
+ // A standard appliance has one organization with ID 1. Multi-org
79
+ // deployments should pass --org or set CT_ORG_ID.
80
+ return 1;
81
+ }
82
+ export async function resolveApiToken(baseUrl, explicit, requireAuth = true, login, loginOptions = {}) {
83
+ const envToken = process.env.CT_API_TOKEN || process.env.CT_API_KEY;
84
+ const supplied = explicit?.trim() || envToken?.trim();
85
+ if (supplied) {
86
+ const token = supplied.replace(/^Bearer\s+/i, '').trim();
87
+ if (!token)
88
+ throw new ApplianceApiError('API token is empty');
89
+ return token;
90
+ }
91
+ // A full_admin session login uses a short-lived JWT and bypasses the REST
92
+ // API license check that applies to machine API keys.
93
+ if (login) {
94
+ // Public spec discovery should not fail on stale optional credentials;
95
+ // callers that need auth retry with requireAuth enabled.
96
+ if (!requireAuth)
97
+ return undefined;
98
+ return loginForToken(baseUrl, login, loginOptions);
99
+ }
100
+ // Spec discovery should be usable without resolving credentials. On current
101
+ // releases `/api/openapi` is public; protected deployments can still pass a token.
102
+ if (!requireAuth)
103
+ return undefined;
104
+ throw new ApplianceApiError('No appliance credentials supplied.\n' +
105
+ 'Run interactively to log in as a full_admin user, or set CT_API_EMAIL + ' +
106
+ 'CT_API_PASSWORD for automation. CT_API_TOKEN (machine API key) also works ' +
107
+ 'on REST-capable licenses.', { code: 'AUTH_REQUIRED' });
108
+ }
109
+ function extractServerMessage(body, status) {
110
+ const text = body.toString('utf-8').trim();
111
+ if (!text)
112
+ return `HTTP ${status}`;
113
+ try {
114
+ const parsed = JSON.parse(text);
115
+ if (typeof parsed === 'object' && parsed !== null) {
116
+ const record = parsed;
117
+ const message = record.message ?? record.error ?? record.detail;
118
+ if (typeof message === 'string' && message.trim())
119
+ return message;
120
+ if (record.errors !== undefined)
121
+ return JSON.stringify(record.errors);
122
+ }
123
+ }
124
+ catch {
125
+ // fall through to plain text
126
+ }
127
+ return text.length > 600 ? `${text.slice(0, 600)}…` : text;
128
+ }
129
+ function friendlyTransportError(err, method, url) {
130
+ const code = err.code ?? '';
131
+ let detail = err.message;
132
+ switch (code) {
133
+ case 'ECONNREFUSED':
134
+ detail = 'connection refused — is the appliance web service running?';
135
+ break;
136
+ case 'ENOTFOUND':
137
+ detail = 'host not found — check the API URL';
138
+ break;
139
+ case 'ETIMEDOUT':
140
+ detail = 'request timed out';
141
+ break;
142
+ case 'ECONNRESET':
143
+ detail = 'connection reset by the appliance';
144
+ break;
145
+ case 'CERT_HAS_EXPIRED':
146
+ case 'DEPTH_ZERO_SELF_SIGNED_CERT':
147
+ case 'SELF_SIGNED_CERT_IN_CHAIN':
148
+ detail = `${err.message} (use --verify-tls=false or the default local mode)`;
149
+ break;
150
+ }
151
+ return new ApplianceApiError(`Cannot reach appliance API: ${detail}`, {
152
+ code: code || 'TRANSPORT',
153
+ method,
154
+ url,
155
+ });
156
+ }
157
+ export const nodeTransport = (options) => {
158
+ return new Promise((resolve, reject) => {
159
+ let parsed;
160
+ try {
161
+ parsed = new URL(options.url);
162
+ }
163
+ catch {
164
+ reject(new ApplianceApiError(`Invalid API URL: ${options.url}`));
165
+ return;
166
+ }
167
+ const isHttps = parsed.protocol === 'https:';
168
+ if (!isHttps && parsed.protocol !== 'http:') {
169
+ reject(new ApplianceApiError(`Unsupported API URL protocol: ${parsed.protocol}`));
170
+ return;
171
+ }
172
+ const requestFn = isHttps ? httpsRequest : httpRequest;
173
+ const req = requestFn(parsed, {
174
+ method: options.method,
175
+ headers: options.headers,
176
+ rejectUnauthorized: options.rejectUnauthorized,
177
+ }, (res) => {
178
+ const status = res.statusCode ?? 0;
179
+ const headers = res.headers;
180
+ if (options.outputPath) {
181
+ const out = createWriteStream(options.outputPath);
182
+ out.on('error', reject);
183
+ res.on('error', reject);
184
+ res.pipe(out);
185
+ out.on('finish', () => resolve({ status, headers, body: Buffer.alloc(0) }));
186
+ return;
187
+ }
188
+ const chunks = [];
189
+ res.on('data', (chunk) => chunks.push(chunk));
190
+ res.on('end', () => resolve({ status, headers, body: Buffer.concat(chunks) }));
191
+ res.on('error', reject);
192
+ });
193
+ req.on('error', reject);
194
+ req.setTimeout(options.timeoutMs, () => {
195
+ req.destroy(new Error(`Request timed out after ${options.timeoutMs}ms`));
196
+ });
197
+ if (options.body)
198
+ req.write(options.body);
199
+ req.end();
200
+ });
201
+ };
202
+ export function buildMultipartBody(fields, files = []) {
203
+ const boundary = `----ct${randomBytes(12).toString('hex')}`;
204
+ const chunks = [];
205
+ for (const [name, value] of Object.entries(fields)) {
206
+ if (value === undefined)
207
+ continue;
208
+ chunks.push(Buffer.from(`--${boundary}\r\n` +
209
+ `Content-Disposition: form-data; name="${name.replace(/"/g, '\\"')}"\r\n\r\n` +
210
+ `${value}\r\n`));
211
+ }
212
+ for (const file of files) {
213
+ chunks.push(Buffer.from(`--${boundary}\r\n` +
214
+ `Content-Disposition: form-data; name="${file.field.replace(/"/g, '\\"')}"; ` +
215
+ `filename="${file.filename.replace(/"/g, '\\"')}"\r\n` +
216
+ `Content-Type: ${file.contentType}\r\n\r\n`), file.data, Buffer.from('\r\n'));
217
+ }
218
+ chunks.push(Buffer.from(`--${boundary}--\r\n`));
219
+ return {
220
+ body: Buffer.concat(chunks),
221
+ contentType: `multipart/form-data; boundary=${boundary}`,
222
+ };
223
+ }
224
+ /** Log in with a full_admin web session and return its access token. */
225
+ export async function loginForToken(baseUrl, credentials, options = {}) {
226
+ const api = new ApplianceApi({
227
+ baseUrl,
228
+ orgId: 1,
229
+ timeoutMs: options.timeoutMs,
230
+ verifyTls: options.verifyTls,
231
+ transport: options.transport,
232
+ });
233
+ let response;
234
+ try {
235
+ response = await api.request('POST', '/api/session', {
236
+ body: { user: { email: credentials.email, password: credentials.password } },
237
+ headers: { 'Content-Type': 'application/json' },
238
+ });
239
+ }
240
+ catch (err) {
241
+ if (err instanceof ApplianceApiError) {
242
+ throw new ApplianceApiError(`Session login failed for ${credentials.email}: ${err.message}`, { status: err.status, code: 'LOGIN_FAILED' });
243
+ }
244
+ throw err;
245
+ }
246
+ const data = response.data;
247
+ const token = data?.access_token ?? data?.data?.access_token;
248
+ if (!token) {
249
+ throw new ApplianceApiError('Session login succeeded but returned no access_token', {
250
+ code: 'LOGIN_FAILED',
251
+ });
252
+ }
253
+ return token;
254
+ }
255
+ export class ApplianceApi {
256
+ baseUrl;
257
+ orgId;
258
+ timeoutMs;
259
+ verifyTls;
260
+ token;
261
+ transport;
262
+ spec;
263
+ constructor(options) {
264
+ this.baseUrl = options.baseUrl;
265
+ this.orgId = options.orgId;
266
+ this.token = options.token;
267
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
268
+ this.verifyTls = options.verifyTls ?? !isLocalBaseUrl(options.baseUrl);
269
+ this.transport = options.transport ?? nodeTransport;
270
+ }
271
+ static async connect(options = {}) {
272
+ const baseUrl = normalizeBaseUrl(options.baseUrl);
273
+ const requireAuth = options.requireAuth ?? true;
274
+ const orgId = await resolveOrgId(options.orgId);
275
+ let email = options.email ?? process.env.CT_API_EMAIL;
276
+ let password = options.password ?? process.env.CT_API_PASSWORD;
277
+ const hasSuppliedToken = Boolean(options.token?.trim() || process.env.CT_API_TOKEN?.trim() || process.env.CT_API_KEY?.trim());
278
+ // Humans authenticate as themselves. Prompt only when we actually need an
279
+ // authenticated API call and no token was supplied. `--json` prompts go to
280
+ // stderr so stdout remains a valid JSON document.
281
+ if (requireAuth && !hasSuppliedToken && !(email && password)) {
282
+ const promptOutput = process.argv.includes('--json') ? process.stderr : process.stdout;
283
+ if (options.credentialProvider) {
284
+ const supplied = await options.credentialProvider();
285
+ if (supplied) {
286
+ email = supplied.email;
287
+ password = supplied.password;
288
+ }
289
+ }
290
+ else if (process.stdin.isTTY) {
291
+ if (!email) {
292
+ email = (await promptText('Appliance admin email', { output: promptOutput })) ?? undefined;
293
+ }
294
+ if (email && !password) {
295
+ password = (await promptPassword(`Password for ${email}`, { output: promptOutput })) ?? undefined;
296
+ }
297
+ }
298
+ }
299
+ const login = email && password ? { email, password } : undefined;
300
+ const token = await resolveApiToken(baseUrl, options.token, requireAuth, login, {
301
+ timeoutMs: options.timeoutMs,
302
+ verifyTls: options.verifyTls,
303
+ transport: options.transport,
304
+ });
305
+ return new ApplianceApi({
306
+ baseUrl,
307
+ orgId,
308
+ token,
309
+ timeoutMs: options.timeoutMs,
310
+ verifyTls: options.verifyTls,
311
+ transport: options.transport,
312
+ });
313
+ }
314
+ /** Build an org-scoped API path (or pass through absolute API paths). */
315
+ apiPath(pathOrResource) {
316
+ const path = pathOrResource.trim();
317
+ if (/^https?:\/\//i.test(path))
318
+ return path;
319
+ if (path.startsWith('/api/'))
320
+ return path;
321
+ return `/api/org/${this.orgId}/${path.replace(/^\//, '')}`;
322
+ }
323
+ urlFor(pathOrResource, query) {
324
+ const path = this.apiPath(pathOrResource);
325
+ const base = path.startsWith('http') ? path : `${this.baseUrl}${path}`;
326
+ const url = new URL(base);
327
+ for (const [key, value] of Object.entries(query ?? {})) {
328
+ if (value === undefined || value === null || value === '')
329
+ continue;
330
+ url.searchParams.append(key, String(value));
331
+ }
332
+ return url.toString();
333
+ }
334
+ async request(method, pathOrResource, options = {}) {
335
+ const upperMethod = method.toUpperCase();
336
+ const url = this.urlFor(pathOrResource, options.query);
337
+ const headers = {
338
+ Accept: options.accept ?? 'application/json',
339
+ ...(options.headers ?? {}),
340
+ };
341
+ if (this.token) {
342
+ headers.Authorization = authHeaderValue(this.token);
343
+ }
344
+ let body;
345
+ if (options.body !== undefined && options.form !== undefined) {
346
+ throw new ApplianceApiError('Specify either a JSON body or multipart form data, not both');
347
+ }
348
+ if (options.body !== undefined) {
349
+ headers['Content-Type'] = 'application/json';
350
+ body = Buffer.from(JSON.stringify(options.body));
351
+ }
352
+ else if (options.form !== undefined) {
353
+ const multipart = buildMultipartBody(options.form.fields ?? {}, options.form.files ?? []);
354
+ headers['Content-Type'] = multipart.contentType;
355
+ body = multipart.body;
356
+ }
357
+ let response;
358
+ try {
359
+ response = await this.transport({
360
+ method: upperMethod,
361
+ url,
362
+ headers,
363
+ body,
364
+ timeoutMs: this.timeoutMs,
365
+ rejectUnauthorized: this.verifyTls,
366
+ outputPath: options.outputPath,
367
+ });
368
+ }
369
+ catch (err) {
370
+ if (err instanceof ApplianceApiError)
371
+ throw err;
372
+ throw friendlyTransportError(err, upperMethod, url);
373
+ }
374
+ const status = response.status;
375
+ const text = response.body.toString('utf-8');
376
+ if (status < 200 || status >= 300) {
377
+ const message = extractServerMessage(response.body, status);
378
+ let friendly = message;
379
+ if (status === 401 || status === 403) {
380
+ if (text.includes('license_restricted')) {
381
+ friendly =
382
+ `${message}\nThis appliance license does not include machine REST API access. ` +
383
+ 'Set CT_API_EMAIL and CT_API_PASSWORD for a full_admin user (session login), ' +
384
+ 'or set CT_API_TOKEN to a full_admin session JWT.';
385
+ }
386
+ else {
387
+ friendly =
388
+ `${message}\nAuthentication failed for ${upperMethod} ${this.apiPath(pathOrResource)}. ` +
389
+ 'Use an organization API key with full_admin access (CT_API_TOKEN).';
390
+ }
391
+ }
392
+ else if (status === 404) {
393
+ friendly =
394
+ `${message}\nNot found: ${upperMethod} ${this.apiPath(pathOrResource)}. ` +
395
+ 'The installed appliance release may not expose this operation.';
396
+ }
397
+ throw new ApplianceApiError(friendly, {
398
+ status,
399
+ method: upperMethod,
400
+ url,
401
+ body: text,
402
+ });
403
+ }
404
+ const parse = options.parse ?? (options.outputPath ? 'none' : 'json');
405
+ if (parse === 'none') {
406
+ return { status, data: undefined, headers: response.headers };
407
+ }
408
+ if (parse === 'text') {
409
+ return { status, data: text, headers: response.headers };
410
+ }
411
+ if (!text.trim()) {
412
+ return { status, data: undefined, headers: response.headers };
413
+ }
414
+ try {
415
+ return { status, data: JSON.parse(text), headers: response.headers };
416
+ }
417
+ catch {
418
+ throw new ApplianceApiError(`Expected JSON from ${upperMethod} ${this.apiPath(pathOrResource)} but received: ` +
419
+ text.slice(0, 200), { status, method: upperMethod, url });
420
+ }
421
+ }
422
+ get(path, options) {
423
+ return this.request('GET', path, options);
424
+ }
425
+ post(path, body, options) {
426
+ return this.request('POST', path, { ...options, body });
427
+ }
428
+ put(path, body, options) {
429
+ return this.request('PUT', path, { ...options, body });
430
+ }
431
+ patch(path, body, options) {
432
+ return this.request('PATCH', path, { ...options, body });
433
+ }
434
+ delete(path, options) {
435
+ return this.request('DELETE', path, options);
436
+ }
437
+ /**
438
+ * Fetch and cache the OpenAPI document generated by the appliance build.
439
+ * Tries `/api/openapi` first, then `/api/openapi.json`.
440
+ */
441
+ async fetchSpec(force = false) {
442
+ if (this.spec && !force)
443
+ return this.spec;
444
+ const candidates = ['/api/openapi', '/api/openapi.json'];
445
+ let lastError;
446
+ for (const path of candidates) {
447
+ try {
448
+ const response = await this.request('GET', path, {
449
+ accept: 'application/json',
450
+ });
451
+ const spec = response.data;
452
+ if (!spec || typeof spec !== 'object' || typeof spec.paths !== 'object') {
453
+ throw new ApplianceApiError('Appliance returned an invalid OpenAPI document');
454
+ }
455
+ this.spec = spec;
456
+ return spec;
457
+ }
458
+ catch (err) {
459
+ lastError = err;
460
+ if (err instanceof ApplianceApiError && err.status !== 404)
461
+ throw err;
462
+ }
463
+ }
464
+ throw lastError instanceof Error
465
+ ? lastError
466
+ : new ApplianceApiError('Could not load the appliance OpenAPI spec');
467
+ }
468
+ describe() {
469
+ return { baseUrl: this.baseUrl, orgId: this.orgId, authenticated: Boolean(this.token) };
470
+ }
471
+ }
472
+ /** Read an `@file` or literal JSON value from a CLI option. */
473
+ export function readJsonOption(value, label) {
474
+ const trimmed = value.trim();
475
+ let text = trimmed;
476
+ if (trimmed.startsWith('@')) {
477
+ const path = trimmed.slice(1);
478
+ try {
479
+ text = readFileSync(path, 'utf-8');
480
+ }
481
+ catch (err) {
482
+ throw new ApplianceApiError(`Could not read ${path} for ${label}: ${err.message}`);
483
+ }
484
+ }
485
+ try {
486
+ return JSON.parse(text);
487
+ }
488
+ catch (err) {
489
+ throw new ApplianceApiError(`Invalid JSON for ${label}: ${err.message}`);
490
+ }
491
+ }
492
+ //# sourceMappingURL=appliance-api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"appliance-api.js","sourceRoot":"","sources":["../../src/lib/appliance-api.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,12 @@
10
10
  * keepalive; this bundle surfaces the DB state, NATS KV view, and the log lines
11
11
  * that explain why that keepalive never lands.
12
12
  */
13
+ /**
14
+ * Public entry point for `ct cube doctor --pcap`: resolve the shared network
15
+ * and run the same two-leg XCC wire capture used by `ct cube diag --pcap`.
16
+ * Writes xcc-bridge.pcap / xcc-ingress.pcap / xcc.pcap into `bundleDir`.
17
+ */
18
+ export declare function captureCubePcap(secs: number, bundleDir: string): Promise<string>;
13
19
  /**
14
20
  * Collect the full cube-diag bundle and write it to a single .log file (plus,
15
21
  * when `--pcap` is requested, sibling `xcc-bridge.pcap` / `xcc-ingress.pcap` /
@@ -1 +1 @@
1
- {"version":3,"file":"cube-diag.d.ts","sourceRoot":"","sources":["../../src/lib/cube-diag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAmtBH;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5F,OAAO,CAAC,MAAM,CAAC,CAqOjB"}
1
+ {"version":3,"file":"cube-diag.d.ts","sourceRoot":"","sources":["../../src/lib/cube-diag.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAupBH;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAGtF;AA8DD;;;;;;;;;;GAUG;AACH,wBAAsB,eAAe,CACnC,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAC5F,OAAO,CAAC,MAAM,CAAC,CAqOjB"}
@@ -622,6 +622,15 @@ async function collectPcap(net, secs, bundleDir) {
622
622
  lines.push(pcapStatLine('xcc.pcap (compat)', compatPath));
623
623
  return lines.join('\n');
624
624
  }
625
+ /**
626
+ * Public entry point for `ct cube doctor --pcap`: resolve the shared network
627
+ * and run the same two-leg XCC wire capture used by `ct cube diag --pcap`.
628
+ * Writes xcc-bridge.pcap / xcc-ingress.pcap / xcc.pcap into `bundleDir`.
629
+ */
630
+ export async function captureCubePcap(secs, bundleDir) {
631
+ const net = await resolveCtNetwork();
632
+ return collectPcap(net, secs, bundleDir);
633
+ }
625
634
  // ── Rejected-keepalive summary (API-1792 parity) ────────────────────────────
626
635
  //
627
636
  // Distinct api_key_prefix x distinct source_ip x count table, so a stale CUBE