crosspad-mcp-server 5.1.0 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -44
- package/dist/config.d.ts +2 -2
- package/dist/config.js +42 -8
- package/dist/config.js.map +1 -1
- package/dist/index.js +953 -219
- package/dist/index.js.map +1 -1
- package/dist/tools/app-manager.d.ts +13 -5
- package/dist/tools/app-manager.js +94 -28
- package/dist/tools/app-manager.js.map +1 -1
- package/dist/tools/architecture.js +13 -4
- package/dist/tools/architecture.js.map +1 -1
- package/dist/tools/build-check.d.ts +1 -1
- package/dist/tools/build-check.js +19 -9
- package/dist/tools/build-check.js.map +1 -1
- package/dist/tools/build.d.ts +43 -4
- package/dist/tools/build.js +147 -15
- package/dist/tools/build.js.map +1 -1
- package/dist/tools/diff-core.d.ts +5 -1
- package/dist/tools/diff-core.js +11 -6
- package/dist/tools/diff-core.js.map +1 -1
- package/dist/tools/idf-build.d.ts +1 -1
- package/dist/tools/idf-build.js +5 -5
- package/dist/tools/idf-build.js.map +1 -1
- package/dist/tools/idf-flash.d.ts +20 -0
- package/dist/tools/idf-flash.js +185 -0
- package/dist/tools/idf-flash.js.map +1 -0
- package/dist/tools/idf-monitor.d.ts +29 -0
- package/dist/tools/idf-monitor.js +222 -0
- package/dist/tools/idf-monitor.js.map +1 -0
- package/dist/tools/log.d.ts +2 -2
- package/dist/tools/log.js +6 -5
- package/dist/tools/log.js.map +1 -1
- package/dist/tools/midi.d.ts +27 -0
- package/dist/tools/midi.js +112 -0
- package/dist/tools/midi.js.map +1 -0
- package/dist/tools/repo-actions.d.ts +46 -0
- package/dist/tools/repo-actions.js +286 -0
- package/dist/tools/repo-actions.js.map +1 -0
- package/dist/tools/repos.js +14 -10
- package/dist/tools/repos.js.map +1 -1
- package/dist/tools/screenshot.js +42 -7
- package/dist/tools/screenshot.js.map +1 -1
- package/dist/tools/settings.js +11 -1
- package/dist/tools/settings.js.map +1 -1
- package/dist/tools/symbols.d.ts +2 -1
- package/dist/tools/symbols.js +121 -53
- package/dist/tools/symbols.js.map +1 -1
- package/dist/tools/test.d.ts +1 -9
- package/dist/tools/test.js +11 -92
- package/dist/tools/test.js.map +1 -1
- package/dist/utils/device.d.ts +38 -0
- package/dist/utils/device.js +287 -0
- package/dist/utils/device.js.map +1 -0
- package/dist/utils/exec.d.ts +17 -5
- package/dist/utils/exec.js +73 -27
- package/dist/utils/exec.js.map +1 -1
- package/dist/utils/git.d.ts +9 -0
- package/dist/utils/git.js +61 -1
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/remote-client.d.ts +1 -0
- package/dist/utils/remote-client.js +56 -15
- package/dist/utils/remote-client.js.map +1 -1
- package/package.json +4 -1
- package/dist/tools/scaffold.d.ts +0 -15
- package/dist/tools/scaffold.js +0 -192
- package/dist/tools/scaffold.js.map +0 -1
package/dist/tools/symbols.js
CHANGED
|
@@ -9,24 +9,29 @@ import { runCommand } from "../utils/exec.js";
|
|
|
9
9
|
export function buildPattern(query, kind) {
|
|
10
10
|
const q = query; // Already escaped by caller
|
|
11
11
|
const patterns = [];
|
|
12
|
+
// Use explicit character classes — `\w` / `\s` inside `[...]` are not
|
|
13
|
+
// portable across POSIX ERE implementations.
|
|
14
|
+
const W = "[A-Za-z0-9_]"; // word char
|
|
15
|
+
const WS = "[ \\t]"; // whitespace (intra-line)
|
|
12
16
|
if (kind === "class" || kind === "all") {
|
|
13
17
|
// class/struct definition: class Foo { or class Foo : public Bar {
|
|
14
|
-
patterns.push(`(class|struct)
|
|
15
|
-
patterns.push(`(class|struct)
|
|
18
|
+
patterns.push(`(class|struct)${WS}+${W}*${q}${W}*${WS}*[:{]`);
|
|
19
|
+
patterns.push(`(class|struct)${WS}+${W}*${q}${W}*${WS}*$`); // multi-line def
|
|
16
20
|
}
|
|
17
21
|
if (kind === "macro" || kind === "all") {
|
|
18
|
-
patterns.push(`#define
|
|
22
|
+
patterns.push(`#define${WS}+${W}*${q}${W}*`);
|
|
19
23
|
}
|
|
20
24
|
if (kind === "enum" || kind === "all") {
|
|
21
|
-
patterns.push(`enum
|
|
25
|
+
patterns.push(`enum${WS}+(class${WS}+)?${W}*${q}${W}*`);
|
|
22
26
|
}
|
|
23
27
|
if (kind === "typedef" || kind === "all") {
|
|
24
|
-
patterns.push(`using
|
|
25
|
-
patterns.push(`typedef
|
|
28
|
+
patterns.push(`using${WS}+${W}*${q}${W}*${WS}*=`);
|
|
29
|
+
patterns.push(`typedef${WS}+.*${W}*${q}${W}*${WS}*;`);
|
|
26
30
|
}
|
|
27
31
|
if (kind === "function" || kind === "all") {
|
|
28
|
-
// Function definition:
|
|
29
|
-
|
|
32
|
+
// Function definition: starts with type qualifier (word char), then
|
|
33
|
+
// type tokens (word/colon/space/tab/star/amp/angle), then the name and `(`.
|
|
34
|
+
patterns.push(`^${W}[${W.slice(1, -1)}: \\t*&<>]+${W}*${q}${W}*${WS}*\\(`);
|
|
30
35
|
}
|
|
31
36
|
return patterns.join("|");
|
|
32
37
|
}
|
|
@@ -34,7 +39,7 @@ export function buildPattern(query, kind) {
|
|
|
34
39
|
* Search for symbol definitions (classes, functions, macros, enums) across CrossPad repos.
|
|
35
40
|
* Only matches definition lines, not usages.
|
|
36
41
|
*/
|
|
37
|
-
export function crosspadSearchSymbols(query, kind = "all", repos = ["all"], maxResults = 50) {
|
|
42
|
+
export function crosspadSearchSymbols(query, kind = "all", repos = ["all"], maxResults = 50, contextLines = 0) {
|
|
38
43
|
const results = [];
|
|
39
44
|
const allRepos = getRepos();
|
|
40
45
|
const targetRepos = repos.includes("all")
|
|
@@ -44,56 +49,119 @@ export function crosspadSearchSymbols(query, kind = "all", repos = ["all"], maxR
|
|
|
44
49
|
if (!pattern) {
|
|
45
50
|
return { query, kind_filter: kind, results: [], total_matches: 0, truncated: false };
|
|
46
51
|
}
|
|
52
|
+
const clampedContext = Math.min(Math.max(contextLines, 0), 10);
|
|
53
|
+
const useContext = clampedContext > 0;
|
|
47
54
|
for (const [repoName, repoPath] of targetRepos) {
|
|
48
55
|
if (!fs.existsSync(repoPath))
|
|
49
56
|
continue;
|
|
50
|
-
const
|
|
57
|
+
const contextFlag = useContext ? `-C ${clampedContext}` : "";
|
|
58
|
+
const grepCmd = `git grep --recurse-submodules -n ${contextFlag} -E "${escapeForShell(pattern)}" -- "*.hpp" "*.h" "*.cpp" "*.c"`;
|
|
51
59
|
const result = runCommand(grepCmd, repoPath, 30_000);
|
|
52
60
|
if (!result.success && result.stdout.length === 0)
|
|
53
61
|
continue;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
62
|
+
if (useContext) {
|
|
63
|
+
// Context mode: output has `--` separators between groups
|
|
64
|
+
const blocks = result.stdout.split(/^--$/m);
|
|
65
|
+
for (const block of blocks) {
|
|
66
|
+
const blockLines = block.split("\n").filter((l) => l.trim());
|
|
67
|
+
if (blockLines.length === 0)
|
|
68
|
+
continue;
|
|
69
|
+
// Find the matching line (has line number, not `-` context separator)
|
|
70
|
+
let matchFile = "";
|
|
71
|
+
let matchLine = 0;
|
|
72
|
+
let matchContent = "";
|
|
73
|
+
const surrounding = [];
|
|
74
|
+
for (const bline of blockLines) {
|
|
75
|
+
// Match line format: file:123:content (colon separator for match)
|
|
76
|
+
const matchResult = bline.match(/^([^:]+):(\d+):(.*)$/);
|
|
77
|
+
// Context line format: file-123-content (dash separator)
|
|
78
|
+
const contextResult = bline.match(/^([^-]+)-(\d+)-(.*)$/);
|
|
79
|
+
if (matchResult && !matchFile) {
|
|
80
|
+
matchFile = matchResult[1];
|
|
81
|
+
matchLine = parseInt(matchResult[2], 10);
|
|
82
|
+
matchContent = matchResult[3].trim();
|
|
83
|
+
}
|
|
84
|
+
if (matchResult || contextResult) {
|
|
85
|
+
const content = matchResult ? matchResult[3] : contextResult[3];
|
|
86
|
+
surrounding.push(content);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (!matchFile || !matchContent)
|
|
90
|
+
continue;
|
|
91
|
+
// Apply same filters as non-context mode
|
|
92
|
+
if (/^\s*(class|struct)\s+\w+\s*;/.test(matchContent))
|
|
93
|
+
continue;
|
|
94
|
+
if (/^\s*#include/.test(matchContent))
|
|
95
|
+
continue;
|
|
96
|
+
if (/^\s*(\/\/|\/\*|\*)/.test(matchContent))
|
|
97
|
+
continue;
|
|
98
|
+
const detectedKind = classifyDefinition(matchContent);
|
|
99
|
+
if (!detectedKind)
|
|
100
|
+
continue;
|
|
101
|
+
if (kind !== "all" && detectedKind !== kind)
|
|
102
|
+
continue;
|
|
103
|
+
const symbolName = extractSymbolName(matchContent, detectedKind);
|
|
104
|
+
if (!symbolName)
|
|
105
|
+
continue;
|
|
106
|
+
if (!symbolName.toLowerCase().includes(query.toLowerCase()))
|
|
107
|
+
continue;
|
|
108
|
+
const key = `${symbolName}:${matchFile}`;
|
|
109
|
+
if (results.some((r) => `${r.symbol}:${r.file.split("/").pop()}` === key))
|
|
110
|
+
continue;
|
|
111
|
+
results.push({
|
|
112
|
+
symbol: symbolName,
|
|
113
|
+
kind: detectedKind,
|
|
114
|
+
file: `${repoPath}/${matchFile}`.replace(/\\/g, "/"),
|
|
115
|
+
line: matchLine,
|
|
116
|
+
context: matchContent.slice(0, 150),
|
|
117
|
+
surrounding,
|
|
118
|
+
repo: repoName,
|
|
119
|
+
});
|
|
120
|
+
if (results.length >= maxResults)
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
// Standard mode (no context)
|
|
126
|
+
for (const line of result.stdout.split("\n")) {
|
|
127
|
+
if (!line.trim())
|
|
128
|
+
continue;
|
|
129
|
+
const match = line.match(/^([^:]+):(\d+):(.*)$/);
|
|
130
|
+
if (!match)
|
|
131
|
+
continue;
|
|
132
|
+
const [, file, lineStr, content] = match;
|
|
133
|
+
const lineNum = parseInt(lineStr, 10);
|
|
134
|
+
const trimmedContent = content.trim();
|
|
135
|
+
if (/^\s*(class|struct)\s+\w+\s*;/.test(trimmedContent))
|
|
136
|
+
continue;
|
|
137
|
+
if (/^\s*#include/.test(trimmedContent))
|
|
138
|
+
continue;
|
|
139
|
+
if (/^\s*(\/\/|\/\*|\*)/.test(trimmedContent))
|
|
140
|
+
continue;
|
|
141
|
+
const detectedKind = classifyDefinition(trimmedContent);
|
|
142
|
+
if (!detectedKind)
|
|
143
|
+
continue;
|
|
144
|
+
if (kind !== "all" && detectedKind !== kind)
|
|
145
|
+
continue;
|
|
146
|
+
const symbolName = extractSymbolName(trimmedContent, detectedKind);
|
|
147
|
+
if (!symbolName)
|
|
148
|
+
continue;
|
|
149
|
+
if (!symbolName.toLowerCase().includes(query.toLowerCase()))
|
|
150
|
+
continue;
|
|
151
|
+
const key = `${symbolName}:${file}`;
|
|
152
|
+
if (results.some((r) => `${r.symbol}:${r.file.split("/").pop()}` === key))
|
|
153
|
+
continue;
|
|
154
|
+
results.push({
|
|
155
|
+
symbol: symbolName,
|
|
156
|
+
kind: detectedKind,
|
|
157
|
+
file: `${repoPath}/${file}`.replace(/\\/g, "/"),
|
|
158
|
+
line: lineNum,
|
|
159
|
+
context: trimmedContent.slice(0, 150),
|
|
160
|
+
repo: repoName,
|
|
161
|
+
});
|
|
162
|
+
if (results.length >= maxResults)
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
97
165
|
}
|
|
98
166
|
if (results.length >= maxResults)
|
|
99
167
|
break;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/tools/symbols.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"symbols.js","sourceRoot":"","sources":["../../src/tools/symbols.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/test.d.ts
CHANGED
|
@@ -13,15 +13,7 @@ export interface TestResult {
|
|
|
13
13
|
* Build and run the crosspad test suite (Catch2).
|
|
14
14
|
* If tests/ dir doesn't exist, offers to scaffold it.
|
|
15
15
|
*/
|
|
16
|
-
export declare function crosspadTest(filter?: string, listOnly?: boolean, onLine?: OnLine): Promise<TestResult>;
|
|
17
|
-
/**
|
|
18
|
-
* Scaffold the test infrastructure: CMakeLists.txt additions + sample test file.
|
|
19
|
-
* Returns file contents — does NOT write to disk.
|
|
20
|
-
*/
|
|
21
|
-
export declare function crosspadTestScaffold(): {
|
|
22
|
-
files: Record<string, string>;
|
|
23
|
-
cmake_patch: string;
|
|
24
|
-
};
|
|
16
|
+
export declare function crosspadTest(filter?: string, listOnly?: boolean, onLine?: OnLine, signal?: AbortSignal): Promise<TestResult>;
|
|
25
17
|
/** @internal exported for testing */
|
|
26
18
|
export declare function parseCatch2Output(output: string): {
|
|
27
19
|
passed: number;
|
package/dist/tools/test.js
CHANGED
|
@@ -10,7 +10,7 @@ const TEST_EXE = path.join(BIN_DIR, `crosspad_tests${EXE_EXT}`);
|
|
|
10
10
|
* Build and run the crosspad test suite (Catch2).
|
|
11
11
|
* If tests/ dir doesn't exist, offers to scaffold it.
|
|
12
12
|
*/
|
|
13
|
-
export async function crosspadTest(filter = "", listOnly = false, onLine) {
|
|
13
|
+
export async function crosspadTest(filter = "", listOnly = false, onLine, signal) {
|
|
14
14
|
const startTime = Date.now();
|
|
15
15
|
// Check if test infrastructure exists
|
|
16
16
|
if (!fs.existsSync(TESTS_DIR)) {
|
|
@@ -18,7 +18,7 @@ export async function crosspadTest(filter = "", listOnly = false, onLine) {
|
|
|
18
18
|
success: false,
|
|
19
19
|
tests_found: false,
|
|
20
20
|
build_output: "",
|
|
21
|
-
test_output: `No tests/ directory found.
|
|
21
|
+
test_output: `No tests/ directory found. See docs for the Catch2 setup snippet.`,
|
|
22
22
|
passed: 0,
|
|
23
23
|
failed: 0,
|
|
24
24
|
errors: ["tests/ directory not found"],
|
|
@@ -30,7 +30,7 @@ export async function crosspadTest(filter = "", listOnly = false, onLine) {
|
|
|
30
30
|
const configCmd = `cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=${VCPKG_TOOLCHAIN} -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=ON`;
|
|
31
31
|
let configResult;
|
|
32
32
|
if (onLine) {
|
|
33
|
-
configResult = await runBuildStream(configCmd, CROSSPAD_PC_ROOT, onLine, 120_000);
|
|
33
|
+
configResult = await runBuildStream(configCmd, CROSSPAD_PC_ROOT, onLine, 120_000, signal);
|
|
34
34
|
}
|
|
35
35
|
else {
|
|
36
36
|
configResult = runBuild(configCmd, CROSSPAD_PC_ROOT, 120_000);
|
|
@@ -52,7 +52,7 @@ export async function crosspadTest(filter = "", listOnly = false, onLine) {
|
|
|
52
52
|
const buildCmd = "cmake --build build --target crosspad_tests";
|
|
53
53
|
let buildResult;
|
|
54
54
|
if (onLine) {
|
|
55
|
-
buildResult = await runBuildStream(buildCmd, CROSSPAD_PC_ROOT, onLine, 300_000);
|
|
55
|
+
buildResult = await runBuildStream(buildCmd, CROSSPAD_PC_ROOT, onLine, 300_000, signal);
|
|
56
56
|
}
|
|
57
57
|
else {
|
|
58
58
|
buildResult = runBuild(buildCmd, CROSSPAD_PC_ROOT, 300_000);
|
|
@@ -82,20 +82,24 @@ export async function crosspadTest(filter = "", listOnly = false, onLine) {
|
|
|
82
82
|
};
|
|
83
83
|
}
|
|
84
84
|
// Run tests
|
|
85
|
+
// Escape double-quotes / backticks / dollars in the filter to prevent
|
|
86
|
+
// shell injection. Catch2 filters are simple tag/glob strings so this
|
|
87
|
+
// sanitization doesn't lose semantics.
|
|
88
|
+
const safeFilter = filter.replace(/[`"$\\]/g, "\\$&");
|
|
85
89
|
let testCmd = `"${TEST_EXE}"`;
|
|
86
90
|
if (listOnly) {
|
|
87
91
|
testCmd += " --list-tests";
|
|
88
92
|
}
|
|
89
93
|
else {
|
|
90
94
|
testCmd += " --reporter compact";
|
|
91
|
-
if (
|
|
92
|
-
testCmd += ` "${
|
|
95
|
+
if (safeFilter) {
|
|
96
|
+
testCmd += ` "${safeFilter}"`;
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
99
|
onLine?.("stdout", "[crosspad] Running tests...");
|
|
96
100
|
let testResult;
|
|
97
101
|
if (onLine) {
|
|
98
|
-
testResult = await runBuildStream(testCmd, CROSSPAD_PC_ROOT, onLine, 120_000);
|
|
102
|
+
testResult = await runBuildStream(testCmd, CROSSPAD_PC_ROOT, onLine, 120_000, signal);
|
|
99
103
|
}
|
|
100
104
|
else {
|
|
101
105
|
testResult = runBuild(testCmd, CROSSPAD_PC_ROOT, 120_000);
|
|
@@ -116,91 +120,6 @@ export async function crosspadTest(filter = "", listOnly = false, onLine) {
|
|
|
116
120
|
onLine?.("stdout", `[crosspad] Tests ${result.success ? "PASSED" : "FAILED"}: ${passed} passed, ${failed} failed (${result.duration_seconds.toFixed(1)}s)`);
|
|
117
121
|
return result;
|
|
118
122
|
}
|
|
119
|
-
/**
|
|
120
|
-
* Scaffold the test infrastructure: CMakeLists.txt additions + sample test file.
|
|
121
|
-
* Returns file contents — does NOT write to disk.
|
|
122
|
-
*/
|
|
123
|
-
export function crosspadTestScaffold() {
|
|
124
|
-
const files = {};
|
|
125
|
-
// tests/CMakeLists.txt
|
|
126
|
-
files["tests/CMakeLists.txt"] = `# CrossPad test suite — Catch2 v3
|
|
127
|
-
Include(FetchContent)
|
|
128
|
-
|
|
129
|
-
FetchContent_Declare(
|
|
130
|
-
Catch2
|
|
131
|
-
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
|
132
|
-
GIT_TAG v3.5.2
|
|
133
|
-
)
|
|
134
|
-
FetchContent_MakeAvailable(Catch2)
|
|
135
|
-
|
|
136
|
-
# Collect test sources
|
|
137
|
-
file(GLOB_RECURSE TEST_SOURCES "\${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
|
|
138
|
-
|
|
139
|
-
add_executable(crosspad_tests \${TEST_SOURCES})
|
|
140
|
-
|
|
141
|
-
target_link_libraries(crosspad_tests PRIVATE
|
|
142
|
-
Catch2::Catch2WithMain
|
|
143
|
-
)
|
|
144
|
-
|
|
145
|
-
# Include crosspad-core headers (for testing core logic)
|
|
146
|
-
target_include_directories(crosspad_tests PRIVATE
|
|
147
|
-
\${CMAKE_SOURCE_DIR}/crosspad-core/include
|
|
148
|
-
\${CMAKE_SOURCE_DIR}/crosspad-gui/include
|
|
149
|
-
\${CMAKE_SOURCE_DIR}/src
|
|
150
|
-
)
|
|
151
|
-
|
|
152
|
-
# Same defines as main target
|
|
153
|
-
target_compile_definitions(crosspad_tests PRIVATE
|
|
154
|
-
PLATFORM_PC=1
|
|
155
|
-
CP_LCD_HOR_RES=320
|
|
156
|
-
CP_LCD_VER_RES=240
|
|
157
|
-
)
|
|
158
|
-
|
|
159
|
-
# Add crosspad-core sources we want to test (non-platform-specific)
|
|
160
|
-
# Add individual source files as needed:
|
|
161
|
-
# target_sources(crosspad_tests PRIVATE
|
|
162
|
-
# \${CMAKE_SOURCE_DIR}/crosspad-core/src/SomeFile.cpp
|
|
163
|
-
# )
|
|
164
|
-
|
|
165
|
-
include(CTest)
|
|
166
|
-
include(Catch)
|
|
167
|
-
catch_discover_tests(crosspad_tests)
|
|
168
|
-
`;
|
|
169
|
-
// tests/test_pad_manager.cpp — sample test
|
|
170
|
-
files["tests/test_pad_manager.cpp"] = `#include <catch2/catch_test_macros.hpp>
|
|
171
|
-
|
|
172
|
-
// Example: test crosspad-core types without full platform init
|
|
173
|
-
// #include <crosspad/pad/PadManager.hpp>
|
|
174
|
-
// #include <crosspad/platform/PlatformCapabilities.hpp>
|
|
175
|
-
|
|
176
|
-
TEST_CASE("Sanity check", "[core]") {
|
|
177
|
-
REQUIRE(1 + 1 == 2);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// TEST_CASE("PlatformCapabilities bitflags", "[core][capabilities]") {
|
|
181
|
-
// using crosspad::Capability;
|
|
182
|
-
// using crosspad::setPlatformCapabilities;
|
|
183
|
-
// using crosspad::hasCapability;
|
|
184
|
-
// using crosspad::hasAnyCapability;
|
|
185
|
-
//
|
|
186
|
-
// setPlatformCapabilities(Capability::Midi | Capability::Pads);
|
|
187
|
-
//
|
|
188
|
-
// REQUIRE(hasCapability(Capability::Midi));
|
|
189
|
-
// REQUIRE(hasCapability(Capability::Pads));
|
|
190
|
-
// REQUIRE_FALSE(hasCapability(Capability::AudioOut));
|
|
191
|
-
// REQUIRE(hasAnyCapability(Capability::Midi | Capability::AudioOut));
|
|
192
|
-
// }
|
|
193
|
-
`;
|
|
194
|
-
// Patch for root CMakeLists.txt
|
|
195
|
-
const cmakePatch = `
|
|
196
|
-
# Add this near the end of your CMakeLists.txt, before any final install/packaging:
|
|
197
|
-
# --- Test suite ---
|
|
198
|
-
if(EXISTS "\${CMAKE_SOURCE_DIR}/tests/CMakeLists.txt")
|
|
199
|
-
add_subdirectory(tests)
|
|
200
|
-
endif()
|
|
201
|
-
`;
|
|
202
|
-
return { files, cmake_patch: cmakePatch };
|
|
203
|
-
}
|
|
204
123
|
/** @internal exported for testing */
|
|
205
124
|
export function parseCatch2Output(output) {
|
|
206
125
|
// Catch2 compact reporter: "Passed X test(s)" / "Failed X test(s)"
|
package/dist/tools/test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/tools/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,gBAAgB,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAU,MAAM,kBAAkB,CAAC;AAapE,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;AACvD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;AACnD,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;AACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,OAAO,EAAE,CAAC,CAAC;AAEhE;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,SAAiB,EAAE,EACnB,WAAoB,KAAK,EACzB,MAAe;
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/tools/test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform USB device discovery for CrossPad.
|
|
3
|
+
*
|
|
4
|
+
* Primary method: Python/pyserial (required for IDF builds anyway).
|
|
5
|
+
* Fallback: platform-specific commands (Linux sysfs, macOS system_profiler, Windows PowerShell).
|
|
6
|
+
*
|
|
7
|
+
* Supports multiple simultaneous CrossPad devices — each identified by port path.
|
|
8
|
+
*/
|
|
9
|
+
export interface CrosspadDevice {
|
|
10
|
+
port: string;
|
|
11
|
+
vid: number;
|
|
12
|
+
pid: number;
|
|
13
|
+
serial_number: string | null;
|
|
14
|
+
description: string;
|
|
15
|
+
manufacturer: string | null;
|
|
16
|
+
is_crosspad: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface DeviceListResult {
|
|
19
|
+
success: boolean;
|
|
20
|
+
devices: CrosspadDevice[];
|
|
21
|
+
all_ports: CrosspadDevice[];
|
|
22
|
+
error?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* List all connected USB serial devices. Returns CrossPad devices separately.
|
|
26
|
+
* Tries Python/pyserial first, falls back to platform-specific methods.
|
|
27
|
+
*/
|
|
28
|
+
export declare function listDevices(): DeviceListResult;
|
|
29
|
+
/**
|
|
30
|
+
* Find a CrossPad device, optionally by port.
|
|
31
|
+
* If port is specified, validates it's a CrossPad device.
|
|
32
|
+
* If not specified, auto-detects (fails if 0 or >1 found).
|
|
33
|
+
*/
|
|
34
|
+
export declare function findCrosspadPort(port?: string): {
|
|
35
|
+
port: string;
|
|
36
|
+
device?: CrosspadDevice;
|
|
37
|
+
error?: string;
|
|
38
|
+
};
|