@supatest/cli 0.0.22 → 0.0.23
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/dist/index.js +134 -15
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -3817,6 +3817,34 @@ function installChromium() {
|
|
|
3817
3817
|
};
|
|
3818
3818
|
}
|
|
3819
3819
|
}
|
|
3820
|
+
function createSupatestConfig(cwd) {
|
|
3821
|
+
const supatestDir = path.join(cwd, ".supatest");
|
|
3822
|
+
const mcpJsonPath = path.join(supatestDir, "mcp.json");
|
|
3823
|
+
try {
|
|
3824
|
+
if (fs.existsSync(mcpJsonPath)) {
|
|
3825
|
+
return {
|
|
3826
|
+
ok: true,
|
|
3827
|
+
message: "mcp.json already exists",
|
|
3828
|
+
created: false
|
|
3829
|
+
};
|
|
3830
|
+
}
|
|
3831
|
+
if (!fs.existsSync(supatestDir)) {
|
|
3832
|
+
fs.mkdirSync(supatestDir, { recursive: true });
|
|
3833
|
+
}
|
|
3834
|
+
fs.writeFileSync(mcpJsonPath, JSON.stringify(DEFAULT_MCP_CONFIG, null, 2) + "\n", "utf-8");
|
|
3835
|
+
return {
|
|
3836
|
+
ok: true,
|
|
3837
|
+
message: "Created .supatest/mcp.json with Playwright MCP server configuration",
|
|
3838
|
+
created: true
|
|
3839
|
+
};
|
|
3840
|
+
} catch (error) {
|
|
3841
|
+
return {
|
|
3842
|
+
ok: false,
|
|
3843
|
+
message: `Failed to create mcp.json: ${error instanceof Error ? error.message : String(error)}`,
|
|
3844
|
+
created: false
|
|
3845
|
+
};
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3820
3848
|
function getVersionSummary() {
|
|
3821
3849
|
const nodeVersion = getNodeVersion();
|
|
3822
3850
|
const playwrightVersion = getPlaywrightVersion();
|
|
@@ -3828,7 +3856,7 @@ function getVersionSummary() {
|
|
|
3828
3856
|
lines.push(` Chromium: ${chromiumVersion ? `build ${chromiumVersion}` : "Not installed"}`);
|
|
3829
3857
|
return lines.join("\n");
|
|
3830
3858
|
}
|
|
3831
|
-
async function setupCommand() {
|
|
3859
|
+
async function setupCommand(options) {
|
|
3832
3860
|
const output = [];
|
|
3833
3861
|
const log = (msg) => {
|
|
3834
3862
|
output.push(msg);
|
|
@@ -3876,6 +3904,18 @@ async function setupCommand() {
|
|
|
3876
3904
|
result.errors.push(chromiumResult.message);
|
|
3877
3905
|
}
|
|
3878
3906
|
}
|
|
3907
|
+
log("\n3. Setting up MCP configuration...");
|
|
3908
|
+
const configResult = createSupatestConfig(options.cwd);
|
|
3909
|
+
if (configResult.ok) {
|
|
3910
|
+
if (configResult.created) {
|
|
3911
|
+
log(` \u2705 ${configResult.message}`);
|
|
3912
|
+
} else {
|
|
3913
|
+
log(` \u2705 ${configResult.message}`);
|
|
3914
|
+
}
|
|
3915
|
+
} else {
|
|
3916
|
+
log(` \u274C ${configResult.message}`);
|
|
3917
|
+
result.errors.push(configResult.message);
|
|
3918
|
+
}
|
|
3879
3919
|
const versionSummary = getVersionSummary();
|
|
3880
3920
|
log(versionSummary);
|
|
3881
3921
|
log("\n" + "\u2500".repeat(50));
|
|
@@ -3891,11 +3931,19 @@ async function setupCommand() {
|
|
|
3891
3931
|
result.output = output.join("\n");
|
|
3892
3932
|
return result;
|
|
3893
3933
|
}
|
|
3894
|
-
var MINIMUM_NODE_VERSION;
|
|
3934
|
+
var MINIMUM_NODE_VERSION, DEFAULT_MCP_CONFIG;
|
|
3895
3935
|
var init_setup = __esm({
|
|
3896
3936
|
"src/commands/setup.ts"() {
|
|
3897
3937
|
"use strict";
|
|
3898
3938
|
MINIMUM_NODE_VERSION = 18;
|
|
3939
|
+
DEFAULT_MCP_CONFIG = {
|
|
3940
|
+
mcpServers: {
|
|
3941
|
+
playwright: {
|
|
3942
|
+
command: "npx",
|
|
3943
|
+
args: ["@playwright/mcp@latest"]
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
};
|
|
3899
3947
|
}
|
|
3900
3948
|
});
|
|
3901
3949
|
|
|
@@ -3904,7 +3952,7 @@ var CLI_VERSION;
|
|
|
3904
3952
|
var init_version = __esm({
|
|
3905
3953
|
"src/version.ts"() {
|
|
3906
3954
|
"use strict";
|
|
3907
|
-
CLI_VERSION = "0.0.
|
|
3955
|
+
CLI_VERSION = "0.0.23";
|
|
3908
3956
|
}
|
|
3909
3957
|
});
|
|
3910
3958
|
|
|
@@ -5415,6 +5463,9 @@ var init_SessionContext = __esm({
|
|
|
5415
5463
|
});
|
|
5416
5464
|
setStaticRemountKey((prev) => prev + 1);
|
|
5417
5465
|
}, []);
|
|
5466
|
+
const refreshStatic = useCallback(() => {
|
|
5467
|
+
setStaticRemountKey((prev) => prev + 1);
|
|
5468
|
+
}, []);
|
|
5418
5469
|
const updateStats = useCallback((updates) => {
|
|
5419
5470
|
setStats((prev) => ({ ...prev, ...updates }));
|
|
5420
5471
|
}, []);
|
|
@@ -5460,7 +5511,8 @@ var init_SessionContext = __esm({
|
|
|
5460
5511
|
setPlanFilePath,
|
|
5461
5512
|
selectedModel,
|
|
5462
5513
|
setSelectedModel,
|
|
5463
|
-
staticRemountKey
|
|
5514
|
+
staticRemountKey,
|
|
5515
|
+
refreshStatic
|
|
5464
5516
|
};
|
|
5465
5517
|
return /* @__PURE__ */ React.createElement(SessionContext.Provider, { value }, children);
|
|
5466
5518
|
};
|
|
@@ -6734,7 +6786,7 @@ var init_message_bridge = __esm({
|
|
|
6734
6786
|
});
|
|
6735
6787
|
|
|
6736
6788
|
// src/commands/login.ts
|
|
6737
|
-
import { spawn } from "child_process";
|
|
6789
|
+
import { spawn as spawn2 } from "child_process";
|
|
6738
6790
|
import crypto2 from "crypto";
|
|
6739
6791
|
import http from "http";
|
|
6740
6792
|
import { platform } from "os";
|
|
@@ -6770,7 +6822,7 @@ function openBrowser(url) {
|
|
|
6770
6822
|
default:
|
|
6771
6823
|
command = "xdg-open";
|
|
6772
6824
|
}
|
|
6773
|
-
|
|
6825
|
+
spawn2(command, [url], { detached: true, stdio: "ignore" }).unref();
|
|
6774
6826
|
}
|
|
6775
6827
|
function startCallbackServer(port, expectedState) {
|
|
6776
6828
|
return new Promise((resolve2, reject) => {
|
|
@@ -8681,9 +8733,9 @@ var init_useOverlayEscapeGuard = __esm({
|
|
|
8681
8733
|
});
|
|
8682
8734
|
|
|
8683
8735
|
// src/ui/App.tsx
|
|
8684
|
-
import { execSync as
|
|
8736
|
+
import { execSync as execSync5 } from "child_process";
|
|
8685
8737
|
import { homedir as homedir5 } from "os";
|
|
8686
|
-
import { Box as Box20, Text as Text18, useApp as useApp2 } from "ink";
|
|
8738
|
+
import { Box as Box20, Text as Text18, useApp as useApp2, useStdout as useStdout2 } from "ink";
|
|
8687
8739
|
import Spinner3 from "ink-spinner";
|
|
8688
8740
|
import React23, { useEffect as useEffect10, useRef as useRef4, useState as useState10 } from "react";
|
|
8689
8741
|
var getGitBranch2, getCurrentFolder2, AppContent, App;
|
|
@@ -8713,7 +8765,7 @@ var init_App = __esm({
|
|
|
8713
8765
|
init_theme();
|
|
8714
8766
|
getGitBranch2 = () => {
|
|
8715
8767
|
try {
|
|
8716
|
-
return
|
|
8768
|
+
return execSync5("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
|
|
8717
8769
|
} catch {
|
|
8718
8770
|
return "";
|
|
8719
8771
|
}
|
|
@@ -8728,7 +8780,8 @@ var init_App = __esm({
|
|
|
8728
8780
|
};
|
|
8729
8781
|
AppContent = ({ config: config2, sessionId, webUrl, queuedTasks = [], onExit, onSubmitTask, apiClient, onResumeSession, onClearSession }) => {
|
|
8730
8782
|
const { exit } = useApp2();
|
|
8731
|
-
const {
|
|
8783
|
+
const { stdout } = useStdout2();
|
|
8784
|
+
const { addMessage, clearMessages, isAgentRunning, messages, setSessionId, setWebUrl, setShouldInterruptAgent, setIsAgentRunning, toggleAllToolOutputs, allToolsExpanded, selectedModel, setSelectedModel, refreshStatic } = useSession();
|
|
8732
8785
|
useModeToggle();
|
|
8733
8786
|
const [terminalWidth, setTerminalWidth] = useState10(process.stdout.columns || 80);
|
|
8734
8787
|
const [showHelp, setShowHelp] = useState10(false);
|
|
@@ -8881,7 +8934,7 @@ var init_App = __esm({
|
|
|
8881
8934
|
content: "Running setup..."
|
|
8882
8935
|
});
|
|
8883
8936
|
try {
|
|
8884
|
-
const result = await setupCommand();
|
|
8937
|
+
const result = await setupCommand({ cwd: config2.cwd || process.cwd() });
|
|
8885
8938
|
addMessage({
|
|
8886
8939
|
type: "assistant",
|
|
8887
8940
|
content: result.output
|
|
@@ -9005,6 +9058,7 @@ var init_App = __esm({
|
|
|
9005
9058
|
markOverlayClosed();
|
|
9006
9059
|
setShowHelp(false);
|
|
9007
9060
|
};
|
|
9061
|
+
const isInitialMount = useRef4(true);
|
|
9008
9062
|
useEffect10(() => {
|
|
9009
9063
|
const handleResize = () => {
|
|
9010
9064
|
setTerminalWidth(process.stdout.columns || 80);
|
|
@@ -9014,6 +9068,19 @@ var init_App = __esm({
|
|
|
9014
9068
|
process.stdout.off("resize", handleResize);
|
|
9015
9069
|
};
|
|
9016
9070
|
}, []);
|
|
9071
|
+
useEffect10(() => {
|
|
9072
|
+
if (isInitialMount.current) {
|
|
9073
|
+
isInitialMount.current = false;
|
|
9074
|
+
return;
|
|
9075
|
+
}
|
|
9076
|
+
const handler = setTimeout(() => {
|
|
9077
|
+
stdout?.write("\x1B[3J\x1B[H\x1B[2J");
|
|
9078
|
+
refreshStatic();
|
|
9079
|
+
}, 300);
|
|
9080
|
+
return () => {
|
|
9081
|
+
clearTimeout(handler);
|
|
9082
|
+
};
|
|
9083
|
+
}, [terminalWidth, refreshStatic, stdout]);
|
|
9017
9084
|
useKeypress(
|
|
9018
9085
|
(key) => {
|
|
9019
9086
|
if (key.name === "escape" && isAgentRunning && !isOverlayOpen) {
|
|
@@ -9941,6 +10008,57 @@ async function runAgent(config2) {
|
|
|
9941
10008
|
});
|
|
9942
10009
|
}
|
|
9943
10010
|
|
|
10011
|
+
// src/utils/auto-update.ts
|
|
10012
|
+
init_error_logger();
|
|
10013
|
+
init_version();
|
|
10014
|
+
import { execSync as execSync3, spawn } from "child_process";
|
|
10015
|
+
import latestVersion from "latest-version";
|
|
10016
|
+
import { gt as gt2 } from "semver";
|
|
10017
|
+
var UPDATE_CHECK_TIMEOUT = 3e3;
|
|
10018
|
+
var INSTALL_TIMEOUT = 6e4;
|
|
10019
|
+
async function checkAndAutoUpdate() {
|
|
10020
|
+
if (process.env.NODE_ENV === "development") {
|
|
10021
|
+
return;
|
|
10022
|
+
}
|
|
10023
|
+
if (process.env.SUPATEST_SKIP_UPDATE === "1") {
|
|
10024
|
+
return;
|
|
10025
|
+
}
|
|
10026
|
+
try {
|
|
10027
|
+
const latest = await Promise.race([
|
|
10028
|
+
latestVersion("@supatest/cli"),
|
|
10029
|
+
new Promise(
|
|
10030
|
+
(_2, reject) => setTimeout(() => reject(new Error("timeout")), UPDATE_CHECK_TIMEOUT)
|
|
10031
|
+
)
|
|
10032
|
+
]);
|
|
10033
|
+
if (!gt2(latest, CLI_VERSION)) {
|
|
10034
|
+
return;
|
|
10035
|
+
}
|
|
10036
|
+
console.log(`
|
|
10037
|
+
Updating Supatest CLI ${CLI_VERSION} \u2192 ${latest}...`);
|
|
10038
|
+
try {
|
|
10039
|
+
execSync3("npm install -g @supatest/cli@latest", {
|
|
10040
|
+
stdio: "inherit",
|
|
10041
|
+
timeout: INSTALL_TIMEOUT
|
|
10042
|
+
});
|
|
10043
|
+
console.log("\u2713 Updated successfully\n");
|
|
10044
|
+
const child = spawn(process.argv[0], process.argv.slice(1), {
|
|
10045
|
+
stdio: "inherit",
|
|
10046
|
+
detached: false
|
|
10047
|
+
});
|
|
10048
|
+
child.on("exit", (code) => process.exit(code ?? 0));
|
|
10049
|
+
await new Promise(() => {
|
|
10050
|
+
});
|
|
10051
|
+
} catch (installError) {
|
|
10052
|
+
logError(installError, { source: "auto-update", action: "install" });
|
|
10053
|
+
const errMsg = installError instanceof Error ? installError.message : String(installError);
|
|
10054
|
+
console.error("Failed to update:", errMsg);
|
|
10055
|
+
console.log("Continuing with current version...\n");
|
|
10056
|
+
}
|
|
10057
|
+
} catch (error) {
|
|
10058
|
+
logError(error, { source: "auto-update", action: "check" });
|
|
10059
|
+
}
|
|
10060
|
+
}
|
|
10061
|
+
|
|
9944
10062
|
// src/index.ts
|
|
9945
10063
|
init_banner();
|
|
9946
10064
|
init_error_logger();
|
|
@@ -9948,7 +10066,7 @@ init_logger();
|
|
|
9948
10066
|
|
|
9949
10067
|
// src/utils/node-version.ts
|
|
9950
10068
|
init_logger();
|
|
9951
|
-
import { execSync as
|
|
10069
|
+
import { execSync as execSync4 } from "child_process";
|
|
9952
10070
|
var MINIMUM_NODE_VERSION2 = 18;
|
|
9953
10071
|
function parseVersion2(versionString) {
|
|
9954
10072
|
const cleaned = versionString.trim().replace(/^v/, "");
|
|
@@ -9965,7 +10083,7 @@ function parseVersion2(versionString) {
|
|
|
9965
10083
|
}
|
|
9966
10084
|
function getNodeVersion2() {
|
|
9967
10085
|
try {
|
|
9968
|
-
const versionOutput =
|
|
10086
|
+
const versionOutput = execSync4("node --version", {
|
|
9969
10087
|
encoding: "utf-8",
|
|
9970
10088
|
stdio: ["ignore", "pipe", "ignore"]
|
|
9971
10089
|
});
|
|
@@ -10085,6 +10203,7 @@ program.name("supatest").description(
|
|
|
10085
10203
|
).option("--supatest-api-key <key>", "Supatest API key (or use SUPATEST_API_KEY env)").option("--supatest-api-url <url>", "Supatest API URL (or use SUPATEST_API_URL env, defaults to https://code-api.supatest.ai)").option("--headless", "Run in headless mode (for CI/CD, minimal output)").option("--verbose", "Enable verbose logging").option("--model <model>", "Claude model to use (or use ANTHROPIC_MODEL_NAME env)").action(async (task, options) => {
|
|
10086
10204
|
try {
|
|
10087
10205
|
checkNodeVersion2();
|
|
10206
|
+
await checkAndAutoUpdate();
|
|
10088
10207
|
const isHeadlessMode = options.headless || process.stdin.isTTY === false;
|
|
10089
10208
|
if (options.verbose) {
|
|
10090
10209
|
logger.setVerbose(true);
|
|
@@ -10193,9 +10312,9 @@ program.name("supatest").description(
|
|
|
10193
10312
|
process.exit(1);
|
|
10194
10313
|
}
|
|
10195
10314
|
});
|
|
10196
|
-
program.command("setup").description("Check prerequisites and set up required tools (Node.js, Playwright MCP)").action(async () => {
|
|
10315
|
+
program.command("setup").description("Check prerequisites and set up required tools (Node.js, Playwright MCP)").option("-C, --cwd <path>", "Working directory for setup", process.cwd()).action(async (options) => {
|
|
10197
10316
|
try {
|
|
10198
|
-
const result = await setupCommand();
|
|
10317
|
+
const result = await setupCommand({ cwd: options.cwd });
|
|
10199
10318
|
process.exit(result.errors.length === 0 ? 0 : 1);
|
|
10200
10319
|
} catch (error) {
|
|
10201
10320
|
logError(error, { source: "setup" });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supatest/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "Supatest CLI - AI-powered task automation for CI/CD",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -64,10 +64,13 @@
|
|
|
64
64
|
"string-width": "^8.1.0",
|
|
65
65
|
"strip-ansi": "^7.1.2",
|
|
66
66
|
"undici": "^7.16.0",
|
|
67
|
-
"wrap-ansi": "^9.0.2"
|
|
67
|
+
"wrap-ansi": "^9.0.2",
|
|
68
|
+
"latest-version": "^9.0.0",
|
|
69
|
+
"semver": "^7.6.0"
|
|
68
70
|
},
|
|
69
71
|
"devDependencies": {
|
|
70
72
|
"@types/node": "^20.12.12",
|
|
73
|
+
"@types/semver": "^7.5.8",
|
|
71
74
|
"@types/react": "^19.0.0",
|
|
72
75
|
"nodemon": "^3.1.11",
|
|
73
76
|
"tsup": "^8.5.1",
|