gsd-pi 0.3.1 → 2.3.4

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.
@@ -0,0 +1,76 @@
1
+ import Foundation
2
+ import Speech
3
+ import AVFoundation
4
+
5
+ // Unbuffered stdout
6
+ setbuf(stdout, nil)
7
+
8
+ guard SFSpeechRecognizer.authorizationStatus() == .authorized ||
9
+ SFSpeechRecognizer.authorizationStatus() == .notDetermined else {
10
+ print("ERROR:Speech recognition not authorized")
11
+ exit(1)
12
+ }
13
+
14
+ SFSpeechRecognizer.requestAuthorization { status in
15
+ guard status == .authorized else {
16
+ print("ERROR:Speech recognition denied")
17
+ exit(1)
18
+ }
19
+ }
20
+
21
+ let recognizer = SFSpeechRecognizer(locale: Locale(identifier: "en-US"))!
22
+ guard recognizer.isAvailable else {
23
+ print("ERROR:Speech recognizer not available")
24
+ exit(1)
25
+ }
26
+
27
+ let audioEngine = AVAudioEngine()
28
+ let request = SFSpeechAudioBufferRecognitionRequest()
29
+ request.shouldReportPartialResults = true
30
+ request.requiresOnDeviceRecognition = true
31
+
32
+ let node = audioEngine.inputNode
33
+ let format = node.outputFormat(forBus: 0)
34
+
35
+ node.installTap(onBus: 0, bufferSize: 1024, format: format) { buffer, _ in
36
+ request.append(buffer)
37
+ }
38
+
39
+ audioEngine.prepare()
40
+ do {
41
+ try audioEngine.start()
42
+ print("READY")
43
+ } catch {
44
+ print("ERROR:Failed to start audio engine: \(error.localizedDescription)")
45
+ exit(1)
46
+ }
47
+
48
+ var lastText = ""
49
+
50
+ recognizer.recognitionTask(with: request) { result, error in
51
+ if let result = result {
52
+ let text = result.bestTranscription.formattedString
53
+ if text != lastText {
54
+ lastText = text
55
+ let prefix = result.isFinal ? "FINAL" : "PARTIAL"
56
+ print("\(prefix):\(text)")
57
+ }
58
+ }
59
+ if let error = error {
60
+ // Task finished errors are normal on kill
61
+ let nsError = error as NSError
62
+ if nsError.code != 216 { // kAFAssistantErrorDomain code for cancelled
63
+ print("ERROR:\(error.localizedDescription)")
64
+ }
65
+ }
66
+ }
67
+
68
+ // Handle SIGTERM/SIGINT gracefully
69
+ signal(SIGTERM) { _ in
70
+ exit(0)
71
+ }
72
+ signal(SIGINT) { _ in
73
+ exit(0)
74
+ }
75
+
76
+ RunLoop.current.run()
@@ -1,34 +0,0 @@
1
- import { readFileSync } from "node:fs";
2
- import { join } from "node:path";
3
- import type { ExtensionAPI, ExtensionCommandContext } from "@mariozechner/pi-coding-agent";
4
-
5
- export default function gsdRun(pi: ExtensionAPI) {
6
- pi.registerCommand("gsd-run", {
7
- description: "Read GSD-WORKFLOW.md and execute — lightweight protocol-driven GSD",
8
- async handler(args: string, ctx: ExtensionCommandContext) {
9
- const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(process.env.HOME ?? "~", ".pi", "GSD-WORKFLOW.md");
10
-
11
- let workflow: string;
12
- try {
13
- workflow = readFileSync(workflowPath, "utf-8");
14
- } catch {
15
- ctx.ui.notify(`Cannot read ${workflowPath}`, "error");
16
- return;
17
- }
18
-
19
- const userNote = (typeof args === "string" ? args : "").trim();
20
- const noteSection = userNote
21
- ? `\n\n## User Note\n\n${userNote}\n`
22
- : "";
23
-
24
- pi.sendMessage(
25
- {
26
- customType: "gsd-run",
27
- content: `Read the following GSD workflow protocol and execute exactly.\n\n${workflow}${noteSection}`,
28
- display: false,
29
- },
30
- { triggerTurn: true },
31
- );
32
- },
33
- });
34
- }