crosspad-mcp-server 4.0.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.
- package/README.md +187 -0
- package/dist/config.d.ts +10 -0
- package/dist/config.js +33 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +360 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/architecture.d.ts +16 -0
- package/dist/tools/architecture.js +198 -0
- package/dist/tools/architecture.js.map +1 -0
- package/dist/tools/build-check.d.ts +23 -0
- package/dist/tools/build-check.js +162 -0
- package/dist/tools/build-check.js.map +1 -0
- package/dist/tools/build.d.ts +14 -0
- package/dist/tools/build.js +101 -0
- package/dist/tools/build.js.map +1 -0
- package/dist/tools/diff-core.d.ts +24 -0
- package/dist/tools/diff-core.js +88 -0
- package/dist/tools/diff-core.js.map +1 -0
- package/dist/tools/idf-build.d.ts +10 -0
- package/dist/tools/idf-build.js +155 -0
- package/dist/tools/idf-build.js.map +1 -0
- package/dist/tools/input.d.ts +36 -0
- package/dist/tools/input.js +61 -0
- package/dist/tools/input.js.map +1 -0
- package/dist/tools/log.d.ts +16 -0
- package/dist/tools/log.js +49 -0
- package/dist/tools/log.js.map +1 -0
- package/dist/tools/repos.d.ts +12 -0
- package/dist/tools/repos.js +63 -0
- package/dist/tools/repos.js.map +1 -0
- package/dist/tools/scaffold.d.ts +15 -0
- package/dist/tools/scaffold.js +192 -0
- package/dist/tools/scaffold.js.map +1 -0
- package/dist/tools/screenshot.d.ts +24 -0
- package/dist/tools/screenshot.js +80 -0
- package/dist/tools/screenshot.js.map +1 -0
- package/dist/tools/settings.d.ts +25 -0
- package/dist/tools/settings.js +48 -0
- package/dist/tools/settings.js.map +1 -0
- package/dist/tools/stats.d.ts +18 -0
- package/dist/tools/stats.js +31 -0
- package/dist/tools/stats.js.map +1 -0
- package/dist/tools/symbols.d.ts +20 -0
- package/dist/tools/symbols.js +157 -0
- package/dist/tools/symbols.js.map +1 -0
- package/dist/tools/test.d.ts +24 -0
- package/dist/tools/test.js +227 -0
- package/dist/tools/test.js.map +1 -0
- package/dist/utils/exec.d.ts +58 -0
- package/dist/utils/exec.js +292 -0
- package/dist/utils/exec.js.map +1 -0
- package/dist/utils/git.d.ts +10 -0
- package/dist/utils/git.js +29 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/remote-client.d.ts +17 -0
- package/dist/utils/remote-client.js +94 -0
- package/dist/utils/remote-client.js.map +1 -0
- package/package.json +21 -0
- package/server.json +23 -0
- package/src/config.ts +45 -0
- package/src/index.ts +484 -0
- package/src/tools/architecture.ts +260 -0
- package/src/tools/build-check.ts +178 -0
- package/src/tools/build.ts +130 -0
- package/src/tools/diff-core.ts +130 -0
- package/src/tools/idf-build.ts +182 -0
- package/src/tools/input.ts +80 -0
- package/src/tools/log.ts +75 -0
- package/src/tools/repos.ts +75 -0
- package/src/tools/scaffold.ts +229 -0
- package/src/tools/screenshot.ts +100 -0
- package/src/tools/settings.ts +68 -0
- package/src/tools/stats.ts +38 -0
- package/src/tools/symbols.ts +185 -0
- package/src/tools/test.ts +264 -0
- package/src/utils/exec.ts +376 -0
- package/src/utils/git.ts +45 -0
- package/src/utils/remote-client.ts +107 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { CROSSPAD_PC_ROOT, VCPKG_TOOLCHAIN } from "../config.js";
|
|
4
|
+
import { runBuild, runBuildStream } from "../utils/exec.js";
|
|
5
|
+
import { IS_WINDOWS } from "../config.js";
|
|
6
|
+
const TESTS_DIR = path.join(CROSSPAD_PC_ROOT, "tests");
|
|
7
|
+
const BIN_DIR = path.join(CROSSPAD_PC_ROOT, "bin");
|
|
8
|
+
const EXE_EXT = IS_WINDOWS ? ".exe" : "";
|
|
9
|
+
const TEST_EXE = path.join(BIN_DIR, `crosspad_tests${EXE_EXT}`);
|
|
10
|
+
/**
|
|
11
|
+
* Build and run the crosspad test suite (Catch2).
|
|
12
|
+
* If tests/ dir doesn't exist, offers to scaffold it.
|
|
13
|
+
*/
|
|
14
|
+
export async function crosspadTest(filter = "", listOnly = false, onLine) {
|
|
15
|
+
const startTime = Date.now();
|
|
16
|
+
// Check if test infrastructure exists
|
|
17
|
+
if (!fs.existsSync(TESTS_DIR)) {
|
|
18
|
+
return {
|
|
19
|
+
success: false,
|
|
20
|
+
tests_found: false,
|
|
21
|
+
build_output: "",
|
|
22
|
+
test_output: `No tests/ directory found. Use crosspad_test_scaffold to create test infrastructure.`,
|
|
23
|
+
passed: 0,
|
|
24
|
+
failed: 0,
|
|
25
|
+
errors: ["tests/ directory not found"],
|
|
26
|
+
duration_seconds: 0,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
// Ensure cmake is configured with BUILD_TESTING=ON
|
|
30
|
+
onLine?.("stdout", "[crosspad] Configuring cmake with BUILD_TESTING=ON...");
|
|
31
|
+
const generator = process.env.CMAKE_GENERATOR || (IS_WINDOWS ? "Ninja" : "");
|
|
32
|
+
const genFlag = generator ? ` -G ${generator}` : "";
|
|
33
|
+
const configCmd = `cmake -B build${genFlag} -DCMAKE_TOOLCHAIN_FILE=${VCPKG_TOOLCHAIN} -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON`;
|
|
34
|
+
let configResult;
|
|
35
|
+
if (onLine) {
|
|
36
|
+
configResult = await runBuildStream(configCmd, CROSSPAD_PC_ROOT, onLine, 120_000);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
configResult = runBuild(configCmd, CROSSPAD_PC_ROOT, 120_000);
|
|
40
|
+
}
|
|
41
|
+
if (!configResult.success) {
|
|
42
|
+
return {
|
|
43
|
+
success: false,
|
|
44
|
+
tests_found: true,
|
|
45
|
+
build_output: (configResult.stdout + "\n" + configResult.stderr).slice(-3000),
|
|
46
|
+
test_output: "",
|
|
47
|
+
passed: 0,
|
|
48
|
+
failed: 0,
|
|
49
|
+
errors: parseErrors(configResult.stdout + "\n" + configResult.stderr),
|
|
50
|
+
duration_seconds: (Date.now() - startTime) / 1000,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Build tests target
|
|
54
|
+
onLine?.("stdout", "[crosspad] Building test target...");
|
|
55
|
+
const buildCmd = "cmake --build build --target crosspad_tests";
|
|
56
|
+
let buildResult;
|
|
57
|
+
if (onLine) {
|
|
58
|
+
buildResult = await runBuildStream(buildCmd, CROSSPAD_PC_ROOT, onLine, 300_000);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
buildResult = runBuild(buildCmd, CROSSPAD_PC_ROOT, 300_000);
|
|
62
|
+
}
|
|
63
|
+
if (!buildResult.success) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
tests_found: true,
|
|
67
|
+
build_output: (buildResult.stdout + "\n" + buildResult.stderr).slice(-3000),
|
|
68
|
+
test_output: "",
|
|
69
|
+
passed: 0,
|
|
70
|
+
failed: 0,
|
|
71
|
+
errors: parseErrors(buildResult.stdout + "\n" + buildResult.stderr),
|
|
72
|
+
duration_seconds: (Date.now() - startTime) / 1000,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (!fs.existsSync(TEST_EXE)) {
|
|
76
|
+
return {
|
|
77
|
+
success: false,
|
|
78
|
+
tests_found: true,
|
|
79
|
+
build_output: buildResult.stdout.slice(-1000),
|
|
80
|
+
test_output: "Test executable not found after build",
|
|
81
|
+
passed: 0,
|
|
82
|
+
failed: 0,
|
|
83
|
+
errors: [`${TEST_EXE} not found`],
|
|
84
|
+
duration_seconds: (Date.now() - startTime) / 1000,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// Run tests
|
|
88
|
+
let testCmd = `"${TEST_EXE}"`;
|
|
89
|
+
if (listOnly) {
|
|
90
|
+
testCmd += " --list-tests";
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
testCmd += " --reporter compact";
|
|
94
|
+
if (filter) {
|
|
95
|
+
testCmd += ` "${filter}"`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
onLine?.("stdout", "[crosspad] Running tests...");
|
|
99
|
+
let testResult;
|
|
100
|
+
if (onLine) {
|
|
101
|
+
testResult = await runBuildStream(testCmd, CROSSPAD_PC_ROOT, onLine, 120_000);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
testResult = runBuild(testCmd, CROSSPAD_PC_ROOT, 120_000);
|
|
105
|
+
}
|
|
106
|
+
const testOutput = testResult.stdout + "\n" + testResult.stderr;
|
|
107
|
+
// Parse Catch2 compact output
|
|
108
|
+
const { passed, failed } = parseCatch2Output(testOutput);
|
|
109
|
+
const result = {
|
|
110
|
+
success: testResult.success,
|
|
111
|
+
tests_found: true,
|
|
112
|
+
build_output: buildResult.stdout.slice(-500),
|
|
113
|
+
test_output: testOutput.slice(-5000),
|
|
114
|
+
passed,
|
|
115
|
+
failed,
|
|
116
|
+
errors: testResult.success ? [] : parseErrors(testOutput),
|
|
117
|
+
duration_seconds: (Date.now() - startTime) / 1000,
|
|
118
|
+
};
|
|
119
|
+
onLine?.("stdout", `[crosspad] Tests ${result.success ? "PASSED" : "FAILED"}: ${passed} passed, ${failed} failed (${result.duration_seconds.toFixed(1)}s)`);
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Scaffold the test infrastructure: CMakeLists.txt additions + sample test file.
|
|
124
|
+
* Returns file contents — does NOT write to disk.
|
|
125
|
+
*/
|
|
126
|
+
export function crosspadTestScaffold() {
|
|
127
|
+
const files = {};
|
|
128
|
+
// tests/CMakeLists.txt
|
|
129
|
+
files["tests/CMakeLists.txt"] = `# CrossPad test suite — Catch2 v3
|
|
130
|
+
Include(FetchContent)
|
|
131
|
+
|
|
132
|
+
FetchContent_Declare(
|
|
133
|
+
Catch2
|
|
134
|
+
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
|
135
|
+
GIT_TAG v3.5.2
|
|
136
|
+
)
|
|
137
|
+
FetchContent_MakeAvailable(Catch2)
|
|
138
|
+
|
|
139
|
+
# Collect test sources
|
|
140
|
+
file(GLOB_RECURSE TEST_SOURCES "\${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
|
141
|
+
|
|
142
|
+
add_executable(crosspad_tests \${TEST_SOURCES})
|
|
143
|
+
|
|
144
|
+
target_link_libraries(crosspad_tests PRIVATE
|
|
145
|
+
Catch2::Catch2WithMain
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
# Include crosspad-core headers (for testing core logic)
|
|
149
|
+
target_include_directories(crosspad_tests PRIVATE
|
|
150
|
+
\${CMAKE_SOURCE_DIR}/crosspad-core/include
|
|
151
|
+
\${CMAKE_SOURCE_DIR}/crosspad-gui/include
|
|
152
|
+
\${CMAKE_SOURCE_DIR}/src
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Same defines as main target
|
|
156
|
+
target_compile_definitions(crosspad_tests PRIVATE
|
|
157
|
+
PLATFORM_PC=1
|
|
158
|
+
CP_LCD_HOR_RES=320
|
|
159
|
+
CP_LCD_VER_RES=240
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
# Add crosspad-core sources we want to test (non-platform-specific)
|
|
163
|
+
# Add individual source files as needed:
|
|
164
|
+
# target_sources(crosspad_tests PRIVATE
|
|
165
|
+
# \${CMAKE_SOURCE_DIR}/crosspad-core/src/SomeFile.cpp
|
|
166
|
+
# )
|
|
167
|
+
|
|
168
|
+
include(CTest)
|
|
169
|
+
include(Catch)
|
|
170
|
+
catch_discover_tests(crosspad_tests)
|
|
171
|
+
`;
|
|
172
|
+
// tests/test_pad_manager.cpp — sample test
|
|
173
|
+
files["tests/test_pad_manager.cpp"] = `#include <catch2/catch_test_macros.hpp>
|
|
174
|
+
|
|
175
|
+
// Example: test crosspad-core types without full platform init
|
|
176
|
+
// #include <crosspad/pad/PadManager.hpp>
|
|
177
|
+
// #include <crosspad/platform/PlatformCapabilities.hpp>
|
|
178
|
+
|
|
179
|
+
TEST_CASE("Sanity check", "[core]") {
|
|
180
|
+
REQUIRE(1 + 1 == 2);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// TEST_CASE("PlatformCapabilities bitflags", "[core][capabilities]") {
|
|
184
|
+
// using crosspad::Capability;
|
|
185
|
+
// using crosspad::setPlatformCapabilities;
|
|
186
|
+
// using crosspad::hasCapability;
|
|
187
|
+
// using crosspad::hasAnyCapability;
|
|
188
|
+
//
|
|
189
|
+
// setPlatformCapabilities(Capability::Midi | Capability::Pads);
|
|
190
|
+
//
|
|
191
|
+
// REQUIRE(hasCapability(Capability::Midi));
|
|
192
|
+
// REQUIRE(hasCapability(Capability::Pads));
|
|
193
|
+
// REQUIRE_FALSE(hasCapability(Capability::AudioOut));
|
|
194
|
+
// REQUIRE(hasAnyCapability(Capability::Midi | Capability::AudioOut));
|
|
195
|
+
// }
|
|
196
|
+
`;
|
|
197
|
+
// Patch for root CMakeLists.txt
|
|
198
|
+
const cmakePatch = `
|
|
199
|
+
# Add this near the end of your CMakeLists.txt, before any final install/packaging:
|
|
200
|
+
# --- Test suite ---
|
|
201
|
+
if(EXISTS "\${CMAKE_SOURCE_DIR}/tests/CMakeLists.txt")
|
|
202
|
+
add_subdirectory(tests)
|
|
203
|
+
endif()
|
|
204
|
+
`;
|
|
205
|
+
return { files, cmake_patch: cmakePatch };
|
|
206
|
+
}
|
|
207
|
+
function parseCatch2Output(output) {
|
|
208
|
+
// Catch2 compact reporter: "Passed X test(s)" / "Failed X test(s)"
|
|
209
|
+
const passedMatch = output.match(/(\d+)\s+assertion[s]?\s+.*passed/i) ||
|
|
210
|
+
output.match(/All tests passed\s*\((\d+)/i);
|
|
211
|
+
const failedMatch = output.match(/(\d+)\s+assertion[s]?\s+.*failed/i) ||
|
|
212
|
+
output.match(/test cases?:\s*\d+\s*\|\s*(\d+)\s+failed/i);
|
|
213
|
+
return {
|
|
214
|
+
passed: passedMatch ? parseInt(passedMatch[1], 10) : 0,
|
|
215
|
+
failed: failedMatch ? parseInt(failedMatch[1], 10) : 0,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function parseErrors(output) {
|
|
219
|
+
const errors = [];
|
|
220
|
+
for (const line of output.split("\n")) {
|
|
221
|
+
if (/\berror\b/i.test(line) && !line.includes("error(s)")) {
|
|
222
|
+
errors.push(line.trim());
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
return errors.slice(0, 20);
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/tools/test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** Callback invoked for each line of stdout/stderr during streaming exec. */
|
|
2
|
+
export type OnLine = (stream: "stdout" | "stderr", line: string) => void;
|
|
3
|
+
/**
|
|
4
|
+
* Capture MSVC environment by running vcvarsall.bat and parsing `set` output.
|
|
5
|
+
* Cached for the lifetime of the server process. Windows-only.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getMsvcEnv(): Record<string, string>;
|
|
8
|
+
export interface ExecResult {
|
|
9
|
+
success: boolean;
|
|
10
|
+
stdout: string;
|
|
11
|
+
stderr: string;
|
|
12
|
+
exitCode: number;
|
|
13
|
+
durationMs: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Run a command with the MSVC environment, capturing output.
|
|
17
|
+
*/
|
|
18
|
+
export declare function runWithMsvc(cmd: string, cwd: string, timeoutMs?: number): ExecResult;
|
|
19
|
+
/**
|
|
20
|
+
* Run a command in the default shell, capturing output.
|
|
21
|
+
*/
|
|
22
|
+
export declare function runCommand(cmd: string, cwd: string, timeoutMs?: number): ExecResult;
|
|
23
|
+
/**
|
|
24
|
+
* Run a command with the MSVC environment, streaming output line-by-line.
|
|
25
|
+
*/
|
|
26
|
+
export declare function runWithMsvcStream(cmd: string, cwd: string, onLine: OnLine, timeoutMs?: number): Promise<ExecResult>;
|
|
27
|
+
/**
|
|
28
|
+
* Run a command in the default shell, streaming output line-by-line.
|
|
29
|
+
*/
|
|
30
|
+
export declare function runCommandStream(cmd: string, cwd: string, onLine: OnLine, timeoutMs?: number): Promise<ExecResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Capture ESP-IDF environment by running export.bat and parsing `set` output.
|
|
33
|
+
* Must unset MSYSTEM to prevent ESP-IDF from rejecting MSYS shells.
|
|
34
|
+
* Cached for the lifetime of the server process. Windows-only.
|
|
35
|
+
*/
|
|
36
|
+
export declare function getIdfEnv(): Record<string, string>;
|
|
37
|
+
/**
|
|
38
|
+
* Run a command with the ESP-IDF environment, capturing output.
|
|
39
|
+
*/
|
|
40
|
+
export declare function runWithIdf(cmd: string, cwd: string, timeoutMs?: number): ExecResult;
|
|
41
|
+
/**
|
|
42
|
+
* Run a command with the ESP-IDF environment, streaming output line-by-line.
|
|
43
|
+
*/
|
|
44
|
+
export declare function runWithIdfStream(cmd: string, cwd: string, onLine: OnLine, timeoutMs?: number): Promise<ExecResult>;
|
|
45
|
+
/**
|
|
46
|
+
* Run a build command with the appropriate environment for the current platform.
|
|
47
|
+
* Windows: MSVC env + cmd.exe shell. Unix: default shell.
|
|
48
|
+
*/
|
|
49
|
+
export declare function runBuild(cmd: string, cwd: string, timeoutMs?: number): ExecResult;
|
|
50
|
+
/**
|
|
51
|
+
* Run a build command with streaming output, platform-aware.
|
|
52
|
+
* Windows: MSVC env + cmd.exe shell. Unix: default shell.
|
|
53
|
+
*/
|
|
54
|
+
export declare function runBuildStream(cmd: string, cwd: string, onLine: OnLine, timeoutMs?: number): Promise<ExecResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Spawn a detached process (for crosspad_run).
|
|
57
|
+
*/
|
|
58
|
+
export declare function spawnDetached(exe: string, args: string[], cwd: string): number | null;
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { execSync, spawn } from "child_process";
|
|
2
|
+
import { VCVARSALL, IS_WINDOWS, IDF_PATH } from "../config.js";
|
|
3
|
+
let cachedMsvcEnv = null;
|
|
4
|
+
/**
|
|
5
|
+
* Capture MSVC environment by running vcvarsall.bat and parsing `set` output.
|
|
6
|
+
* Cached for the lifetime of the server process. Windows-only.
|
|
7
|
+
*/
|
|
8
|
+
export function getMsvcEnv() {
|
|
9
|
+
if (!IS_WINDOWS) {
|
|
10
|
+
return { ...process.env };
|
|
11
|
+
}
|
|
12
|
+
if (cachedMsvcEnv)
|
|
13
|
+
return cachedMsvcEnv;
|
|
14
|
+
const cmd = `"${VCVARSALL}" x64 >nul 2>&1 && set`;
|
|
15
|
+
const output = execSync(cmd, {
|
|
16
|
+
shell: "cmd.exe",
|
|
17
|
+
encoding: "utf-8",
|
|
18
|
+
timeout: 30_000,
|
|
19
|
+
});
|
|
20
|
+
const env = {};
|
|
21
|
+
for (const line of output.split("\n")) {
|
|
22
|
+
const eq = line.indexOf("=");
|
|
23
|
+
if (eq > 0) {
|
|
24
|
+
env[line.slice(0, eq)] = line.slice(eq + 1).trimEnd();
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
cachedMsvcEnv = env;
|
|
28
|
+
return env;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Run a command with the MSVC environment, capturing output.
|
|
32
|
+
*/
|
|
33
|
+
export function runWithMsvc(cmd, cwd, timeoutMs = 300_000) {
|
|
34
|
+
const env = getMsvcEnv();
|
|
35
|
+
const start = Date.now();
|
|
36
|
+
try {
|
|
37
|
+
const stdout = execSync(cmd, {
|
|
38
|
+
cwd,
|
|
39
|
+
env,
|
|
40
|
+
shell: "cmd.exe",
|
|
41
|
+
encoding: "utf-8",
|
|
42
|
+
timeout: timeoutMs,
|
|
43
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
44
|
+
});
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
stdout: normalizeLineEndings(stdout),
|
|
48
|
+
stderr: "",
|
|
49
|
+
exitCode: 0,
|
|
50
|
+
durationMs: Date.now() - start,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
stdout: normalizeLineEndings(err.stdout?.toString() ?? ""),
|
|
57
|
+
stderr: normalizeLineEndings(err.stderr?.toString() ?? ""),
|
|
58
|
+
exitCode: err.status ?? 1,
|
|
59
|
+
durationMs: Date.now() - start,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Run a command in the default shell, capturing output.
|
|
65
|
+
*/
|
|
66
|
+
export function runCommand(cmd, cwd, timeoutMs = 60_000) {
|
|
67
|
+
const start = Date.now();
|
|
68
|
+
try {
|
|
69
|
+
const stdout = execSync(cmd, {
|
|
70
|
+
cwd,
|
|
71
|
+
encoding: "utf-8",
|
|
72
|
+
timeout: timeoutMs,
|
|
73
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
success: true,
|
|
77
|
+
stdout: normalizeLineEndings(stdout),
|
|
78
|
+
stderr: "",
|
|
79
|
+
exitCode: 0,
|
|
80
|
+
durationMs: Date.now() - start,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
return {
|
|
85
|
+
success: false,
|
|
86
|
+
stdout: normalizeLineEndings(err.stdout?.toString() ?? ""),
|
|
87
|
+
stderr: normalizeLineEndings(err.stderr?.toString() ?? ""),
|
|
88
|
+
exitCode: err.status ?? 1,
|
|
89
|
+
durationMs: Date.now() - start,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
94
|
+
// STREAMING VARIANTS (spawn-based, line-by-line callbacks)
|
|
95
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
96
|
+
/**
|
|
97
|
+
* Helper: spawn a process and stream stdout/stderr line-by-line via onLine.
|
|
98
|
+
* Returns the same ExecResult as the sync variants.
|
|
99
|
+
*/
|
|
100
|
+
function spawnStreaming(cmd, cwd, env, shell, onLine, timeoutMs) {
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
const start = Date.now();
|
|
103
|
+
const child = spawn(cmd, [], {
|
|
104
|
+
cwd,
|
|
105
|
+
env,
|
|
106
|
+
shell,
|
|
107
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
108
|
+
windowsHide: true,
|
|
109
|
+
});
|
|
110
|
+
let stdout = "";
|
|
111
|
+
let stderr = "";
|
|
112
|
+
let stdoutBuf = "";
|
|
113
|
+
let stderrBuf = "";
|
|
114
|
+
let killed = false;
|
|
115
|
+
const timer = setTimeout(() => {
|
|
116
|
+
killed = true;
|
|
117
|
+
child.kill("SIGTERM");
|
|
118
|
+
}, timeoutMs);
|
|
119
|
+
function flushLines(buf, stream) {
|
|
120
|
+
const parts = buf.split("\n");
|
|
121
|
+
// Last part is incomplete — keep it in buffer
|
|
122
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
123
|
+
const line = parts[i].replace(/\r$/, "");
|
|
124
|
+
onLine(stream, line);
|
|
125
|
+
}
|
|
126
|
+
return parts[parts.length - 1];
|
|
127
|
+
}
|
|
128
|
+
child.stdout?.on("data", (chunk) => {
|
|
129
|
+
const text = chunk.toString();
|
|
130
|
+
stdout += text;
|
|
131
|
+
stdoutBuf += text;
|
|
132
|
+
stdoutBuf = flushLines(stdoutBuf, "stdout");
|
|
133
|
+
});
|
|
134
|
+
child.stderr?.on("data", (chunk) => {
|
|
135
|
+
const text = chunk.toString();
|
|
136
|
+
stderr += text;
|
|
137
|
+
stderrBuf += text;
|
|
138
|
+
stderrBuf = flushLines(stderrBuf, "stderr");
|
|
139
|
+
});
|
|
140
|
+
child.on("close", (code) => {
|
|
141
|
+
clearTimeout(timer);
|
|
142
|
+
// Flush remaining partial lines
|
|
143
|
+
if (stdoutBuf.length > 0)
|
|
144
|
+
onLine("stdout", stdoutBuf.replace(/\r$/, ""));
|
|
145
|
+
if (stderrBuf.length > 0)
|
|
146
|
+
onLine("stderr", stderrBuf.replace(/\r$/, ""));
|
|
147
|
+
resolve({
|
|
148
|
+
success: killed ? false : code === 0,
|
|
149
|
+
stdout: normalizeLineEndings(stdout),
|
|
150
|
+
stderr: normalizeLineEndings(stderr),
|
|
151
|
+
exitCode: killed ? -1 : (code ?? 1),
|
|
152
|
+
durationMs: Date.now() - start,
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
child.on("error", (err) => {
|
|
156
|
+
clearTimeout(timer);
|
|
157
|
+
resolve({
|
|
158
|
+
success: false,
|
|
159
|
+
stdout: normalizeLineEndings(stdout),
|
|
160
|
+
stderr: normalizeLineEndings(stderr + "\n" + err.message),
|
|
161
|
+
exitCode: 1,
|
|
162
|
+
durationMs: Date.now() - start,
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Run a command with the MSVC environment, streaming output line-by-line.
|
|
169
|
+
*/
|
|
170
|
+
export function runWithMsvcStream(cmd, cwd, onLine, timeoutMs = 300_000) {
|
|
171
|
+
const env = getMsvcEnv();
|
|
172
|
+
return spawnStreaming(cmd, cwd, env, "cmd.exe", onLine, timeoutMs);
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Run a command in the default shell, streaming output line-by-line.
|
|
176
|
+
*/
|
|
177
|
+
export function runCommandStream(cmd, cwd, onLine, timeoutMs = 60_000) {
|
|
178
|
+
return spawnStreaming(cmd, cwd, undefined, true, onLine, timeoutMs);
|
|
179
|
+
}
|
|
180
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
181
|
+
// ESP-IDF ENVIRONMENT
|
|
182
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
183
|
+
let cachedIdfEnv = null;
|
|
184
|
+
/**
|
|
185
|
+
* Capture ESP-IDF environment by running export.bat and parsing `set` output.
|
|
186
|
+
* Must unset MSYSTEM to prevent ESP-IDF from rejecting MSYS shells.
|
|
187
|
+
* Cached for the lifetime of the server process. Windows-only.
|
|
188
|
+
*/
|
|
189
|
+
export function getIdfEnv() {
|
|
190
|
+
if (!IS_WINDOWS) {
|
|
191
|
+
return { ...process.env };
|
|
192
|
+
}
|
|
193
|
+
if (cachedIdfEnv)
|
|
194
|
+
return cachedIdfEnv;
|
|
195
|
+
const exportBat = `${IDF_PATH}\\export.bat`;
|
|
196
|
+
const cmd = `set MSYSTEM=&& set PYTHONIOENCODING=utf-8&& call ${exportBat} >nul 2>&1 && set`;
|
|
197
|
+
const output = execSync(cmd, {
|
|
198
|
+
shell: "cmd.exe",
|
|
199
|
+
encoding: "utf-8",
|
|
200
|
+
timeout: 60_000,
|
|
201
|
+
});
|
|
202
|
+
const env = {};
|
|
203
|
+
for (const line of output.split("\n")) {
|
|
204
|
+
const eq = line.indexOf("=");
|
|
205
|
+
if (eq > 0) {
|
|
206
|
+
env[line.slice(0, eq)] = line.slice(eq + 1).trimEnd();
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
cachedIdfEnv = env;
|
|
210
|
+
return env;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Run a command with the ESP-IDF environment, capturing output.
|
|
214
|
+
*/
|
|
215
|
+
export function runWithIdf(cmd, cwd, timeoutMs = 600_000) {
|
|
216
|
+
const env = getIdfEnv();
|
|
217
|
+
const start = Date.now();
|
|
218
|
+
try {
|
|
219
|
+
const stdout = execSync(cmd, {
|
|
220
|
+
cwd,
|
|
221
|
+
env,
|
|
222
|
+
shell: "cmd.exe",
|
|
223
|
+
encoding: "utf-8",
|
|
224
|
+
timeout: timeoutMs,
|
|
225
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
226
|
+
});
|
|
227
|
+
return {
|
|
228
|
+
success: true,
|
|
229
|
+
stdout: normalizeLineEndings(stdout),
|
|
230
|
+
stderr: "",
|
|
231
|
+
exitCode: 0,
|
|
232
|
+
durationMs: Date.now() - start,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
catch (err) {
|
|
236
|
+
return {
|
|
237
|
+
success: false,
|
|
238
|
+
stdout: normalizeLineEndings(err.stdout?.toString() ?? ""),
|
|
239
|
+
stderr: normalizeLineEndings(err.stderr?.toString() ?? ""),
|
|
240
|
+
exitCode: err.status ?? 1,
|
|
241
|
+
durationMs: Date.now() - start,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Run a command with the ESP-IDF environment, streaming output line-by-line.
|
|
247
|
+
*/
|
|
248
|
+
export function runWithIdfStream(cmd, cwd, onLine, timeoutMs = 600_000) {
|
|
249
|
+
const env = getIdfEnv();
|
|
250
|
+
return spawnStreaming(cmd, cwd, env, "cmd.exe", onLine, timeoutMs);
|
|
251
|
+
}
|
|
252
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
253
|
+
// PLATFORM-AGNOSTIC BUILD WRAPPERS
|
|
254
|
+
// ═══════════════════════════════════════════════════════════════════════
|
|
255
|
+
/**
|
|
256
|
+
* Run a build command with the appropriate environment for the current platform.
|
|
257
|
+
* Windows: MSVC env + cmd.exe shell. Unix: default shell.
|
|
258
|
+
*/
|
|
259
|
+
export function runBuild(cmd, cwd, timeoutMs = 300_000) {
|
|
260
|
+
if (IS_WINDOWS) {
|
|
261
|
+
return runWithMsvc(cmd, cwd, timeoutMs);
|
|
262
|
+
}
|
|
263
|
+
return runCommand(cmd, cwd, timeoutMs);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Run a build command with streaming output, platform-aware.
|
|
267
|
+
* Windows: MSVC env + cmd.exe shell. Unix: default shell.
|
|
268
|
+
*/
|
|
269
|
+
export function runBuildStream(cmd, cwd, onLine, timeoutMs = 300_000) {
|
|
270
|
+
if (IS_WINDOWS) {
|
|
271
|
+
return runWithMsvcStream(cmd, cwd, onLine, timeoutMs);
|
|
272
|
+
}
|
|
273
|
+
return runCommandStream(cmd, cwd, onLine, timeoutMs);
|
|
274
|
+
}
|
|
275
|
+
/** Strip \r from Windows line endings */
|
|
276
|
+
function normalizeLineEndings(s) {
|
|
277
|
+
return s.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Spawn a detached process (for crosspad_run).
|
|
281
|
+
*/
|
|
282
|
+
export function spawnDetached(exe, args, cwd) {
|
|
283
|
+
const opts = {
|
|
284
|
+
cwd,
|
|
285
|
+
detached: true,
|
|
286
|
+
stdio: "ignore",
|
|
287
|
+
};
|
|
288
|
+
const child = spawn(exe, args, opts);
|
|
289
|
+
child.unref();
|
|
290
|
+
return child.pid ?? null;
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=exec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exec.js","sourceRoot":"","sources":["../../src/utils/exec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export interface RepoStatus {
|
|
2
|
+
name: string;
|
|
3
|
+
path: string;
|
|
4
|
+
branch: string;
|
|
5
|
+
head: string;
|
|
6
|
+
dirtyFiles: string[];
|
|
7
|
+
}
|
|
8
|
+
export declare function getRepoStatus(name: string, repoPath: string): RepoStatus;
|
|
9
|
+
export declare function getSubmodulePin(repoPath: string, submodule: string): string | null;
|
|
10
|
+
export declare function getHead(repoPath: string): string | null;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { runCommand } from "./exec.js";
|
|
2
|
+
export function getRepoStatus(name, repoPath) {
|
|
3
|
+
const branch = runCommand("git branch --show-current", repoPath);
|
|
4
|
+
const log = runCommand("git log --oneline -1", repoPath);
|
|
5
|
+
const status = runCommand("git status --porcelain", repoPath);
|
|
6
|
+
return {
|
|
7
|
+
name,
|
|
8
|
+
path: repoPath,
|
|
9
|
+
branch: branch.stdout.trim(),
|
|
10
|
+
head: log.stdout.trim(),
|
|
11
|
+
dirtyFiles: status.stdout
|
|
12
|
+
.trim()
|
|
13
|
+
.split("\n")
|
|
14
|
+
.filter((l) => l.length > 0),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export function getSubmodulePin(repoPath, submodule) {
|
|
18
|
+
const result = runCommand(`git submodule status ${submodule}`, repoPath);
|
|
19
|
+
if (!result.success)
|
|
20
|
+
return null;
|
|
21
|
+
// Output format: " abc1234 submodule-name (desc)" or "+abc1234 ..."
|
|
22
|
+
const match = result.stdout.match(/[+ -]?([0-9a-f]+)/);
|
|
23
|
+
return match ? match[1] : null;
|
|
24
|
+
}
|
|
25
|
+
export function getHead(repoPath) {
|
|
26
|
+
const result = runCommand("git rev-parse HEAD", repoPath);
|
|
27
|
+
return result.success ? result.stdout.trim() : null;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=git.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAUvC,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,QAAgB;IAC1D,MAAM,MAAM,GAAG,UAAU,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC;IACjE,MAAM,GAAG,GAAG,UAAU,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,UAAU,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC;IAE9D,OAAO;QACL,IAAI;QACJ,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;QAC5B,IAAI,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE;QACvB,UAAU,EAAE,MAAM,CAAC,MAAM;aACtB,IAAI,EAAE;aACN,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,QAAgB,EAChB,SAAiB;IAEjB,MAAM,MAAM,GAAG,UAAU,CACvB,wBAAwB,SAAS,EAAE,EACnC,QAAQ,CACT,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IACjC,oEAAoE;IACpE,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,QAAgB;IACtC,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;IAC1D,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TCP client for communicating with the CrossPad simulator's remote control server.
|
|
3
|
+
* Protocol: newline-delimited JSON over TCP on localhost:19840.
|
|
4
|
+
*/
|
|
5
|
+
export interface RemoteResponse {
|
|
6
|
+
ok: boolean;
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Send a JSON command to the running simulator and return the response.
|
|
11
|
+
* Opens a fresh TCP connection per call (simple, stateless).
|
|
12
|
+
*/
|
|
13
|
+
export declare function sendRemoteCommand(command: Record<string, unknown>): Promise<RemoteResponse>;
|
|
14
|
+
/**
|
|
15
|
+
* Check if the simulator's remote control server is reachable.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isSimulatorRunning(): Promise<boolean>;
|