@goodandready/dsh-voice 0.9.26 → 0.9.27
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/README.md +12 -7
- package/README.ru.md +15 -8
- package/README.zh.md +15 -8
- package/lib/client.js +6 -6
- package/lib/updater.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -226,16 +226,21 @@ Registers `transcribe_audio(file_path, language?)` in `ctx.tools`, allowing agen
|
|
|
226
226
|
* `POST /api/dsh-voice/update` — Triggers plugin self-update to latest compatible npm version (protected by local caller verification and profile lock check).
|
|
227
227
|
* `GET /api/dsh-voice/update` — Returns update check status (current version, latest version, updateAvailable).
|
|
228
228
|
|
|
229
|
-
### 🔒 Profile Lock & Operator Recovery Policy
|
|
230
|
-
When updating or installing plugins, DeepSeek Harness profiles coordinate concurrent operations using `<profile-dir>/package.json.lock
|
|
229
|
+
### 🔒 Profile Lock & Controlled Operator Recovery Policy
|
|
230
|
+
When updating or installing plugins, DeepSeek Harness profiles coordinate concurrent operations using `<profile-dir>/package.json.lock` (for example, `~/.dsh/profiles/<profile>/package.json.lock`).
|
|
231
231
|
* **Canonical Contender Policy**: The contender process never deletes or unlinks an existing lockfile. Automatic stale lock removal by contenders is prohibited to eliminate TOCTOU (Time-of-Check to Time-of-Use) race conditions and prevent unintended lockfile clobbering.
|
|
232
232
|
* **Diagnostics**: If `<profile-dir>/package.json.lock` is present, update attempts return `409 Conflict` with clear diagnostics:
|
|
233
233
|
- If held by an active process, the PID is reported.
|
|
234
|
-
- If filesystem inspection encounters access errors (`EACCES`, `EIO`), the operation fails closed with the error code preserved.
|
|
235
|
-
* **Operator Recovery**:
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
234
|
+
- If filesystem inspection encounters access errors (`EACCES`, `EIO`), the operation fails closed with the error code preserved. Filesystem errors require inspecting filesystem health, permissions, or mount options — **do not** remove the lockfile in response to `EACCES`/`EIO`.
|
|
235
|
+
* **Controlled Operator Recovery Workflow**:
|
|
236
|
+
If a previous installation was forcefully interrupted (e.g. system crash, OOM kill) leaving a stale lockfile, recovery is strictly an operator action and must follow this controlled procedure:
|
|
237
|
+
1. **Establish Exclusive Maintenance**: Ensure no concurrent processes, CLI commands (`dsh plugin add`), web UI operations, or automated updaters are running or scheduled to start for the target profile.
|
|
238
|
+
2. **Verify Quiescence and Ownership**: Check for active processes (`pgrep`, `ps`, `fuser`, or `lsof`) to confirm that no live process is currently performing package operations in the target profile directory. Lock age alone or observing an unparsed PID is **not** sufficient justification to delete a lock while another installer could start. If quiescence or non-ownership cannot be verified, do not remove the lock.
|
|
239
|
+
3. **Remove Confirmed Orphan Lock**: Only after confirming the lock is an orphan and exclusive maintenance is established, remove the specific profile lock without recursive or force flags:
|
|
240
|
+
```bash
|
|
241
|
+
rm ~/.dsh/profiles/<profile>/package.json.lock
|
|
242
|
+
```
|
|
243
|
+
4. **Resume Operations**: Re-enable installations and retry the plugin update.
|
|
239
244
|
|
|
240
245
|
---
|
|
241
246
|
|
package/README.ru.md
CHANGED
|
@@ -225,14 +225,21 @@ dsh plugin --profile web add @goodandready/dsh-voice
|
|
|
225
225
|
* `POST /api/dsh-voice/update` — запуск обновления плагина до актуальной версии из npm (с проверкой прав и блокировки профиля).
|
|
226
226
|
* `GET /api/dsh-voice/update` — проверка наличия обновлений.
|
|
227
227
|
|
|
228
|
-
### 🔒 Политика блокировок профиля и
|
|
229
|
-
При установке и обновлении плагинов DeepSeek Harness синхронизирует параллельные процессы через `<profile-dir>/package.json.lock
|
|
230
|
-
* **Канонический принцип претендента**: Процесс-претендент никогда не удаляет
|
|
231
|
-
* **Диагностика**: При наличии lock-файла запрос на обновление возвращает `409 Conflict` с подробной
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
228
|
+
### 🔒 Политика блокировок профиля и контролируемое восстановление оператором
|
|
229
|
+
При установке и обновлении плагинов DeepSeek Harness синхронизирует параллельные процессы через `<profile-dir>/package.json.lock` (например, `~/.dsh/profiles/<profile>/package.json.lock`).
|
|
230
|
+
* **Канонический принцип претендента**: Процесс-претендент никогда не удаляет чужой lock-файл. Автоматическое удаление чужих блокировок претендентом запрещено для исключения TOCTOU-гонок и повреждения состояния профиля.
|
|
231
|
+
* **Диагностика**: При наличии lock-файла запрос на обновление возвращает `409 Conflict` с подробной информацией:
|
|
232
|
+
- Если блокировка удерживается активным процессом, выводится его PID.
|
|
233
|
+
- При ошибках файловой системы (`EACCES`, `EIO`) операция завершается безопасно (fail-closed) с сохранением кода ошибки. Ошибки ФС требуют проверки прав доступа, состояния диска или опций монтирования — **не удаляйте** lock-файл при ошибках `EACCES`/`EIO`.
|
|
234
|
+
* **Регламент контролируемого восстановления оператором**:
|
|
235
|
+
Если предыдущий процесс установки аварийно оборвался (например, OOM или сбой питания) и оставил зависший lock-файл, снятие блокировки выполняет оператор по следующему регламенту:
|
|
236
|
+
1. **Обеспечение эксклюзивного окна обслуживания**: Убедитесь, что никакие параллельные процессы, команды CLI (`dsh plugin add`), веб-интерфейс или фоновые апдейтеры не выполняют установку и не могут запуститься для данного профиля.
|
|
237
|
+
2. **Проверка отсутствия живого владельца (quiescence)**: Проверьте с помощью `pgrep`, `ps`, `fuser` или `lsof`, что в каталоге профиля действительно нет активных процессов-установщиков. Сам по себе возраст файла или нераспарсенный PID **не являются** достаточным основанием для удаления lock-файла, пока не исключён параллельный запуск другого процесса. Если состояние покоя не подтверждено, удаление запрещено.
|
|
238
|
+
3. **Удаление только подтверждённого осиротевшего lock-файла**: Только после подтверждения статуса сироты удалите конкретный файл блокировки без рекурсивных и force-флагов:
|
|
239
|
+
```bash
|
|
240
|
+
rm ~/.dsh/profiles/<profile>/package.json.lock
|
|
241
|
+
```
|
|
242
|
+
4. **Возобновление работы**: Разрешите запуск процессов установки и повторите обновление плагина.
|
|
236
243
|
|
|
237
244
|
---
|
|
238
245
|
|
package/README.zh.md
CHANGED
|
@@ -145,14 +145,21 @@ v0.8.18 质量审查后的修复批次(Gitea #79–#87,PR #88):
|
|
|
145
145
|
* `POST /api/dsh-voice/update` — 触发插件自动更新至 npm 最新兼容版本(受本地调用与锁校验保护)
|
|
146
146
|
* `GET /api/dsh-voice/update` — 获取更新检查状态与版本信息
|
|
147
147
|
|
|
148
|
-
### 🔒
|
|
149
|
-
在安装或更新插件时,DeepSeek Harness 使用 `<profile-dir>/package.json.lock
|
|
150
|
-
* **规范竞争者策略**: 竞争者进程绝不删除现有的锁定文件。禁止竞争者自动清理残留锁,以杜绝 TOCTOU
|
|
151
|
-
* **诊断信息**: 若存在 lock 文件,更新请求将返回 `409 Conflict`
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
148
|
+
### 🔒 配置文件锁与受控操作员恢复机制
|
|
149
|
+
在安装或更新插件时,DeepSeek Harness 使用 `<profile-dir>/package.json.lock`(例如 `~/.dsh/profiles/<profile>/package.json.lock`)协调并发操作。
|
|
150
|
+
* **规范竞争者策略**: 竞争者进程绝不删除现有的锁定文件。禁止竞争者自动清理残留锁,以杜绝 TOCTOU 竞态条件并避免破坏配置文件状态。
|
|
151
|
+
* **诊断信息**: 若存在 lock 文件,更新请求将返回 `409 Conflict` 并附带诊断说明:
|
|
152
|
+
- 若由活跃进程持有,则报告其 PID。
|
|
153
|
+
- 若遭遇文件系统访问错误(`EACCES`、`EIO`),则安全失败(fail-closed)并保留错误码。文件系统错误需要检查磁盘健康度、目录权限或挂载选项——**请勿**因 `EACCES`/`EIO` 错误而删除锁文件。
|
|
154
|
+
* **受控操作员恢复流程**:
|
|
155
|
+
若先前安装进程异常终止(如 OOM 终止或系统断电)留下僵死锁,必须由操作员按以下受控流程进行清理:
|
|
156
|
+
1. **建立独占维护窗口**: 确保目标配置文件当前没有正在运行或计划启动的并发安装任务(CLI 命令 `dsh plugin add`、Web UI 交互或自动更新器)。
|
|
157
|
+
2. **确认静止状态与无活跃属主**: 通过 `pgrep`、`ps`、`fuser` 或 `lsof` 确认目标配置文件目录下确实没有正在执行包操作的活跃进程。仅凭锁文件存在时间较长或 PID 未能解析**不足以**作为删除依据,前提必须是彻底排除其他进程启动的可能。若无法确认静止状态,切勿删除。
|
|
158
|
+
3. **安全删除已确认的孤立锁**: 只有在完全确认锁文件已孤立且处于维护窗口期时,才允许由操作员手动删除该特定锁文件(严禁使用递归或 force 标志):
|
|
159
|
+
```bash
|
|
160
|
+
rm ~/.dsh/profiles/<profile>/package.json.lock
|
|
161
|
+
```
|
|
162
|
+
4. **恢复正常运行**: 重新开启安装通道并重试插件更新。
|
|
156
163
|
|
|
157
164
|
---
|
|
158
165
|
|
package/lib/client.js
CHANGED
|
@@ -219,9 +219,9 @@ window.__ModuleLoader__.load({
|
|
|
219
219
|
'updateSuccess': 'Updated successfully! Restart DSH to apply.',
|
|
220
220
|
'updateFailed': 'Update failed. Check logs.',
|
|
221
221
|
'updateCheckFailed': 'Update check failed',
|
|
222
|
-
'profileLockedPid': 'Profile is locked by process (PID {pid}).
|
|
223
|
-
'profileLockedExisting': 'Profile is locked by an existing lockfile.
|
|
224
|
-
'profileLockCheckError': 'Profile lock check failed. Filesystem inspection
|
|
222
|
+
'profileLockedPid': 'Profile is locked by process (PID {pid}). Follow documented controlled operator recovery procedure if stale.',
|
|
223
|
+
'profileLockedExisting': 'Profile is locked by an existing lockfile. Follow documented controlled operator recovery procedure if stale.',
|
|
224
|
+
'profileLockCheckError': 'Profile lock check failed. Filesystem inspection required (do not remove lockfile).',
|
|
225
225
|
'checkingUpdates': 'Checking updates…',
|
|
226
226
|
'updateStatusUnknown': 'Version status unknown',
|
|
227
227
|
'sensevoiceTitle': 'SenseVoice Local ASR (1-Click Setup)',
|
|
@@ -437,9 +437,9 @@ window.__ModuleLoader__.load({
|
|
|
437
437
|
'updateSuccess': '更新成功!请重启 DSH 生效。',
|
|
438
438
|
'updateFailed': '更新失败,请查看日志。',
|
|
439
439
|
'updateCheckFailed': '检查更新失败',
|
|
440
|
-
'profileLockedPid': '配置文件已被进程锁定 (PID {pid})
|
|
441
|
-
'profileLockedExisting': '
|
|
442
|
-
'profileLockCheckError': '
|
|
440
|
+
'profileLockedPid': '配置文件已被进程锁定 (PID {pid})。若残留请按受控操作员恢复流程处理。',
|
|
441
|
+
'profileLockedExisting': '配置文件已被现有锁定文件锁定。若残留请按受控操作员恢复流程处理。',
|
|
442
|
+
'profileLockCheckError': '检查配置文件锁失败。需排查文件系统,请勿直接删除锁文件。',
|
|
443
443
|
'checkingUpdates': '正在检查更新…',
|
|
444
444
|
'updateStatusUnknown': '版本状态未知',
|
|
445
445
|
'sensevoiceTitle': 'SenseVoice 本地 ASR (一键部署)',
|
package/lib/updater.js
CHANGED
|
@@ -211,12 +211,12 @@ export function checkProfileLock(profileDir) {
|
|
|
211
211
|
export function formatLockDiagnostic(lockStatus) {
|
|
212
212
|
if (!lockStatus?.locked) return null;
|
|
213
213
|
if (lockStatus.error) {
|
|
214
|
-
return `Profile lock check failed with error ${lockStatus.error}.
|
|
214
|
+
return `Profile lock check failed with error ${lockStatus.error}. Filesystem inspection required (do not remove lockfile).`;
|
|
215
215
|
}
|
|
216
216
|
if (lockStatus.pid) {
|
|
217
|
-
return `Profile is locked by process (PID ${lockStatus.pid}).
|
|
217
|
+
return `Profile is locked by process (PID ${lockStatus.pid}). Follow documented controlled operator recovery procedure if the process terminated abnormally.`;
|
|
218
218
|
}
|
|
219
|
-
return 'Profile is locked by an existing lockfile.
|
|
219
|
+
return 'Profile is locked by an existing lockfile. Follow documented controlled operator recovery procedure if the process terminated abnormally.';
|
|
220
220
|
}
|
|
221
221
|
|
|
222
222
|
async function installExact(target, packageSpec, options) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goodandready/dsh-voice",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.27",
|
|
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",
|