tjbot-ce 3.0.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 (224) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +382 -0
  3. package/dist/camera/camera.d.ts +62 -0
  4. package/dist/camera/camera.d.ts.map +1 -0
  5. package/dist/camera/camera.js +155 -0
  6. package/dist/camera/camera.js.map +1 -0
  7. package/dist/camera/index.d.ts +18 -0
  8. package/dist/camera/index.d.ts.map +1 -0
  9. package/dist/camera/index.js +18 -0
  10. package/dist/camera/index.js.map +1 -0
  11. package/dist/config/config-types.d.ts +75 -0
  12. package/dist/config/config-types.d.ts.map +1 -0
  13. package/dist/config/config-types.generated.d.ts +495 -0
  14. package/dist/config/config-types.generated.d.ts.map +1 -0
  15. package/dist/config/config-types.generated.js +2 -0
  16. package/dist/config/config-types.generated.js.map +1 -0
  17. package/dist/config/config-types.js +175 -0
  18. package/dist/config/config-types.js.map +1 -0
  19. package/dist/config/index.d.ts +20 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +19 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/tjbot-config.d.ts +98 -0
  24. package/dist/config/tjbot-config.d.ts.map +1 -0
  25. package/dist/config/tjbot-config.js +309 -0
  26. package/dist/config/tjbot-config.js.map +1 -0
  27. package/dist/config/vendor/colors.yaml +61 -0
  28. package/dist/config/vendor/model-registry.yaml +275 -0
  29. package/dist/config/vendor/tjbot-config.schema.yaml +792 -0
  30. package/dist/config/vendor/tjbot.default.toml +452 -0
  31. package/dist/led/index.d.ts +20 -0
  32. package/dist/led/index.d.ts.map +1 -0
  33. package/dist/led/index.js +20 -0
  34. package/dist/led/index.js.map +1 -0
  35. package/dist/led/led-common-anode.d.ts +38 -0
  36. package/dist/led/led-common-anode.d.ts.map +1 -0
  37. package/dist/led/led-common-anode.js +79 -0
  38. package/dist/led/led-common-anode.js.map +1 -0
  39. package/dist/led/led-neopixel-spi.d.ts +60 -0
  40. package/dist/led/led-neopixel-spi.d.ts.map +1 -0
  41. package/dist/led/led-neopixel-spi.js +216 -0
  42. package/dist/led/led-neopixel-spi.js.map +1 -0
  43. package/dist/led/led-neopixel-ws281x.js +186 -0
  44. package/dist/led/led-neopixel.d.ts +57 -0
  45. package/dist/led/led-neopixel.d.ts.map +1 -0
  46. package/dist/led/led-neopixel.js +235 -0
  47. package/dist/led/led-neopixel.js.map +1 -0
  48. package/dist/microphone/index.d.ts +18 -0
  49. package/dist/microphone/index.d.ts.map +1 -0
  50. package/dist/microphone/index.js +18 -0
  51. package/dist/microphone/index.js.map +1 -0
  52. package/dist/microphone/microphone.d.ts +65 -0
  53. package/dist/microphone/microphone.d.ts.map +1 -0
  54. package/dist/microphone/microphone.js +179 -0
  55. package/dist/microphone/microphone.js.map +1 -0
  56. package/dist/rpi-drivers/index.d.ts +22 -0
  57. package/dist/rpi-drivers/index.d.ts.map +1 -0
  58. package/dist/rpi-drivers/index.js +22 -0
  59. package/dist/rpi-drivers/index.js.map +1 -0
  60. package/dist/rpi-drivers/rpi-detect.d.ts +24 -0
  61. package/dist/rpi-drivers/rpi-detect.d.ts.map +1 -0
  62. package/dist/rpi-drivers/rpi-detect.js +49 -0
  63. package/dist/rpi-drivers/rpi-detect.js.map +1 -0
  64. package/dist/rpi-drivers/rpi-driver.d.ts +116 -0
  65. package/dist/rpi-drivers/rpi-driver.d.ts.map +1 -0
  66. package/dist/rpi-drivers/rpi-driver.js +261 -0
  67. package/dist/rpi-drivers/rpi-driver.js.map +1 -0
  68. package/dist/rpi-drivers/rpi3-driver.d.ts +47 -0
  69. package/dist/rpi-drivers/rpi3-driver.d.ts.map +1 -0
  70. package/dist/rpi-drivers/rpi3-driver.js +145 -0
  71. package/dist/rpi-drivers/rpi3-driver.js.map +1 -0
  72. package/dist/rpi-drivers/rpi4-driver.d.ts +35 -0
  73. package/dist/rpi-drivers/rpi4-driver.d.ts.map +1 -0
  74. package/dist/rpi-drivers/rpi4-driver.js +101 -0
  75. package/dist/rpi-drivers/rpi4-driver.js.map +1 -0
  76. package/dist/rpi-drivers/rpi5-driver.d.ts +33 -0
  77. package/dist/rpi-drivers/rpi5-driver.d.ts.map +1 -0
  78. package/dist/rpi-drivers/rpi5-driver.js +78 -0
  79. package/dist/rpi-drivers/rpi5-driver.js.map +1 -0
  80. package/dist/servo/index.d.ts +19 -0
  81. package/dist/servo/index.d.ts.map +1 -0
  82. package/dist/servo/index.js +19 -0
  83. package/dist/servo/index.js.map +1 -0
  84. package/dist/servo/servo-constants.d.ts +33 -0
  85. package/dist/servo/servo-constants.d.ts.map +1 -0
  86. package/dist/servo/servo-constants.js +34 -0
  87. package/dist/servo/servo-constants.js.map +1 -0
  88. package/dist/servo/servo-lgpio.d.ts +82 -0
  89. package/dist/servo/servo-lgpio.d.ts.map +1 -0
  90. package/dist/servo/servo-lgpio.js +178 -0
  91. package/dist/servo/servo-lgpio.js.map +1 -0
  92. package/dist/speaker/audio-player.d.ts +30 -0
  93. package/dist/speaker/audio-player.d.ts.map +1 -0
  94. package/dist/speaker/audio-player.js +68 -0
  95. package/dist/speaker/audio-player.js.map +1 -0
  96. package/dist/speaker/index.d.ts +18 -0
  97. package/dist/speaker/index.d.ts.map +1 -0
  98. package/dist/speaker/index.js +18 -0
  99. package/dist/speaker/index.js.map +1 -0
  100. package/dist/speaker/speaker.d.ts +53 -0
  101. package/dist/speaker/speaker.d.ts.map +1 -0
  102. package/dist/speaker/speaker.js +125 -0
  103. package/dist/speaker/speaker.js.map +1 -0
  104. package/dist/stt/backends/azure-stt.d.ts +32 -0
  105. package/dist/stt/backends/azure-stt.d.ts.map +1 -0
  106. package/dist/stt/backends/azure-stt.js +227 -0
  107. package/dist/stt/backends/azure-stt.js.map +1 -0
  108. package/dist/stt/backends/google-cloud-stt.d.ts +31 -0
  109. package/dist/stt/backends/google-cloud-stt.d.ts.map +1 -0
  110. package/dist/stt/backends/google-cloud-stt.js +371 -0
  111. package/dist/stt/backends/google-cloud-stt.js.map +1 -0
  112. package/dist/stt/backends/ibm-watson-stt.d.ts +32 -0
  113. package/dist/stt/backends/ibm-watson-stt.d.ts.map +1 -0
  114. package/dist/stt/backends/ibm-watson-stt.js +190 -0
  115. package/dist/stt/backends/ibm-watson-stt.js.map +1 -0
  116. package/dist/stt/backends/sherpa-onnx-stt.d.ts +117 -0
  117. package/dist/stt/backends/sherpa-onnx-stt.d.ts.map +1 -0
  118. package/dist/stt/backends/sherpa-onnx-stt.js +694 -0
  119. package/dist/stt/backends/sherpa-onnx-stt.js.map +1 -0
  120. package/dist/stt/index.d.ts +20 -0
  121. package/dist/stt/index.d.ts.map +1 -0
  122. package/dist/stt/index.js +21 -0
  123. package/dist/stt/index.js.map +1 -0
  124. package/dist/stt/stt-engine.d.ts +68 -0
  125. package/dist/stt/stt-engine.d.ts.map +1 -0
  126. package/dist/stt/stt-engine.js +99 -0
  127. package/dist/stt/stt-engine.js.map +1 -0
  128. package/dist/stt/stt-utils.d.ts +36 -0
  129. package/dist/stt/stt-utils.d.ts.map +1 -0
  130. package/dist/stt/stt-utils.js +112 -0
  131. package/dist/stt/stt-utils.js.map +1 -0
  132. package/dist/stt/stt.d.ts +52 -0
  133. package/dist/stt/stt.d.ts.map +1 -0
  134. package/dist/stt/stt.js +100 -0
  135. package/dist/stt/stt.js.map +1 -0
  136. package/dist/tjbot.d.ts +317 -0
  137. package/dist/tjbot.d.ts.map +1 -0
  138. package/dist/tjbot.js +736 -0
  139. package/dist/tjbot.js.map +1 -0
  140. package/dist/tts/backends/azure-tts.d.ts +30 -0
  141. package/dist/tts/backends/azure-tts.d.ts.map +1 -0
  142. package/dist/tts/backends/azure-tts.js +92 -0
  143. package/dist/tts/backends/azure-tts.js.map +1 -0
  144. package/dist/tts/backends/google-cloud-tts.d.ts +38 -0
  145. package/dist/tts/backends/google-cloud-tts.d.ts.map +1 -0
  146. package/dist/tts/backends/google-cloud-tts.js +116 -0
  147. package/dist/tts/backends/google-cloud-tts.js.map +1 -0
  148. package/dist/tts/backends/ibm-watson-tts.d.ts +42 -0
  149. package/dist/tts/backends/ibm-watson-tts.d.ts.map +1 -0
  150. package/dist/tts/backends/ibm-watson-tts.js +99 -0
  151. package/dist/tts/backends/ibm-watson-tts.js.map +1 -0
  152. package/dist/tts/backends/sherpa-onnx-tts.d.ts +80 -0
  153. package/dist/tts/backends/sherpa-onnx-tts.d.ts.map +1 -0
  154. package/dist/tts/backends/sherpa-onnx-tts.js +237 -0
  155. package/dist/tts/backends/sherpa-onnx-tts.js.map +1 -0
  156. package/dist/tts/index.d.ts +19 -0
  157. package/dist/tts/index.d.ts.map +1 -0
  158. package/dist/tts/index.js +20 -0
  159. package/dist/tts/index.js.map +1 -0
  160. package/dist/tts/tts-engine.d.ts +67 -0
  161. package/dist/tts/tts-engine.d.ts.map +1 -0
  162. package/dist/tts/tts-engine.js +109 -0
  163. package/dist/tts/tts-engine.js.map +1 -0
  164. package/dist/tts/tts.d.ts +47 -0
  165. package/dist/tts/tts.d.ts.map +1 -0
  166. package/dist/tts/tts.js +101 -0
  167. package/dist/tts/tts.js.map +1 -0
  168. package/dist/utils/colors.d.ts +39 -0
  169. package/dist/utils/colors.d.ts.map +1 -0
  170. package/dist/utils/colors.js +155 -0
  171. package/dist/utils/colors.js.map +1 -0
  172. package/dist/utils/constants.d.ts +41 -0
  173. package/dist/utils/constants.d.ts.map +1 -0
  174. package/dist/utils/constants.js +43 -0
  175. package/dist/utils/constants.js.map +1 -0
  176. package/dist/utils/credentials.d.ts +43 -0
  177. package/dist/utils/credentials.d.ts.map +1 -0
  178. package/dist/utils/credentials.js +121 -0
  179. package/dist/utils/credentials.js.map +1 -0
  180. package/dist/utils/errors.d.ts +26 -0
  181. package/dist/utils/errors.d.ts.map +1 -0
  182. package/dist/utils/errors.js +32 -0
  183. package/dist/utils/errors.js.map +1 -0
  184. package/dist/utils/index.d.ts +25 -0
  185. package/dist/utils/index.d.ts.map +1 -0
  186. package/dist/utils/index.js +23 -0
  187. package/dist/utils/index.js.map +1 -0
  188. package/dist/utils/logging.d.ts +44 -0
  189. package/dist/utils/logging.d.ts.map +1 -0
  190. package/dist/utils/logging.js +113 -0
  191. package/dist/utils/logging.js.map +1 -0
  192. package/dist/utils/model-registry.d.ts +142 -0
  193. package/dist/utils/model-registry.d.ts.map +1 -0
  194. package/dist/utils/model-registry.js +391 -0
  195. package/dist/utils/model-registry.js.map +1 -0
  196. package/dist/utils/utils.d.ts +33 -0
  197. package/dist/utils/utils.d.ts.map +1 -0
  198. package/dist/utils/utils.js +50 -0
  199. package/dist/utils/utils.js.map +1 -0
  200. package/dist/vision/backends/azure-vision.d.ts +33 -0
  201. package/dist/vision/backends/azure-vision.d.ts.map +1 -0
  202. package/dist/vision/backends/azure-vision.js +151 -0
  203. package/dist/vision/backends/azure-vision.js.map +1 -0
  204. package/dist/vision/backends/google-cloud-vision.d.ts +32 -0
  205. package/dist/vision/backends/google-cloud-vision.d.ts.map +1 -0
  206. package/dist/vision/backends/google-cloud-vision.js +193 -0
  207. package/dist/vision/backends/google-cloud-vision.js.map +1 -0
  208. package/dist/vision/backends/onnx.d.ts +116 -0
  209. package/dist/vision/backends/onnx.d.ts.map +1 -0
  210. package/dist/vision/backends/onnx.js +781 -0
  211. package/dist/vision/backends/onnx.js.map +1 -0
  212. package/dist/vision/index.d.ts +19 -0
  213. package/dist/vision/index.d.ts.map +1 -0
  214. package/dist/vision/index.js +20 -0
  215. package/dist/vision/index.js.map +1 -0
  216. package/dist/vision/vision-engine.d.ts +131 -0
  217. package/dist/vision/vision-engine.d.ts.map +1 -0
  218. package/dist/vision/vision-engine.js +97 -0
  219. package/dist/vision/vision-engine.js.map +1 -0
  220. package/dist/vision/vision.d.ts +48 -0
  221. package/dist/vision/vision.d.ts.map +1 -0
  222. package/dist/vision/vision.js +83 -0
  223. package/dist/vision/vision.js.map +1 -0
  224. package/package.json +124 -0
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { spawn, spawnSync } from 'child_process';
18
+ import { createInterface } from 'readline';
19
+ import { fileURLToPath } from 'url';
20
+ import { dirname, join } from 'path';
21
+ import { TJBotError } from '../utils/errors.js';
22
+ import { getLogger } from '../utils/logging.js';
23
+ const logger = getLogger(import.meta.url);
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+ /** Absolute path to the root helper script (plain JS so it runs under raw node). */
27
+ const HELPER_PATH = join(__dirname, 'led-neopixel-ws281x.js');
28
+ /**
29
+ * LED controller for NeoPixel (WS281x) LEDs on Raspberry Pi 3/4.
30
+ *
31
+ * rpi-ws281x-native requires root privileges. Rather than launching every
32
+ * TJBot recipe that uses the LED as root, this class spawns a small, long-lived
33
+ * helper process (in led-neopixel-ws281x.js) using sudo and communicates with it
34
+ * over a newline-delimited JSON IPC channel on stdin/stdout.
35
+ *
36
+ * Sudo authentication is performed once at construction time (either
37
+ * passwordless or via an interactive prompt). Subsequent render() calls are
38
+ * cheap IPC messages with no additional privilege escalation.
39
+ */
40
+ export class LEDNeopixel {
41
+ helper;
42
+ reader;
43
+ helperStderrTail = [];
44
+ _ready;
45
+ _pendingById = new Map();
46
+ _nextId = 1;
47
+ _helperDead = null;
48
+ constructor(pin) {
49
+ const isRoot = process.getuid?.() === 0;
50
+ let spawnCmd;
51
+ let spawnArgs;
52
+ if (isRoot) {
53
+ // Already root — run the helper directly, no sudo needed.
54
+ spawnCmd = process.execPath;
55
+ spawnArgs = [HELPER_PATH];
56
+ }
57
+ else {
58
+ // Test whether passwordless sudo is available.
59
+ const probe = spawnSync('sudo', ['-n', 'true'], { stdio: 'pipe' });
60
+ if (probe.status !== 0) {
61
+ // Password is required. Print a clear rationale before prompting.
62
+ console.log('\nThe NeoPixel LED on Raspberry Pi 3/4 requires elevated hardware access.\n' +
63
+ 'TJBot will now request sudo authentication to launch a dedicated LED\n' +
64
+ 'helper process. This is a one-time authentication per session.\n');
65
+ const auth = spawnSync('sudo', ['-v'], { stdio: 'inherit' });
66
+ if (auth.status !== 0) {
67
+ throw new TJBotError('sudo authentication failed. The NeoPixel LED requires root privileges on Raspberry Pi 3/4. ' +
68
+ 'Enable passwordless sudo for this command or run `sudo -v` before starting TJBot.');
69
+ }
70
+ }
71
+ // Credentials are now cached; use -n so the helper spawn never blocks.
72
+ spawnCmd = 'sudo';
73
+ spawnArgs = ['-n', process.execPath, HELPER_PATH];
74
+ }
75
+ logger.verbose(`Spawning NeoPixel helper: ${spawnCmd} ${spawnArgs.join(' ')}`);
76
+ this.helper = spawn(spawnCmd, spawnArgs, {
77
+ stdio: ['pipe', 'pipe', 'pipe'],
78
+ });
79
+ if (!this.helper.stdout) {
80
+ throw new TJBotError('NeoPixel helper process stdout is not available.');
81
+ }
82
+ // Line-based JSON reader on helper stdout.
83
+ this.reader = createInterface({ input: this.helper.stdout });
84
+ this.reader.on('line', (line) => this._handleLine(line));
85
+ if (this.helper.stderr) {
86
+ this.helper.stderr.setEncoding('utf8');
87
+ this.helper.stderr.on('data', (chunk) => {
88
+ process.stderr.write(chunk);
89
+ const lines = chunk.split(/\r?\n/).filter((line) => line.trim().length > 0);
90
+ if (lines.length > 0) {
91
+ this.helperStderrTail.push(...lines);
92
+ if (this.helperStderrTail.length > 8) {
93
+ this.helperStderrTail = this.helperStderrTail.slice(-8);
94
+ }
95
+ }
96
+ });
97
+ }
98
+ this.helper.on('exit', (code, signal) => {
99
+ const stderrSummary = this.helperStderrTail.length > 0 ? `; stderr: ${this.helperStderrTail.join(' | ')}` : '';
100
+ this._helperDead = new TJBotError(`NeoPixel helper exited unexpectedly (code=${code}, signal=${signal}${stderrSummary})`);
101
+ for (const [, pending] of this._pendingById) {
102
+ clearTimeout(pending.timer);
103
+ pending.reject(this._helperDead);
104
+ }
105
+ this._pendingById.clear();
106
+ logger.error(`NeoPixel helper exited (code=${code}, signal=${signal})`);
107
+ });
108
+ // Send the init command; store the promise so render() can await readiness.
109
+ this._ready = this._send({ cmd: 'init', pin, numLeds: 1 }, 10_000);
110
+ this._ready
111
+ .then(() => {
112
+ logger.verbose(`NeoPixel helper ready on pin ${pin}`);
113
+ this._setHelperHandleRefState(false);
114
+ })
115
+ .catch(() => {
116
+ this._setHelperHandleRefState(false);
117
+ });
118
+ // Tear down the helper when the parent process exits (covers normal exit,
119
+ // SIGINT, and SIGTERM). The helper's own stdin-close handler calls
120
+ // ws281x.reset() so the LED is turned off cleanly.
121
+ process.on('exit', () => this._killHelper());
122
+ }
123
+ /**
124
+ * Wait for the NeoPixel helper to be fully initialized and ready.
125
+ * Call this before loading long-running tasks if the LED needs to be available early.
126
+ */
127
+ async initialize() {
128
+ await this._ready;
129
+ }
130
+ /**
131
+ * Render the NeoPixel to a specific color.
132
+ * @param color Color as a 32-bit integer in RGB format (0xRRGGBB)
133
+ */
134
+ async render(color) {
135
+ logger.debug(`Rendering NeoPixel LED (IPC) with color: ${color}`);
136
+ await this._ready;
137
+ await this._send({ cmd: 'render', color }, 2_000);
138
+ }
139
+ /**
140
+ * Send a reset command and terminate the helper process.
141
+ */
142
+ async cleanup() {
143
+ logger.debug('LEDNeopixel cleanup');
144
+ if (this._helperDead)
145
+ return;
146
+ try {
147
+ await this._send({ cmd: 'shutdown' }, 2_000);
148
+ }
149
+ finally {
150
+ this._killHelper();
151
+ }
152
+ }
153
+ // ── Private helpers ───────────────────────────────────────────────────────
154
+ _handleLine(line) {
155
+ let msg;
156
+ try {
157
+ msg = JSON.parse(line);
158
+ }
159
+ catch {
160
+ logger.warn(`NeoPixel helper sent unparseable response: ${line}`);
161
+ return;
162
+ }
163
+ const pending = this._pendingById.get(msg.id);
164
+ if (!pending) {
165
+ logger.warn(`NeoPixel helper sent response for unknown id: ${msg.id}`);
166
+ return;
167
+ }
168
+ this._pendingById.delete(msg.id);
169
+ clearTimeout(pending.timer);
170
+ if (this._pendingById.size === 0) {
171
+ this._setHelperHandleRefState(false);
172
+ }
173
+ if (msg.ok) {
174
+ pending.resolve();
175
+ }
176
+ else {
177
+ pending.reject(new TJBotError(`NeoPixel helper error: ${msg.error ?? 'unknown'}`));
178
+ }
179
+ }
180
+ _send(payload, timeoutMs) {
181
+ if (this._helperDead) {
182
+ return Promise.reject(this._helperDead);
183
+ }
184
+ return new Promise((resolve, reject) => {
185
+ const id = this._nextId++;
186
+ this._setHelperHandleRefState(true);
187
+ const timer = setTimeout(() => {
188
+ this._pendingById.delete(id);
189
+ if (this._pendingById.size === 0) {
190
+ this._setHelperHandleRefState(false);
191
+ }
192
+ reject(new TJBotError(`NeoPixel helper timed out waiting for response to '${payload.cmd}' (${timeoutMs}ms)`));
193
+ }, timeoutMs);
194
+ timer.unref();
195
+ this._pendingById.set(id, { resolve, reject, timer });
196
+ this.helper.stdin?.write(JSON.stringify({ ...payload, id }) + '\n');
197
+ });
198
+ }
199
+ _setHelperHandleRefState(referenced) {
200
+ const maybeRefUnref = (handle) => {
201
+ if (!handle || typeof handle !== 'object')
202
+ return;
203
+ const h = handle;
204
+ if (referenced) {
205
+ h.ref?.();
206
+ }
207
+ else {
208
+ h.unref?.();
209
+ }
210
+ };
211
+ if (referenced) {
212
+ this.helper.ref();
213
+ }
214
+ else {
215
+ this.helper.unref();
216
+ }
217
+ maybeRefUnref(this.helper.stdin);
218
+ maybeRefUnref(this.helper.stdout);
219
+ maybeRefUnref(this.helper.stderr);
220
+ }
221
+ _killHelper() {
222
+ if (this.helper && !this.helper.killed) {
223
+ try {
224
+ this.reader?.close();
225
+ this.reader = undefined;
226
+ this.helper.stdin?.end();
227
+ }
228
+ catch {
229
+ /* best effort */
230
+ }
231
+ this.helper.kill('SIGTERM');
232
+ }
233
+ }
234
+ }
235
+ //# sourceMappingURL=led-neopixel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"led-neopixel.js","sourceRoot":"","sources":["../../src/led/led-neopixel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export { MicrophoneController } from './microphone.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/microphone/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export { MicrophoneController } from './microphone.js';
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/microphone/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { Transform } from 'stream';
18
+ /**
19
+ * Microphone controller for TJBot
20
+ * Handles microphone initialization and audio stream management
21
+ */
22
+ export declare class MicrophoneController {
23
+ private mic;
24
+ private micInputStream;
25
+ private isStarted;
26
+ private isPaused;
27
+ constructor();
28
+ /**
29
+ * Auto-detect the first available audio recording device
30
+ * @returns The device string (e.g., 'plughw:2,0') or empty string if none found
31
+ */
32
+ private detectMicrophoneDevice;
33
+ /**
34
+ * Initialize the microphone with configuration
35
+ * @param rate Microphone sampling rate in Hz
36
+ * @param channels Number of audio channels
37
+ * @param device Optional specific audio device to use (auto-detected if not specified)
38
+ */
39
+ initialize(rate: number, channels: number, device?: string, exitOnSilenceSeconds?: number): void;
40
+ /**
41
+ * Start microphone recording
42
+ */
43
+ start(): void;
44
+ /**
45
+ * Pause microphone recording
46
+ */
47
+ pause(): void;
48
+ /**
49
+ * Resume microphone recording
50
+ */
51
+ resume(): void;
52
+ /**
53
+ * Stop microphone recording
54
+ */
55
+ stop(): void;
56
+ /**
57
+ * Get the microphone input stream
58
+ */
59
+ getInputStream(): Transform;
60
+ /**
61
+ * Clean up resources
62
+ */
63
+ cleanup(): void;
64
+ }
65
+ //# sourceMappingURL=microphone.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microphone.d.ts","sourceRoot":"","sources":["../../src/microphone/microphone.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAgBnC;;;GAGG;AACH,qBAAa,oBAAoB;IAC7B,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,cAAc,CAAY;IAClC,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,QAAQ,CAAU;;IAU1B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAyB9B;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI;IAgEhG;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb;;OAEG;IACH,MAAM,IAAI,IAAI;IAUd;;OAEG;IACH,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACH,cAAc,IAAI,SAAS;IAI3B;;OAEG;IACH,OAAO,IAAI,IAAI;CAIlB"}
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import Mic from 'mic';
18
+ import { execSync } from 'child_process';
19
+ import { getLogger } from '../utils/logging.js';
20
+ const logger = getLogger(import.meta.url);
21
+ /**
22
+ * Microphone controller for TJBot
23
+ * Handles microphone initialization and audio stream management
24
+ */
25
+ export class MicrophoneController {
26
+ mic;
27
+ micInputStream;
28
+ isStarted;
29
+ isPaused;
30
+ constructor() {
31
+ const params = {};
32
+ this.mic = Mic(params);
33
+ this.micInputStream = this.mic.getAudioStream();
34
+ this.isStarted = false;
35
+ this.isPaused = false;
36
+ }
37
+ /**
38
+ * Auto-detect the first available audio recording device
39
+ * @returns The device string (e.g., 'plughw:2,0') or empty string if none found
40
+ */
41
+ detectMicrophoneDevice() {
42
+ try {
43
+ // Run arecord -l to list capture devices
44
+ const output = execSync('arecord -l', { encoding: 'utf8' });
45
+ // Parse output to find first card and device
46
+ // Example line: "card 2: Device [USB PnP Sound Device], device 0: USB Audio [USB Audio]"
47
+ const match = output.match(/card (\d+):.*device (\d+):/);
48
+ if (match) {
49
+ const card = match[1];
50
+ const device = match[2];
51
+ const deviceString = `plughw:${card},${device}`;
52
+ logger.debug(`auto-detected microphone device: ${deviceString}`);
53
+ return deviceString;
54
+ }
55
+ logger.warn('no audio capture devices found');
56
+ return '';
57
+ }
58
+ catch (error) {
59
+ logger.error('error detecting microphone device:', error);
60
+ return '';
61
+ }
62
+ }
63
+ /**
64
+ * Initialize the microphone with configuration
65
+ * @param rate Microphone sampling rate in Hz
66
+ * @param channels Number of audio channels
67
+ * @param device Optional specific audio device to use (auto-detected if not specified)
68
+ */
69
+ initialize(rate, channels, device, exitOnSilenceSeconds) {
70
+ const params = {
71
+ rate: String(rate),
72
+ channels: String(channels),
73
+ bitwidth: '16',
74
+ encoding: 'signed-integer',
75
+ endian: 'little',
76
+ debug: false,
77
+ };
78
+ // Only enable auto-stop on silence if a positive value is provided
79
+ if (typeof exitOnSilenceSeconds === 'number' && exitOnSilenceSeconds > 0) {
80
+ params['exitOnSilence'] = exitOnSilenceSeconds;
81
+ }
82
+ if (device && device !== '') {
83
+ params['device'] = device;
84
+ logger.verbose(`Initializing microphone with user-defined audio device: ${device}`);
85
+ }
86
+ else {
87
+ const selectedDevice = this.detectMicrophoneDevice();
88
+ params['device'] = selectedDevice;
89
+ logger.verbose(`Initializing microphone with auto-detected audio device: ${selectedDevice}`);
90
+ }
91
+ // create the microphone
92
+ this.mic = Mic(params);
93
+ // save the input stream so we can pipe it to STT
94
+ this.micInputStream = this.mic.getAudioStream();
95
+ // event handlers
96
+ this.micInputStream.on('startComplete', () => {
97
+ logger.verbose('Microphone started');
98
+ });
99
+ this.micInputStream.on('pauseComplete', () => {
100
+ logger.verbose('Microphone paused');
101
+ });
102
+ this.micInputStream.on('data', (data) => {
103
+ logger.silly(`microphone received ${data.length} bytes`);
104
+ });
105
+ // log errors in the mic input stream
106
+ this.micInputStream.on('error', (err) => {
107
+ logger.error('Microphone input stream experienced an error', err);
108
+ });
109
+ this.micInputStream.on('processExitComplete', () => {
110
+ logger.verbose('Microphone recording process exited');
111
+ });
112
+ // ignore silence
113
+ this.micInputStream.on('silence', () => {
114
+ logger.verbose('Microphone silence');
115
+ });
116
+ logger.debug(`initialized microphone with config:
117
+ rate: ${rate}
118
+ channels: ${channels}
119
+ device: ${device}
120
+ exitOnSilenceSeconds: ${exitOnSilenceSeconds}`);
121
+ }
122
+ /**
123
+ * Start microphone recording
124
+ */
125
+ start() {
126
+ if (this.mic !== undefined && !this.isStarted) {
127
+ this.mic.start();
128
+ this.isStarted = true;
129
+ this.isPaused = false;
130
+ }
131
+ else if (this.mic !== undefined && this.isPaused) {
132
+ this.resume();
133
+ }
134
+ }
135
+ /**
136
+ * Pause microphone recording
137
+ */
138
+ pause() {
139
+ if (this.mic !== undefined && this.isStarted && !this.isPaused) {
140
+ this.mic.pause();
141
+ this.isPaused = true;
142
+ }
143
+ }
144
+ /**
145
+ * Resume microphone recording
146
+ */
147
+ resume() {
148
+ if (this.mic !== undefined && this.isStarted && this.isPaused) {
149
+ this.mic.resume();
150
+ this.isPaused = false;
151
+ // there is no resume event, so log it here
152
+ logger.verbose('Microphone resumed');
153
+ }
154
+ }
155
+ /**
156
+ * Stop microphone recording
157
+ */
158
+ stop() {
159
+ if (this.mic !== undefined) {
160
+ this.mic.stop();
161
+ this.isStarted = false;
162
+ this.isPaused = false;
163
+ }
164
+ }
165
+ /**
166
+ * Get the microphone input stream
167
+ */
168
+ getInputStream() {
169
+ return this.micInputStream;
170
+ }
171
+ /**
172
+ * Clean up resources
173
+ */
174
+ cleanup() {
175
+ logger.debug('MicrophoneController cleanup');
176
+ this.stop();
177
+ }
178
+ }
179
+ //# sourceMappingURL=microphone.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microphone.js","sourceRoot":"","sources":["../../src/microphone/microphone.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export { RPiHardwareDriver, RPiBaseHardwareDriver } from './rpi-driver.js';
18
+ export { default as RPi3Driver } from './rpi3-driver.js';
19
+ export { default as RPi4Driver } from './rpi4-driver.js';
20
+ export { default as RPi5Driver } from './rpi5-driver.js';
21
+ export { default as RPiDetect } from './rpi-detect.js';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/rpi-drivers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export { RPiHardwareDriver, RPiBaseHardwareDriver } from './rpi-driver.js';
18
+ export { default as RPi3Driver } from './rpi3-driver.js';
19
+ export { default as RPi4Driver } from './rpi4-driver.js';
20
+ export { default as RPi5Driver } from './rpi5-driver.js';
21
+ export { default as RPiDetect } from './rpi-detect.js';
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/rpi-drivers/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ declare class RPiDetect {
18
+ static model(): string;
19
+ static isPi3(): boolean;
20
+ static isPi4(): boolean;
21
+ static isPi5(): boolean;
22
+ }
23
+ export default RPiDetect;
24
+ //# sourceMappingURL=rpi-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rpi-detect.d.ts","sourceRoot":"","sources":["../../src/rpi-drivers/rpi-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,cAAM,SAAS;IACX,MAAM,CAAC,KAAK,IAAI,MAAM;IAkBtB,MAAM,CAAC,KAAK,IAAI,OAAO;IAKvB,MAAM,CAAC,KAAK,IAAI,OAAO;IAKvB,MAAM,CAAC,KAAK,IAAI,OAAO;CAI1B;AAED,eAAe,SAAS,CAAC"}