aibroker 0.1.0
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/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/adapters/iterm/core.d.ts +28 -0
- package/dist/adapters/iterm/core.d.ts.map +1 -0
- package/dist/adapters/iterm/core.js +191 -0
- package/dist/adapters/iterm/core.js.map +1 -0
- package/dist/adapters/iterm/dictation.d.ts +26 -0
- package/dist/adapters/iterm/dictation.d.ts.map +1 -0
- package/dist/adapters/iterm/dictation.js +99 -0
- package/dist/adapters/iterm/dictation.js.map +1 -0
- package/dist/adapters/iterm/sessions.d.ts +31 -0
- package/dist/adapters/iterm/sessions.d.ts.map +1 -0
- package/dist/adapters/iterm/sessions.js +156 -0
- package/dist/adapters/iterm/sessions.js.map +1 -0
- package/dist/adapters/kokoro/media.d.ts +32 -0
- package/dist/adapters/kokoro/media.d.ts.map +1 -0
- package/dist/adapters/kokoro/media.js +157 -0
- package/dist/adapters/kokoro/media.js.map +1 -0
- package/dist/adapters/kokoro/tts.d.ts +19 -0
- package/dist/adapters/kokoro/tts.d.ts.map +1 -0
- package/dist/adapters/kokoro/tts.js +157 -0
- package/dist/adapters/kokoro/tts.js.map +1 -0
- package/dist/adapters/session/backend.d.ts +22 -0
- package/dist/adapters/session/backend.d.ts.map +1 -0
- package/dist/adapters/session/backend.js +43 -0
- package/dist/adapters/session/backend.js.map +1 -0
- package/dist/backend/api.d.ts +20 -0
- package/dist/backend/api.d.ts.map +1 -0
- package/dist/backend/api.js +26 -0
- package/dist/backend/api.js.map +1 -0
- package/dist/core/log.d.ts +7 -0
- package/dist/core/log.d.ts.map +1 -0
- package/dist/core/log.js +14 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/markdown.d.ts +32 -0
- package/dist/core/markdown.d.ts.map +1 -0
- package/dist/core/markdown.js +71 -0
- package/dist/core/markdown.js.map +1 -0
- package/dist/core/mime.d.ts +11 -0
- package/dist/core/mime.d.ts.map +1 -0
- package/dist/core/mime.js +46 -0
- package/dist/core/mime.js.map +1 -0
- package/dist/core/persistence.d.ts +20 -0
- package/dist/core/persistence.d.ts.map +1 -0
- package/dist/core/persistence.js +108 -0
- package/dist/core/persistence.js.map +1 -0
- package/dist/core/router.d.ts +24 -0
- package/dist/core/router.d.ts.map +1 -0
- package/dist/core/router.js +38 -0
- package/dist/core/router.js.map +1 -0
- package/dist/core/state.d.ts +45 -0
- package/dist/core/state.d.ts.map +1 -0
- package/dist/core/state.js +82 -0
- package/dist/core/state.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +38 -0
- package/dist/index.js.map +1 -0
- package/dist/ipc/client.d.ts +45 -0
- package/dist/ipc/client.d.ts.map +1 -0
- package/dist/ipc/client.js +199 -0
- package/dist/ipc/client.js.map +1 -0
- package/dist/ipc/server.d.ts +34 -0
- package/dist/ipc/server.d.ts.map +1 -0
- package/dist/ipc/server.js +123 -0
- package/dist/ipc/server.js.map +1 -0
- package/dist/types/backend.d.ts +25 -0
- package/dist/types/backend.d.ts.map +1 -0
- package/dist/types/backend.js +9 -0
- package/dist/types/backend.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/ipc.d.ts +18 -0
- package/dist/types/ipc.d.ts.map +1 -0
- package/dist/types/ipc.js +6 -0
- package/dist/types/ipc.js.map +1 -0
- package/dist/types/session.d.ts +29 -0
- package/dist/types/session.d.ts.map +1 -0
- package/dist/types/session.js +5 -0
- package/dist/types/session.js.map +1 -0
- package/dist/types/transport.d.ts +43 -0
- package/dist/types/transport.d.ts.map +1 -0
- package/dist/types/transport.js +8 -0
- package/dist/types/transport.js.map +1 -0
- package/dist/types/voice.d.ts +17 -0
- package/dist/types/voice.d.ts.map +1 -0
- package/dist/types/voice.js +5 -0
- package/dist/types/voice.js.map +1 -0
- package/package.json +35 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Matthias Nott
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# aibroker
|
|
2
|
+
|
|
3
|
+
Platform-agnostic AI message broker — shared infrastructure for messaging
|
|
4
|
+
bridges that connect WhatsApp, Telegram, and other channels to Claude Code.
|
|
5
|
+
|
|
6
|
+
## Family
|
|
7
|
+
|
|
8
|
+
| Package | Channel | Repo |
|
|
9
|
+
|---------|---------|------|
|
|
10
|
+
| **aibroker** | Shared core | [github.com/mnott/AIBroker](https://github.com/mnott/AIBroker) |
|
|
11
|
+
| **whazaa** | WhatsApp | [github.com/mnott/Whazaa](https://github.com/mnott/Whazaa) |
|
|
12
|
+
| **telex** | Telegram | [github.com/mnott/Telex](https://github.com/mnott/Telex) |
|
|
13
|
+
|
|
14
|
+
## What's Inside
|
|
15
|
+
|
|
16
|
+
- Logging with configurable prefix (`setLogPrefix`)
|
|
17
|
+
- Session state management and message queuing
|
|
18
|
+
- File persistence with configurable data dir (`setAppDir`)
|
|
19
|
+
- Unix Domain Socket IPC (server + client)
|
|
20
|
+
- macOS iTerm2 adapter (AppleScript session management)
|
|
21
|
+
- Kokoro TTS (local speech synthesis + Whisper transcription)
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { setLogPrefix, setAppDir } from "aibroker";
|
|
27
|
+
|
|
28
|
+
setLogPrefix("my-app");
|
|
29
|
+
setAppDir("/path/to/data");
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Hard Rule
|
|
33
|
+
|
|
34
|
+
aibroker never imports `@whiskeysockets/baileys`, `telegram`/`gramjs`,
|
|
35
|
+
`better-sqlite3`, `qrcode`, or any transport SDK. Those belong in
|
|
36
|
+
the per-channel packages.
|
|
37
|
+
|
|
38
|
+
## License
|
|
39
|
+
|
|
40
|
+
MIT — Matthias Nott
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/iterm/core.ts — Low-level iTerm2 AppleScript primitives.
|
|
3
|
+
*
|
|
4
|
+
* Foundation of all iTerm2 communication. Wraps `osascript` and `spawnSync`
|
|
5
|
+
* with zero transport-specific imports.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runAppleScript(script: string): string | null;
|
|
8
|
+
export declare function stripItermPrefix(id: string | undefined): string | undefined;
|
|
9
|
+
export declare function withSessionAppleScript(sessionId: string, body: string, fallback?: string): string;
|
|
10
|
+
export declare function sendKeystrokeToSession(sessionId: string, asciiCode: number): boolean;
|
|
11
|
+
export declare function sendEscapeSequenceToSession(sessionId: string, dirChar: string): boolean;
|
|
12
|
+
export declare function typeIntoSession(sessionId: string, text: string): boolean;
|
|
13
|
+
export declare function pasteTextIntoSession(sessionId: string, text: string): boolean;
|
|
14
|
+
export declare function findClaudeSession(): string | null;
|
|
15
|
+
export declare function isClaudeRunningInSession(sessionId: string): boolean;
|
|
16
|
+
export declare function isItermRunning(): boolean;
|
|
17
|
+
export declare function isItermSessionAlive(sessionId: string): boolean;
|
|
18
|
+
export declare function isScreenLocked(): boolean;
|
|
19
|
+
export declare function writeToTty(ttyPath: string, text: string): boolean;
|
|
20
|
+
export interface SessionSnapshot {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
tty: string;
|
|
24
|
+
atPrompt: boolean;
|
|
25
|
+
paiName: string | null;
|
|
26
|
+
}
|
|
27
|
+
export declare function snapshotAllSessions(): SessionSnapshot[];
|
|
28
|
+
//# sourceMappingURL=core.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../../src/adapters/iterm/core.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ5D;AAED,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAI3E;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,SAAc,GAAG,MAAM,CActG;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAQpF;AAED,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAQvF;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAIxE;AAED,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAQ7E;AAED,wBAAgB,iBAAiB,IAAI,MAAM,GAAG,IAAI,CA+BjD;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAcnE;AAED,wBAAgB,cAAc,IAAI,OAAO,CAMxC;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAO9D;AAED,wBAAgB,cAAc,IAAI,OAAO,CAWxC;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CA8BjE;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,wBAAgB,mBAAmB,IAAI,eAAe,EAAE,CAyCvD"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/iterm/core.ts — Low-level iTerm2 AppleScript primitives.
|
|
3
|
+
*
|
|
4
|
+
* Foundation of all iTerm2 communication. Wraps `osascript` and `spawnSync`
|
|
5
|
+
* with zero transport-specific imports.
|
|
6
|
+
*/
|
|
7
|
+
import { spawnSync } from "node:child_process";
|
|
8
|
+
import { log } from "../../core/log.js";
|
|
9
|
+
export function runAppleScript(script) {
|
|
10
|
+
const result = spawnSync("osascript", [], {
|
|
11
|
+
input: script,
|
|
12
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
13
|
+
timeout: 4_000,
|
|
14
|
+
});
|
|
15
|
+
if (result.status !== 0)
|
|
16
|
+
return null;
|
|
17
|
+
return result.stdout?.toString().trim() ?? null;
|
|
18
|
+
}
|
|
19
|
+
export function stripItermPrefix(id) {
|
|
20
|
+
if (!id)
|
|
21
|
+
return id;
|
|
22
|
+
const colonIdx = id.lastIndexOf(":");
|
|
23
|
+
return colonIdx >= 0 ? id.slice(colonIdx + 1) : id;
|
|
24
|
+
}
|
|
25
|
+
export function withSessionAppleScript(sessionId, body, fallback = 'return ""') {
|
|
26
|
+
const escaped = sessionId.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
27
|
+
return `tell application "iTerm2"
|
|
28
|
+
repeat with aWindow in windows
|
|
29
|
+
repeat with aTab in tabs of aWindow
|
|
30
|
+
repeat with aSession in sessions of aTab
|
|
31
|
+
if id of aSession is "${escaped}" then
|
|
32
|
+
${body}
|
|
33
|
+
end if
|
|
34
|
+
end repeat
|
|
35
|
+
end repeat
|
|
36
|
+
end repeat
|
|
37
|
+
${fallback}
|
|
38
|
+
end tell`;
|
|
39
|
+
}
|
|
40
|
+
export function sendKeystrokeToSession(sessionId, asciiCode) {
|
|
41
|
+
const script = withSessionAppleScript(sessionId, ` tell aSession to write text (ASCII character ${asciiCode}) newline no\n return "ok"`, 'return "not_found"');
|
|
42
|
+
const result = runAppleScript(script);
|
|
43
|
+
return result === "ok";
|
|
44
|
+
}
|
|
45
|
+
export function sendEscapeSequenceToSession(sessionId, dirChar) {
|
|
46
|
+
const script = withSessionAppleScript(sessionId, ` tell aSession to write text (ASCII character 27) & "[${dirChar}" newline no\n return "ok"`, 'return "not_found"');
|
|
47
|
+
const result = runAppleScript(script);
|
|
48
|
+
return result === "ok";
|
|
49
|
+
}
|
|
50
|
+
export function typeIntoSession(sessionId, text) {
|
|
51
|
+
if (!pasteTextIntoSession(sessionId, text))
|
|
52
|
+
return false;
|
|
53
|
+
sendKeystrokeToSession(sessionId, 13);
|
|
54
|
+
return true;
|
|
55
|
+
}
|
|
56
|
+
export function pasteTextIntoSession(sessionId, text) {
|
|
57
|
+
const escaped = text.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
58
|
+
const textScript = withSessionAppleScript(sessionId, ` tell aSession to write text "${escaped}" newline no\n return "ok"`, 'return "not_found"');
|
|
59
|
+
return runAppleScript(textScript) === "ok";
|
|
60
|
+
}
|
|
61
|
+
export function findClaudeSession() {
|
|
62
|
+
const script = `
|
|
63
|
+
tell application "iTerm2"
|
|
64
|
+
set output to ""
|
|
65
|
+
repeat with aWindow in windows
|
|
66
|
+
repeat with aTab in tabs of aWindow
|
|
67
|
+
repeat with aSession in sessions of aTab
|
|
68
|
+
set sessionId to id of aSession
|
|
69
|
+
set sessionName to name of aSession
|
|
70
|
+
set output to output & sessionId & (ASCII character 9) & sessionName & linefeed
|
|
71
|
+
end repeat
|
|
72
|
+
end repeat
|
|
73
|
+
end repeat
|
|
74
|
+
return output
|
|
75
|
+
end tell`;
|
|
76
|
+
const result = runAppleScript(script);
|
|
77
|
+
if (!result)
|
|
78
|
+
return null;
|
|
79
|
+
const lines = result.split("\n").filter(Boolean);
|
|
80
|
+
for (const line of lines) {
|
|
81
|
+
const tabIdx = line.indexOf("\t");
|
|
82
|
+
if (tabIdx < 0)
|
|
83
|
+
continue;
|
|
84
|
+
const id = line.substring(0, tabIdx);
|
|
85
|
+
const name = line.substring(tabIdx + 1).toLowerCase();
|
|
86
|
+
if (name.includes("claude")) {
|
|
87
|
+
log(`Found claude session: ${id} ("${line.substring(tabIdx + 1)}")`);
|
|
88
|
+
return id;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
export function isClaudeRunningInSession(sessionId) {
|
|
94
|
+
const script = withSessionAppleScript(sessionId, ` if (is at shell prompt of aSession) then\n return "shell"\n else\n return "running"\n end if`, 'return "not_found"');
|
|
95
|
+
const result = runAppleScript(script);
|
|
96
|
+
if (result === "running")
|
|
97
|
+
return true;
|
|
98
|
+
if (result === "shell") {
|
|
99
|
+
log(`Session ${sessionId} is at shell prompt — Claude has exited.`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
log(`Session ${sessionId} not found in iTerm2.`);
|
|
103
|
+
}
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
export function isItermRunning() {
|
|
107
|
+
const result = spawnSync("pgrep", ["-x", "iTerm2"], {
|
|
108
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
109
|
+
timeout: 3_000,
|
|
110
|
+
});
|
|
111
|
+
return result.status === 0;
|
|
112
|
+
}
|
|
113
|
+
export function isItermSessionAlive(sessionId) {
|
|
114
|
+
const script = withSessionAppleScript(sessionId, ` return "alive"`, 'return "gone"');
|
|
115
|
+
return runAppleScript(script) === "alive";
|
|
116
|
+
}
|
|
117
|
+
export function isScreenLocked() {
|
|
118
|
+
try {
|
|
119
|
+
const result = spawnSync("sh", ["-c", "ioreg -n Root -d1 -a | grep -c CGSSessionScreenIsLocked"], { timeout: 3_000, encoding: "utf8" });
|
|
120
|
+
return parseInt((result.stdout ?? "0").trim(), 10) > 0;
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export function writeToTty(ttyPath, text) {
|
|
127
|
+
if (!ttyPath || !ttyPath.startsWith("/dev/ttys")) {
|
|
128
|
+
log(`writeToTty: invalid tty path "${ttyPath}"`);
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
const statResult = spawnSync("test", ["-c", ttyPath], {
|
|
132
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
133
|
+
timeout: 1_000,
|
|
134
|
+
});
|
|
135
|
+
if (statResult.status !== 0) {
|
|
136
|
+
log(`writeToTty: device not found: ${ttyPath}`);
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
const safeText = text.replace(/'/g, "'\\''");
|
|
140
|
+
const writeResult = spawnSync("sh", ["-c", `printf '%s\\n' '${safeText}' > ${ttyPath}`], { stdio: ["pipe", "pipe", "pipe"], timeout: 2_000 });
|
|
141
|
+
if (writeResult.status !== 0) {
|
|
142
|
+
const stderr = writeResult.stderr?.toString().trim() ?? "";
|
|
143
|
+
log(`writeToTty: failed for ${ttyPath} — ${stderr || "exit " + writeResult.status}`);
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
log(`writeToTty: delivered ${text.length} chars to ${ttyPath}`);
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
export function snapshotAllSessions() {
|
|
150
|
+
const script = `
|
|
151
|
+
tell application "iTerm2"
|
|
152
|
+
set output to ""
|
|
153
|
+
repeat with aWindow in windows
|
|
154
|
+
repeat with aTab in tabs of aWindow
|
|
155
|
+
repeat with aSession in sessions of aTab
|
|
156
|
+
set sessionId to id of aSession
|
|
157
|
+
set sessionName to name of aSession
|
|
158
|
+
set sessionTty to tty of aSession
|
|
159
|
+
set isAtPrompt to (is at shell prompt of aSession)
|
|
160
|
+
tell aSession
|
|
161
|
+
try
|
|
162
|
+
set paiName to (variable named "user.paiName")
|
|
163
|
+
on error
|
|
164
|
+
set paiName to ""
|
|
165
|
+
end try
|
|
166
|
+
end tell
|
|
167
|
+
set output to output & sessionId & (ASCII character 9) & sessionName & (ASCII character 9) & sessionTty & (ASCII character 9) & (isAtPrompt as text) & (ASCII character 9) & paiName & linefeed
|
|
168
|
+
end repeat
|
|
169
|
+
end repeat
|
|
170
|
+
end repeat
|
|
171
|
+
return output
|
|
172
|
+
end tell`;
|
|
173
|
+
const result = runAppleScript(script);
|
|
174
|
+
if (!result)
|
|
175
|
+
return [];
|
|
176
|
+
const sessions = [];
|
|
177
|
+
for (const line of result.split("\n").filter(Boolean)) {
|
|
178
|
+
const parts = line.split("\t");
|
|
179
|
+
if (parts.length < 4)
|
|
180
|
+
continue;
|
|
181
|
+
sessions.push({
|
|
182
|
+
id: parts[0],
|
|
183
|
+
name: parts[1],
|
|
184
|
+
tty: parts[2],
|
|
185
|
+
atPrompt: parts[3] === "true",
|
|
186
|
+
paiName: (parts[4] && parts[4] !== "missing value" && parts[4] !== "") ? parts[4] : null,
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
return sessions;
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/adapters/iterm/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/iterm/dictation.ts — Local mic recording and Whisper transcription.
|
|
3
|
+
*
|
|
4
|
+
* Provides recordFromMic() and transcribeLocalAudio() for desk dictation.
|
|
5
|
+
* Both functions use sox for recording and the Whisper CLI for transcription.
|
|
6
|
+
*/
|
|
7
|
+
/** Absolute path to the Whisper CLI binary. */
|
|
8
|
+
export declare const WHISPER_BIN: string;
|
|
9
|
+
/** Whisper model name (overridable via AIBROKER_WHISPER_MODEL env). */
|
|
10
|
+
export declare const WHISPER_MODEL: string;
|
|
11
|
+
/**
|
|
12
|
+
* Record audio from the default Mac microphone using sox.
|
|
13
|
+
* Stops automatically after ~2 seconds of silence.
|
|
14
|
+
*
|
|
15
|
+
* @param maxDurationSec - Maximum recording duration (default 60s).
|
|
16
|
+
* @returns Absolute path to the recorded WAV file.
|
|
17
|
+
*/
|
|
18
|
+
export declare function recordFromMic(maxDurationSec?: number): Promise<string>;
|
|
19
|
+
/**
|
|
20
|
+
* Transcribe a local audio file using the Whisper CLI.
|
|
21
|
+
*
|
|
22
|
+
* @param audioPath - Absolute path to the audio file.
|
|
23
|
+
* @returns The raw transcript text.
|
|
24
|
+
*/
|
|
25
|
+
export declare function transcribeLocalAudio(audioPath: string): Promise<string>;
|
|
26
|
+
//# sourceMappingURL=dictation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dictation.d.ts","sourceRoot":"","sources":["../../../src/adapters/iterm/dictation.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,+CAA+C;AAC/C,eAAO,MAAM,WAAW,QAGR,CAAC;AAEjB,uEAAuE;AACvE,eAAO,MAAM,aAAa,QAA2H,CAAC;AAQtJ;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,cAAc,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAoCxE;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAyC7E"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/iterm/dictation.ts — Local mic recording and Whisper transcription.
|
|
3
|
+
*
|
|
4
|
+
* Provides recordFromMic() and transcribeLocalAudio() for desk dictation.
|
|
5
|
+
* Both functions use sox for recording and the Whisper CLI for transcription.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, unlinkSync } from "node:fs";
|
|
8
|
+
import { promisify } from "node:util";
|
|
9
|
+
import { tmpdir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { execFile } from "node:child_process";
|
|
12
|
+
import { log } from "../../core/log.js";
|
|
13
|
+
const execFileAsync = promisify(execFile);
|
|
14
|
+
/** Absolute path to the Whisper CLI binary. */
|
|
15
|
+
export const WHISPER_BIN = ["/opt/homebrew/bin/whisper", "/usr/local/bin/whisper", "whisper"].find((p) => p === "whisper" || existsSync(p)) ?? "whisper";
|
|
16
|
+
/** Whisper model name (overridable via AIBROKER_WHISPER_MODEL env). */
|
|
17
|
+
export const WHISPER_MODEL = process.env.AIBROKER_WHISPER_MODEL ?? process.env.MSGBRIDGE_WHISPER_MODEL ?? process.env.WHAZAA_WHISPER_MODEL ?? "small";
|
|
18
|
+
/** Absolute path to the sox binary. */
|
|
19
|
+
const SOX_BIN = ["/opt/homebrew/bin/sox", "/usr/local/bin/sox", "sox"].find((p) => p === "sox" || existsSync(p)) ?? "sox";
|
|
20
|
+
/**
|
|
21
|
+
* Record audio from the default Mac microphone using sox.
|
|
22
|
+
* Stops automatically after ~2 seconds of silence.
|
|
23
|
+
*
|
|
24
|
+
* @param maxDurationSec - Maximum recording duration (default 60s).
|
|
25
|
+
* @returns Absolute path to the recorded WAV file.
|
|
26
|
+
*/
|
|
27
|
+
export async function recordFromMic(maxDurationSec = 60) {
|
|
28
|
+
const wavPath = join(tmpdir(), `aibroker-dictation-${Date.now()}.wav`);
|
|
29
|
+
// Audible start indicator
|
|
30
|
+
execFile("afplay", ["/System/Library/Sounds/Tink.aiff"], () => { });
|
|
31
|
+
log(`Dictation: recording to ${wavPath} (max ${maxDurationSec}s)...`);
|
|
32
|
+
try {
|
|
33
|
+
await execFileAsync(SOX_BIN, [
|
|
34
|
+
"-d", "-r", "16000", "-c", "1", "-b", "16",
|
|
35
|
+
wavPath,
|
|
36
|
+
"silence", "1", "0.2", "1%", "1", "2.0", "1%",
|
|
37
|
+
], {
|
|
38
|
+
timeout: maxDurationSec * 1000,
|
|
39
|
+
env: {
|
|
40
|
+
...process.env,
|
|
41
|
+
PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env.PATH || "/usr/bin:/bin"}`,
|
|
42
|
+
},
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
if (!existsSync(wavPath)) {
|
|
47
|
+
throw new Error(`Recording failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
48
|
+
}
|
|
49
|
+
log("Dictation: sox exited (likely timeout/silence stop) — file exists, continuing.");
|
|
50
|
+
}
|
|
51
|
+
// Audible stop indicator
|
|
52
|
+
execFile("afplay", ["/System/Library/Sounds/Pop.aiff"], () => { });
|
|
53
|
+
log(`Dictation: recorded ${wavPath}`);
|
|
54
|
+
return wavPath;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Transcribe a local audio file using the Whisper CLI.
|
|
58
|
+
*
|
|
59
|
+
* @param audioPath - Absolute path to the audio file.
|
|
60
|
+
* @returns The raw transcript text.
|
|
61
|
+
*/
|
|
62
|
+
export async function transcribeLocalAudio(audioPath) {
|
|
63
|
+
const base = audioPath.replace(/\.[^.]+$/, "");
|
|
64
|
+
const baseName = base.split("/").pop();
|
|
65
|
+
const outDir = tmpdir();
|
|
66
|
+
const filesToClean = [
|
|
67
|
+
join(outDir, `${baseName}.txt`),
|
|
68
|
+
join(outDir, `${baseName}.json`),
|
|
69
|
+
join(outDir, `${baseName}.vtt`),
|
|
70
|
+
join(outDir, `${baseName}.srt`),
|
|
71
|
+
join(outDir, `${baseName}.tsv`),
|
|
72
|
+
];
|
|
73
|
+
try {
|
|
74
|
+
log(`Dictation: transcribing ${audioPath} (model=${WHISPER_MODEL})...`);
|
|
75
|
+
await execFileAsync(WHISPER_BIN, [audioPath, "--model", WHISPER_MODEL, "--output_format", "txt", "--output_dir", outDir, "--verbose", "False"], {
|
|
76
|
+
timeout: 120_000,
|
|
77
|
+
env: {
|
|
78
|
+
...process.env,
|
|
79
|
+
PATH: `/opt/homebrew/bin:/usr/local/bin:${process.env.PATH || "/usr/bin:/bin"}`,
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
const txtPath = join(outDir, `${baseName}.txt`);
|
|
83
|
+
if (!existsSync(txtPath)) {
|
|
84
|
+
throw new Error(`Whisper did not produce output at ${txtPath}`);
|
|
85
|
+
}
|
|
86
|
+
const transcript = readFileSync(txtPath, "utf-8").trim();
|
|
87
|
+
log(`Dictation: transcript (${transcript.length} chars): ${transcript.slice(0, 80)}`);
|
|
88
|
+
return transcript;
|
|
89
|
+
}
|
|
90
|
+
finally {
|
|
91
|
+
for (const f of filesToClean) {
|
|
92
|
+
try {
|
|
93
|
+
unlinkSync(f);
|
|
94
|
+
}
|
|
95
|
+
catch { /* ignore */ }
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=dictation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dictation.js","sourceRoot":"","sources":["../../../src/adapters/iterm/dictation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/iterm/sessions.ts — Higher-level iTerm2 session management.
|
|
3
|
+
*
|
|
4
|
+
* Session variables, tab naming, discovery, creation, and lifecycle.
|
|
5
|
+
* Does NOT import any transport send functions — callers handle message delivery.
|
|
6
|
+
*/
|
|
7
|
+
export declare function setItermSessionVar(itermSessionId: string, name: string): void;
|
|
8
|
+
export declare function setItermTabName(itermSessionId: string, name: string): void;
|
|
9
|
+
export declare function getItermSessionVar(itermSessionId: string): string | null;
|
|
10
|
+
export declare function findItermSessionForTermId(termSessionId: string, itermSessionIdHint?: string): string | null;
|
|
11
|
+
export declare function listClaudeSessions(): Array<{
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* Build a full session list with type classification and PAI name resolution.
|
|
17
|
+
* Returns the data used by /s command.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getSessionList(): Array<{
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
path: string;
|
|
23
|
+
type: "claude" | "terminal";
|
|
24
|
+
paiName: string | null;
|
|
25
|
+
atPrompt: boolean;
|
|
26
|
+
}>;
|
|
27
|
+
export declare function createClaudeSession(command?: string): string | null;
|
|
28
|
+
export declare function createTerminalTab(command?: string): string | null;
|
|
29
|
+
export declare function restartSession(itermSessionId: string, command?: string): Promise<void>;
|
|
30
|
+
export declare function killSession(itermSessionId: string): void;
|
|
31
|
+
//# sourceMappingURL=sessions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.d.ts","sourceRoot":"","sources":["../../../src/adapters/iterm/sessions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA6CH,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG7E;AAED,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAG1E;AAED,wBAAgB,kBAAkB,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBxE;AAID,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,kBAAkB,CAAC,EAAE,MAAM,GAC1B,MAAM,GAAG,IAAI,CA0Bf;AAID,wBAAgB,kBAAkB,IAAI,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAKxE;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,KAAK,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC,CAoBD;AAID,wBAAgB,mBAAmB,CAAC,OAAO,SAAW,GAAG,MAAM,GAAG,IAAI,CAkBrE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqBjE;AAID,wBAAsB,cAAc,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,SAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAI9F;AAED,wBAAgB,WAAW,CAAC,cAAc,EAAE,MAAM,GAAG,IAAI,CAMxD"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* adapters/iterm/sessions.ts — Higher-level iTerm2 session management.
|
|
3
|
+
*
|
|
4
|
+
* Session variables, tab naming, discovery, creation, and lifecycle.
|
|
5
|
+
* Does NOT import any transport send functions — callers handle message delivery.
|
|
6
|
+
*/
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
8
|
+
import { runAppleScript, typeIntoSession, sendKeystrokeToSession, stripItermPrefix, withSessionAppleScript, snapshotAllSessions, } from "./core.js";
|
|
9
|
+
import { log } from "../../core/log.js";
|
|
10
|
+
import { managedSessions, updateSessionTtyCache, } from "../../core/state.js";
|
|
11
|
+
// ── Session Variable Helpers ──
|
|
12
|
+
function setItermSessionProperty(itermSessionId, body) {
|
|
13
|
+
try {
|
|
14
|
+
const script = withSessionAppleScript(itermSessionId, ` tell aSession\n ${body}\n end tell\n return`, "");
|
|
15
|
+
execSync(`osascript <<'APPLESCRIPT'\n${script}\nAPPLESCRIPT`, {
|
|
16
|
+
timeout: 5000,
|
|
17
|
+
shell: "/bin/bash",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
// silently ignore
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function setItermSessionVar(itermSessionId, name) {
|
|
25
|
+
const escaped = name.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/[\n\r]/g, " ");
|
|
26
|
+
setItermSessionProperty(itermSessionId, `set variable named "user.paiName" to "${escaped}"`);
|
|
27
|
+
}
|
|
28
|
+
export function setItermTabName(itermSessionId, name) {
|
|
29
|
+
const escaped = name.replace(/\\/g, "\\\\").replace(/"/g, '\\"').replace(/[\n\r]/g, " ");
|
|
30
|
+
setItermSessionProperty(itermSessionId, `set name to "${escaped}"`);
|
|
31
|
+
}
|
|
32
|
+
export function getItermSessionVar(itermSessionId) {
|
|
33
|
+
try {
|
|
34
|
+
const script = withSessionAppleScript(itermSessionId, ` tell aSession\n try\n return (variable named "user.paiName")\n on error\n return ""\n end try\n end tell`, 'return ""');
|
|
35
|
+
const result = execSync(`osascript <<'APPLESCRIPT'\n${script}\nAPPLESCRIPT`, {
|
|
36
|
+
timeout: 5000,
|
|
37
|
+
encoding: "utf8",
|
|
38
|
+
shell: "/bin/bash",
|
|
39
|
+
}).trim();
|
|
40
|
+
return (result && result !== "missing value") ? result : null;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// ── Session Resolution ──
|
|
47
|
+
export function findItermSessionForTermId(termSessionId, itermSessionIdHint) {
|
|
48
|
+
if (itermSessionIdHint) {
|
|
49
|
+
return stripItermPrefix(itermSessionIdHint) ?? itermSessionIdHint;
|
|
50
|
+
}
|
|
51
|
+
const script = `
|
|
52
|
+
tell application "iTerm2"
|
|
53
|
+
set output to ""
|
|
54
|
+
repeat with aWindow in windows
|
|
55
|
+
repeat with aTab in tabs of aWindow
|
|
56
|
+
repeat with aSession in sessions of aTab
|
|
57
|
+
set envVal to ""
|
|
58
|
+
try
|
|
59
|
+
tell aSession to set envVal to (variable named "TERM_SESSION_ID")
|
|
60
|
+
end try
|
|
61
|
+
if envVal is "${termSessionId.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}" then
|
|
62
|
+
return id of aSession
|
|
63
|
+
end if
|
|
64
|
+
end repeat
|
|
65
|
+
end repeat
|
|
66
|
+
end repeat
|
|
67
|
+
return ""
|
|
68
|
+
end tell`;
|
|
69
|
+
const result = runAppleScript(script);
|
|
70
|
+
return (result && result.length > 0) ? result : null;
|
|
71
|
+
}
|
|
72
|
+
// ── Session Listing ──
|
|
73
|
+
export function listClaudeSessions() {
|
|
74
|
+
const sessions = snapshotAllSessions();
|
|
75
|
+
return sessions
|
|
76
|
+
.filter((s) => s.name.toLowerCase().includes("claude") || s.paiName)
|
|
77
|
+
.map((s) => ({ id: s.id, name: s.paiName ?? s.name }));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Build a full session list with type classification and PAI name resolution.
|
|
81
|
+
* Returns the data used by /s command.
|
|
82
|
+
*/
|
|
83
|
+
export function getSessionList() {
|
|
84
|
+
const snapshots = snapshotAllSessions();
|
|
85
|
+
// Update TTY cache
|
|
86
|
+
updateSessionTtyCache(snapshots.map((s) => ({ id: s.id, tty: s.tty })));
|
|
87
|
+
// Prune dead managed sessions
|
|
88
|
+
const aliveIds = new Set(snapshots.map((s) => s.id));
|
|
89
|
+
for (const [id] of managedSessions) {
|
|
90
|
+
if (!aliveIds.has(id))
|
|
91
|
+
managedSessions.delete(id);
|
|
92
|
+
}
|
|
93
|
+
return snapshots.map((s) => ({
|
|
94
|
+
id: s.id,
|
|
95
|
+
name: s.paiName ?? s.name,
|
|
96
|
+
path: "",
|
|
97
|
+
type: (s.name.toLowerCase().includes("claude") || !s.atPrompt) ? "claude" : "terminal",
|
|
98
|
+
paiName: s.paiName,
|
|
99
|
+
atPrompt: s.atPrompt,
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
// ── Session Creation ──
|
|
103
|
+
export function createClaudeSession(command = "claude") {
|
|
104
|
+
try {
|
|
105
|
+
const script = `tell application "iTerm2"
|
|
106
|
+
tell current window
|
|
107
|
+
set newTab to (create tab with default profile)
|
|
108
|
+
tell newTab
|
|
109
|
+
tell current session
|
|
110
|
+
write text "${command.replace(/"/g, '\\"')}"
|
|
111
|
+
return id
|
|
112
|
+
end tell
|
|
113
|
+
end tell
|
|
114
|
+
end tell
|
|
115
|
+
end tell`;
|
|
116
|
+
return runAppleScript(script) ?? null;
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
log("Failed to create session:", String(err));
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export function createTerminalTab(command) {
|
|
124
|
+
try {
|
|
125
|
+
const writeCmd = command
|
|
126
|
+
? `write text "${command.replace(/"/g, '\\"')}"`
|
|
127
|
+
: "";
|
|
128
|
+
const script = `tell application "iTerm2"
|
|
129
|
+
tell current window
|
|
130
|
+
set newTab to (create tab with default profile)
|
|
131
|
+
tell newTab
|
|
132
|
+
tell current session
|
|
133
|
+
${writeCmd}
|
|
134
|
+
return id
|
|
135
|
+
end tell
|
|
136
|
+
end tell
|
|
137
|
+
end tell
|
|
138
|
+
end tell`;
|
|
139
|
+
return runAppleScript(script) ?? null;
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
log("Failed to create terminal tab:", String(err));
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// ── Session Lifecycle ──
|
|
147
|
+
export async function restartSession(itermSessionId, command = "claude") {
|
|
148
|
+
sendKeystrokeToSession(itermSessionId, 3); // Ctrl+C
|
|
149
|
+
await new Promise((r) => setTimeout(r, 500));
|
|
150
|
+
typeIntoSession(itermSessionId, command);
|
|
151
|
+
}
|
|
152
|
+
export function killSession(itermSessionId) {
|
|
153
|
+
const script = withSessionAppleScript(itermSessionId, ` close aSession\n return "ok"`);
|
|
154
|
+
runAppleScript(script);
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=sessions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sessions.js","sourceRoot":"","sources":["../../../src/adapters/iterm/sessions.ts"],"names":[],"mappings":"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"}
|