opencode-interrupt-plugin 0.4.24 → 0.4.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/dist/index.d.ts +2 -4
- package/dist/index.js +53 -3
- package/package.json +2 -3
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,6 @@ import type { Plugin } from '@opencode-ai/plugin';
|
|
|
2
2
|
import type { TuiPlugin } from '@opencode-ai/plugin/tui';
|
|
3
3
|
import { type PluginConfig } from './config.js';
|
|
4
4
|
export declare const InterruptPlugin: (userConfig?: PluginConfig) => Plugin;
|
|
5
|
-
declare const
|
|
6
|
-
|
|
7
|
-
tui: TuiPlugin;
|
|
8
|
-
};
|
|
5
|
+
export declare const tui: TuiPlugin;
|
|
6
|
+
declare const _default: Plugin;
|
|
9
7
|
export default _default;
|
package/dist/index.js
CHANGED
|
@@ -113,10 +113,41 @@ async function transcribeAndSend(sessionID, directory, api) {
|
|
|
113
113
|
await api.client.session.prompt({ sessionID, directory, parts: [{ type: "text", text }] });
|
|
114
114
|
api.ui.toast({ variant: "success", title: "PTT", message: `Sent: "${text.slice(0, 60)}"` });
|
|
115
115
|
}
|
|
116
|
+
async function transcribeAndSendV1(sessionID, client) {
|
|
117
|
+
pttStopRecording();
|
|
118
|
+
if (!existsSync(RECORDING_FILE)) {
|
|
119
|
+
await client.tui.showToast({ body: { title: "PTT", message: "No audio captured", variant: "warning" } });
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
await client.tui.showToast({ body: { title: "PTT", message: "Transcribing...", variant: "info" } });
|
|
123
|
+
let text = null;
|
|
124
|
+
text = await transcribeLocal();
|
|
125
|
+
if (!text)
|
|
126
|
+
text = await transcribeAPI();
|
|
127
|
+
if (!text) {
|
|
128
|
+
await client.tui.showToast({ body: { title: "PTT", message: "Missing whisper — run scripts/install-whisper.sh or set OPENAI_API_KEY", variant: "error" } });
|
|
129
|
+
try {
|
|
130
|
+
unlinkSync(RECORDING_FILE);
|
|
131
|
+
}
|
|
132
|
+
catch { /* ignore */ }
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
unlinkSync(RECORDING_FILE);
|
|
137
|
+
}
|
|
138
|
+
catch { /* ignore */ }
|
|
139
|
+
if (!sessionID) {
|
|
140
|
+
await client.tui.showToast({ body: { title: "PTT", message: "No active session", variant: "warning" } });
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
await client.session.prompt({ path: { id: sessionID }, body: { parts: [{ type: "text", text }] } });
|
|
144
|
+
await client.tui.showToast({ body: { title: "PTT", message: `Sent: "${text.slice(0, 60)}"`, variant: "success" } });
|
|
145
|
+
}
|
|
116
146
|
const TTS_COMMANDS = [
|
|
117
147
|
{ name: 'tts-on', description: 'Enable streaming TTS', template: 'TTS enabled.' },
|
|
118
148
|
{ name: 'tts-off', description: 'Disable streaming TTS', template: 'TTS disabled.' },
|
|
119
149
|
{ name: 'tts-speak', description: 'Speak text immediately', template: '$ARGUMENTS' },
|
|
150
|
+
{ name: 'interrupt-ptt', description: 'Toggle walkie-talkie recording (start/stop + transcribe)', template: 'Toggles PTT recording.' },
|
|
120
151
|
];
|
|
121
152
|
export const InterruptPlugin = (userConfig = {}) => {
|
|
122
153
|
return async ({ client }) => {
|
|
@@ -289,8 +320,27 @@ export const InterruptPlugin = (userConfig = {}) => {
|
|
|
289
320
|
}
|
|
290
321
|
},
|
|
291
322
|
'command.execute.before': async (cmdInput) => {
|
|
292
|
-
if (!cmdInput.command.startsWith('tts-'))
|
|
323
|
+
if (!cmdInput.command.startsWith('tts-') && cmdInput.command !== 'interrupt-ptt')
|
|
293
324
|
return;
|
|
325
|
+
if (cmdInput.command === 'interrupt-ptt') {
|
|
326
|
+
const sessionID = cmdInput.sessionID;
|
|
327
|
+
if (pttActive) {
|
|
328
|
+
pttActive = false;
|
|
329
|
+
await transcribeAndSendV1(sessionID, client);
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
pttActive = true;
|
|
333
|
+
if (sessionID) {
|
|
334
|
+
try {
|
|
335
|
+
await client.session.abort({ path: { id: sessionID } });
|
|
336
|
+
}
|
|
337
|
+
catch { /* ignore */ }
|
|
338
|
+
}
|
|
339
|
+
pttStartRecording();
|
|
340
|
+
await client.tui.showToast({ body: { title: "PTT", message: "Recording... (/ptt again to send)", variant: "info" } });
|
|
341
|
+
}
|
|
342
|
+
throw new Error('Command handled by interrupt plugin');
|
|
343
|
+
}
|
|
294
344
|
if (cmdInput.command === 'tts-on') {
|
|
295
345
|
ttsStreamer.enable();
|
|
296
346
|
throw new Error('Command handled by interrupt plugin');
|
|
@@ -393,7 +443,7 @@ function extractText(parts) {
|
|
|
393
443
|
return '';
|
|
394
444
|
}
|
|
395
445
|
}
|
|
396
|
-
const
|
|
446
|
+
export const tui = async (api, _options, _meta) => {
|
|
397
447
|
console.log("[interrupt] TUI plugin initializing");
|
|
398
448
|
try {
|
|
399
449
|
api.keymap.registerLayer({
|
|
@@ -444,4 +494,4 @@ const tuiFn = async (api, _options, _meta) => {
|
|
|
444
494
|
pttActive = false;
|
|
445
495
|
});
|
|
446
496
|
};
|
|
447
|
-
export default
|
|
497
|
+
export default InterruptPlugin();
|
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "opencode-interrupt-plugin",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.27",
|
|
4
4
|
"description": "Streaming TTS + voice interruption for OpenCode. Speaks responses as they arrive and detects when you talk over it.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"exports": {
|
|
9
|
-
".": "./dist/index.js"
|
|
10
|
-
"./tui": "./dist/index.js"
|
|
9
|
+
".": "./dist/index.js"
|
|
11
10
|
},
|
|
12
11
|
"files": [
|
|
13
12
|
"dist/",
|