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
package/dist/lib.js ADDED
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Library Exports
3
+ *
4
+ * This file exports all public APIs for use as a library.
5
+ * The main index.ts is the CLI entry point; this file is for programmatic usage.
6
+ */
7
+ // Terminal management
8
+ export { TerminalSession, TerminalManager } from "./terminal/index.js";
9
+ // Transport layer - GUI streaming
10
+ export { GUIOutputStream, createGUIOutputStream, } from "./transport/index.js";
11
+ // GUI protocol types
12
+ export { encodeData, decodeData, isGuiMessageToBackend, isGuiMessageToFrontend, } from "./transport/index.js";
13
+ // Socket transport
14
+ export { SocketTransport, createSocketServer, createToolProxyServer, isSocketInUse, checkSocketAndWarn, } from "./transport/index.js";
15
+ // Recording
16
+ export { RecordingManager } from "./recording/index.js";
17
+ // Utilities
18
+ export { getDefaultShell, getDefaultSocketPath, getDefaultRecordDir } from "./utils/platform.js";
19
+ export { getKeySequence, KEY_SEQUENCES, getAvailableKeys } from "./utils/keys.js";
20
+ // Sandbox/Mode selection
21
+ export { promptForMode } from "./sandbox/mode-prompt.js";
22
+ export { promptForPermissions } from "./sandbox/prompt.js";
23
+ export { SandboxController, loadConfigFromFile, DEFAULT_PERMISSIONS } from "./sandbox/index.js";
24
+ // MCP Client Info types
25
+ export { ClientInfoSchema, RuntimeInfoSchema, CapabilitiesSchema, SessionMetadataSchema, ObservabilitySchema, ExtendedClientInfoSchema, generateClientId, } from "./types/mcp-client-info.js";
26
+ // Session logging
27
+ export { SessionLogger } from "./utils/session-logger.js";
28
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sBAAsB;AACtB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AASvE,kCAAkC;AAClC,OAAO,EACL,eAAe,EACf,qBAAqB,GACtB,MAAM,sBAAsB,CAAC;AAM9B,qBAAqB;AACrB,OAAO,EACL,UAAU,EACV,UAAU,EACV,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,sBAAsB,CAAC;AAuB9B,mBAAmB;AACnB,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,GACnB,MAAM,sBAAsB,CAAC;AAE9B,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAQxD,YAAY;AACZ,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAElF,yBAAyB;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGhG,wBAAwB;AACxB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,wBAAwB,EACxB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AAepC,kBAAkB;AAClB,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Standalone mode selector - minimal script for GUI wrapper
4
+ * Outputs JSON: {"mode": "direct"|"sandbox"} or {"mode": null, "cancelled": true}
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=mode-selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-selector.d.ts","sourceRoot":"","sources":["../src/mode-selector.ts"],"names":[],"mappings":";AACA;;;GAGG"}
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Standalone mode selector - minimal script for GUI wrapper
4
+ * Outputs JSON: {"mode": "direct"|"sandbox"} or {"mode": null, "cancelled": true}
5
+ */
6
+ // ANSI escape codes
7
+ const ESC = "\x1b";
8
+ const CURSOR_HIDE = `${ESC}[?25l`;
9
+ const CURSOR_SHOW = `${ESC}[?25h`;
10
+ const CLEAR_SCREEN = `${ESC}[2J`;
11
+ const CURSOR_HOME = `${ESC}[H`;
12
+ const CURSOR_TO = (row, col) => `${ESC}[${row};${col}H`;
13
+ // Colors
14
+ const BOLD = `${ESC}[1m`;
15
+ const DIM = `${ESC}[2m`;
16
+ const RESET = `${ESC}[0m`;
17
+ const GREEN = `${ESC}[32m`;
18
+ const YELLOW = `${ESC}[33m`;
19
+ const GRAY = `${ESC}[90m`;
20
+ const WHITE = `${ESC}[97m`;
21
+ // Box drawing
22
+ const BOX = {
23
+ topLeft: "╭",
24
+ topRight: "╮",
25
+ bottomLeft: "╰",
26
+ bottomRight: "╯",
27
+ horizontal: "─",
28
+ vertical: "│",
29
+ };
30
+ // Helper to pad string, handling negative values
31
+ const pad = (n) => " ".repeat(Math.max(0, n));
32
+ const repeat = (s, n) => s.repeat(Math.max(0, n));
33
+ async function main() {
34
+ // Check if we can use raw mode
35
+ if (typeof process.stdin.setRawMode !== 'function') {
36
+ console.log(JSON.stringify({ mode: 'direct' }));
37
+ process.exit(0);
38
+ }
39
+ let selected = 'direct';
40
+ const boxWidth = 38;
41
+ try {
42
+ process.stdin.setRawMode(true);
43
+ process.stdin.resume();
44
+ process.stdin.setEncoding("utf8");
45
+ }
46
+ catch {
47
+ console.log(JSON.stringify({ mode: 'direct' }));
48
+ process.exit(0);
49
+ }
50
+ // Get terminal size
51
+ const cols = process.stdout.columns || 80;
52
+ const rows = process.stdout.rows || 24;
53
+ // Calculate center position
54
+ const startCol = Math.max(1, Math.floor((cols - boxWidth) / 2));
55
+ const startRow = Math.max(1, Math.floor((rows - 10) / 2));
56
+ const render = () => {
57
+ const output = [];
58
+ output.push(CLEAR_SCREEN + CURSOR_HOME + CURSOR_HIDE);
59
+ const innerWidth = boxWidth - 2;
60
+ const lines = [];
61
+ // Title bar
62
+ const title = " Terminal Mode ";
63
+ const titlePadLeft = Math.floor((innerWidth - title.length) / 2);
64
+ const titlePadRight = innerWidth - titlePadLeft - title.length;
65
+ lines.push(`${YELLOW}${BOX.topLeft}${repeat(BOX.horizontal, titlePadLeft)}${WHITE}${BOLD}${title}${RESET}${YELLOW}${repeat(BOX.horizontal, titlePadRight)}${BOX.topRight}${RESET}`);
66
+ // Empty line
67
+ lines.push(`${YELLOW}${BOX.vertical}${RESET}${pad(innerWidth)}${YELLOW}${BOX.vertical}${RESET}`);
68
+ // Standard option
69
+ const stdSelected = selected === 'direct';
70
+ const stdBullet = stdSelected ? `${GREEN}●${RESET}` : `${GRAY}○${RESET}`;
71
+ const stdLabel = stdSelected ? `${WHITE}${BOLD}Standard${RESET}` : `${GRAY}Standard${RESET}`;
72
+ const stdContent = ` ${stdBullet} ${stdLabel}`;
73
+ // Account for ANSI codes in length calculation
74
+ const stdVisibleLen = 2 + 1 + 1 + 8; // " " + bullet + " " + "Standard"
75
+ lines.push(`${YELLOW}${BOX.vertical}${RESET}${stdContent}${pad(innerWidth - stdVisibleLen)}${YELLOW}${BOX.vertical}${RESET}`);
76
+ // Standard description
77
+ const stdDesc = "full access to resources";
78
+ lines.push(`${YELLOW}${BOX.vertical}${RESET} ${DIM}${stdDesc}${RESET}${pad(innerWidth - 6 - stdDesc.length)}${YELLOW}${BOX.vertical}${RESET}`);
79
+ // Empty line
80
+ lines.push(`${YELLOW}${BOX.vertical}${RESET}${pad(innerWidth)}${YELLOW}${BOX.vertical}${RESET}`);
81
+ // Sandboxed option
82
+ const sbxSelected = selected === 'sandbox';
83
+ const sbxBullet = sbxSelected ? `${GREEN}●${RESET}` : `${GRAY}○${RESET}`;
84
+ const sbxLabel = sbxSelected ? `${WHITE}${BOLD}Sandboxed${RESET}` : `${GRAY}Sandboxed${RESET}`;
85
+ const sbxContent = ` ${sbxBullet} ${sbxLabel}`;
86
+ const sbxVisibleLen = 2 + 1 + 1 + 9; // " " + bullet + " " + "Sandboxed"
87
+ lines.push(`${YELLOW}${BOX.vertical}${RESET}${sbxContent}${pad(innerWidth - sbxVisibleLen)}${YELLOW}${BOX.vertical}${RESET}`);
88
+ // Sandboxed description
89
+ const sbxDesc = "restricted access with controls";
90
+ lines.push(`${YELLOW}${BOX.vertical}${RESET} ${DIM}${sbxDesc}${RESET}${pad(innerWidth - 6 - sbxDesc.length)}${YELLOW}${BOX.vertical}${RESET}`);
91
+ // Empty line
92
+ lines.push(`${YELLOW}${BOX.vertical}${RESET}${pad(innerWidth)}${YELLOW}${BOX.vertical}${RESET}`);
93
+ // Bottom border
94
+ lines.push(`${YELLOW}${BOX.bottomLeft}${repeat(BOX.horizontal, innerWidth)}${BOX.bottomRight}${RESET}`);
95
+ for (let i = 0; i < lines.length; i++) {
96
+ output.push(CURSOR_TO(startRow + i, startCol) + lines[i]);
97
+ }
98
+ process.stdout.write(output.join(''));
99
+ };
100
+ const cleanup = () => {
101
+ try {
102
+ process.stdin.setRawMode(false);
103
+ process.stdin.pause();
104
+ process.stdin.removeAllListeners("data");
105
+ process.stdout.write(CLEAR_SCREEN + CURSOR_HOME + CURSOR_SHOW);
106
+ }
107
+ catch {
108
+ // Ignore
109
+ }
110
+ };
111
+ render();
112
+ process.stdin.on("data", (key) => {
113
+ if (key === "\r" || key === "\n") {
114
+ cleanup();
115
+ console.log(JSON.stringify({ mode: selected }));
116
+ process.exit(0);
117
+ }
118
+ else if (key === "\x1b[A" || key === "k" || key === "1") {
119
+ selected = 'direct';
120
+ render();
121
+ }
122
+ else if (key === "\x1b[B" || key === "j" || key === "2") {
123
+ selected = 'sandbox';
124
+ render();
125
+ }
126
+ else if (key === "\x03" || key === "q") {
127
+ cleanup();
128
+ console.log(JSON.stringify({ mode: null, cancelled: true }));
129
+ process.exit(0);
130
+ }
131
+ });
132
+ }
133
+ main().catch((err) => {
134
+ console.error(err);
135
+ process.exit(1);
136
+ });
137
+ export {};
138
+ //# sourceMappingURL=mode-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mode-selector.js","sourceRoot":"","sources":["../src/mode-selector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
2
+ export declare function registerPrompts(server: Server): void;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AA+DnE,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAwBpD"}
@@ -0,0 +1,79 @@
1
+ import { ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
2
+ const TOOL_USAGE_PROMPT = `# brosh Tool Usage Guide
3
+
4
+ ## Overview
5
+ This MCP server provides tools to interact with a terminal emulator. Use these tools to execute commands and read output.
6
+
7
+ ## Tools
8
+
9
+ ### type
10
+ Send text input to the terminal. Text is written exactly as provided - no Enter key is sent automatically.
11
+
12
+ To execute a command, use type() followed by sendKey('Enter').
13
+
14
+ **Example workflow:**
15
+ 1. type('ls -la') - types the command
16
+ 2. sendKey('Enter') - executes it
17
+ 3. getContent() - reads the output
18
+
19
+ ### sendKey
20
+ Send a special key or key combination to the terminal.
21
+
22
+ **Common keys:** Enter, Tab, Escape, Backspace, Delete, ArrowUp, ArrowDown, ArrowLeft, ArrowRight
23
+
24
+ **Navigation:** Home, End, PageUp, PageDown
25
+
26
+ **Control sequences:**
27
+ - Ctrl+C - interrupt current process
28
+ - Ctrl+D - EOF/exit
29
+ - Ctrl+Z - suspend process
30
+ - Ctrl+L - clear screen
31
+ - Ctrl+A - move to start of line
32
+ - Ctrl+E - move to end of line
33
+
34
+ **Function keys:** F1-F12
35
+
36
+ ### getContent
37
+ Get terminal content as plain text. Use after sending commands to see output.
38
+
39
+ Returns full scrollback buffer by default (up to 1000 lines). Set visibleOnly=true for just the current viewport (useful when output is very long).
40
+
41
+ Prefer this over takeScreenshot when you only need text content.
42
+
43
+ ### takeScreenshot
44
+ Capture terminal state as structured JSON with:
45
+ - content: visible text
46
+ - cursor: {x, y} position
47
+ - dimensions: {cols, rows}
48
+
49
+ Use when you need cursor position (e.g., for interactive apps, editors) or terminal dimensions. For simple command output, prefer getContent().
50
+ `;
51
+ const prompts = [
52
+ {
53
+ name: "tool-usage",
54
+ description: "Instructions for effectively using brosh tools",
55
+ },
56
+ ];
57
+ export function registerPrompts(server) {
58
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
59
+ prompts,
60
+ }));
61
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
62
+ const { name } = request.params;
63
+ if (name === "tool-usage") {
64
+ return {
65
+ messages: [
66
+ {
67
+ role: "user",
68
+ content: {
69
+ type: "text",
70
+ text: TOOL_USAGE_PROMPT,
71
+ },
72
+ },
73
+ ],
74
+ };
75
+ }
76
+ throw new Error(`Unknown prompt: ${name}`);
77
+ });
78
+ }
79
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/prompts/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,sBAAsB,GACvB,MAAM,oCAAoC,CAAC;AAE5C,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDzB,CAAC;AAEF,MAAM,OAAO,GAAG;IACd;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,gDAAgD;KAC9D;CACF,CAAC;AAEF,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC9D,OAAO;KACR,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QACjE,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAEhC,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;YAC1B,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,IAAI,EAAE,MAAe;wBACrB,OAAO,EAAE;4BACP,IAAI,EAAE,MAAe;4BACrB,IAAI,EAAE,iBAAiB;yBACxB;qBACF;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,KAAK,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { Recorder } from "./recorder.js";
2
+ export { RecordingManager } from "./manager.js";
3
+ export type { RecordingMode, RecordingFormat, RecordingOptions, AsciicastHeader, AsciicastEvent, AsciicastOutputEvent, AsciicastResizeEvent, RecordingMetadata, StopReason, } from "./types.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recording/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,YAAY,EACV,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,GACX,MAAM,YAAY,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { Recorder } from "./recorder.js";
2
+ export { RecordingManager } from "./manager.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/recording/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { Recorder } from "./recorder.js";
2
+ import { RecordingMode, RecordingOptions, RecordingMetadata, StopReason } from "./types.js";
3
+ /**
4
+ * RecordingManager tracks and manages multiple recordings
5
+ */
6
+ export declare class RecordingManager {
7
+ private recordings;
8
+ private defaultOptions;
9
+ constructor(options?: Partial<RecordingOptions>);
10
+ /**
11
+ * Create a new recording
12
+ * Returns the recorder instance
13
+ */
14
+ createRecording(options?: Partial<RecordingOptions>): Recorder;
15
+ /**
16
+ * Get a recording by ID
17
+ */
18
+ getRecording(id: string): Recorder | undefined;
19
+ /**
20
+ * Check if a recording exists
21
+ */
22
+ hasRecording(id: string): boolean;
23
+ /**
24
+ * Get all active recordings
25
+ */
26
+ getActiveRecordings(): Recorder[];
27
+ /**
28
+ * Get the count of active recordings
29
+ */
30
+ getActiveCount(): number;
31
+ /**
32
+ * Record output to all active recordings
33
+ */
34
+ recordOutputToAll(data: string): void;
35
+ /**
36
+ * Record resize to all active recordings
37
+ */
38
+ recordResizeToAll(cols: number, rows: number): void;
39
+ /**
40
+ * Finalize a specific recording
41
+ */
42
+ finalizeRecording(id: string, exitCode: number | null, stopReason?: StopReason): Promise<RecordingMetadata | undefined>;
43
+ /**
44
+ * Finalize all active recordings
45
+ * Returns array of metadata for all finalized recordings
46
+ */
47
+ finalizeAll(exitCode: number | null, stopReason?: StopReason): Promise<RecordingMetadata[]>;
48
+ /**
49
+ * Get default recording mode
50
+ */
51
+ getDefaultMode(): RecordingMode;
52
+ /**
53
+ * Get default output directory
54
+ */
55
+ getDefaultOutputDir(): string;
56
+ /**
57
+ * Check if auto-recording is enabled (mode !== 'off')
58
+ */
59
+ isAutoRecordingEnabled(): boolean;
60
+ private generateId;
61
+ }
62
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/recording/manager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EACL,aAAa,EAEb,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACX,MAAM,YAAY,CAAC;AAGpB;;GAEG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,UAAU,CAAoC;IACtD,OAAO,CAAC,cAAc,CAAmB;gBAE7B,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAW/C;;;OAGG;IACH,eAAe,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GAAG,QAAQ;IAqB9D;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAI9C;;OAEG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAIjC;;OAEG;IACH,mBAAmB,IAAI,QAAQ,EAAE;IAIjC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMrC;;OAEG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAMnD;;OAEG;IACG,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC;IAW7H;;;OAGG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,GAAE,UAA2B,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAcjH;;OAEG;IACH,cAAc,IAAI,aAAa;IAI/B;;OAEG;IACH,mBAAmB,IAAI,MAAM;IAI7B;;OAEG;IACH,sBAAsB,IAAI,OAAO;IAIjC,OAAO,CAAC,UAAU;CAGnB"}
@@ -0,0 +1,123 @@
1
+ import * as crypto from "crypto";
2
+ import { Recorder } from "./recorder.js";
3
+ import { getDefaultRecordDir } from "../utils/platform.js";
4
+ /**
5
+ * RecordingManager tracks and manages multiple recordings
6
+ */
7
+ export class RecordingManager {
8
+ recordings = new Map();
9
+ defaultOptions;
10
+ constructor(options) {
11
+ this.defaultOptions = {
12
+ mode: options?.mode ?? 'off',
13
+ format: options?.format ?? 'v2',
14
+ outputDir: options?.outputDir ?? getDefaultRecordDir(),
15
+ idleTimeLimit: options?.idleTimeLimit ?? 2,
16
+ maxDuration: options?.maxDuration ?? 3600, // 60 minutes default
17
+ inactivityTimeout: options?.inactivityTimeout ?? 600, // 10 minutes default
18
+ };
19
+ }
20
+ /**
21
+ * Create a new recording
22
+ * Returns the recorder instance
23
+ */
24
+ createRecording(options) {
25
+ const id = this.generateId();
26
+ const mergedOptions = {
27
+ ...this.defaultOptions,
28
+ ...options,
29
+ };
30
+ const recorder = new Recorder(id, mergedOptions.mode, mergedOptions.outputDir, mergedOptions.format, mergedOptions.idleTimeLimit, mergedOptions.maxDuration, mergedOptions.inactivityTimeout);
31
+ this.recordings.set(id, recorder);
32
+ return recorder;
33
+ }
34
+ /**
35
+ * Get a recording by ID
36
+ */
37
+ getRecording(id) {
38
+ return this.recordings.get(id);
39
+ }
40
+ /**
41
+ * Check if a recording exists
42
+ */
43
+ hasRecording(id) {
44
+ return this.recordings.has(id);
45
+ }
46
+ /**
47
+ * Get all active recordings
48
+ */
49
+ getActiveRecordings() {
50
+ return Array.from(this.recordings.values()).filter(r => r.isActive());
51
+ }
52
+ /**
53
+ * Get the count of active recordings
54
+ */
55
+ getActiveCount() {
56
+ return this.getActiveRecordings().length;
57
+ }
58
+ /**
59
+ * Record output to all active recordings
60
+ */
61
+ recordOutputToAll(data) {
62
+ for (const recorder of this.getActiveRecordings()) {
63
+ recorder.recordOutput(data);
64
+ }
65
+ }
66
+ /**
67
+ * Record resize to all active recordings
68
+ */
69
+ recordResizeToAll(cols, rows) {
70
+ for (const recorder of this.getActiveRecordings()) {
71
+ recorder.recordResize(cols, rows);
72
+ }
73
+ }
74
+ /**
75
+ * Finalize a specific recording
76
+ */
77
+ async finalizeRecording(id, exitCode, stopReason) {
78
+ const recorder = this.recordings.get(id);
79
+ if (!recorder) {
80
+ return undefined;
81
+ }
82
+ const metadata = await recorder.finalize(exitCode, stopReason);
83
+ this.recordings.delete(id);
84
+ return metadata;
85
+ }
86
+ /**
87
+ * Finalize all active recordings
88
+ * Returns array of metadata for all finalized recordings
89
+ */
90
+ async finalizeAll(exitCode, stopReason = 'session_exit') {
91
+ const results = [];
92
+ for (const [id, recorder] of this.recordings) {
93
+ if (recorder.isActive()) {
94
+ const metadata = await recorder.finalize(exitCode, stopReason);
95
+ results.push(metadata);
96
+ }
97
+ this.recordings.delete(id);
98
+ }
99
+ return results;
100
+ }
101
+ /**
102
+ * Get default recording mode
103
+ */
104
+ getDefaultMode() {
105
+ return this.defaultOptions.mode;
106
+ }
107
+ /**
108
+ * Get default output directory
109
+ */
110
+ getDefaultOutputDir() {
111
+ return this.defaultOptions.outputDir;
112
+ }
113
+ /**
114
+ * Check if auto-recording is enabled (mode !== 'off')
115
+ */
116
+ isAutoRecordingEnabled() {
117
+ return this.defaultOptions.mode !== 'off';
118
+ }
119
+ generateId() {
120
+ return crypto.randomBytes(8).toString('hex');
121
+ }
122
+ }
123
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/recording/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ import type { RecordingMode, RecordingFormat, RecordingMetadata, StopReason } from "./types.js";
2
+ /**
3
+ * Recorder handles writing asciicast v2 format recordings
4
+ *
5
+ * Asciicast v2 format:
6
+ * - First line: JSON header with version, dimensions, timestamp
7
+ * - Subsequent lines: JSON arrays [time, type, data]
8
+ * - time: seconds since start (float)
9
+ * - type: "o" for output, "r" for resize
10
+ * - data: string content
11
+ */
12
+ export declare class Recorder {
13
+ readonly id: string;
14
+ private mode;
15
+ private format;
16
+ private outputDir;
17
+ private tempPath;
18
+ private finalPath;
19
+ private writeStream;
20
+ private startTime;
21
+ private bytesWritten;
22
+ private finalized;
23
+ private idleTimeLimit;
24
+ private lastEventTime;
25
+ private adjustedElapsed;
26
+ private maxDuration;
27
+ private inactivityTimeout;
28
+ private maxDurationTimer;
29
+ private inactivityTimer;
30
+ private stopReason;
31
+ private onAutoFinalize?;
32
+ constructor(id: string, mode: RecordingMode, outputDir: string, format?: RecordingFormat, idleTimeLimit?: number, maxDuration?: number, // 60 minutes default
33
+ inactivityTimeout?: number);
34
+ /**
35
+ * Start the recording
36
+ * Writes the asciicast header to the temp file
37
+ */
38
+ start(width: number, height: number, env?: {
39
+ SHELL?: string;
40
+ TERM?: string;
41
+ }): void;
42
+ /**
43
+ * Record output data
44
+ */
45
+ recordOutput(data: string): void;
46
+ /**
47
+ * Record terminal resize event
48
+ */
49
+ recordResize(cols: number, rows: number): void;
50
+ /**
51
+ * Finalize the recording
52
+ * - For 'always' mode: move temp file to output dir
53
+ * - For 'on-failure' mode: move if exitCode !== 0, delete otherwise
54
+ *
55
+ * Returns metadata about the recording
56
+ */
57
+ finalize(exitCode: number | null, stopReason?: StopReason): Promise<RecordingMetadata>;
58
+ /**
59
+ * Check if recording is active
60
+ */
61
+ isActive(): boolean;
62
+ /**
63
+ * Get the temp file path (for debugging/testing)
64
+ */
65
+ getTempPath(): string;
66
+ /**
67
+ * Get the final file path
68
+ */
69
+ getFinalPath(): string;
70
+ private getElapsedSeconds;
71
+ private writeLine;
72
+ /**
73
+ * Clear all active timers
74
+ */
75
+ private clearTimers;
76
+ /**
77
+ * Auto-finalize the recording due to timeout
78
+ * Called internally when max duration or inactivity timeout is reached
79
+ */
80
+ private _autoFinalize;
81
+ /**
82
+ * Set callback for auto-finalize events (timeout triggered)
83
+ */
84
+ setOnAutoFinalize(callback: (metadata: RecordingMetadata) => void): void;
85
+ /**
86
+ * Get timeout configuration and remaining time
87
+ */
88
+ getTimeoutInfo(): {
89
+ maxDuration: number;
90
+ inactivityTimeout: number;
91
+ elapsedSeconds: number;
92
+ remainingMaxDuration: number;
93
+ };
94
+ }
95
+ //# sourceMappingURL=recorder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../src/recording/recorder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EAGf,iBAAiB,EACjB,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;GASG;AACH,qBAAa,QAAQ;IACnB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,eAAe,CAAa;IAGpC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,gBAAgB,CAA8C;IACtE,OAAO,CAAC,eAAe,CAA8C;IACrE,OAAO,CAAC,UAAU,CAA0B;IAG5C,OAAO,CAAC,cAAc,CAAC,CAAwC;gBAG7D,EAAE,EAAE,MAAM,EACV,IAAI,EAAE,aAAa,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,eAAsB,EAC9B,aAAa,GAAE,MAAU,EACzB,WAAW,GAAE,MAAa,EAAS,qBAAqB;IACxD,iBAAiB,GAAE,MAAY;IAiBjC;;;OAGG;IACH,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IA8CnF;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAoBhC;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAU9C;;;;;;OAMG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA8G5F;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,YAAY,IAAI,MAAM;IAItB,OAAO,CAAC,iBAAiB;IA0BzB,OAAO,CAAC,SAAS;IAQjB;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;;OAGG;YACW,aAAa;IAc3B;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,iBAAiB,KAAK,IAAI,GAAG,IAAI;IAIxE;;OAEG;IACH,cAAc,IAAI;QAChB,WAAW,EAAE,MAAM,CAAC;QACpB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC;QACvB,oBAAoB,EAAE,MAAM,CAAC;KAC9B;CAWF"}