brosh 0.2.2

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 (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +181 -0
  3. package/brosh_brandmark.svg +3 -0
  4. package/brosh_logo.svg +27 -0
  5. package/cli_icon.svg +52 -0
  6. package/dist/client.d.ts +5 -0
  7. package/dist/client.d.ts.map +1 -0
  8. package/dist/client.js +138 -0
  9. package/dist/client.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +618 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/lib.d.ts +25 -0
  15. package/dist/lib.d.ts.map +1 -0
  16. package/dist/lib.js +28 -0
  17. package/dist/lib.js.map +1 -0
  18. package/dist/mode-selector.d.ts +7 -0
  19. package/dist/mode-selector.d.ts.map +1 -0
  20. package/dist/mode-selector.js +138 -0
  21. package/dist/mode-selector.js.map +1 -0
  22. package/dist/prompts/index.d.ts +3 -0
  23. package/dist/prompts/index.d.ts.map +1 -0
  24. package/dist/prompts/index.js +79 -0
  25. package/dist/prompts/index.js.map +1 -0
  26. package/dist/recording/index.d.ts +4 -0
  27. package/dist/recording/index.d.ts.map +1 -0
  28. package/dist/recording/index.js +3 -0
  29. package/dist/recording/index.js.map +1 -0
  30. package/dist/recording/manager.d.ts +62 -0
  31. package/dist/recording/manager.d.ts.map +1 -0
  32. package/dist/recording/manager.js +123 -0
  33. package/dist/recording/manager.js.map +1 -0
  34. package/dist/recording/recorder.d.ts +95 -0
  35. package/dist/recording/recorder.d.ts.map +1 -0
  36. package/dist/recording/recorder.js +330 -0
  37. package/dist/recording/recorder.js.map +1 -0
  38. package/dist/recording/types.d.ts +65 -0
  39. package/dist/recording/types.d.ts.map +1 -0
  40. package/dist/recording/types.js +2 -0
  41. package/dist/recording/types.js.map +1 -0
  42. package/dist/sandbox/ModeSelector.d.ts +2 -0
  43. package/dist/sandbox/ModeSelector.d.ts.map +1 -0
  44. package/dist/sandbox/ModeSelector.js +2 -0
  45. package/dist/sandbox/ModeSelector.js.map +1 -0
  46. package/dist/sandbox/config.d.ts +46 -0
  47. package/dist/sandbox/config.d.ts.map +1 -0
  48. package/dist/sandbox/config.js +144 -0
  49. package/dist/sandbox/config.js.map +1 -0
  50. package/dist/sandbox/controller.d.ts +72 -0
  51. package/dist/sandbox/controller.d.ts.map +1 -0
  52. package/dist/sandbox/controller.js +208 -0
  53. package/dist/sandbox/controller.js.map +1 -0
  54. package/dist/sandbox/index.d.ts +6 -0
  55. package/dist/sandbox/index.d.ts.map +1 -0
  56. package/dist/sandbox/index.js +4 -0
  57. package/dist/sandbox/index.js.map +1 -0
  58. package/dist/sandbox/mode-prompt.d.ts +10 -0
  59. package/dist/sandbox/mode-prompt.d.ts.map +1 -0
  60. package/dist/sandbox/mode-prompt.js +130 -0
  61. package/dist/sandbox/mode-prompt.js.map +1 -0
  62. package/dist/sandbox/prompt.d.ts +10 -0
  63. package/dist/sandbox/prompt.d.ts.map +1 -0
  64. package/dist/sandbox/prompt.js +434 -0
  65. package/dist/sandbox/prompt.js.map +1 -0
  66. package/dist/server.d.ts +28 -0
  67. package/dist/server.d.ts.map +1 -0
  68. package/dist/server.js +59 -0
  69. package/dist/server.js.map +1 -0
  70. package/dist/terminal/index.d.ts +5 -0
  71. package/dist/terminal/index.d.ts.map +1 -0
  72. package/dist/terminal/index.js +3 -0
  73. package/dist/terminal/index.js.map +1 -0
  74. package/dist/terminal/manager.d.ts +153 -0
  75. package/dist/terminal/manager.d.ts.map +1 -0
  76. package/dist/terminal/manager.js +276 -0
  77. package/dist/terminal/manager.js.map +1 -0
  78. package/dist/terminal/session.d.ts +137 -0
  79. package/dist/terminal/session.d.ts.map +1 -0
  80. package/dist/terminal/session.js +752 -0
  81. package/dist/terminal/session.js.map +1 -0
  82. package/dist/tools/definitions.d.ts +18 -0
  83. package/dist/tools/definitions.d.ts.map +1 -0
  84. package/dist/tools/definitions.js +114 -0
  85. package/dist/tools/definitions.js.map +1 -0
  86. package/dist/tools/getContent.d.ts +32 -0
  87. package/dist/tools/getContent.d.ts.map +1 -0
  88. package/dist/tools/getContent.js +38 -0
  89. package/dist/tools/getContent.js.map +1 -0
  90. package/dist/tools/index.d.ts +4 -0
  91. package/dist/tools/index.d.ts.map +1 -0
  92. package/dist/tools/index.js +49 -0
  93. package/dist/tools/index.js.map +1 -0
  94. package/dist/tools/screenshot.d.ts +20 -0
  95. package/dist/tools/screenshot.d.ts.map +1 -0
  96. package/dist/tools/screenshot.js +28 -0
  97. package/dist/tools/screenshot.js.map +1 -0
  98. package/dist/tools/sendKey.d.ts +31 -0
  99. package/dist/tools/sendKey.d.ts.map +1 -0
  100. package/dist/tools/sendKey.js +38 -0
  101. package/dist/tools/sendKey.js.map +1 -0
  102. package/dist/tools/startRecording.d.ts +68 -0
  103. package/dist/tools/startRecording.d.ts.map +1 -0
  104. package/dist/tools/startRecording.js +111 -0
  105. package/dist/tools/startRecording.js.map +1 -0
  106. package/dist/tools/stopRecording.d.ts +31 -0
  107. package/dist/tools/stopRecording.d.ts.map +1 -0
  108. package/dist/tools/stopRecording.js +76 -0
  109. package/dist/tools/stopRecording.js.map +1 -0
  110. package/dist/tools/type.d.ts +31 -0
  111. package/dist/tools/type.d.ts.map +1 -0
  112. package/dist/tools/type.js +31 -0
  113. package/dist/tools/type.js.map +1 -0
  114. package/dist/transport/gui-protocol.d.ts +163 -0
  115. package/dist/transport/gui-protocol.d.ts.map +1 -0
  116. package/dist/transport/gui-protocol.js +68 -0
  117. package/dist/transport/gui-protocol.js.map +1 -0
  118. package/dist/transport/gui-stream.d.ts +139 -0
  119. package/dist/transport/gui-stream.d.ts.map +1 -0
  120. package/dist/transport/gui-stream.js +440 -0
  121. package/dist/transport/gui-stream.js.map +1 -0
  122. package/dist/transport/index.d.ts +6 -0
  123. package/dist/transport/index.d.ts.map +1 -0
  124. package/dist/transport/index.js +6 -0
  125. package/dist/transport/index.js.map +1 -0
  126. package/dist/transport/socket.d.ts +46 -0
  127. package/dist/transport/socket.d.ts.map +1 -0
  128. package/dist/transport/socket.js +310 -0
  129. package/dist/transport/socket.js.map +1 -0
  130. package/dist/types/mcp-client-info.d.ts +226 -0
  131. package/dist/types/mcp-client-info.d.ts.map +1 -0
  132. package/dist/types/mcp-client-info.js +62 -0
  133. package/dist/types/mcp-client-info.js.map +1 -0
  134. package/dist/ui/index.d.ts +12 -0
  135. package/dist/ui/index.d.ts.map +1 -0
  136. package/dist/ui/index.js +84 -0
  137. package/dist/ui/index.js.map +1 -0
  138. package/dist/utils/env.d.ts +17 -0
  139. package/dist/utils/env.d.ts.map +1 -0
  140. package/dist/utils/env.js +35 -0
  141. package/dist/utils/env.js.map +1 -0
  142. package/dist/utils/keys.d.ts +16 -0
  143. package/dist/utils/keys.d.ts.map +1 -0
  144. package/dist/utils/keys.js +155 -0
  145. package/dist/utils/keys.js.map +1 -0
  146. package/dist/utils/platform.d.ts +16 -0
  147. package/dist/utils/platform.d.ts.map +1 -0
  148. package/dist/utils/platform.js +41 -0
  149. package/dist/utils/platform.js.map +1 -0
  150. package/dist/utils/session-logger.d.ts +31 -0
  151. package/dist/utils/session-logger.d.ts.map +1 -0
  152. package/dist/utils/session-logger.js +125 -0
  153. package/dist/utils/session-logger.js.map +1 -0
  154. package/dist/utils/stats.d.ts +46 -0
  155. package/dist/utils/stats.d.ts.map +1 -0
  156. package/dist/utils/stats.js +89 -0
  157. package/dist/utils/stats.js.map +1 -0
  158. package/dist/utils/version.d.ts +2 -0
  159. package/dist/utils/version.d.ts.map +1 -0
  160. package/dist/utils/version.js +9 -0
  161. package/dist/utils/version.js.map +1 -0
  162. package/logo.png +0 -0
  163. package/package.json +61 -0
  164. package/packages/desktop-electron/THIRD-PARTY-NOTICES +56 -0
  165. package/packages/desktop-electron/build/afterPack.cjs +147 -0
  166. package/packages/desktop-electron/package-lock.json +10071 -0
  167. package/packages/desktop-electron/package.json +170 -0
  168. package/packages/desktop-electron/resources/icons/mac/icon.icns +0 -0
  169. package/packages/desktop-electron/resources/icons/png/1024x1024.png +0 -0
  170. package/packages/desktop-electron/resources/icons/png/128x128.png +0 -0
  171. package/packages/desktop-electron/resources/icons/png/16x16.png +0 -0
  172. package/packages/desktop-electron/resources/icons/png/24x24.png +0 -0
  173. package/packages/desktop-electron/resources/icons/png/256x256.png +0 -0
  174. package/packages/desktop-electron/resources/icons/png/32x32.png +0 -0
  175. package/packages/desktop-electron/resources/icons/png/48x48.png +0 -0
  176. package/packages/desktop-electron/resources/icons/png/512x512.png +0 -0
  177. package/packages/desktop-electron/resources/icons/png/64x64.png +0 -0
  178. package/packages/desktop-electron/resources/icons/win/icon.ico +0 -0
  179. package/packages/desktop-electron/scripts/download-models.js +97 -0
  180. package/packages/desktop-electron/scripts/prepare-sandbox-bins.js +186 -0
  181. package/packages/desktop-electron/tests/main/ai-detection/additionalFunctions.test.ts +224 -0
  182. package/packages/desktop-electron/tests/main/ai-detection/checkOverridePrefix.test.ts +162 -0
  183. package/packages/desktop-electron/tests/main/ai-detection/classifyInput.test.ts +132 -0
  184. package/packages/desktop-electron/tests/main/ai-detection/detectTypos.test.ts +342 -0
  185. package/packages/desktop-electron/tests/main/ai-detection/fixtures/commands.ts +134 -0
  186. package/packages/desktop-electron/tests/main/ai-detection/fixtures/natural-language.ts +133 -0
  187. package/packages/desktop-electron/tests/main/ai-detection/fixtures/typos.ts +123 -0
  188. package/packages/desktop-electron/tests/main/ai-detection/hasValidSubcommand.test.ts +218 -0
  189. package/packages/desktop-electron/tests/main/ai-detection/isCommandNotFound.test.ts +117 -0
  190. package/packages/desktop-electron/tests/main/error-triage/buildTriagePrompt.test.ts +133 -0
  191. package/packages/desktop-electron/tests/main/error-triage/parseTriageResponse.test.ts +123 -0
  192. package/packages/desktop-electron/tests/main/terminal-bridge/battery-optimization.test.ts +243 -0
  193. package/packages/desktop-electron/tests/main/terminal-bridge/command-fast-track.test.ts +292 -0
  194. package/packages/desktop-electron/tests/main/terminal-bridge/default-cwd.test.ts +70 -0
  195. package/packages/desktop-electron/tests/setup.ts +274 -0
  196. package/packages/desktop-electron/tsconfig.json +18 -0
  197. package/packages/desktop-electron/tsconfig.main.json +20 -0
  198. package/packages/desktop-electron/vite.config.ts +19 -0
  199. package/packages/desktop-electron/vitest.config.ts +18 -0
  200. package/tsconfig.json +19 -0
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Simple stats tracking for terminal MCP sessions
3
+ */
4
+ export class Stats {
5
+ startTime;
6
+ toolCalls;
7
+ totalCalls;
8
+ constructor() {
9
+ this.startTime = Date.now();
10
+ this.toolCalls = new Map();
11
+ this.totalCalls = 0;
12
+ }
13
+ /**
14
+ * Record a tool call
15
+ */
16
+ recordToolCall(toolName) {
17
+ const current = this.toolCalls.get(toolName) || 0;
18
+ this.toolCalls.set(toolName, current + 1);
19
+ this.totalCalls++;
20
+ }
21
+ /**
22
+ * Get uptime in seconds
23
+ */
24
+ getUptimeSeconds() {
25
+ return Math.floor((Date.now() - this.startTime) / 1000);
26
+ }
27
+ /**
28
+ * Get formatted uptime string
29
+ */
30
+ getFormattedUptime() {
31
+ const seconds = this.getUptimeSeconds();
32
+ const hours = Math.floor(seconds / 3600);
33
+ const minutes = Math.floor((seconds % 3600) / 60);
34
+ const secs = seconds % 60;
35
+ if (hours > 0) {
36
+ return `${hours}h ${minutes}m ${secs}s`;
37
+ }
38
+ else if (minutes > 0) {
39
+ return `${minutes}m ${secs}s`;
40
+ }
41
+ else {
42
+ return `${secs}s`;
43
+ }
44
+ }
45
+ /**
46
+ * Get total tool calls
47
+ */
48
+ getTotalCalls() {
49
+ return this.totalCalls;
50
+ }
51
+ /**
52
+ * Get tool calls breakdown
53
+ */
54
+ getToolCallsBreakdown() {
55
+ return new Map(this.toolCalls);
56
+ }
57
+ /**
58
+ * Get stats summary
59
+ */
60
+ getSummary() {
61
+ const toolCalls = {};
62
+ for (const [tool, count] of this.toolCalls) {
63
+ toolCalls[tool] = count;
64
+ }
65
+ return {
66
+ uptime: this.getFormattedUptime(),
67
+ totalCalls: this.totalCalls,
68
+ toolCalls,
69
+ };
70
+ }
71
+ }
72
+ // Global stats instance
73
+ let globalStats = null;
74
+ /**
75
+ * Get or create the global stats instance
76
+ */
77
+ export function getStats() {
78
+ if (!globalStats) {
79
+ globalStats = new Stats();
80
+ }
81
+ return globalStats;
82
+ }
83
+ /**
84
+ * Reset stats (mainly for testing)
85
+ */
86
+ export function resetStats() {
87
+ globalStats = new Stats();
88
+ }
89
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/utils/stats.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,KAAK;IACR,SAAS,CAAS;IAClB,SAAS,CAAsB;IAC/B,UAAU,CAAS;IAE3B;QACE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,CAAC,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,cAAc,CAAC,QAAgB;QAC7B,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,GAAG,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,kBAAkB;QAChB,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,OAAO,GAAG,EAAE,CAAC;QAE1B,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACd,OAAO,GAAG,KAAK,KAAK,OAAO,KAAK,IAAI,GAAG,CAAC;QAC1C,CAAC;aAAM,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,GAAG,OAAO,KAAK,IAAI,GAAG,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,OAAO,GAAG,IAAI,GAAG,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED;;OAEG;IACH,qBAAqB;QACnB,OAAO,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,UAAU;QAKR,MAAM,SAAS,GAA2B,EAAE,CAAC;QAC7C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YAC3C,SAAS,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QAC1B,CAAC;QACD,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE;YACjC,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,SAAS;SACV,CAAC;IACJ,CAAC;CACF;AAED,wBAAwB;AACxB,IAAI,WAAW,GAAiB,IAAI,CAAC;AAErC;;GAEG;AACH,MAAM,UAAU,QAAQ;IACtB,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,WAAW,GAAG,IAAI,KAAK,EAAE,CAAC;IAC5B,CAAC;IACD,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,WAAW,GAAG,IAAI,KAAK,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,OAAO,EAAE,MAAoB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { readFileSync } from "fs";
2
+ import { dirname, join } from "path";
3
+ import { fileURLToPath } from "url";
4
+ // Navigate from dist/utils/version.js to package.json at project root
5
+ const __dirname = dirname(fileURLToPath(import.meta.url));
6
+ const packagePath = join(__dirname, "..", "..", "package.json");
7
+ const pkg = JSON.parse(readFileSync(packagePath, "utf-8"));
8
+ export const VERSION = pkg.version;
9
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,sEAAsE;AACtE,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC;AAEhE,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3D,MAAM,CAAC,MAAM,OAAO,GAAW,GAAG,CAAC,OAAO,CAAC"}
package/logo.png ADDED
Binary file
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "brosh",
3
+ "version": "0.2.2",
4
+ "description": "A modern terminal emulator with built-in AI integration via MCP",
5
+ "author": "Ellery Familia",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/elleryfamilia/brosh.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/elleryfamilia/brosh/issues"
12
+ },
13
+ "homepage": "https://github.com/elleryfamilia/brosh#readme",
14
+ "type": "module",
15
+ "main": "dist/lib.js",
16
+ "bin": {
17
+ "brosh": "dist/index.js"
18
+ },
19
+ "exports": {
20
+ ".": {
21
+ "import": "./dist/lib.js",
22
+ "types": "./dist/lib.d.ts"
23
+ },
24
+ "./cli": {
25
+ "import": "./dist/index.js"
26
+ }
27
+ },
28
+ "scripts": {
29
+ "build": "tsc",
30
+ "dev": "tsx src/index.ts",
31
+ "prepare": "npm run build"
32
+ },
33
+ "dependencies": {
34
+ "@anthropic-ai/sandbox-runtime": "^0.0.32",
35
+ "@modelcontextprotocol/sdk": "^1.0.0",
36
+ "@xterm/headless": "^5.3.0",
37
+ "ink": "^5.0.1",
38
+ "node-pty": "^1.2.0-beta.8",
39
+ "react": "^18.3.1",
40
+ "zod": "^3.23.0"
41
+ },
42
+ "devDependencies": {
43
+ "@types/node": "^20.0.0",
44
+ "@types/react": "^18.3.12",
45
+ "tsx": "^4.0.0",
46
+ "typescript": "^5.0.0"
47
+ },
48
+ "engines": {
49
+ "node": ">=18.0.0"
50
+ },
51
+ "keywords": [
52
+ "mcp",
53
+ "terminal",
54
+ "pty",
55
+ "xterm",
56
+ "ai",
57
+ "claude",
58
+ "brosh"
59
+ ],
60
+ "license": "MIT"
61
+ }
@@ -0,0 +1,56 @@
1
+ Third-Party Notices
2
+ ====================
3
+
4
+ The brosh desktop application bundles the following third-party binaries
5
+ on Linux. These are executed as separate child processes and are not
6
+ linked into the application code.
7
+
8
+ ----------------------------------------------------------------------
9
+
10
+ socat - Multipurpose relay (SOcket CAT)
11
+ http://www.dest-unreach.org/socat/
12
+
13
+ Copyright (c) 2001-2024 Gerhard Rieger
14
+
15
+ License: GNU General Public License, version 2 (GPL-2.0)
16
+
17
+ This program is free software; you can redistribute it and/or modify
18
+ it under the terms of the GNU General Public License as published by
19
+ the Free Software Foundation; either version 2 of the License, or
20
+ (at your option) any later version.
21
+
22
+ This program is distributed in the hope that it will be useful,
23
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
24
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
+ GNU General Public License for more details.
26
+
27
+ You should have received a copy of the GNU General Public License
28
+ along with this program; if not, see <https://www.gnu.org/licenses/>.
29
+
30
+ Source code: http://www.dest-unreach.org/socat/
31
+
32
+ ----------------------------------------------------------------------
33
+
34
+ bubblewrap (bwrap) - Unprivileged sandboxing tool
35
+ https://github.com/containers/bubblewrap
36
+
37
+ Copyright (c) 2016 Alexander Larsson
38
+ Copyright (c) 2016 Colin Walters
39
+
40
+ License: GNU Lesser General Public License, version 2.1 (LGPL-2.1)
41
+
42
+ This library is free software; you can redistribute it and/or modify
43
+ it under the terms of the GNU Lesser General Public License as
44
+ published by the Free Software Foundation; either version 2.1 of the
45
+ License, or (at your option) any later version.
46
+
47
+ This library is distributed in the hope that it will be useful,
48
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
49
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
50
+ GNU Lesser General Public License for more details.
51
+
52
+ You should have received a copy of the GNU Lesser General Public
53
+ License along with this library; if not, see
54
+ <https://www.gnu.org/licenses/>.
55
+
56
+ Source code: https://github.com/containers/bubblewrap
@@ -0,0 +1,147 @@
1
+ // afterPack hook for electron-builder
2
+ // Strips cross-platform native binaries to reduce package size.
3
+ //
4
+ // Target platforms: macOS (x64, arm64), Linux (x64, arm64)
5
+
6
+ const fs = require("fs");
7
+ const path = require("path");
8
+
9
+ // electron-builder arch enum: 0=ia32, 1=x64, 2=armv7l, 3=arm64, 4=universal
10
+ const ARCH_MAP = {
11
+ 0: "ia32",
12
+ 1: "x64",
13
+ 2: "armv7l",
14
+ 3: "arm64",
15
+ 4: "universal",
16
+ };
17
+
18
+ function getResourcesDir(context) {
19
+ // macOS: <appOutDir>/<productName>.app/Contents/Resources/
20
+ // Linux/Windows: <appOutDir>/resources/
21
+ if (context.electronPlatformName === "darwin") {
22
+ const appName =
23
+ context.packager.appInfo.productFilename || context.packager.appInfo.name;
24
+ return path.join(context.appOutDir, `${appName}.app`, "Contents", "Resources");
25
+ }
26
+ return path.join(context.appOutDir, "resources");
27
+ }
28
+
29
+ function rmSyncSafe(dirPath) {
30
+ if (fs.existsSync(dirPath)) {
31
+ fs.rmSync(dirPath, { recursive: true, force: true });
32
+ return true;
33
+ }
34
+ return false;
35
+ }
36
+
37
+ function dirSize(dirPath) {
38
+ let total = 0;
39
+ if (!fs.existsSync(dirPath)) return 0;
40
+ for (const entry of fs.readdirSync(dirPath, { withFileTypes: true })) {
41
+ const entryPath = path.join(dirPath, entry.name);
42
+ if (entry.isDirectory()) {
43
+ total += dirSize(entryPath);
44
+ } else {
45
+ total += fs.statSync(entryPath).size;
46
+ }
47
+ }
48
+ return total;
49
+ }
50
+
51
+ function formatMB(bytes) {
52
+ return (bytes / 1024 / 1024).toFixed(1) + "MB";
53
+ }
54
+
55
+ function stripOnnxruntimeNode(resourcesDir, platform, arch) {
56
+ const onnxBinDir = path.join(
57
+ resourcesDir,
58
+ "app.asar.unpacked/node_modules/onnxruntime-node/bin/napi-v3"
59
+ );
60
+ if (!fs.existsSync(onnxBinDir)) return 0;
61
+
62
+ let removed = 0;
63
+ for (const platformDir of fs.readdirSync(onnxBinDir)) {
64
+ const platformPath = path.join(onnxBinDir, platformDir);
65
+ if (!fs.statSync(platformPath).isDirectory()) continue;
66
+
67
+ if (platformDir !== platform) {
68
+ const size = dirSize(platformPath);
69
+ rmSyncSafe(platformPath);
70
+ console.log(` removed onnxruntime-node/${platformDir} (${formatMB(size)})`);
71
+ removed += size;
72
+ } else {
73
+ for (const archDir of fs.readdirSync(platformPath)) {
74
+ const archPath = path.join(platformPath, archDir);
75
+ if (!fs.statSync(archPath).isDirectory()) continue;
76
+ if (archDir !== arch) {
77
+ const size = dirSize(archPath);
78
+ rmSyncSafe(archPath);
79
+ console.log(` removed onnxruntime-node/${platformDir}/${archDir} (${formatMB(size)})`);
80
+ removed += size;
81
+ }
82
+ }
83
+ }
84
+ }
85
+ return removed;
86
+ }
87
+
88
+ function stripOnnxruntimeWeb(resourcesDir) {
89
+ // onnxruntime-web is only needed for browser/WASM contexts.
90
+ // We use onnxruntime-node for main process ML inference, so this is dead weight.
91
+ const loc = path.join(
92
+ resourcesDir,
93
+ "app.asar.unpacked/node_modules/onnxruntime-web"
94
+ );
95
+ const size = dirSize(loc);
96
+ if (rmSyncSafe(loc)) {
97
+ console.log(` removed onnxruntime-web (${formatMB(size)})`);
98
+ return size;
99
+ }
100
+ return 0;
101
+ }
102
+
103
+ function stripSharpPlatformModules(resourcesDir, platform, arch) {
104
+ const unpackedModules = path.join(
105
+ resourcesDir,
106
+ "app.asar.unpacked/node_modules"
107
+ );
108
+ if (!fs.existsSync(unpackedModules)) return 0;
109
+
110
+ const targetSuffix = `${platform}-${arch}`;
111
+ let removed = 0;
112
+
113
+ for (const dir of fs.readdirSync(unpackedModules)) {
114
+ if (!dir.startsWith("@img")) continue;
115
+ const imgDir = path.join(unpackedModules, dir);
116
+ if (!fs.statSync(imgDir).isDirectory()) continue;
117
+ for (const sub of fs.readdirSync(imgDir)) {
118
+ const subPath = path.join(imgDir, sub);
119
+ if (!fs.statSync(subPath).isDirectory()) continue;
120
+ if (!sub.startsWith("sharp-")) continue;
121
+ if (!sub.includes(targetSuffix)) {
122
+ const size = dirSize(subPath);
123
+ rmSyncSafe(subPath);
124
+ console.log(` removed @img/${sub} (${formatMB(size)})`);
125
+ removed += size;
126
+ }
127
+ }
128
+ }
129
+ return removed;
130
+ }
131
+
132
+ exports.default = async function afterPack(context) {
133
+ const platform = context.electronPlatformName;
134
+ const arch = ARCH_MAP[context.arch] || "x64";
135
+ const resourcesDir = getResourcesDir(context);
136
+
137
+ console.log(`\n afterPack: stripping binaries for ${platform}/${arch}`);
138
+ console.log(` afterPack: resources at ${resourcesDir}`);
139
+
140
+ let totalSaved = 0;
141
+
142
+ totalSaved += stripOnnxruntimeNode(resourcesDir, platform, arch);
143
+ totalSaved += stripOnnxruntimeWeb(resourcesDir);
144
+ totalSaved += stripSharpPlatformModules(resourcesDir, platform, arch);
145
+
146
+ console.log(` afterPack: total saved ${formatMB(totalSaved)}\n`);
147
+ };