crosspad-mcp-server 6.0.0 → 8.1.1

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 (58) hide show
  1. package/README.md +109 -44
  2. package/dist/config.d.ts +2 -2
  3. package/dist/config.js +42 -8
  4. package/dist/config.js.map +1 -1
  5. package/dist/index.d.ts +14 -1
  6. package/dist/index.js +956 -312
  7. package/dist/index.js.map +1 -1
  8. package/dist/tools/app-manager.d.ts +13 -5
  9. package/dist/tools/app-manager.js +69 -46
  10. package/dist/tools/app-manager.js.map +1 -1
  11. package/dist/tools/architecture.js +13 -4
  12. package/dist/tools/architecture.js.map +1 -1
  13. package/dist/tools/build-check.d.ts +1 -1
  14. package/dist/tools/build-check.js +19 -9
  15. package/dist/tools/build-check.js.map +1 -1
  16. package/dist/tools/build.d.ts +95 -4
  17. package/dist/tools/build.js +312 -15
  18. package/dist/tools/build.js.map +1 -1
  19. package/dist/tools/diff-core.d.ts +5 -1
  20. package/dist/tools/diff-core.js +11 -6
  21. package/dist/tools/diff-core.js.map +1 -1
  22. package/dist/tools/idf-build.d.ts +1 -1
  23. package/dist/tools/idf-build.js +5 -5
  24. package/dist/tools/idf-build.js.map +1 -1
  25. package/dist/tools/idf-flash.d.ts +2 -2
  26. package/dist/tools/idf-flash.js +12 -11
  27. package/dist/tools/idf-flash.js.map +1 -1
  28. package/dist/tools/idf-monitor.d.ts +1 -1
  29. package/dist/tools/idf-monitor.js +57 -3
  30. package/dist/tools/idf-monitor.js.map +1 -1
  31. package/dist/tools/log.d.ts +2 -2
  32. package/dist/tools/log.js +6 -5
  33. package/dist/tools/log.js.map +1 -1
  34. package/dist/tools/repo-actions.js +88 -75
  35. package/dist/tools/repo-actions.js.map +1 -1
  36. package/dist/tools/repos.js +14 -10
  37. package/dist/tools/repos.js.map +1 -1
  38. package/dist/tools/screenshot.js +42 -7
  39. package/dist/tools/screenshot.js.map +1 -1
  40. package/dist/tools/settings.js +11 -1
  41. package/dist/tools/settings.js.map +1 -1
  42. package/dist/tools/symbols.js +13 -8
  43. package/dist/tools/symbols.js.map +1 -1
  44. package/dist/tools/test.d.ts +1 -9
  45. package/dist/tools/test.js +11 -92
  46. package/dist/tools/test.js.map +1 -1
  47. package/dist/utils/exec.d.ts +17 -5
  48. package/dist/utils/exec.js +73 -27
  49. package/dist/utils/exec.js.map +1 -1
  50. package/dist/utils/git.d.ts +9 -0
  51. package/dist/utils/git.js +61 -1
  52. package/dist/utils/git.js.map +1 -1
  53. package/dist/utils/remote-client.js +32 -14
  54. package/dist/utils/remote-client.js.map +1 -1
  55. package/package.json +4 -1
  56. package/dist/tools/scaffold.d.ts +0 -15
  57. package/dist/tools/scaffold.js +0 -192
  58. package/dist/tools/scaffold.js.map +0 -1
@@ -6,13 +6,104 @@ export interface BuildResult {
6
6
  warnings_count: number;
7
7
  output_path: string;
8
8
  }
9
- /** @internal exported for testing */
9
+ /**
10
+ * Match real compiler / linker / build-system errors only. Keyword-only
11
+ * matching ("any line containing 'error'") is too greedy — it picks up
12
+ * comments like `// error handling` from cmake output and inflates the
13
+ * error list.
14
+ *
15
+ * Patterns: GCC/Clang/MSVC compiler diagnostics, linker errors, CMake
16
+ * Errors, Ninja FAILED markers.
17
+ *
18
+ * @internal exported for testing
19
+ */
10
20
  export declare function parseErrors(output: string): string[];
11
- /** @internal exported for testing */
21
+ /**
22
+ * Count compiler warnings only — same tightening logic as parseErrors.
23
+ * @internal exported for testing
24
+ */
12
25
  export declare function countWarnings(output: string): number;
13
- export declare function crosspadBuild(mode: "incremental" | "clean" | "reconfigure", onLine?: OnLine): Promise<BuildResult>;
26
+ export type BuildType = "Debug" | "Release" | "RelWithDebInfo";
27
+ export declare function crosspadBuild(mode: "incremental" | "clean" | "reconfigure", onLine?: OnLine, buildType?: BuildType, signal?: AbortSignal): Promise<BuildResult>;
14
28
  export interface RunResult {
15
29
  pid: number | null;
16
30
  exe_path: string;
31
+ already_running?: boolean;
32
+ responsive?: boolean;
33
+ error?: string;
17
34
  }
18
- export declare function crosspadRun(): RunResult;
35
+ /**
36
+ * Launch the simulator binary in the background.
37
+ *
38
+ * Refuses to spawn a second instance if one is already responding on the
39
+ * remote-control port — multiple instances clobber each other's window
40
+ * state and the TCP listener binds to the same port.
41
+ *
42
+ * After spawn we poll the TCP control port for up to ~3s — this distinguishes
43
+ * "process started, ready to accept commands" from "process started but
44
+ * crashed before binding" so callers don't fire screenshot/stats too early.
45
+ */
46
+ export declare function crosspadRun(force?: boolean): Promise<RunResult>;
47
+ export interface KillResult {
48
+ success: boolean;
49
+ killed_pids: number[];
50
+ was_running: boolean;
51
+ error?: string;
52
+ }
53
+ /**
54
+ * Canonicalize a filesystem path. realpath resolves every symlink in the
55
+ * chain — needed because /proc/<pid>/exe always returns the kernel's view
56
+ * (post-symlink) while BIN_EXE comes from string concatenation under
57
+ * CROSSPAD_PC_ROOT, which is commonly itself a symlink (e.g. ~/GIT/crosspad-pc
58
+ * → /mnt/big-disk/crosspad-pc). Without canonicalization the string compare
59
+ * silently misses every running sim.
60
+ *
61
+ * Falls back to path.resolve when realpath fails (binary not built yet, or
62
+ * a non-existent /proc path during a TOCTOU race) so callers always get a
63
+ * comparable absolute path.
64
+ *
65
+ * @internal exported for testing
66
+ */
67
+ export declare function canonicalize(p: string): string;
68
+ /**
69
+ * Strip the kernel's " (deleted)" suffix that appears in /proc/<pid>/exe
70
+ * when the executable was unlinked or replaced after the process started
71
+ * (typical during dev: rebuild while sim is still running). Without this
72
+ * strip the path compare misses any running-but-rebuilt sim — the most
73
+ * common reason a developer would hit "agent can't kill the simulator."
74
+ *
75
+ * @internal exported for testing
76
+ */
77
+ export declare function stripDeletedSuffix(p: string): string;
78
+ /**
79
+ * Find PIDs running the CrossPad simulator binary.
80
+ *
81
+ * On Linux scans /proc/<pid>/exe and matches the resolved+canonicalized
82
+ * symlink against BIN_EXE. This is the only reliable identification:
83
+ * pgrep -x compares /proc/<pid>/comm, which Qt/pthread routinely overwrite
84
+ * via pthread_setname_np / prctl(PR_SET_NAME), so a sim launched as
85
+ * "CrossPad" shows up under whatever Qt named the main thread last.
86
+ * /proc/<pid>/exe is the kernel's record of the executed binary and cannot
87
+ * be spoofed by userspace renames.
88
+ *
89
+ * On macOS/Windows there's no /proc, so fall back to pgrep by basename.
90
+ * macOS suffers the same Qt comm-rename in theory but our binary name is
91
+ * 8 chars (fits in comm's 15-char limit) and PC builds are predominantly
92
+ * exercised on Linux, so this is documented as best-effort.
93
+ *
94
+ * @internal exported for testing
95
+ */
96
+ export declare function findCrosspadPids(): number[];
97
+ /**
98
+ * Kill the running PC simulator. SIGTERM matched PIDs, poll up to 3s for
99
+ * graceful exit, SIGKILL stragglers. Detection uses both /proc and the TCP
100
+ * control port — either signal alone has been observed to lie (TCP port
101
+ * occasionally lingers after the binary exits, and a crashed process may
102
+ * keep its socket past the syscall return).
103
+ *
104
+ * Per-PID kill errors (EPERM, EUNKNOWN) are aggregated and surfaced in
105
+ * `error` so the caller sees *why* a kill didn't take, not just "still
106
+ * running" — historically this was the hardest kill failure to debug
107
+ * because Node swallowed EPERM and the user just saw success=false.
108
+ */
109
+ export declare function crosspadKill(): Promise<KillResult>;
@@ -1,27 +1,84 @@
1
1
  import fs from "fs";
2
+ import path from "path";
3
+ import { spawnSync } from "child_process";
2
4
  import { CROSSPAD_PC_ROOT, BUILD_DIR, BIN_EXE, VCPKG_TOOLCHAIN } from "../config.js";
3
5
  import { runBuild, runBuildStream, spawnDetached } from "../utils/exec.js";
4
- /** @internal exported for testing */
6
+ import { isSimulatorRunning } from "../utils/remote-client.js";
7
+ /**
8
+ * Match real compiler / linker / build-system errors only. Keyword-only
9
+ * matching ("any line containing 'error'") is too greedy — it picks up
10
+ * comments like `// error handling` from cmake output and inflates the
11
+ * error list.
12
+ *
13
+ * Patterns: GCC/Clang/MSVC compiler diagnostics, linker errors, CMake
14
+ * Errors, Ninja FAILED markers.
15
+ *
16
+ * @internal exported for testing
17
+ */
5
18
  export function parseErrors(output) {
6
19
  const errors = [];
7
- for (const line of output.split("\n")) {
8
- if (/\berror\b/i.test(line) && !line.includes("error(s)")) {
9
- errors.push(line.trim());
20
+ for (const raw of output.split("\n")) {
21
+ const line = raw.trim();
22
+ if (!line)
23
+ continue;
24
+ // GCC/Clang: foo.cpp:10:5: error: ... (also "fatal error:")
25
+ if (/:\d+:\d+:\s*(?:fatal\s+)?error\s*:/i.test(line)) {
26
+ errors.push(line);
27
+ continue;
28
+ }
29
+ // MSVC: foo.cpp(10,5): error C1234: ...
30
+ if (/\(\d+(?:,\d+)?\):\s*(?:fatal\s+)?error\s+[A-Z]\d+\s*:/i.test(line)) {
31
+ errors.push(line);
32
+ continue;
33
+ }
34
+ // Linker
35
+ if (/undefined reference to /.test(line)) {
36
+ errors.push(line);
37
+ continue;
38
+ }
39
+ if (/^.*ld(?:\.exe)?\s*:\s*error\s*:/i.test(line)) {
40
+ errors.push(line);
41
+ continue;
42
+ }
43
+ if (/LNK\d+:\s*error\b/i.test(line)) {
44
+ errors.push(line);
45
+ continue;
46
+ }
47
+ // CMake
48
+ if (/^CMake Error\b/i.test(line)) {
49
+ errors.push(line);
50
+ continue;
51
+ }
52
+ // Ninja
53
+ if (/^FAILED:\s/.test(line)) {
54
+ errors.push(line);
55
+ continue;
10
56
  }
11
57
  }
12
- return errors.slice(0, 20); // Cap at 20 errors
58
+ return errors.slice(0, 20);
13
59
  }
14
- /** @internal exported for testing */
60
+ /**
61
+ * Count compiler warnings only — same tightening logic as parseErrors.
62
+ * @internal exported for testing
63
+ */
15
64
  export function countWarnings(output) {
16
65
  let count = 0;
17
- for (const line of output.split("\n")) {
18
- if (/\bwarning\b/i.test(line) && !line.includes("warning(s)")) {
66
+ for (const raw of output.split("\n")) {
67
+ const line = raw.trim();
68
+ if (!line)
69
+ continue;
70
+ if (/:\d+:\d+:\s*warning\s*:/i.test(line)) {
19
71
  count++;
72
+ continue;
73
+ }
74
+ if (/\(\d+(?:,\d+)?\):\s*warning\s+[A-Z]\d+\s*:/i.test(line)) {
75
+ count++;
76
+ continue;
20
77
  }
21
78
  }
22
79
  return count;
23
80
  }
24
- export async function crosspadBuild(mode, onLine) {
81
+ export async function crosspadBuild(mode, onLine, buildType = "Debug", signal) {
25
82
  const startTime = Date.now();
26
83
  // Clean: remove build dir
27
84
  if (mode === "clean" && fs.existsSync(BUILD_DIR)) {
@@ -33,11 +90,11 @@ export async function crosspadBuild(mode, onLine) {
33
90
  const configCmd = [
34
91
  "cmake -B build -G Ninja",
35
92
  `-DCMAKE_TOOLCHAIN_FILE=${VCPKG_TOOLCHAIN}`,
36
- "-DCMAKE_BUILD_TYPE=Debug",
93
+ `-DCMAKE_BUILD_TYPE=${buildType}`,
37
94
  ].join(" ");
38
- onLine?.("stdout", `[crosspad] Configuring: ${mode}...`);
95
+ onLine?.("stdout", `[crosspad] Configuring: ${mode} (${buildType})...`);
39
96
  if (onLine) {
40
- const configResult = await runBuildStream(configCmd, CROSSPAD_PC_ROOT, onLine, 600_000);
97
+ const configResult = await runBuildStream(configCmd, CROSSPAD_PC_ROOT, onLine, 600_000, signal);
41
98
  if (!configResult.success) {
42
99
  const combined = configResult.stdout + "\n" + configResult.stderr;
43
100
  return {
@@ -69,7 +126,7 @@ export async function crosspadBuild(mode, onLine) {
69
126
  let buildStderr;
70
127
  let buildSuccess;
71
128
  if (onLine) {
72
- const buildResult = await runBuildStream("cmake --build build", CROSSPAD_PC_ROOT, onLine, 600_000);
129
+ const buildResult = await runBuildStream("cmake --build build", CROSSPAD_PC_ROOT, onLine, 600_000, signal);
73
130
  buildStdout = buildResult.stdout;
74
131
  buildStderr = buildResult.stderr;
75
132
  buildSuccess = buildResult.success;
@@ -91,11 +148,251 @@ export async function crosspadBuild(mode, onLine) {
91
148
  onLine?.("stdout", `[crosspad] Build ${result.success ? "succeeded" : "FAILED"} in ${result.duration_seconds.toFixed(1)}s`);
92
149
  return result;
93
150
  }
94
- export function crosspadRun() {
151
+ function delay(ms) {
152
+ return new Promise((r) => setTimeout(r, ms));
153
+ }
154
+ /**
155
+ * Launch the simulator binary in the background.
156
+ *
157
+ * Refuses to spawn a second instance if one is already responding on the
158
+ * remote-control port — multiple instances clobber each other's window
159
+ * state and the TCP listener binds to the same port.
160
+ *
161
+ * After spawn we poll the TCP control port for up to ~3s — this distinguishes
162
+ * "process started, ready to accept commands" from "process started but
163
+ * crashed before binding" so callers don't fire screenshot/stats too early.
164
+ */
165
+ export async function crosspadRun(force = false) {
95
166
  if (!fs.existsSync(BIN_EXE)) {
96
167
  return { pid: null, exe_path: BIN_EXE };
97
168
  }
169
+ if (!force && (await isSimulatorRunning())) {
170
+ return {
171
+ pid: null,
172
+ exe_path: BIN_EXE,
173
+ already_running: true,
174
+ error: "Simulator already running on port 19840. Pass force=true to spawn another instance anyway.",
175
+ };
176
+ }
98
177
  const pid = spawnDetached(BIN_EXE, [], CROSSPAD_PC_ROOT);
99
- return { pid, exe_path: BIN_EXE };
178
+ if (pid === null)
179
+ return { pid, exe_path: BIN_EXE };
180
+ // Poll for TCP readiness so callers know if the sim actually came up.
181
+ let responsive = false;
182
+ for (let i = 0; i < 6; i++) {
183
+ await delay(500);
184
+ if (await isSimulatorRunning()) {
185
+ responsive = true;
186
+ break;
187
+ }
188
+ }
189
+ return { pid, exe_path: BIN_EXE, responsive };
190
+ }
191
+ /**
192
+ * Canonicalize a filesystem path. realpath resolves every symlink in the
193
+ * chain — needed because /proc/<pid>/exe always returns the kernel's view
194
+ * (post-symlink) while BIN_EXE comes from string concatenation under
195
+ * CROSSPAD_PC_ROOT, which is commonly itself a symlink (e.g. ~/GIT/crosspad-pc
196
+ * → /mnt/big-disk/crosspad-pc). Without canonicalization the string compare
197
+ * silently misses every running sim.
198
+ *
199
+ * Falls back to path.resolve when realpath fails (binary not built yet, or
200
+ * a non-existent /proc path during a TOCTOU race) so callers always get a
201
+ * comparable absolute path.
202
+ *
203
+ * @internal exported for testing
204
+ */
205
+ export function canonicalize(p) {
206
+ try {
207
+ return fs.realpathSync(p);
208
+ }
209
+ catch {
210
+ return path.resolve(p);
211
+ }
212
+ }
213
+ /**
214
+ * Strip the kernel's " (deleted)" suffix that appears in /proc/<pid>/exe
215
+ * when the executable was unlinked or replaced after the process started
216
+ * (typical during dev: rebuild while sim is still running). Without this
217
+ * strip the path compare misses any running-but-rebuilt sim — the most
218
+ * common reason a developer would hit "agent can't kill the simulator."
219
+ *
220
+ * @internal exported for testing
221
+ */
222
+ export function stripDeletedSuffix(p) {
223
+ return p.replace(/ \(deleted\)$/, "");
224
+ }
225
+ /**
226
+ * Find PIDs running the CrossPad simulator binary.
227
+ *
228
+ * On Linux scans /proc/<pid>/exe and matches the resolved+canonicalized
229
+ * symlink against BIN_EXE. This is the only reliable identification:
230
+ * pgrep -x compares /proc/<pid>/comm, which Qt/pthread routinely overwrite
231
+ * via pthread_setname_np / prctl(PR_SET_NAME), so a sim launched as
232
+ * "CrossPad" shows up under whatever Qt named the main thread last.
233
+ * /proc/<pid>/exe is the kernel's record of the executed binary and cannot
234
+ * be spoofed by userspace renames.
235
+ *
236
+ * On macOS/Windows there's no /proc, so fall back to pgrep by basename.
237
+ * macOS suffers the same Qt comm-rename in theory but our binary name is
238
+ * 8 chars (fits in comm's 15-char limit) and PC builds are predominantly
239
+ * exercised on Linux, so this is documented as best-effort.
240
+ *
241
+ * @internal exported for testing
242
+ */
243
+ export function findCrosspadPids() {
244
+ if (process.platform === "linux") {
245
+ const target = canonicalize(BIN_EXE);
246
+ let entries;
247
+ try {
248
+ entries = fs.readdirSync("/proc");
249
+ }
250
+ catch {
251
+ return [];
252
+ }
253
+ const pids = [];
254
+ const self = process.pid;
255
+ for (const entry of entries) {
256
+ // /proc has many non-pid entries (cpuinfo, self, etc.) — skip anything
257
+ // that doesn't round-trip as an integer. Also skip our own PID; node
258
+ // can't be CrossPad but defensive in case BIN_EXE is misconfigured to
259
+ // /usr/bin/node during testing.
260
+ if (!/^\d+$/.test(entry))
261
+ continue;
262
+ const pid = parseInt(entry, 10);
263
+ if (pid === self)
264
+ continue;
265
+ try {
266
+ const raw = fs.readlinkSync(`/proc/${pid}/exe`);
267
+ const exe = canonicalize(stripDeletedSuffix(raw));
268
+ if (exe === target)
269
+ pids.push(pid);
270
+ }
271
+ catch {
272
+ // Process exited mid-scan, or no permission. Either is fine.
273
+ }
274
+ }
275
+ return pids;
276
+ }
277
+ // macOS / Windows / other: pgrep by basename. Strip .exe so the same
278
+ // binary works under wine/CI and on real Windows (where pgrep is absent
279
+ // — spawnSync.error is caught and we return []).
280
+ try {
281
+ const base = path.basename(BIN_EXE).replace(/\.exe$/i, "");
282
+ const r = spawnSync("pgrep", ["-x", base], { encoding: "utf-8", timeout: 5000 });
283
+ return (r.stdout || "")
284
+ .split("\n")
285
+ .map((s) => parseInt(s.trim(), 10))
286
+ .filter((n) => Number.isFinite(n));
287
+ }
288
+ catch {
289
+ return [];
290
+ }
291
+ }
292
+ /**
293
+ * Try to deliver a signal; returns the errno code on failure, undefined on
294
+ * success. ESRCH is folded into success ("already dead" is the desired state).
295
+ *
296
+ * @internal
297
+ */
298
+ function trySignal(pid, signal) {
299
+ try {
300
+ process.kill(pid, signal);
301
+ return undefined;
302
+ }
303
+ catch (e) {
304
+ const code = e?.code;
305
+ if (code === "ESRCH")
306
+ return undefined; // already exited — fine
307
+ return code ?? "EUNKNOWN";
308
+ }
309
+ }
310
+ /**
311
+ * Kill the running PC simulator. SIGTERM matched PIDs, poll up to 3s for
312
+ * graceful exit, SIGKILL stragglers. Detection uses both /proc and the TCP
313
+ * control port — either signal alone has been observed to lie (TCP port
314
+ * occasionally lingers after the binary exits, and a crashed process may
315
+ * keep its socket past the syscall return).
316
+ *
317
+ * Per-PID kill errors (EPERM, EUNKNOWN) are aggregated and surfaced in
318
+ * `error` so the caller sees *why* a kill didn't take, not just "still
319
+ * running" — historically this was the hardest kill failure to debug
320
+ * because Node swallowed EPERM and the user just saw success=false.
321
+ */
322
+ export async function crosspadKill() {
323
+ const initialPids = findCrosspadPids();
324
+ const tcpAliveInitial = await isSimulatorRunning();
325
+ const wasRunning = initialPids.length > 0 || tcpAliveInitial;
326
+ if (!wasRunning) {
327
+ return { success: true, killed_pids: [], was_running: false };
328
+ }
329
+ const killedPids = [];
330
+ const failures = [];
331
+ for (const pid of initialPids) {
332
+ const errCode = trySignal(pid, "SIGTERM");
333
+ if (errCode === undefined) {
334
+ killedPids.push(pid);
335
+ }
336
+ else {
337
+ failures.push(`SIGTERM pid=${pid} ${errCode}`);
338
+ }
339
+ }
340
+ // Poll up to 3s for SIGTERM to take effect. The first poll runs after a
341
+ // single 150 ms beat; this is enough for a Qt event loop to acknowledge
342
+ // SIGTERM in the common case so the kill returns fast.
343
+ const deadline = Date.now() + 3000;
344
+ let stillAlive = initialPids;
345
+ while (Date.now() < deadline) {
346
+ await delay(150);
347
+ stillAlive = findCrosspadPids();
348
+ if (stillAlive.length === 0) {
349
+ // /proc is clean — confirm the TCP port is gone too. We only pay the
350
+ // TCP probe in this branch to avoid stretching the polling deadline:
351
+ // isSimulatorRunning can take seconds when the sim is hung.
352
+ if (!(await isSimulatorRunning()))
353
+ break;
354
+ }
355
+ }
356
+ // Force-kill anything that survived SIGTERM. Re-check /proc/<pid>/exe by
357
+ // way of findCrosspadPids (already done above) — guards against PID
358
+ // recycling in the gap between SIGTERM and SIGKILL.
359
+ if (stillAlive.length > 0) {
360
+ for (const pid of stillAlive) {
361
+ const errCode = trySignal(pid, "SIGKILL");
362
+ if (errCode === undefined) {
363
+ if (!killedPids.includes(pid))
364
+ killedPids.push(pid);
365
+ }
366
+ else {
367
+ failures.push(`SIGKILL pid=${pid} ${errCode}`);
368
+ }
369
+ }
370
+ await delay(300);
371
+ }
372
+ const finalAlive = findCrosspadPids();
373
+ const tcpAliveFinal = await isSimulatorRunning();
374
+ const stillRunning = finalAlive.length > 0 || tcpAliveFinal;
375
+ let errorMsg;
376
+ if (stillRunning) {
377
+ const parts = [
378
+ `Simulator still alive after SIGTERM+SIGKILL`,
379
+ `pids=${finalAlive.join(",") || "none"}`,
380
+ `tcp_alive=${tcpAliveFinal}`,
381
+ ];
382
+ if (failures.length > 0)
383
+ parts.push(`failures=[${failures.join("; ")}]`);
384
+ errorMsg = parts.join(", ") + ".";
385
+ }
386
+ else if (failures.length > 0) {
387
+ // Sim is dead but some kill attempts errored (e.g. PID gone before our
388
+ // SIGKILL). Worth surfacing but not a hard failure.
389
+ errorMsg = `Sim stopped, but some signals errored: ${failures.join("; ")}.`;
390
+ }
391
+ return {
392
+ success: !stillRunning,
393
+ killed_pids: killedPids,
394
+ was_running: true,
395
+ error: errorMsg,
396
+ };
100
397
  }
101
398
  //# sourceMappingURL=build.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/tools/build.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../../src/tools/build.ts"],"names":[],"mappings":"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"}
@@ -14,11 +14,15 @@ export interface SubmoduleDiff {
14
14
  commit_log: string[];
15
15
  }
16
16
  export interface DiffCoreResult {
17
+ parent_repo: string;
17
18
  submodules: SubmoduleDiff[];
18
19
  }
19
20
  /**
20
21
  * Show what changed in crosspad-core and/or crosspad-gui relative to the
21
22
  * pinned submodule commit. Essential for dev-mode workflows where you're
22
23
  * editing shared repos but haven't committed/pinned yet.
24
+ *
25
+ * Submodule paths are resolved dynamically from .gitmodules (handles both
26
+ * `crosspad-core` and `lib/crosspad-core` layouts).
23
27
  */
24
- export declare function crosspadDiffCore(submodule?: "crosspad-core" | "crosspad-gui" | "both"): DiffCoreResult;
28
+ export declare function crosspadDiffCore(submodule?: "crosspad-core" | "crosspad-gui" | "both", parent?: "crosspad-pc" | "platform-idf"): DiffCoreResult;
@@ -1,22 +1,27 @@
1
1
  import fs from "fs";
2
2
  import path from "path";
3
- import { CROSSPAD_PC_ROOT } from "../config.js";
3
+ import { CROSSPAD_PC_ROOT, CROSSPAD_IDF_ROOT } from "../config.js";
4
4
  import { runCommand } from "../utils/exec.js";
5
- import { getSubmodulePin } from "../utils/git.js";
5
+ import { getSubmodulePin, findSubmodulePath } from "../utils/git.js";
6
6
  /**
7
7
  * Show what changed in crosspad-core and/or crosspad-gui relative to the
8
8
  * pinned submodule commit. Essential for dev-mode workflows where you're
9
9
  * editing shared repos but haven't committed/pinned yet.
10
+ *
11
+ * Submodule paths are resolved dynamically from .gitmodules (handles both
12
+ * `crosspad-core` and `lib/crosspad-core` layouts).
10
13
  */
11
- export function crosspadDiffCore(submodule = "both") {
14
+ export function crosspadDiffCore(submodule = "both", parent = "crosspad-pc") {
15
+ const parentRoot = parent === "platform-idf" ? CROSSPAD_IDF_ROOT : CROSSPAD_PC_ROOT;
12
16
  const targets = submodule === "both"
13
17
  ? ["crosspad-core", "crosspad-gui"]
14
18
  : [submodule];
15
19
  const submodules = [];
16
20
  for (const sub of targets) {
17
- const subPath = path.join(CROSSPAD_PC_ROOT, sub);
21
+ const relPath = findSubmodulePath(parentRoot, sub);
22
+ const subPath = relPath ? path.join(parentRoot, relPath) : path.join(parentRoot, sub);
18
23
  const isDevMode = isJunction(subPath);
19
- const pinnedCommit = getSubmodulePin(CROSSPAD_PC_ROOT, sub);
24
+ const pinnedCommit = getSubmodulePin(parentRoot, sub);
20
25
  // Get current HEAD
21
26
  const headResult = runCommand("git rev-parse HEAD", subPath);
22
27
  const currentCommit = headResult.success ? headResult.stdout.trim() : null;
@@ -74,7 +79,7 @@ export function crosspadDiffCore(submodule = "both") {
74
79
  commit_log: commitLog,
75
80
  });
76
81
  }
77
- return { submodules };
82
+ return { parent_repo: parent, submodules };
78
83
  }
79
84
  function isJunction(p) {
80
85
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"diff-core.js","sourceRoot":"","sources":["../../src/tools/diff-core.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"diff-core.js","sourceRoot":"","sources":["../../src/tools/diff-core.ts"],"names":[],"mappings":"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"}
@@ -20,4 +20,4 @@ export declare function parseErrors(output: string): string[];
20
20
  export declare function parseWarnings(output: string): string[];
21
21
  /** @internal exported for testing */
22
22
  export declare function getTail(output: string, n: number): string[];
23
- export declare function crosspadIdfBuild(mode: "build" | "fullclean" | "clean", onLine?: OnLine): Promise<IdfBuildResult>;
23
+ export declare function crosspadIdfBuild(mode: "build" | "fullclean" | "clean", onLine?: OnLine, signal?: AbortSignal): Promise<IdfBuildResult>;
@@ -97,14 +97,14 @@ export function parseWarnings(output) {
97
97
  export function getTail(output, n) {
98
98
  return output.split("\n").filter(l => l.trim()).slice(-n);
99
99
  }
100
- async function runIdfCmd(cmd, onLine, timeoutMs) {
100
+ async function runIdfCmd(cmd, onLine, timeoutMs, signal) {
101
101
  if (onLine) {
102
- const r = await runIdfStream(cmd, CROSSPAD_IDF_ROOT, onLine, timeoutMs);
102
+ const r = await runIdfStream(cmd, CROSSPAD_IDF_ROOT, onLine, timeoutMs, signal);
103
103
  return r;
104
104
  }
105
105
  return runIdf(cmd, CROSSPAD_IDF_ROOT, timeoutMs);
106
106
  }
107
- export async function crosspadIdfBuild(mode, onLine) {
107
+ export async function crosspadIdfBuild(mode, onLine, signal) {
108
108
  const startTime = Date.now();
109
109
  let autoReconfigured = false;
110
110
  // Auto-detect unregistered apps — if found, escalate to fullclean
@@ -118,7 +118,7 @@ export async function crosspadIdfBuild(mode, onLine) {
118
118
  }
119
119
  if (mode === "fullclean") {
120
120
  onLine?.("stdout", "[idf] Running idf.py fullclean...");
121
- const r = await runIdfCmd("idf.py fullclean", onLine, 60_000);
121
+ const r = await runIdfCmd("idf.py fullclean", onLine, 60_000, signal);
122
122
  if (!r.success) {
123
123
  const combined = r.stdout + "\n" + r.stderr;
124
124
  return {
@@ -139,7 +139,7 @@ export async function crosspadIdfBuild(mode, onLine) {
139
139
  }
140
140
  }
141
141
  onLine?.("stdout", "[idf] Building...");
142
- const r = await runIdfCmd("idf.py build", onLine, 600_000);
142
+ const r = await runIdfCmd("idf.py build", onLine, 600_000, signal);
143
143
  const combined = r.stdout + "\n" + r.stderr;
144
144
  const errors = parseErrors(combined);
145
145
  const warnings = parseWarnings(combined);