dsh-agent-voice 0.1.6 → 0.1.7

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/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.1.7
2
+
3
+ - System-level playback: announcement WAV is played through macOS afplay (independent of browser autoplay policy), so the voice is heard on every tab and in the background.
4
+ - macOS notification (osascript) on attention requests: visible alert + sound when the agent needs the user at the keyboard.
5
+
1
6
  # Changelog
2
7
 
3
8
  ## 0.1.0
package/lib/index.js CHANGED
@@ -125,6 +125,34 @@ function apply(ctx) {
125
125
  return await readFile(res.audio);
126
126
  }
127
127
 
128
+ // System-level playback: browsers block audio.play() until a user gesture,
129
+ // so the in-page overlay player alone is unreliable. Playing the WAV through
130
+ // macOS afplay guarantees the announcement is heard on every tab (and even
131
+ // when the browser is in the background). Fire-and-forget.
132
+ async function systemPlay(wav) {
133
+ try {
134
+ const tmp = join(AUDIO_DIR, "tmp-" + String(Date.now()) + "-" + Math.random().toString(36).slice(2) + ".wav");
135
+ await writeFile(tmp, wav);
136
+ const af = spawn("/usr/bin/afplay", [tmp], { detached: true, stdio: "ignore" });
137
+ af.unref?.();
138
+ setTimeout(() => {
139
+ try { spawn("/bin/rm", ["-f", tmp]); } catch {}
140
+ }, 30000).unref?.();
141
+ } catch {}
142
+ }
143
+
144
+ // macOS notification (attention only): visible alert + sound even when the
145
+ // browser window is not focused — the "I need you at the keyboard" signal.
146
+ function systemNotify(title, text) {
147
+ try {
148
+ const scr = [
149
+ 'display notification ' + JSON.stringify(String(text).slice(0, 120)) + ' with title ' + JSON.stringify(title),
150
+ ].join("\n");
151
+ const osa = spawn("/usr/bin/osascript", ["-e", scr], { detached: true, stdio: "ignore" });
152
+ osa.unref?.();
153
+ } catch {}
154
+ }
155
+
128
156
  async function announce(kind, text) {
129
157
  const cfg = source();
130
158
  if (!cfg.enabled) return { ok: false, skipped: "disabled" };
@@ -141,6 +169,11 @@ function apply(ctx) {
141
169
  await ctx.settings.replace(STATUS_NS, { json: JSON.stringify(payload) });
142
170
  audioCache.set(id, wav);
143
171
  setTimeout(() => audioCache.delete(id), 60000).unref?.();
172
+ // Always play system-wide (independent of browser autoplay policy).
173
+ systemPlay(wav);
174
+ if (kind === "attention") {
175
+ systemNotify("🔔 DSH — potřebuji tě", text);
176
+ }
144
177
  return { ok: true, kind, text };
145
178
  }
146
179
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dsh-agent-voice",
3
- "version": "0.1.6",
4
- "description": "DeepSeek Harness plugin: gives the agent a voice it reads completed tasks and attention requests aloud (never reasoning or interim reports) via local Piper / XTTS v2, with a settings panel and a curated set of voices.",
3
+ "version": "0.1.7",
4
+ "description": "DeepSeek Harness plugin: gives the agent a voice \u2014 it reads completed tasks and attention requests aloud (never reasoning or interim reports) via local Piper / XTTS v2, with a settings panel and a curated set of voices.",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
7
7
  "files": [
@@ -17,7 +17,7 @@
17
17
  "node": ">=22"
18
18
  },
19
19
  "license": "MIT",
20
- "author": "Michal Ožuch",
20
+ "author": "Michal O\u017euch",
21
21
  "keywords": [
22
22
  "deepseek-harness",
23
23
  "dsh",
@@ -57,4 +57,4 @@
57
57
  "@deepseek-ai/dsh-settings": "^0.1.1-rc.2"
58
58
  },
59
59
  "dependencies": {}
60
- }
60
+ }