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.
Files changed (66) 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.js +953 -219
  6. package/dist/index.js.map +1 -1
  7. package/dist/tools/app-manager.d.ts +13 -5
  8. package/dist/tools/app-manager.js +94 -28
  9. package/dist/tools/app-manager.js.map +1 -1
  10. package/dist/tools/architecture.js +13 -4
  11. package/dist/tools/architecture.js.map +1 -1
  12. package/dist/tools/build-check.d.ts +1 -1
  13. package/dist/tools/build-check.js +19 -9
  14. package/dist/tools/build-check.js.map +1 -1
  15. package/dist/tools/build.d.ts +43 -4
  16. package/dist/tools/build.js +147 -15
  17. package/dist/tools/build.js.map +1 -1
  18. package/dist/tools/diff-core.d.ts +5 -1
  19. package/dist/tools/diff-core.js +11 -6
  20. package/dist/tools/diff-core.js.map +1 -1
  21. package/dist/tools/idf-build.d.ts +1 -1
  22. package/dist/tools/idf-build.js +5 -5
  23. package/dist/tools/idf-build.js.map +1 -1
  24. package/dist/tools/idf-flash.d.ts +20 -0
  25. package/dist/tools/idf-flash.js +185 -0
  26. package/dist/tools/idf-flash.js.map +1 -0
  27. package/dist/tools/idf-monitor.d.ts +29 -0
  28. package/dist/tools/idf-monitor.js +222 -0
  29. package/dist/tools/idf-monitor.js.map +1 -0
  30. package/dist/tools/log.d.ts +2 -2
  31. package/dist/tools/log.js +6 -5
  32. package/dist/tools/log.js.map +1 -1
  33. package/dist/tools/midi.d.ts +27 -0
  34. package/dist/tools/midi.js +112 -0
  35. package/dist/tools/midi.js.map +1 -0
  36. package/dist/tools/repo-actions.d.ts +46 -0
  37. package/dist/tools/repo-actions.js +286 -0
  38. package/dist/tools/repo-actions.js.map +1 -0
  39. package/dist/tools/repos.js +14 -10
  40. package/dist/tools/repos.js.map +1 -1
  41. package/dist/tools/screenshot.js +42 -7
  42. package/dist/tools/screenshot.js.map +1 -1
  43. package/dist/tools/settings.js +11 -1
  44. package/dist/tools/settings.js.map +1 -1
  45. package/dist/tools/symbols.d.ts +2 -1
  46. package/dist/tools/symbols.js +121 -53
  47. package/dist/tools/symbols.js.map +1 -1
  48. package/dist/tools/test.d.ts +1 -9
  49. package/dist/tools/test.js +11 -92
  50. package/dist/tools/test.js.map +1 -1
  51. package/dist/utils/device.d.ts +38 -0
  52. package/dist/utils/device.js +287 -0
  53. package/dist/utils/device.js.map +1 -0
  54. package/dist/utils/exec.d.ts +17 -5
  55. package/dist/utils/exec.js +73 -27
  56. package/dist/utils/exec.js.map +1 -1
  57. package/dist/utils/git.d.ts +9 -0
  58. package/dist/utils/git.js +61 -1
  59. package/dist/utils/git.js.map +1 -1
  60. package/dist/utils/remote-client.d.ts +1 -0
  61. package/dist/utils/remote-client.js +56 -15
  62. package/dist/utils/remote-client.js.map +1 -1
  63. package/package.json +4 -1
  64. package/dist/tools/scaffold.d.ts +0 -15
  65. package/dist/tools/scaffold.js +0 -192
  66. package/dist/tools/scaffold.js.map +0 -1
package/dist/utils/git.js CHANGED
@@ -1,3 +1,5 @@
1
+ import fs from "fs";
2
+ import path from "path";
1
3
  import { runCommand } from "./exec.js";
2
4
  export function getRepoStatus(name, repoPath) {
3
5
  const branch = runCommand("git branch --show-current", repoPath);
@@ -14,8 +16,25 @@ export function getRepoStatus(name, repoPath) {
14
16
  .filter((l) => l.length > 0),
15
17
  };
16
18
  }
19
+ /**
20
+ * Get the pinned commit hash of a submodule.
21
+ *
22
+ * `submodule` may be either a canonical name (e.g. "crosspad-core") or a
23
+ * relative path (e.g. "lib/crosspad-core"). Names are resolved via .gitmodules.
24
+ */
17
25
  export function getSubmodulePin(repoPath, submodule) {
18
- const result = runCommand(`git submodule status ${submodule}`, repoPath);
26
+ // Resolve name path if needed
27
+ let subPath = submodule;
28
+ const subs = listSubmodules(repoPath);
29
+ if (!subs[submodule] && Object.values(subs).includes(submodule)) {
30
+ // already a path, keep as-is
31
+ }
32
+ else {
33
+ const resolved = findSubmodulePath(repoPath, submodule);
34
+ if (resolved)
35
+ subPath = resolved;
36
+ }
37
+ const result = runCommand(`git submodule status "${subPath}"`, repoPath);
19
38
  if (!result.success)
20
39
  return null;
21
40
  // Output format: " abc1234 submodule-name (desc)" or "+abc1234 ..."
@@ -26,4 +45,45 @@ export function getHead(repoPath) {
26
45
  const result = runCommand("git rev-parse HEAD", repoPath);
27
46
  return result.success ? result.stdout.trim() : null;
28
47
  }
48
+ /**
49
+ * Parse `.gitmodules` and return map of submodule name → path within parent.
50
+ * Returns empty map if no submodules or `.gitmodules` missing.
51
+ *
52
+ * Cached per repoPath since `.gitmodules` rarely changes during server lifetime.
53
+ */
54
+ const submoduleMapCache = new Map();
55
+ export function listSubmodules(repoPath) {
56
+ const cached = submoduleMapCache.get(repoPath);
57
+ if (cached)
58
+ return cached;
59
+ const gitmodules = path.join(repoPath, ".gitmodules");
60
+ if (!fs.existsSync(gitmodules)) {
61
+ submoduleMapCache.set(repoPath, {});
62
+ return {};
63
+ }
64
+ // git config returns lines like: submodule.<name>.path <relative-path>
65
+ const result = runCommand(`git config -f .gitmodules --get-regexp "^submodule\\..*\\.path$"`, repoPath);
66
+ const map = {};
67
+ if (result.success) {
68
+ for (const line of result.stdout.split("\n")) {
69
+ const m = line.match(/^submodule\.(.+)\.path\s+(.+)$/);
70
+ if (m)
71
+ map[m[1]] = m[2].trim();
72
+ }
73
+ }
74
+ submoduleMapCache.set(repoPath, map);
75
+ return map;
76
+ }
77
+ /** Resolve a submodule's path within a parent repo by canonical name. Null if not present. */
78
+ export function findSubmodulePath(repoPath, submoduleName) {
79
+ const subs = listSubmodules(repoPath);
80
+ if (subs[submoduleName])
81
+ return subs[submoduleName];
82
+ // Fallback: search by basename match (e.g. "crosspad-core" matching "lib/crosspad-core")
83
+ for (const [, p] of Object.entries(subs)) {
84
+ if (path.basename(p) === submoduleName)
85
+ return p;
86
+ }
87
+ return null;
88
+ }
29
89
  //# sourceMappingURL=git.js.map
@@ -1 +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"}
1
+ {"version":3,"file":"git.js","sourceRoot":"","sources":["../../src/utils/git.ts"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@ export interface RemoteResponse {
8
8
  }
9
9
  /**
10
10
  * Send a JSON command to the running simulator and return the response.
11
+ * Retries up to MAX_RETRIES times on timeout errors (simulator may be loading).
11
12
  * Opens a fresh TCP connection per call (simple, stateless).
12
13
  */
13
14
  export declare function sendRemoteCommand(command: Record<string, unknown>): Promise<RemoteResponse>;
@@ -3,15 +3,66 @@
3
3
  * Protocol: newline-delimited JSON over TCP on localhost:19840.
4
4
  */
5
5
  import { Socket } from "net";
6
- const REMOTE_PORT = 19840;
7
- const REMOTE_HOST = "127.0.0.1";
6
+ import { z } from "zod";
7
+ /**
8
+ * Minimal contract enforced on every TCP simulator response.
9
+ * Body must be a JSON object with `ok` boolean. Anything else (array, scalar,
10
+ * missing `ok`) is treated as a malformed response — caller gets a synthetic
11
+ * `{ok:false, error:"..."}` so downstream code can rely on the shape.
12
+ */
13
+ const RemoteEnvelopeSchema = z.object({ ok: z.boolean() }).passthrough();
14
+ function parseRemoteResponse(raw) {
15
+ let parsed;
16
+ try {
17
+ parsed = JSON.parse(raw);
18
+ }
19
+ catch {
20
+ return { ok: false, error: "invalid JSON response", raw };
21
+ }
22
+ const result = RemoteEnvelopeSchema.safeParse(parsed);
23
+ if (!result.success) {
24
+ return { ok: false, error: "malformed response (expected object with `ok` boolean)", raw };
25
+ }
26
+ return result.data;
27
+ }
28
+ const REMOTE_PORT = (() => {
29
+ const raw = process.env.CROSSPAD_REMOTE_PORT;
30
+ if (!raw)
31
+ return 19840;
32
+ const n = parseInt(raw, 10);
33
+ return Number.isFinite(n) && n > 0 && n < 65536 ? n : 19840;
34
+ })();
35
+ const REMOTE_HOST = process.env.CROSSPAD_REMOTE_HOST || "127.0.0.1";
8
36
  const CONNECT_TIMEOUT = 3000;
9
37
  const RESPONSE_TIMEOUT = 15000;
38
+ const MAX_RETRIES = 3;
39
+ const RETRY_DELAY_MS = 500;
40
+ function delay(ms) {
41
+ return new Promise((resolve) => setTimeout(resolve, ms));
42
+ }
10
43
  /**
11
44
  * Send a JSON command to the running simulator and return the response.
45
+ * Retries up to MAX_RETRIES times on timeout errors (simulator may be loading).
12
46
  * Opens a fresh TCP connection per call (simple, stateless).
13
47
  */
14
- export function sendRemoteCommand(command) {
48
+ export async function sendRemoteCommand(command) {
49
+ let lastError;
50
+ for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
51
+ try {
52
+ return await sendRemoteCommandOnce(command);
53
+ }
54
+ catch (err) {
55
+ lastError = err;
56
+ // Only retry on timeout, not on connection refused (simulator not running)
57
+ if (err.message?.includes("Connection refused"))
58
+ throw err;
59
+ if (attempt < MAX_RETRIES)
60
+ await delay(RETRY_DELAY_MS * attempt);
61
+ }
62
+ }
63
+ throw lastError;
64
+ }
65
+ function sendRemoteCommandOnce(command) {
15
66
  return new Promise((resolve, reject) => {
16
67
  const socket = new Socket();
17
68
  let buffer = "";
@@ -39,12 +90,7 @@ export function sendRemoteCommand(command) {
39
90
  const line = buffer.slice(0, nlIdx);
40
91
  resolved = true;
41
92
  socket.destroy();
42
- try {
43
- resolve(JSON.parse(line));
44
- }
45
- catch {
46
- resolve({ ok: false, error: "invalid JSON response", raw: line });
47
- }
93
+ resolve(parseRemoteResponse(line));
48
94
  }
49
95
  });
50
96
  socket.on("timeout", () => {
@@ -64,12 +110,7 @@ export function sendRemoteCommand(command) {
64
110
  if (!resolved) {
65
111
  resolved = true;
66
112
  if (buffer.length > 0) {
67
- try {
68
- resolve(JSON.parse(buffer));
69
- }
70
- catch {
71
- resolve({ ok: false, error: "incomplete response", raw: buffer });
72
- }
113
+ resolve(parseRemoteResponse(buffer));
73
114
  }
74
115
  else {
75
116
  reject(new Error("Connection closed without response"));
@@ -1 +1 @@
1
- {"version":3,"file":"remote-client.js","sourceRoot":"","sources":["../../src/utils/remote-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"remote-client.js","sourceRoot":"","sources":["../../src/utils/remote-client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "crosspad-mcp-server",
3
- "version": "5.1.0",
3
+ "version": "8.1.0",
4
4
  "description": "MCP development server for CrossPad — build, test, manage apps, interact with simulator",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,6 +25,9 @@
25
25
  "url": "https://github.com/CrossPad/crosspad-mcp.git"
26
26
  },
27
27
  "license": "MIT",
28
+ "engines": {
29
+ "node": ">=18.0.0"
30
+ },
28
31
  "scripts": {
29
32
  "build": "tsc",
30
33
  "prepublishOnly": "tsc",
@@ -1,15 +0,0 @@
1
- export interface ScaffoldParams {
2
- name: string;
3
- display_name?: string;
4
- has_pad_logic?: boolean;
5
- icon?: string;
6
- }
7
- export interface ScaffoldResult {
8
- files: Record<string, string>;
9
- cmake_patch: {
10
- file: string;
11
- after_pattern: string;
12
- content: string;
13
- };
14
- }
15
- export declare function crosspadScaffoldApp(params: ScaffoldParams): ScaffoldResult;
@@ -1,192 +0,0 @@
1
- export function crosspadScaffoldApp(params) {
2
- const { name, display_name = name, has_pad_logic = false, icon = "CrossPad_Logo_110w.png", } = params;
3
- const lower = name.toLowerCase();
4
- const upper = name.toUpperCase();
5
- const dir = `src/apps/${lower}`;
6
- const files = {};
7
- // --- CMakeLists.txt ---
8
- const sources = [`\${CMAKE_CURRENT_SOURCE_DIR}/${name}App.cpp`];
9
- if (has_pad_logic) {
10
- sources.push(`\${CMAKE_CURRENT_SOURCE_DIR}/${name}PadLogic.cpp`);
11
- }
12
- files[`${dir}/CMakeLists.txt`] = `# ${display_name} app sources
13
- set(${upper}_APP_SOURCES
14
- ${sources.join("\n ")}
15
- PARENT_SCOPE
16
- )
17
- `;
18
- // --- App header ---
19
- files[`${dir}/${name}App.hpp`] = `#pragma once
20
-
21
- #include "lvgl.h"
22
-
23
- class App;
24
-
25
- lv_obj_t* ${name}_create(lv_obj_t* parent, App* app);
26
- void ${name}_destroy(lv_obj_t* app_obj);
27
- `;
28
- // --- App implementation ---
29
- let appCpp = `/**
30
- * @file ${name}App.cpp
31
- * @brief ${display_name} app — LVGL GUI
32
- */
33
-
34
- #include "${name}App.hpp"
35
- #include "pc_stubs/PcApp.hpp"
36
- #include "pc_stubs/pc_platform.h"
37
-
38
- #include <crosspad/app/AppRegistry.hpp>
39
- #include <crosspad/pad/PadManager.hpp>
40
- #include "crosspad-gui/components/app_lifecycle.h"
41
- #include "crosspad-gui/platform/IGuiPlatform.h"
42
- #include "crosspad_app.hpp"
43
-
44
- #include "lvgl.h"
45
-
46
- #include <cstdio>
47
- `;
48
- if (has_pad_logic) {
49
- appCpp += `#include "${name}PadLogic.hpp"
50
- #include <memory>
51
-
52
- static std::shared_ptr<${name}PadLogic> s_padLogic;
53
- `;
54
- }
55
- appCpp += `
56
- static App* s_app = nullptr;
57
-
58
- /* ── App create / destroy ────────────────────────────────────────────── */
59
-
60
- lv_obj_t* ${name}_create(lv_obj_t* parent, App* a)
61
- {
62
- s_app = a;
63
- lv_obj_t* cont = lv_obj_create(parent);
64
- lv_obj_set_size(cont, lv_pct(100), lv_pct(100));
65
- lv_obj_set_style_bg_color(cont, lv_color_black(), 0);
66
- lv_obj_set_style_bg_opa(cont, LV_OPA_COVER, 0);
67
- lv_obj_set_style_pad_all(cont, 4, 0);
68
- lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
69
- lv_obj_set_style_pad_row(cont, 2, 0);
70
- lv_obj_remove_flag(cont, LV_OBJ_FLAG_SCROLLABLE);
71
-
72
- /* ── Title bar with close button ─────────────────────────── */
73
- lv_obj_t* titleBar = lv_obj_create(cont);
74
- lv_obj_set_size(titleBar, lv_pct(100), 24);
75
- lv_obj_set_style_bg_opa(titleBar, LV_OPA_TRANSP, 0);
76
- lv_obj_set_style_border_width(titleBar, 0, 0);
77
- lv_obj_set_style_pad_all(titleBar, 0, 0);
78
- lv_obj_remove_flag(titleBar, LV_OBJ_FLAG_SCROLLABLE);
79
-
80
- lv_obj_t* titleLabel = lv_label_create(titleBar);
81
- lv_label_set_text(titleLabel, "${display_name}");
82
- lv_obj_set_style_text_color(titleLabel, lv_color_white(), 0);
83
- lv_obj_set_style_text_font(titleLabel, &lv_font_montserrat_14, 0);
84
- lv_obj_align(titleLabel, LV_ALIGN_LEFT_MID, 4, 0);
85
-
86
- lv_obj_t* closeBtn = lv_button_create(titleBar);
87
- lv_obj_set_size(closeBtn, 28, 20);
88
- lv_obj_align(closeBtn, LV_ALIGN_RIGHT_MID, -2, 0);
89
- lv_obj_set_style_bg_color(closeBtn, lv_color_hex(0x662222), 0);
90
- lv_obj_set_style_bg_color(closeBtn, lv_color_hex(0xAA3333), LV_STATE_PRESSED);
91
- lv_obj_set_style_radius(closeBtn, 4, 0);
92
- lv_obj_set_style_shadow_width(closeBtn, 0, 0);
93
- lv_obj_t* closeLbl = lv_label_create(closeBtn);
94
- lv_label_set_text(closeLbl, "X");
95
- lv_obj_set_style_text_font(closeLbl, &lv_font_montserrat_12, 0);
96
- lv_obj_center(closeLbl);
97
- lv_obj_add_event_cb(closeBtn, [](lv_event_t*) {
98
- if (s_app) crosspad_gui::app_request_close(s_app);
99
- }, LV_EVENT_CLICKED, nullptr);
100
- `;
101
- if (has_pad_logic) {
102
- appCpp += `
103
- /* ── Register pad logic ──────────────────────────────────── */
104
- s_padLogic = std::make_shared<${name}PadLogic>();
105
- crosspad::getPadManager().registerPadLogic("${name}", s_padLogic);
106
-
107
- if (a) {
108
- a->setOnShow([](lv_obj_t*) {
109
- crosspad::getPadManager().setActivePadLogic("${name}");
110
- crosspad_app_update_pad_icon();
111
- });
112
- a->setOnHide([](lv_obj_t*) {
113
- crosspad::getPadManager().setActivePadLogic("");
114
- crosspad_app_update_pad_icon();
115
- });
116
- }
117
- `;
118
- }
119
- appCpp += `
120
- /* ── TODO: Add your UI here ──────────────────────────────── */
121
-
122
- printf("[${name}] App created\\n");
123
- return cont;
124
- }
125
-
126
- void ${name}_destroy(lv_obj_t* app_obj)
127
- {
128
- `;
129
- if (has_pad_logic) {
130
- appCpp += ` crosspad::getPadManager().setActivePadLogic("");
131
- crosspad::getPadManager().unregisterPadLogic("${name}");
132
- crosspad_app_update_pad_icon();
133
- s_padLogic.reset();
134
- `;
135
- }
136
- appCpp += ` s_app = nullptr;
137
- lv_obj_delete_async(app_obj);
138
- printf("[${name}] App destroyed\\n");
139
- }
140
-
141
- /* ── App registration ────────────────────────────────────────────────── */
142
-
143
- void _register_${name}_app() {
144
- static char icon_path[256];
145
- snprintf(icon_path, sizeof(icon_path), "%s${icon}",
146
- crosspad_gui::getGuiPlatform().assetPathPrefix());
147
-
148
- static const crosspad::AppEntry entry = {
149
- "${name}", icon_path, ${name}_create, ${name}_destroy,
150
- nullptr, nullptr, nullptr, nullptr, 0
151
- };
152
- crosspad::AppRegistry::getInstance().registerApp(entry);
153
- }
154
- `;
155
- files[`${dir}/${name}App.cpp`] = appCpp;
156
- // --- Pad logic (optional) ---
157
- if (has_pad_logic) {
158
- files[`${dir}/${name}PadLogic.hpp`] = `#pragma once
159
-
160
- #include <crosspad/pad/IPadLogicHandler.hpp>
161
-
162
- class ${name}PadLogic : public crosspad::IPadLogicHandler {
163
- public:
164
- void onPadPressed(uint8_t padIndex, uint8_t velocity) override;
165
- void onPadReleased(uint8_t padIndex) override;
166
- };
167
- `;
168
- files[`${dir}/${name}PadLogic.cpp`] = `#include "${name}PadLogic.hpp"
169
- #include <cstdio>
170
-
171
- void ${name}PadLogic::onPadPressed(uint8_t padIndex, uint8_t velocity)
172
- {
173
- printf("[${name}PadLogic] Pad %d pressed (vel=%d)\\n", padIndex, velocity);
174
- // TODO: Implement pad press logic
175
- }
176
-
177
- void ${name}PadLogic::onPadReleased(uint8_t padIndex)
178
- {
179
- printf("[${name}PadLogic] Pad %d released\\n", padIndex);
180
- // TODO: Implement pad release logic
181
- }
182
- `;
183
- }
184
- // --- CMake patch instructions ---
185
- const cmakePatch = {
186
- file: "CMakeLists.txt",
187
- after_pattern: "add_subdirectory(src/apps/",
188
- content: `add_subdirectory(${dir})\nlist(APPEND MAIN_SOURCES \${${upper}_APP_SOURCES})`,
189
- };
190
- return { files, cmake_patch: cmakePatch };
191
- }
192
- //# sourceMappingURL=scaffold.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/tools/scaffold.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,MAAM,EACJ,IAAI,EACJ,YAAY,GAAG,IAAI,EACnB,aAAa,GAAG,KAAK,EACrB,IAAI,GAAG,wBAAwB,GAChC,GAAG,MAAM,CAAC;IAEX,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,YAAY,KAAK,EAAE,CAAC;IAEhC,MAAM,KAAK,GAA2B,EAAE,CAAC;IAEzC,yBAAyB;IACzB,MAAM,OAAO,GAAG,CAAC,gCAAgC,IAAI,SAAS,CAAC,CAAC;IAChE,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,CAAC,IAAI,CAAC,gCAAgC,IAAI,cAAc,CAAC,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,GAAG,GAAG,iBAAiB,CAAC,GAAG,KAAK,YAAY;MAC9C,KAAK;MACL,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;;;CAG3B,CAAC;IAEA,qBAAqB;IACrB,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,SAAS,CAAC,GAAG;;;;;;YAMvB,IAAI;OACT,IAAI;CACV,CAAC;IAEA,6BAA6B;IAC7B,IAAI,MAAM,GAAG;WACJ,IAAI;YACH,YAAY;;;YAGZ,IAAI;;;;;;;;;;;;;CAaf,CAAC;IAEA,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,IAAI,aAAa,IAAI;;;yBAGN,IAAI;CAC5B,CAAC;IACA,CAAC;IAED,MAAM,IAAI;;;;;YAKA,IAAI;;;;;;;;;;;;;;;;;;;;;qCAqBqB,YAAY;;;;;;;;;;;;;;;;;;;CAmBhD,CAAC;IAEA,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,IAAI;;oCAEsB,IAAI;kDACU,IAAI;;;;2DAIK,IAAI;;;;;;;;CAQ9D,CAAC;IACA,CAAC;IAED,MAAM,IAAI;;;eAGG,IAAI;;;;OAIZ,IAAI;;CAEV,CAAC;IAEA,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,IAAI;oDACsC,IAAI;;;CAGvD,CAAC;IACA,CAAC;IAED,MAAM,IAAI;;eAEG,IAAI;;;;;iBAKF,IAAI;;gDAE2B,IAAI;;;;WAIzC,IAAI,iBAAiB,IAAI,YAAY,IAAI;;;;;CAKnD,CAAC;IAEA,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,SAAS,CAAC,GAAG,MAAM,CAAC;IAExC,+BAA+B;IAC/B,IAAI,aAAa,EAAE,CAAC;QAClB,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,cAAc,CAAC,GAAG;;;;QAIlC,IAAI;;;;;CAKX,CAAC;QAEE,KAAK,CAAC,GAAG,GAAG,IAAI,IAAI,cAAc,CAAC,GAAG,aAAa,IAAI;;;OAGpD,IAAI;;eAEI,IAAI;;;;OAIZ,IAAI;;eAEI,IAAI;;;CAGlB,CAAC;IACA,CAAC;IAED,mCAAmC;IACnC,MAAM,UAAU,GAAG;QACjB,IAAI,EAAE,gBAAgB;QACtB,aAAa,EAAE,4BAA4B;QAC3C,OAAO,EAAE,oBAAoB,GAAG,kCAAkC,KAAK,gBAAgB;KACxF,CAAC;IAEF,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC;AAC5C,CAAC"}