@goodandready/dsh-voice 0.9.20 → 0.9.22
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.
- package/lib/local-daemon.js +64 -58
- package/lib/updater.js +13 -4
- package/package.json +1 -1
package/lib/local-daemon.js
CHANGED
|
@@ -134,37 +134,40 @@ export function createLocalDaemons({ live, ctx }) {
|
|
|
134
134
|
} catch (_) {}
|
|
135
135
|
}
|
|
136
136
|
let code = child.exitCode
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
if (r
|
|
137
|
+
const isTerminal = (child.status && child.status !== 'running') || (code !== null && code !== undefined)
|
|
138
|
+
if (isTerminal) {
|
|
139
|
+
if (typeof child.result === 'function') {
|
|
140
|
+
try {
|
|
141
|
+
const r = await child.result()
|
|
142
|
+
if (r) {
|
|
143
|
+
if (r.exitCode !== undefined && r.exitCode !== null) code = r.exitCode
|
|
144
|
+
if (r.stderr && !detail) detail = String(r.stderr).trim()
|
|
145
|
+
}
|
|
146
|
+
} catch (err) {
|
|
147
|
+
const msg = err && err.message ? err.message : String(err)
|
|
148
|
+
if (msg && !detail) detail = msg.trim()
|
|
143
149
|
}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (
|
|
150
|
+
} else if (child.result && typeof child.result === 'object') {
|
|
151
|
+
code = child.result.exitCode ?? code
|
|
152
|
+
if (child.result.stderr && !detail) detail = String(child.result.stderr).trim()
|
|
153
|
+
}
|
|
154
|
+
if (child.status === 'killed') {
|
|
155
|
+
whisperError = detail ? `whisper server process was killed: ${detail}` : 'whisper server process was killed'
|
|
156
|
+
return false
|
|
157
|
+
}
|
|
158
|
+
if (child.status === 'completed') {
|
|
159
|
+
code = code ?? 0
|
|
160
|
+
whisperError = `whisper server process exited prematurely with code ${code}${detail ? `: ${detail}` : ''}`
|
|
161
|
+
return false
|
|
162
|
+
}
|
|
163
|
+
if (child.status === 'exited' || child.status === 'failed') {
|
|
164
|
+
whisperError = `whisper server process exited prematurely with status ${child.status}${detail ? `: ${detail}` : ''}`
|
|
165
|
+
return false
|
|
166
|
+
}
|
|
167
|
+
if (child.exitCode !== null && child.exitCode !== undefined) {
|
|
168
|
+
whisperError = `whisper server process exited prematurely with code ${child.exitCode}${detail ? `: ${detail}` : ''}`
|
|
169
|
+
return false
|
|
147
170
|
}
|
|
148
|
-
} else if (child.result && typeof child.result === 'object') {
|
|
149
|
-
code = child.result.exitCode ?? code
|
|
150
|
-
if (child.result.stderr && !detail) detail = String(child.result.stderr).trim()
|
|
151
|
-
}
|
|
152
|
-
if (child.status === 'killed') {
|
|
153
|
-
whisperError = detail ? `whisper server process was killed: ${detail}` : 'whisper server process was killed'
|
|
154
|
-
return false
|
|
155
|
-
}
|
|
156
|
-
if (child.status === 'completed') {
|
|
157
|
-
code = code ?? 0
|
|
158
|
-
whisperError = `whisper server process exited prematurely with code ${code}${detail ? `: ${detail}` : ''}`
|
|
159
|
-
return false
|
|
160
|
-
}
|
|
161
|
-
if (child.status === 'exited' || child.status === 'failed') {
|
|
162
|
-
whisperError = `whisper server process exited prematurely with status ${child.status}${detail ? `: ${detail}` : ''}`
|
|
163
|
-
return false
|
|
164
|
-
}
|
|
165
|
-
if (child.exitCode !== null && child.exitCode !== undefined) {
|
|
166
|
-
whisperError = `whisper server process exited prematurely with code ${child.exitCode}${detail ? `: ${detail}` : ''}`
|
|
167
|
-
return false
|
|
168
171
|
}
|
|
169
172
|
}
|
|
170
173
|
}
|
|
@@ -295,37 +298,40 @@ export function createLocalDaemons({ live, ctx }) {
|
|
|
295
298
|
} catch (_) {}
|
|
296
299
|
}
|
|
297
300
|
let code = sensevoiceChild.exitCode
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
if (r
|
|
301
|
+
const isTerminal = (sensevoiceChild.status && sensevoiceChild.status !== 'running') || (code !== null && code !== undefined)
|
|
302
|
+
if (isTerminal) {
|
|
303
|
+
if (typeof sensevoiceChild.result === 'function') {
|
|
304
|
+
try {
|
|
305
|
+
const r = await sensevoiceChild.result()
|
|
306
|
+
if (r) {
|
|
307
|
+
if (r.exitCode !== undefined && r.exitCode !== null) code = r.exitCode
|
|
308
|
+
if (r.stderr && !detail) detail = String(r.stderr).trim()
|
|
309
|
+
}
|
|
310
|
+
} catch (err) {
|
|
311
|
+
const msg = err && err.message ? err.message : String(err)
|
|
312
|
+
if (msg && !detail) detail = msg.trim()
|
|
304
313
|
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
if (
|
|
314
|
+
} else if (sensevoiceChild.result && typeof sensevoiceChild.result === 'object') {
|
|
315
|
+
code = sensevoiceChild.result.exitCode ?? code
|
|
316
|
+
if (sensevoiceChild.result.stderr && !detail) detail = String(sensevoiceChild.result.stderr).trim()
|
|
317
|
+
}
|
|
318
|
+
if (sensevoiceChild.status === 'killed') {
|
|
319
|
+
sensevoiceError = detail ? `sensevoice process was killed: ${detail}` : 'sensevoice process was killed'
|
|
320
|
+
return false
|
|
321
|
+
}
|
|
322
|
+
if (sensevoiceChild.status === 'completed') {
|
|
323
|
+
code = code ?? 0
|
|
324
|
+
sensevoiceError = `sensevoice process exited prematurely with code ${code}${detail ? `: ${detail}` : ''}`
|
|
325
|
+
return false
|
|
326
|
+
}
|
|
327
|
+
if (sensevoiceChild.status === 'exited' || sensevoiceChild.status === 'failed') {
|
|
328
|
+
sensevoiceError = `sensevoice process exited prematurely with status ${sensevoiceChild.status}${detail ? `: ${detail}` : ''}`
|
|
329
|
+
return false
|
|
330
|
+
}
|
|
331
|
+
if (sensevoiceChild.exitCode !== null && sensevoiceChild.exitCode !== undefined) {
|
|
332
|
+
sensevoiceError = `sensevoice process exited prematurely with code ${sensevoiceChild.exitCode}${detail ? `: ${detail}` : ''}`
|
|
333
|
+
return false
|
|
308
334
|
}
|
|
309
|
-
} else if (sensevoiceChild.result && typeof sensevoiceChild.result === 'object') {
|
|
310
|
-
code = sensevoiceChild.result.exitCode ?? code
|
|
311
|
-
if (sensevoiceChild.result.stderr && !detail) detail = String(sensevoiceChild.result.stderr).trim()
|
|
312
|
-
}
|
|
313
|
-
if (sensevoiceChild.status === 'killed') {
|
|
314
|
-
sensevoiceError = detail ? `sensevoice process was killed: ${detail}` : 'sensevoice process was killed'
|
|
315
|
-
return false
|
|
316
|
-
}
|
|
317
|
-
if (sensevoiceChild.status === 'completed') {
|
|
318
|
-
code = code ?? 0
|
|
319
|
-
sensevoiceError = `sensevoice process exited prematurely with code ${code}${detail ? `: ${detail}` : ''}`
|
|
320
|
-
return false
|
|
321
|
-
}
|
|
322
|
-
if (sensevoiceChild.status === 'exited' || sensevoiceChild.status === 'failed') {
|
|
323
|
-
sensevoiceError = `sensevoice process exited prematurely with status ${sensevoiceChild.status}${detail ? `: ${detail}` : ''}`
|
|
324
|
-
return false
|
|
325
|
-
}
|
|
326
|
-
if (sensevoiceChild.exitCode !== null && sensevoiceChild.exitCode !== undefined) {
|
|
327
|
-
sensevoiceError = `sensevoice process exited prematurely with code ${sensevoiceChild.exitCode}${detail ? `: ${detail}` : ''}`
|
|
328
|
-
return false
|
|
329
335
|
}
|
|
330
336
|
}
|
|
331
337
|
}
|
package/lib/updater.js
CHANGED
|
@@ -197,25 +197,34 @@ export function isProcessAlive(pid) {
|
|
|
197
197
|
export function checkProfileLock(profileDir) {
|
|
198
198
|
const lockPath = resolve(profileDir, 'package.json.lock');
|
|
199
199
|
if (!existsSync(lockPath)) return { locked: false };
|
|
200
|
+
let initialStat;
|
|
201
|
+
try { initialStat = statSync(lockPath); } catch { return { locked: false }; }
|
|
200
202
|
const pid = readLockPid(lockPath);
|
|
201
203
|
if (pid !== null) {
|
|
202
204
|
if (isProcessAlive(pid)) {
|
|
203
205
|
return { locked: true, pid };
|
|
204
206
|
}
|
|
205
207
|
// Stale lock: PID is not running.
|
|
206
|
-
// Verify before unlinking: re-check PID to ensure a concurrent live successor
|
|
208
|
+
// Verify before unlinking: re-check PID and stat to ensure a concurrent live successor
|
|
207
209
|
// was not written during the check (#205).
|
|
208
210
|
try {
|
|
209
211
|
const p1 = readLockPid(lockPath);
|
|
210
212
|
if (p1 !== null && isProcessAlive(p1)) return { locked: true, pid: p1 };
|
|
211
213
|
const p2 = readLockPid(lockPath);
|
|
212
214
|
if (p2 !== null && isProcessAlive(p2)) return { locked: true, pid: p2 };
|
|
213
|
-
|
|
215
|
+
const p3 = readLockPid(lockPath);
|
|
216
|
+
if (p3 !== null && isProcessAlive(p3)) return { locked: true, pid: p3 };
|
|
217
|
+
const currentStat = statSync(lockPath);
|
|
218
|
+
if (currentStat.mtimeMs !== initialStat.mtimeMs || currentStat.size !== initialStat.size) {
|
|
219
|
+
const live = readLockPid(lockPath);
|
|
220
|
+
if (live !== null && isProcessAlive(live)) return { locked: true, pid: live };
|
|
221
|
+
}
|
|
222
|
+
if (p1 === pid && p2 === pid && p3 === pid) {
|
|
214
223
|
unlinkSync(lockPath);
|
|
215
224
|
return { locked: false, cleanedStale: true };
|
|
216
225
|
}
|
|
217
|
-
|
|
218
|
-
if (
|
|
226
|
+
const pFinal = readLockPid(lockPath);
|
|
227
|
+
if (pFinal !== null && isProcessAlive(pFinal)) return { locked: true, pid: pFinal };
|
|
219
228
|
return { locked: false };
|
|
220
229
|
} catch {
|
|
221
230
|
if (!existsSync(lockPath)) return { locked: false };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-voice",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.22",
|
|
4
4
|
"description": "Voice input for DeepSeek Harness: dictation chunked by pauses and voice messages, each with its own provider fallback chain (Deepgram, Groq, HuggingFace, local whisper.cpp, plus any OpenAI-compatible API of your own).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|