@elench/testkit 0.1.97 → 0.1.98
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.
- package/lib/app/browser-bridge.mjs +1 -1
- package/lib/cli/assistant/app.mjs +25 -1
- package/lib/cli/assistant/composer.mjs +1 -1
- package/lib/cli/assistant/context-pack.mjs +4 -4
- package/lib/cli/assistant/interactive.mjs +1 -1
- package/lib/cli/assistant/prompt-builder.mjs +2 -2
- package/lib/cli/{agents → assistant/providers}/index.mjs +3 -3
- package/lib/cli/assistant/session.mjs +5 -5
- package/lib/cli/assistant/slash-commands.mjs +22 -1
- package/lib/cli/assistant/state.mjs +148 -75
- package/lib/cli/assistant/tool-registry.mjs +305 -39
- package/lib/cli/assistant/view-model.mjs +1 -1
- package/lib/cli/commands/assistant.mjs +4 -3
- package/lib/cli/commands/browser/serve.mjs +5 -23
- package/lib/cli/commands/cleanup.mjs +8 -2
- package/lib/cli/commands/db/snapshot/capture.mjs +8 -4
- package/lib/cli/commands/destroy.mjs +8 -2
- package/lib/cli/commands/discover.mjs +5 -27
- package/lib/cli/commands/doctor.mjs +5 -5
- package/lib/cli/commands/flags.mjs +61 -0
- package/lib/cli/commands/run.mjs +10 -2
- package/lib/cli/commands/status.mjs +10 -2
- package/lib/cli/commands/typecheck.mjs +5 -5
- package/lib/cli/{tui/inspect-app.mjs → components/blocks/run-tree.mjs} +29 -54
- package/lib/cli/{tui → components/primitives}/filter-bar.mjs +1 -1
- package/lib/cli/{presentation → components/primitives}/summary-box.mjs +1 -1
- package/lib/cli/config.mjs +63 -0
- package/lib/cli/operations/browser/serve/operation.mjs +23 -0
- package/lib/cli/operations/cleanup/operation.mjs +8 -0
- package/lib/cli/{db.mjs → operations/db/snapshot/capture/operation.mjs} +15 -9
- package/lib/cli/operations/destroy/operation.mjs +12 -0
- package/lib/cli/operations/discover/operation.mjs +32 -0
- package/lib/cli/operations/doctor/operation.mjs +5 -0
- package/lib/cli/operations/run/operation.mjs +129 -0
- package/lib/cli/operations/status/operation.mjs +7 -0
- package/lib/cli/operations/typecheck/operation.mjs +5 -0
- package/lib/cli/renderers/browser-serve/text.mjs +6 -0
- package/lib/cli/renderers/cleanup/text.mjs +3 -0
- package/lib/cli/renderers/db-snapshot-capture/text.mjs +3 -0
- package/lib/cli/renderers/destroy/text.mjs +3 -0
- package/lib/cli/{presentation/discovery-reporter.mjs → renderers/discover/report.mjs} +3 -3
- package/lib/cli/renderers/discover/text.mjs +7 -0
- package/lib/cli/renderers/doctor/text.mjs +7 -0
- package/lib/cli/{presentation/failure-presentation.mjs → renderers/run/failure.mjs} +6 -6
- package/lib/cli/renderers/run/interactive.mjs +119 -0
- package/lib/cli/{presentation/run-reporter.mjs → renderers/run/text-reporter.mjs} +5 -5
- package/lib/cli/renderers/status/text.mjs +7 -0
- package/lib/cli/renderers/typecheck/text.mjs +7 -0
- package/lib/cli/{tui/inspect-model.mjs → state/run/model.mjs} +11 -26
- package/lib/cli/{tui/inspect-state.mjs → state/run/state.mjs} +11 -18
- package/lib/cli/{tui → state/tree}/fuzzy-match.mjs +1 -1
- package/lib/cli/terminal/capabilities.mjs +33 -0
- package/lib/database/index.mjs +9 -21
- package/lib/{cli/viewer.mjs → results/artifacts.mjs} +1 -1
- package/lib/{cli/context-resources.mjs → results/context.mjs} +1 -1
- package/lib/runner/maintenance.mjs +25 -14
- package/lib/runner/readiness.mjs +5 -4
- package/lib/runner/state-io.mjs +10 -4
- package/node_modules/@elench/next-analysis/package.json +1 -1
- package/node_modules/@elench/testkit-bridge/package.json +2 -2
- package/node_modules/@elench/testkit-protocol/package.json +1 -1
- package/node_modules/@elench/ts-analysis/package.json +1 -1
- package/package.json +6 -7
- package/lib/cli/command-helpers.mjs +0 -191
- package/lib/cli/presentation/tree-reporter.mjs +0 -96
- package/lib/cli/tui/inspect-artifact-adapter.mjs +0 -3
- package/lib/cli/tui/inspect-live-adapter.mjs +0 -15
- /package/lib/cli/{agents → assistant}/providers/claude.mjs +0 -0
- /package/lib/cli/{agents → assistant}/providers/codex.mjs +0 -0
- /package/lib/cli/{agents → assistant}/providers/shared.mjs +0 -0
- /package/lib/cli/{presentation/events-reporter.mjs → renderers/run/events.mjs} +0 -0
- /package/lib/cli/{presentation → terminal}/colors.mjs +0 -0
- /package/lib/cli/{presentation/terminal-layout.mjs → terminal/layout.mjs} +0 -0
- /package/lib/{cli/presentation → results}/code-frames.mjs +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elench/testkit-bridge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.98",
|
|
4
4
|
"description": "Browser bridge helpers for testkit",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"typecheck": "tsc -p tsconfig.json --noEmit"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@elench/testkit-protocol": "0.1.
|
|
25
|
+
"@elench/testkit-protocol": "0.1.98"
|
|
26
26
|
},
|
|
27
27
|
"private": false
|
|
28
28
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elench/testkit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.98",
|
|
4
4
|
"description": "Assistant-first CLI for running, inspecting, and debugging local testkit suites",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"workspaces": [
|
|
@@ -62,8 +62,7 @@
|
|
|
62
62
|
"test:audit": "node scripts/test-boundary-audit.mjs",
|
|
63
63
|
"test:unit": "npm run build:packages && npm run test:audit && vitest run --config vitest.unit.config.mjs",
|
|
64
64
|
"test:integration": "npm run build:packages && vitest run test/integration",
|
|
65
|
-
"test:system": "npm run build:packages && vitest run test/system --passWithNoTests"
|
|
66
|
-
"test:live-providers": "npm run build:packages && vitest run --config vitest.live.config.mjs --passWithNoTests"
|
|
65
|
+
"test:system": "npm run build:packages && vitest run test/system --passWithNoTests"
|
|
67
66
|
},
|
|
68
67
|
"files": [
|
|
69
68
|
"bin/",
|
|
@@ -84,10 +83,10 @@
|
|
|
84
83
|
},
|
|
85
84
|
"dependencies": {
|
|
86
85
|
"@babel/code-frame": "^7.29.0",
|
|
87
|
-
"@elench/next-analysis": "0.1.
|
|
88
|
-
"@elench/testkit-bridge": "0.1.
|
|
89
|
-
"@elench/testkit-protocol": "0.1.
|
|
90
|
-
"@elench/ts-analysis": "0.1.
|
|
86
|
+
"@elench/next-analysis": "0.1.98",
|
|
87
|
+
"@elench/testkit-bridge": "0.1.98",
|
|
88
|
+
"@elench/testkit-protocol": "0.1.98",
|
|
89
|
+
"@elench/ts-analysis": "0.1.98",
|
|
91
90
|
"@oclif/core": "^4.10.6",
|
|
92
91
|
"esbuild": "^0.25.11",
|
|
93
92
|
"execa": "^9.5.0",
|
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
import { Flags } from "@oclif/core";
|
|
2
|
-
import path from "path";
|
|
3
|
-
import { loadManagedConfigs } from "../app/configs.mjs";
|
|
4
|
-
import {
|
|
5
|
-
parseFileTimeoutOption,
|
|
6
|
-
parseShardOption,
|
|
7
|
-
parseSuiteOption,
|
|
8
|
-
parseTypeOption,
|
|
9
|
-
parseWorkersOption,
|
|
10
|
-
resolveRequestedFiles,
|
|
11
|
-
} from "./args.mjs";
|
|
12
|
-
import * as runner from "../runner/index.mjs";
|
|
13
|
-
import { createRunReporter } from "./presentation/run-reporter.mjs";
|
|
14
|
-
import { createTreeReporter } from "./presentation/tree-reporter.mjs";
|
|
15
|
-
import { createRunEventsReporter } from "./presentation/events-reporter.mjs";
|
|
16
|
-
|
|
17
|
-
export const sharedFlags = {
|
|
18
|
-
dir: Flags.string({
|
|
19
|
-
description: "Explicit product directory",
|
|
20
|
-
}),
|
|
21
|
-
service: Flags.string({
|
|
22
|
-
description: "Limit the operation or assistant context to one service",
|
|
23
|
-
}),
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export const runFlags = {
|
|
27
|
-
...sharedFlags,
|
|
28
|
-
type: Flags.string({
|
|
29
|
-
char: "t",
|
|
30
|
-
multiple: true,
|
|
31
|
-
description: "Run specific suite type(s): int, e2e, scenario, dal, load, pw, all",
|
|
32
|
-
}),
|
|
33
|
-
suite: Flags.string({
|
|
34
|
-
char: "s",
|
|
35
|
-
multiple: true,
|
|
36
|
-
description: "Run specific suite(s)",
|
|
37
|
-
}),
|
|
38
|
-
file: Flags.string({
|
|
39
|
-
char: "f",
|
|
40
|
-
multiple: true,
|
|
41
|
-
description: "Run specific file(s)",
|
|
42
|
-
}),
|
|
43
|
-
workers: Flags.string({
|
|
44
|
-
description: "Number of test executors for the whole run",
|
|
45
|
-
}),
|
|
46
|
-
"file-timeout-seconds": Flags.string({
|
|
47
|
-
description: "Per-file wall-clock timeout in seconds",
|
|
48
|
-
}),
|
|
49
|
-
shard: Flags.string({
|
|
50
|
-
description: "Run only shard i of n at suite granularity",
|
|
51
|
-
}),
|
|
52
|
-
seed: Flags.string({
|
|
53
|
-
description: "Deterministic seed for scenario suites",
|
|
54
|
-
}),
|
|
55
|
-
"write-status": Flags.boolean({
|
|
56
|
-
description: "Write a deterministic testkit.status.json snapshot",
|
|
57
|
-
default: false,
|
|
58
|
-
}),
|
|
59
|
-
"allow-partial-status": Flags.boolean({
|
|
60
|
-
description: "Allow --write-status for filtered runs",
|
|
61
|
-
default: false,
|
|
62
|
-
}),
|
|
63
|
-
"ignore-skip-rules": Flags.boolean({
|
|
64
|
-
description: "Run files even if testkit.config.ts marks them skipped",
|
|
65
|
-
default: false,
|
|
66
|
-
}),
|
|
67
|
-
"output-mode": Flags.string({
|
|
68
|
-
description: "Reporter mode",
|
|
69
|
-
options: ["compact", "debug", "events"],
|
|
70
|
-
}),
|
|
71
|
-
debug: Flags.boolean({
|
|
72
|
-
description: "Alias for --output-mode debug",
|
|
73
|
-
default: false,
|
|
74
|
-
}),
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export async function resolveConfigsForCommand(flags) {
|
|
78
|
-
return loadManagedConfigs({ dir: flags.dir, service: flags.service });
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export async function executeRunCommand(command, flags, positionalType = null) {
|
|
82
|
-
const request = await buildRunRequest(flags, positionalType, process.cwd(), process.cwd());
|
|
83
|
-
const { allConfigs, configs, typeValues, suiteSelectors, productDir } = request;
|
|
84
|
-
const outputMode = command.jsonEnabled()
|
|
85
|
-
? "json"
|
|
86
|
-
: flags.debug
|
|
87
|
-
? "debug"
|
|
88
|
-
: flags["output-mode"] || "compact";
|
|
89
|
-
|
|
90
|
-
let reporter;
|
|
91
|
-
let finalize = Promise.resolve();
|
|
92
|
-
let close = () => {};
|
|
93
|
-
|
|
94
|
-
if (outputMode === "compact" && process.stdout.isTTY) {
|
|
95
|
-
const tree = createTreeReporter({
|
|
96
|
-
stdout: process.stdout,
|
|
97
|
-
stderr: process.stderr,
|
|
98
|
-
productDir,
|
|
99
|
-
});
|
|
100
|
-
reporter = tree.reporter;
|
|
101
|
-
finalize = tree.finalize;
|
|
102
|
-
close = tree.close;
|
|
103
|
-
} else if (outputMode === "events") {
|
|
104
|
-
reporter = createRunEventsReporter({ stdout: process.stdout, stderr: process.stderr });
|
|
105
|
-
} else {
|
|
106
|
-
reporter = createRunReporter({ outputMode });
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
try {
|
|
110
|
-
const result = await runner.runAll(
|
|
111
|
-
configs,
|
|
112
|
-
typeValues,
|
|
113
|
-
suiteSelectors,
|
|
114
|
-
{
|
|
115
|
-
reporter,
|
|
116
|
-
...request.runOptions,
|
|
117
|
-
},
|
|
118
|
-
allConfigs
|
|
119
|
-
);
|
|
120
|
-
await finalize;
|
|
121
|
-
return {
|
|
122
|
-
outputMode,
|
|
123
|
-
...result,
|
|
124
|
-
};
|
|
125
|
-
} catch (error) {
|
|
126
|
-
close();
|
|
127
|
-
await finalize.catch(() => {});
|
|
128
|
-
throw error;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export async function buildRunRequest(flags, positionalType = null, cwd = process.cwd(), invocationCwd = process.cwd()) {
|
|
133
|
-
const { allConfigs, configs } = await resolveConfigsForCommand(flags);
|
|
134
|
-
const workers = flags.workers == null ? null : parseWorkersOption(flags.workers);
|
|
135
|
-
const fileTimeoutSeconds =
|
|
136
|
-
flags["file-timeout-seconds"] == null
|
|
137
|
-
? null
|
|
138
|
-
: parseFileTimeoutOption(flags["file-timeout-seconds"]);
|
|
139
|
-
const shard = parseShardOption(flags.shard);
|
|
140
|
-
const typeValues = parseTypeOption(flags.type, positionalType);
|
|
141
|
-
const suiteSelectors = parseSuiteOption(flags.suite);
|
|
142
|
-
const rawFileNames = Array.isArray(flags.file) ? flags.file : [flags.file].filter(Boolean);
|
|
143
|
-
const productDir = allConfigs[0]?.productDir || cwd;
|
|
144
|
-
const fileNames = resolveRequestedFiles(rawFileNames, productDir, invocationCwd);
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
allConfigs,
|
|
148
|
-
configs,
|
|
149
|
-
productDir,
|
|
150
|
-
typeValues,
|
|
151
|
-
suiteSelectors,
|
|
152
|
-
runOptions: {
|
|
153
|
-
...flags,
|
|
154
|
-
typeValues,
|
|
155
|
-
fileNames,
|
|
156
|
-
workers,
|
|
157
|
-
fileTimeoutSeconds,
|
|
158
|
-
shard,
|
|
159
|
-
scenarioSeed: flags.seed || null,
|
|
160
|
-
serviceFilter: flags.service || null,
|
|
161
|
-
writeStatus: flags["write-status"],
|
|
162
|
-
allowPartialStatus: flags["allow-partial-status"],
|
|
163
|
-
ignoreSkipRules: flags["ignore-skip-rules"],
|
|
164
|
-
},
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export async function runStatusLike(commandName, flags) {
|
|
169
|
-
const { allConfigs, configs } = await resolveConfigsForCommand(flags);
|
|
170
|
-
|
|
171
|
-
if (commandName === "cleanup") {
|
|
172
|
-
await runner.cleanup(allConfigs[0]?.productDir || process.cwd());
|
|
173
|
-
return { ok: true };
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const productResults = [];
|
|
177
|
-
for (const config of configs) {
|
|
178
|
-
if (commandName === "status") {
|
|
179
|
-
productResults.push(runner.showStatus(config));
|
|
180
|
-
continue;
|
|
181
|
-
}
|
|
182
|
-
await runner.destroy(config);
|
|
183
|
-
productResults.push({ name: config.name, destroyed: true });
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
return { ok: true, results: productResults };
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export function relativeToProduct(productDir, targetPath) {
|
|
190
|
-
return path.relative(productDir, targetPath);
|
|
191
|
-
}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import React, { createElement } from "react";
|
|
2
|
-
import { render } from "ink";
|
|
3
|
-
import { createInspectState } from "../tui/inspect-state.mjs";
|
|
4
|
-
import { InspectApp } from "../tui/inspect-app.mjs";
|
|
5
|
-
import {
|
|
6
|
-
applyReporterPlans,
|
|
7
|
-
applyReporterRunSummary,
|
|
8
|
-
applyReporterTaskFinished,
|
|
9
|
-
applyReporterTaskStarted,
|
|
10
|
-
} from "../tui/inspect-live-adapter.mjs";
|
|
11
|
-
import { suiteSelectionType } from "../../runner/suite-selection.mjs";
|
|
12
|
-
|
|
13
|
-
export function createTreeReporter({ stdout = process.stdout, stderr = process.stderr, productDir } = {}) {
|
|
14
|
-
const inspectState = createInspectState({ dataSource: "live" });
|
|
15
|
-
|
|
16
|
-
const app = render(
|
|
17
|
-
createElement(InspectApp, {
|
|
18
|
-
inspectState,
|
|
19
|
-
stdout,
|
|
20
|
-
productDir,
|
|
21
|
-
onRequestClose: close,
|
|
22
|
-
}),
|
|
23
|
-
{ stdout, exitOnCtrlC: false }
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
const finalize = app.waitUntilExit();
|
|
27
|
-
|
|
28
|
-
const reporter = {
|
|
29
|
-
outputMode: "compact",
|
|
30
|
-
|
|
31
|
-
setServicePlans(plans) {
|
|
32
|
-
applyReporterPlans(inspectState, plans);
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
setTotalFileCount(count) {
|
|
36
|
-
inspectState.setTotalFileCount(count);
|
|
37
|
-
},
|
|
38
|
-
|
|
39
|
-
setRegressionCatalog(document) {
|
|
40
|
-
inspectState.setRegressionCatalog(document);
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
serviceSkipped(config, reason) {
|
|
44
|
-
inspectState.markServiceSkipped(config.name, reason);
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
plannedSkip(entry) {
|
|
48
|
-
inspectState.markPlannedSkip(entry);
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
taskStarted(task, _config) {
|
|
52
|
-
const suiteKey = `${task.displayType || suiteSelectionType(task.type, task.framework)}:${task.suiteName}`;
|
|
53
|
-
applyReporterTaskStarted(inspectState, task, suiteKey);
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
taskFinished(task, outcome) {
|
|
57
|
-
applyReporterTaskFinished(inspectState, task, outcome);
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
runtimeError(task, message) {
|
|
61
|
-
inspectState.markRuntimeError(task, message);
|
|
62
|
-
},
|
|
63
|
-
|
|
64
|
-
setupOperationFinished(_operation) {
|
|
65
|
-
// tree handles this implicitly through phase
|
|
66
|
-
},
|
|
67
|
-
|
|
68
|
-
phaseStarted(label) {
|
|
69
|
-
inspectState.setPhase(label);
|
|
70
|
-
},
|
|
71
|
-
|
|
72
|
-
toolchainResolved() {},
|
|
73
|
-
localServiceStarting() {},
|
|
74
|
-
writeLine() {},
|
|
75
|
-
writeDebugLine() {},
|
|
76
|
-
telemetry() {},
|
|
77
|
-
|
|
78
|
-
runSummary(results, durationMs, regressionReport) {
|
|
79
|
-
applyReporterRunSummary(inspectState, results, durationMs, regressionReport);
|
|
80
|
-
},
|
|
81
|
-
|
|
82
|
-
error(message) {
|
|
83
|
-
stderr.write(`${message}\n`);
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
return {
|
|
88
|
-
reporter,
|
|
89
|
-
finalize,
|
|
90
|
-
close,
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
function close() {
|
|
94
|
-
app.unmount();
|
|
95
|
-
}
|
|
96
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export function applyReporterPlans(inspectState, plans) {
|
|
2
|
-
inspectState.initFromPlans(plans);
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
export function applyReporterTaskStarted(inspectState, task, suiteKey) {
|
|
6
|
-
inspectState.markFileRunning(task.serviceName, suiteKey, task.file);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function applyReporterTaskFinished(inspectState, task, outcome) {
|
|
10
|
-
inspectState.markFileFinished(task, outcome);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function applyReporterRunSummary(inspectState, results, durationMs, regressionReport) {
|
|
14
|
-
inspectState.finish(results, durationMs, regressionReport);
|
|
15
|
-
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|