@stacknext/cli 0.0.0-stage → 0.6.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 (103) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -2
  3. package/dist/bin.d.ts +3 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +4 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/collector/server.d.ts +28 -0
  8. package/dist/collector/server.d.ts.map +1 -0
  9. package/dist/collector/server.js +1258 -0
  10. package/dist/collector/server.js.map +1 -0
  11. package/dist/collector/test-runs.d.ts +40 -0
  12. package/dist/collector/test-runs.d.ts.map +1 -0
  13. package/dist/collector/test-runs.js +153 -0
  14. package/dist/collector/test-runs.js.map +1 -0
  15. package/dist/commands/baseline.d.ts +25 -0
  16. package/dist/commands/baseline.d.ts.map +1 -0
  17. package/dist/commands/baseline.js +151 -0
  18. package/dist/commands/baseline.js.map +1 -0
  19. package/dist/commands/capture.d.ts +13 -0
  20. package/dist/commands/capture.d.ts.map +1 -0
  21. package/dist/commands/capture.js +277 -0
  22. package/dist/commands/capture.js.map +1 -0
  23. package/dist/commands/compare.d.ts +17 -0
  24. package/dist/commands/compare.d.ts.map +1 -0
  25. package/dist/commands/compare.js +95 -0
  26. package/dist/commands/compare.js.map +1 -0
  27. package/dist/commands/coverage.d.ts +9 -0
  28. package/dist/commands/coverage.d.ts.map +1 -0
  29. package/dist/commands/coverage.js +124 -0
  30. package/dist/commands/coverage.js.map +1 -0
  31. package/dist/commands/dev.d.ts +19 -0
  32. package/dist/commands/dev.d.ts.map +1 -0
  33. package/dist/commands/dev.js +296 -0
  34. package/dist/commands/dev.js.map +1 -0
  35. package/dist/commands/diagnose.d.ts +22 -0
  36. package/dist/commands/diagnose.d.ts.map +1 -0
  37. package/dist/commands/diagnose.js +235 -0
  38. package/dist/commands/diagnose.js.map +1 -0
  39. package/dist/commands/doctor.d.ts +7 -0
  40. package/dist/commands/doctor.d.ts.map +1 -0
  41. package/dist/commands/doctor.js +176 -0
  42. package/dist/commands/doctor.js.map +1 -0
  43. package/dist/commands/export.d.ts +9 -0
  44. package/dist/commands/export.d.ts.map +1 -0
  45. package/dist/commands/export.js +55 -0
  46. package/dist/commands/export.js.map +1 -0
  47. package/dist/commands/init.d.ts +11 -0
  48. package/dist/commands/init.d.ts.map +1 -0
  49. package/dist/commands/init.js +203 -0
  50. package/dist/commands/init.js.map +1 -0
  51. package/dist/commands/mcp.d.ts +12 -0
  52. package/dist/commands/mcp.d.ts.map +1 -0
  53. package/dist/commands/mcp.js +32 -0
  54. package/dist/commands/mcp.js.map +1 -0
  55. package/dist/commands/regression-shared.d.ts +12 -0
  56. package/dist/commands/regression-shared.d.ts.map +1 -0
  57. package/dist/commands/regression-shared.js +149 -0
  58. package/dist/commands/regression-shared.js.map +1 -0
  59. package/dist/commands/runs.d.ts +13 -0
  60. package/dist/commands/runs.d.ts.map +1 -0
  61. package/dist/commands/runs.js +85 -0
  62. package/dist/commands/runs.js.map +1 -0
  63. package/dist/commands/status.d.ts +7 -0
  64. package/dist/commands/status.d.ts.map +1 -0
  65. package/dist/commands/status.js +70 -0
  66. package/dist/commands/status.js.map +1 -0
  67. package/dist/commands/uninstall.d.ts +15 -0
  68. package/dist/commands/uninstall.d.ts.map +1 -0
  69. package/dist/commands/uninstall.js +209 -0
  70. package/dist/commands/uninstall.js.map +1 -0
  71. package/dist/http.d.ts +7 -0
  72. package/dist/http.d.ts.map +1 -0
  73. package/dist/http.js +54 -0
  74. package/dist/http.js.map +1 -0
  75. package/dist/index.d.ts +22 -0
  76. package/dist/index.d.ts.map +1 -0
  77. package/dist/index.js +22 -0
  78. package/dist/index.js.map +1 -0
  79. package/dist/output.d.ts +16 -0
  80. package/dist/output.d.ts.map +1 -0
  81. package/dist/output.js +60 -0
  82. package/dist/output.js.map +1 -0
  83. package/dist/program.d.ts +4 -0
  84. package/dist/program.d.ts.map +1 -0
  85. package/dist/program.js +54 -0
  86. package/dist/program.js.map +1 -0
  87. package/dist/project.d.ts +35 -0
  88. package/dist/project.d.ts.map +1 -0
  89. package/dist/project.js +169 -0
  90. package/dist/project.js.map +1 -0
  91. package/dist/runtime.d.ts +26 -0
  92. package/dist/runtime.d.ts.map +1 -0
  93. package/dist/runtime.js +89 -0
  94. package/dist/runtime.js.map +1 -0
  95. package/dist/session.d.ts +10 -0
  96. package/dist/session.d.ts.map +1 -0
  97. package/dist/session.js +23 -0
  98. package/dist/session.js.map +1 -0
  99. package/dist/version.d.ts +2 -0
  100. package/dist/version.d.ts.map +1 -0
  101. package/dist/version.js +2 -0
  102. package/dist/version.js.map +1 -0
  103. package/package.json +58 -3
@@ -0,0 +1,149 @@
1
+ import { createRequire } from 'node:module';
2
+ import { readFile } from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { formatDuration, formatRelativeTime, style } from '../output.js';
5
+ export async function playwrightVersion(projectDir) {
6
+ const require = createRequire(path.join(projectDir, 'package.json'));
7
+ for (const name of ['@playwright/test/package.json', 'playwright/package.json']) {
8
+ try {
9
+ const file = require.resolve(name);
10
+ const parsed = JSON.parse(await readFile(file, 'utf8'));
11
+ if (typeof parsed.version === 'string')
12
+ return parsed.version;
13
+ }
14
+ catch {
15
+ // Try the next package name.
16
+ }
17
+ }
18
+ return undefined;
19
+ }
20
+ export function latestConnection(connections) {
21
+ return [...connections].sort((left, right) => right.lastSeen - left.lastSeen)[0] ?? null;
22
+ }
23
+ export function statusMarker(status) {
24
+ switch (status) {
25
+ case 'regressed':
26
+ return style.red('✗');
27
+ case 'improved':
28
+ return style.green('↑');
29
+ case 'unchanged':
30
+ return style.green('✓');
31
+ case 'inconclusive':
32
+ return style.yellow('!');
33
+ }
34
+ }
35
+ export function markerForRun(status) {
36
+ switch (status) {
37
+ case 'completed':
38
+ return style.green('✓');
39
+ case 'running':
40
+ return style.cyan('·');
41
+ case 'failed':
42
+ return style.red('✗');
43
+ case 'interrupted':
44
+ case 'incomplete':
45
+ return style.yellow('!');
46
+ }
47
+ }
48
+ export function environmentLines(environment) {
49
+ return [
50
+ `Node.js ${environment.nodeVersion}${environment.nextVersion ? ` · Next.js ${environment.nextVersion}` : ''}`,
51
+ `Platform ${environment.platform}/${environment.arch} · ${environment.runtime}`,
52
+ `Databases ${environment.databases.join(', ') || 'none'}`,
53
+ `Tracing ${environment.instrumentation.verbose ? `verbose (${environment.instrumentation.verboseSource})` : `standard (${environment.instrumentation.verboseSource})`} · fetch ${environment.instrumentation.captureFetch ? 'on' : 'off'} · errors ${environment.instrumentation.captureErrors ? 'on' : 'off'}`,
54
+ `SDK ${environment.sdkVersion}${environment.playwrightVersion ? ` · Playwright ${environment.playwrightVersion}` : ''}`,
55
+ ];
56
+ }
57
+ export function scenarioLines(scenario) {
58
+ const verified = scenario.samples.filter((sample) => sample.correlation.status === 'verified').length;
59
+ const incomplete = scenario.samples.length - verified;
60
+ const traces = scenario.samples.reduce((sum, sample) => sum + sample.correlation.traces.length, 0);
61
+ return [
62
+ `${style.bold(scenario.identity.title)} ${style.dim(scenario.identity.id)}`,
63
+ ` ${scenario.identity.file} · ${scenario.identity.project} · ${scenario.samples.length} sample(s), ${verified} verified${incomplete > 0 ? `, ${style.yellow(`${incomplete} incomplete`)}` : ''}, ${traces} trace(s), ${scenario.findings.length} finding(s)`,
64
+ ...scenario.limitations.slice(0, 2).map((limitation) => style.dim(` ${limitation}`)),
65
+ ];
66
+ }
67
+ export function runLines(run, now = Date.now()) {
68
+ const lines = [];
69
+ lines.push(`${markerForRun(run.status)} ${style.bold(run.name)} ${style.dim(run.id)} — ${run.status}`);
70
+ lines.push(`Created ${new Date(run.createdAt).toISOString()} ${style.dim(`(${formatRelativeTime(run.createdAt, now)})`)}`);
71
+ lines.push(`Command ${run.command.executable} ${run.command.args.join(' ')} ${style.dim(`exit ${run.command.exitCode ?? '—'} · ${formatDuration(run.command.durationMs)}`)}`);
72
+ lines.push(`Collector ${run.collector.version} · ${run.collector.connected ? style.green('connected') : style.yellow('not connected')}`);
73
+ lines.push(...environmentLines(run.environment));
74
+ lines.push(`Telemetry ${run.stats.scenarios} scenarios · ${run.stats.samples} samples (${run.stats.verifiedSamples} verified, ${run.stats.incompleteSamples} incomplete) · ${run.stats.traces} traces · ${run.stats.spans} spans · ${run.stats.errors} errors · ${run.stats.databaseQueries} queries`);
75
+ if (run.scenarios.length > 0) {
76
+ lines.push('');
77
+ lines.push(style.bold('Scenarios'));
78
+ for (const scenario of run.scenarios) {
79
+ lines.push(...scenarioLines(scenario));
80
+ }
81
+ }
82
+ if (run.warnings.length > 0) {
83
+ lines.push('');
84
+ lines.push(style.bold('Warnings'));
85
+ for (const warning of run.warnings)
86
+ lines.push(style.yellow(`! ${warning}`));
87
+ }
88
+ if (run.limitations.length > 0) {
89
+ lines.push('');
90
+ lines.push(style.bold('Limitations'));
91
+ for (const limitation of run.limitations.slice(0, 5)) {
92
+ lines.push(style.dim(`· ${limitation}`));
93
+ }
94
+ }
95
+ return lines;
96
+ }
97
+ export function baselineLines(baseline, now = Date.now()) {
98
+ const lines = [];
99
+ lines.push(`${style.bold(baseline.name)} ${style.dim(baseline.id)} — from ${baseline.sourceRunId}`);
100
+ lines.push(`Created ${new Date(baseline.createdAt).toISOString()} ${style.dim(`(${formatRelativeTime(baseline.createdAt, now)})`)}`);
101
+ lines.push(...environmentLines(baseline.environment));
102
+ lines.push(`Telemetry ${baseline.stats.scenarios} scenarios · ${baseline.stats.samples} samples (${baseline.stats.verifiedSamples} verified, ${baseline.stats.incompleteSamples} incomplete) · ${baseline.stats.traces} traces · ${baseline.stats.spans} spans`);
103
+ if (baseline.notes.length > 0) {
104
+ lines.push('');
105
+ lines.push(style.bold('Notes'));
106
+ for (const note of baseline.notes)
107
+ lines.push(`· ${note}`);
108
+ }
109
+ return lines;
110
+ }
111
+ export function comparisonLines(comparison) {
112
+ const lines = [];
113
+ lines.push(`${statusMarker(comparison.status)} ${style.bold(`Comparison ${comparison.status}`)} ${style.dim(`${comparison.id} · baseline ${comparison.baselineId} → ${comparison.candidateId}`)}`);
114
+ lines.push(`Scenarios ${comparison.summary.scenarios} · ${comparison.summary.regressed} regressed · ${comparison.summary.improved} improved · ${comparison.summary.unchanged} unchanged · ${comparison.summary.inconclusive} inconclusive`);
115
+ lines.push(`Environment ${comparison.environment.compatible ? style.green('compatible') : style.yellow('different')}${comparison.environment.ignored ? ' · explicitly ignored' : ''}`);
116
+ if (comparison.environment.differences.length > 0) {
117
+ for (const difference of comparison.environment.differences) {
118
+ lines.push(style.dim(` ${difference.field}: ${difference.baseline} → ${difference.candidate}`));
119
+ }
120
+ }
121
+ lines.push('');
122
+ lines.push(style.bold('Scenarios'));
123
+ for (const scenario of comparison.scenarios) {
124
+ lines.push(`${statusMarker(scenario.status)} ${style.bold(scenario.title)} ${style.dim(`${scenario.scenarioId} · ${scenario.status}${scenario.severity !== 'none' ? ` · ${scenario.severity} severity` : ''}`)}`);
125
+ if (scenario.reasons.length > 0) {
126
+ lines.push(style.dim(` ${scenario.reasons.join('; ')}`));
127
+ }
128
+ for (const metric of scenario.metrics) {
129
+ if (metric.status === 'unchanged')
130
+ continue;
131
+ const baseline = metric.baselineValue === null ? 'null' : String(metric.baselineValue);
132
+ const candidate = metric.candidateValue === null ? 'null' : String(metric.candidateValue);
133
+ lines.push(` ${statusMarker(metric.status)} ${metric.label}: ${baseline} → ${candidate}${metric.delta === null ? '' : ` (${metric.delta > 0 ? '+' : ''}${metric.delta}${metric.percent === null ? '' : `, ${metric.percent}%`})`}${metric.note ? style.dim(` — ${metric.note}`) : ''}`);
134
+ }
135
+ }
136
+ if (comparison.warnings.length > 0) {
137
+ lines.push('');
138
+ lines.push(style.bold('Warnings'));
139
+ for (const warning of comparison.warnings)
140
+ lines.push(style.yellow(`! ${warning}`));
141
+ }
142
+ lines.push('');
143
+ lines.push(style.bold('Limitations'));
144
+ for (const limitation of comparison.limitations.slice(0, 5)) {
145
+ lines.push(style.dim(`· ${limitation}`));
146
+ }
147
+ return lines;
148
+ }
149
+ //# sourceMappingURL=regression-shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regression-shared.js","sourceRoot":"","sources":["../../src/commands/regression-shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Command } from 'commander';
2
+ export interface RunsListOptions {
3
+ json?: boolean;
4
+ limit?: string;
5
+ offset?: string;
6
+ }
7
+ export interface RunsShowOptions {
8
+ json?: boolean;
9
+ }
10
+ export declare function runRunsList(options: RunsListOptions, cwd?: string): Promise<number>;
11
+ export declare function runRunsShow(id: string, options: RunsShowOptions, cwd?: string): Promise<number>;
12
+ export declare function registerRunsCommand(program: Command, cwd: string): void;
13
+ //# sourceMappingURL=runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../../src/commands/runs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWxC,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAeD,wBAAsB,WAAW,CAC/B,OAAO,EAAE,eAAe,EACxB,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED,wBAAsB,WAAW,CAC/B,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,eAAe,EACxB,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CA8BvE"}
@@ -0,0 +1,85 @@
1
+ import { listRuns, loadRun, } from '@stacknext/regression';
2
+ import { formatDuration, formatRelativeTime, printBanner, style } from '../output.js';
3
+ import { detectProject } from '../project.js';
4
+ import { CLI_VERSION } from '../version.js';
5
+ import { markerForRun, runLines } from './regression-shared.js';
6
+ function parseInteger(value, fallback) {
7
+ if (value === undefined)
8
+ return fallback;
9
+ const parsed = Number(value);
10
+ if (!Number.isInteger(parsed) || parsed < 0) {
11
+ throw new Error(`Invalid number "${value}"`);
12
+ }
13
+ return parsed;
14
+ }
15
+ function summaryLine(run, now) {
16
+ return `${markerForRun(run.status)} ${style.bold(run.name)} ${style.dim(run.id)} — ${run.status}, ${run.scenarios} scenarios, ${run.samples} samples (${run.verifiedSamples} verified, ${run.incompleteSamples} incomplete), ${formatRelativeTime(run.createdAt, now)}, ${formatDuration(run.durationMs)}`;
17
+ }
18
+ export async function runRunsList(options, cwd = process.cwd()) {
19
+ const project = await detectProject(cwd);
20
+ const result = await listRuns(project.dir, {
21
+ limit: parseInteger(options.limit, 50),
22
+ offset: parseInteger(options.offset, 0),
23
+ });
24
+ if (options.json) {
25
+ console.log(JSON.stringify(result, null, 2));
26
+ return 0;
27
+ }
28
+ printBanner(CLI_VERSION);
29
+ if (result.items.length === 0) {
30
+ console.log('No captured test runs. Run "stacknext capture --name <name> -- <playwright command>".');
31
+ return 0;
32
+ }
33
+ const now = Date.now();
34
+ for (const run of result.items) {
35
+ console.log(summaryLine(run, now));
36
+ }
37
+ console.log(style.dim(`\nShowing ${result.items.length} of ${result.total} run(s). Stored under .stacknext/runs.`));
38
+ return 0;
39
+ }
40
+ export async function runRunsShow(id, options, cwd = process.cwd()) {
41
+ if (!/^run-[0-9a-f]{16}$/.test(id)) {
42
+ throw new Error(`Invalid run id "${id}"`);
43
+ }
44
+ const project = await detectProject(cwd);
45
+ const run = await loadRun(project.dir, id);
46
+ if (options.json) {
47
+ console.log(JSON.stringify(run, null, 2));
48
+ return 0;
49
+ }
50
+ printBanner(CLI_VERSION);
51
+ console.log(runLines(run));
52
+ return 0;
53
+ }
54
+ export function registerRunsCommand(program, cwd) {
55
+ const runs = program
56
+ .command('runs')
57
+ .description('List saved capture runs (local .stacknext/runs)');
58
+ runs
59
+ .command('list')
60
+ .description('List captured test runs')
61
+ .option('--limit <number>', 'maximum runs to return (1-200)')
62
+ .option('--offset <number>', 'pagination offset')
63
+ .option('--json', 'print machine-readable JSON')
64
+ .action(async (options) => {
65
+ const code = await runRunsList(options, cwd);
66
+ if (code !== 0)
67
+ process.exitCode = code;
68
+ });
69
+ runs
70
+ .command('show')
71
+ .description('Show one captured test run')
72
+ .argument('<run-id>', 'run id (run-...)')
73
+ .option('--json', 'print machine-readable JSON')
74
+ .action(async (id, options) => {
75
+ const code = await runRunsShow(id, options, cwd);
76
+ if (code !== 0)
77
+ process.exitCode = code;
78
+ });
79
+ runs.action(async () => {
80
+ const code = await runRunsList({}, cwd);
81
+ if (code !== 0)
82
+ process.exitCode = code;
83
+ });
84
+ }
85
+ //# sourceMappingURL=runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runs.js","sourceRoot":"","sources":["../../src/commands/runs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Command } from 'commander';
2
+ export interface StatusOptions {
3
+ json?: boolean;
4
+ }
5
+ export declare function runStatus(options: StatusOptions, cwd?: string): Promise<number>;
6
+ export declare function registerStatusCommand(program: Command, cwd: string): void;
7
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAOxC,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,wBAAsB,SAAS,CAC7B,OAAO,EAAE,aAAa,EACtB,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAsFjB;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CASzE"}
@@ -0,0 +1,70 @@
1
+ import { collectorJson } from '../http.js';
2
+ import { style } from '../output.js';
3
+ import { formatDuration, formatRelativeTime } from '../output.js';
4
+ import { requireRunningState } from '../session.js';
5
+ export async function runStatus(options, cwd = process.cwd()) {
6
+ const state = await requireRunningState(cwd);
7
+ let health;
8
+ try {
9
+ health = await collectorJson(state.collectorUrl, '/api/health', state.token);
10
+ }
11
+ catch (error) {
12
+ if (!options.json) {
13
+ console.error(`${style.red('Collector unreachable')} — ${error instanceof Error ? error.message : String(error)}`);
14
+ }
15
+ return 1;
16
+ }
17
+ if (options.json) {
18
+ console.log(JSON.stringify({
19
+ runtime: { ...state, token: '[redacted]' },
20
+ health,
21
+ }, null, 2));
22
+ return 0;
23
+ }
24
+ const connected = health.connections.filter((connection) => connection.connected);
25
+ console.log(`${style.bold('StackNext')} ${style.dim(`v${health.version}`)} — ${health.projectName}`);
26
+ console.log(`Dashboard ${style.cyan(health.dashboardUrl)}`);
27
+ console.log(`Collector ${state.collectorUrl} ${style.dim(`(pid ${state.pid}, up ${formatDuration(health.uptimeMs)})`)}`);
28
+ if (connected.length === 0) {
29
+ console.log(`Instrumentation ${style.yellow('waiting')} ${style.dim('— no app heartbeat received yet')}`);
30
+ }
31
+ else {
32
+ for (const connection of connected) {
33
+ console.log(`Instrumentation ${style.green('connected')} — ${connection.serviceName}` +
34
+ (connection.nextVersion ? ` (Next.js ${connection.nextVersion})` : '') +
35
+ style.dim(` last seen ${formatRelativeTime(connection.lastSeen, health.time)}`));
36
+ }
37
+ }
38
+ console.log(`Requests ${health.counts.requests} total, ${health.counts.failedRequests} failed, ${health.counts.slowRequests} slow`);
39
+ console.log(`Telemetry ${health.counts.spans} spans, ${health.counts.errors} errors, ${health.counts.databaseQueries} database queries`);
40
+ const verbose = health.instrumentation.nextOtelVerbose;
41
+ console.log(`Next.js spans ${verbose.enabled
42
+ ? style.cyan(`verbose (${verbose.source})`)
43
+ : verbose.source === 'unknown'
44
+ ? style.yellow('NEXT_OTEL_VERBOSE has an unrecognized value')
45
+ : style.dim(`standard (${verbose.source})`)}`);
46
+ const drops = health.store.dropped.capacity +
47
+ health.store.dropped.retention +
48
+ health.server.droppedMalformed +
49
+ health.server.droppedPayload +
50
+ health.exporter.droppedSpans +
51
+ health.exporter.droppedEvents;
52
+ console.log(`Drops ${drops} total` +
53
+ (health.exporter.lastError
54
+ ? ` ${style.yellow(`— last exporter error: ${health.exporter.lastError}`)}`
55
+ : ''));
56
+ console.log(style.dim(`Limits: ${health.store.limits.maxSpans} spans / ${formatDuration(health.store.limits.retentionMs)} retention`));
57
+ return 0;
58
+ }
59
+ export function registerStatusCommand(program, cwd) {
60
+ program
61
+ .command('status')
62
+ .description('Show collector and instrumentation status')
63
+ .option('--json', 'print machine-readable JSON')
64
+ .action(async (options) => {
65
+ const code = await runStatus(options, cwd);
66
+ if (code !== 0)
67
+ process.exitCode = code;
68
+ });
69
+ }
70
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { Command } from 'commander';
2
+ export interface UninstallOptions {
3
+ yes?: boolean;
4
+ keepConfig?: boolean;
5
+ removeData?: boolean;
6
+ json?: boolean;
7
+ }
8
+ /**
9
+ * Removes only files that StackNext owns. A user-authored instrumentation file
10
+ * is always preserved, even when it imports StackNext. Generated instrumentation
11
+ * is removed only when its contents still match the generated template.
12
+ */
13
+ export declare function runUninstall(options: UninstallOptions, cwd?: string): Promise<number>;
14
+ export declare function registerUninstallCommand(program: Command, cwd: string): void;
15
+ //# sourceMappingURL=uninstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAYxC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAqCD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,gBAAgB,EACzB,GAAG,SAAgB,GAClB,OAAO,CAAC,MAAM,CAAC,CAiJjB;AA0CD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAY5E"}
@@ -0,0 +1,209 @@
1
+ import { readFile, readdir, rm, rmdir } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { configPath } from '@stacknext/core/config-file';
4
+ import { detectProject, stackNextPackages } from '../project.js';
5
+ import { printCheck, printSection, style } from '../output.js';
6
+ import { isProcessAlive, readRuntimeState, runtimeDir, runtimeStatePath, } from '../runtime.js';
7
+ import { fileExists, isGeneratedInstrumentation } from './init.js';
8
+ async function removeGeneratedRuntimeFiles(dir) {
9
+ try {
10
+ const gitignore = path.join(dir, '.gitignore');
11
+ if ((await readFile(gitignore, 'utf8')) === '*\n') {
12
+ await rm(gitignore, { force: true });
13
+ }
14
+ }
15
+ catch {
16
+ // Nothing to clean up.
17
+ }
18
+ }
19
+ async function isEmptyDirectory(dir) {
20
+ try {
21
+ return (await readdir(dir)).length === 0;
22
+ }
23
+ catch {
24
+ return false;
25
+ }
26
+ }
27
+ /**
28
+ * Removes only files that StackNext owns. A user-authored instrumentation file
29
+ * is always preserved, even when it imports StackNext. Generated instrumentation
30
+ * is removed only when its contents still match the generated template.
31
+ */
32
+ export async function runUninstall(options, cwd = process.cwd()) {
33
+ const project = await detectProject(cwd);
34
+ const removed = [];
35
+ const preserved = [];
36
+ const manual = [];
37
+ let runtimeProcess = null;
38
+ if (project.instrumentationExists && project.instrumentationPath) {
39
+ const file = project.instrumentationPath;
40
+ const source = await readFile(file, 'utf8');
41
+ if (isGeneratedInstrumentation(source)) {
42
+ removed.push({
43
+ kind: 'instrumentation',
44
+ file,
45
+ reason: 'generated StackNext instrumentation',
46
+ });
47
+ }
48
+ else {
49
+ preserved.push({
50
+ file,
51
+ reason: 'existing instrumentation belongs to the application',
52
+ });
53
+ if (source.includes('@stacknext/next')) {
54
+ manual.push(`Remove the StackNext import and registerStackNext()/onRequestError hook from ${path.relative(project.dir, file)}.`);
55
+ }
56
+ }
57
+ }
58
+ const configFile = configPath(project.dir);
59
+ if (await fileExists(configFile)) {
60
+ if (options.keepConfig) {
61
+ preserved.push({ file: configFile, reason: '--keep-config was requested' });
62
+ }
63
+ else {
64
+ removed.push({
65
+ kind: 'config',
66
+ file: configFile,
67
+ reason: 'StackNext configuration',
68
+ });
69
+ }
70
+ }
71
+ const stateFile = runtimeStatePath(project.dir);
72
+ const runtime = await readRuntimeState(project.dir).catch(() => null);
73
+ if (runtime && isProcessAlive(runtime.pid)) {
74
+ runtimeProcess = runtime.pid;
75
+ preserved.push({
76
+ file: stateFile,
77
+ reason: `StackNext is still running (pid ${runtime.pid}); stop it with SIGINT/SIGTERM first`,
78
+ });
79
+ }
80
+ else if (await fileExists(stateFile)) {
81
+ removed.push({ kind: 'runtime', file: stateFile, reason: 'runtime token state' });
82
+ }
83
+ if (options.removeData) {
84
+ const dir = runtimeDir(project.dir);
85
+ if (await fileExists(dir)) {
86
+ removed.push({
87
+ kind: 'data',
88
+ file: dir,
89
+ reason: 'saved runs, baselines and comparisons (--remove-data)',
90
+ });
91
+ }
92
+ }
93
+ const packages = stackNextPackages(project);
94
+ const packageCommand = packages.length > 0
95
+ ? installRemovalCommand(project.packageManager, packages)
96
+ : null;
97
+ const report = {
98
+ project: project.dir,
99
+ applied: false,
100
+ removed,
101
+ preserved,
102
+ manual,
103
+ packageCommand,
104
+ runtimeProcess,
105
+ };
106
+ if (!options.yes) {
107
+ if (options.json) {
108
+ console.log(JSON.stringify(report, null, 2));
109
+ }
110
+ else {
111
+ printSection(`StackNext uninstall — ${project.name}`);
112
+ printPlan(project.dir, removed, preserved, manual, packageCommand);
113
+ console.log(`\n${style.yellow('No changes made.')} Re-run with ${style.cyan('stacknext uninstall --yes')} to remove the listed files.`);
114
+ }
115
+ return runtimeProcess === null ? 0 : 1;
116
+ }
117
+ if (runtimeProcess !== null) {
118
+ if (options.json) {
119
+ console.log(JSON.stringify(report, null, 2));
120
+ }
121
+ else {
122
+ printSection(`StackNext uninstall — ${project.name}`);
123
+ printPlan(project.dir, removed, preserved, manual, packageCommand);
124
+ console.error(`\n${style.red('Refusing to remove files while StackNext is running.')} Stop pid ${runtimeProcess} first.`);
125
+ }
126
+ return 1;
127
+ }
128
+ for (const entry of removed) {
129
+ if (entry.kind === 'data') {
130
+ await rm(entry.file, { recursive: true, force: true });
131
+ }
132
+ else {
133
+ await rm(entry.file, { force: true });
134
+ }
135
+ }
136
+ const dir = runtimeDir(project.dir);
137
+ await removeGeneratedRuntimeFiles(dir);
138
+ if (await isEmptyDirectory(dir)) {
139
+ await rmdir(dir).catch(() => undefined);
140
+ }
141
+ report.applied = true;
142
+ if (options.json) {
143
+ console.log(JSON.stringify(report, null, 2));
144
+ }
145
+ else {
146
+ printSection(`StackNext uninstall — ${project.name}`);
147
+ if (removed.length === 0) {
148
+ printCheck('pass', 'No StackNext-owned files needed removal');
149
+ }
150
+ for (const entry of removed) {
151
+ printCheck('pass', `Removed ${path.relative(project.dir, entry.file)}`, entry.reason);
152
+ }
153
+ for (const entry of preserved) {
154
+ printCheck('warn', `Preserved ${path.relative(project.dir, entry.file)}`, entry.reason);
155
+ }
156
+ for (const instruction of manual) {
157
+ console.log(`${style.yellow('!')} ${instruction}`);
158
+ }
159
+ if (packageCommand) {
160
+ console.log(`\nRemove the packages with: ${style.cyan(packageCommand)}`);
161
+ }
162
+ console.log(`\nRuntime processes and ports were not touched. The dashboard stops when ${style.cyan('stacknext dev')} exits.`);
163
+ }
164
+ return 0;
165
+ }
166
+ function printPlan(projectDir, removed, preserved, manual, packageCommand) {
167
+ if (removed.length === 0) {
168
+ printCheck('pass', 'No StackNext-owned files to remove');
169
+ }
170
+ for (const entry of removed) {
171
+ printCheck('fail', `Will remove ${path.relative(projectDir, entry.file)}`, entry.reason);
172
+ }
173
+ for (const entry of preserved) {
174
+ printCheck('warn', `Will preserve ${path.relative(projectDir, entry.file)}`, entry.reason);
175
+ }
176
+ for (const instruction of manual) {
177
+ console.log(`${style.yellow('!')} ${instruction}`);
178
+ }
179
+ if (packageCommand) {
180
+ console.log(`\nPackage removal command: ${style.cyan(packageCommand)}`);
181
+ }
182
+ }
183
+ function installRemovalCommand(manager, packages) {
184
+ switch (manager) {
185
+ case 'pnpm':
186
+ return `pnpm remove ${packages.join(' ')}`;
187
+ case 'yarn':
188
+ return `yarn remove ${packages.join(' ')}`;
189
+ case 'bun':
190
+ return `bun remove ${packages.join(' ')}`;
191
+ case 'npm':
192
+ return `npm uninstall ${packages.join(' ')}`;
193
+ }
194
+ }
195
+ export function registerUninstallCommand(program, cwd) {
196
+ program
197
+ .command('uninstall')
198
+ .description('Remove StackNext-owned project files without touching user configuration')
199
+ .option('--yes', 'apply the planned removals (without it, only prints the plan)')
200
+ .option('--keep-config', 'keep stacknext.config.json')
201
+ .option('--remove-data', 'also remove saved runs, baselines and comparisons')
202
+ .option('--json', 'print machine-readable JSON')
203
+ .action(async (options) => {
204
+ const code = await runUninstall(options, cwd);
205
+ if (code !== 0)
206
+ process.exitCode = code;
207
+ });
208
+ }
209
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export declare class CollectorApiError extends Error {
2
+ readonly status: number;
3
+ constructor(message: string, status: number);
4
+ }
5
+ export declare function collectorFetch(baseUrl: string, pathname: string, token: string, init?: RequestInit): Promise<Response>;
6
+ export declare function collectorJson<T>(baseUrl: string, pathname: string, token: string, init?: RequestInit): Promise<T>;
7
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../src/http.ts"],"names":[],"mappings":"AAEA,qBAAa,iBAAkB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;gBAEX,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;CAK5C;AAkBD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,QAAQ,CAAC,CAWnB;AAED,wBAAsB,aAAa,CAAC,CAAC,EACnC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,WAAgB,GACrB,OAAO,CAAC,CAAC,CAAC,CAaZ"}