@diegopetrucci/pi-extensions 0.1.7 → 0.1.9
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 +20 -2
- package/extensions/notify/README.md +125 -0
- package/extensions/notify/index.ts +274 -0
- package/extensions/notify/notify.example.json +26 -0
- package/extensions/notify/package.json +28 -0
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ A collection of [pi](https://github.com/badlogic/pi-mono) agent extensions I mad
|
|
|
10
10
|
| [`oracle`](./extensions/oracle) | Adds an Amp-style read-only oracle tool that auto-selects the strongest reasoning model on the current provider/subscription, covers pi’s built-in providers with hardcoded rankings, sets reasoning to xhigh by default, and shows live status while running. |
|
|
11
11
|
| [`permission-gate`](./extensions/permission-gate) | Prompts for confirmation before dangerous bash commands like `rm -rf`, `sudo`, and `chmod 777`. |
|
|
12
12
|
| [`confirm-destructive`](./extensions/confirm-destructive) | Confirms before destructive session actions like clear, switch, and fork. |
|
|
13
|
+
| [`notify`](./extensions/notify) | Sends configurable terminal, desktop, bell, and sound notifications when pi finishes and is ready for input. |
|
|
13
14
|
|
|
14
15
|
## Install
|
|
15
16
|
|
|
@@ -24,7 +25,7 @@ pi install git:github.com/diegopetrucci/pi-extensions
|
|
|
24
25
|
Or pin to a tagged version:
|
|
25
26
|
|
|
26
27
|
```bash
|
|
27
|
-
pi install git:github.com/diegopetrucci/pi-extensions@v0.1.
|
|
28
|
+
pi install git:github.com/diegopetrucci/pi-extensions@v0.1.9
|
|
28
29
|
```
|
|
29
30
|
|
|
30
31
|
### npm
|
|
@@ -63,6 +64,10 @@ pi install npm:@diegopetrucci/pi-permission-gate
|
|
|
63
64
|
pi install npm:@diegopetrucci/pi-confirm-destructive
|
|
64
65
|
```
|
|
65
66
|
|
|
67
|
+
```bash
|
|
68
|
+
pi install npm:@diegopetrucci/pi-notify
|
|
69
|
+
```
|
|
70
|
+
|
|
66
71
|
### Option 2: filter the repo package
|
|
67
72
|
|
|
68
73
|
If you prefer the collection package, you can filter it in your pi settings.
|
|
@@ -119,9 +124,22 @@ Confirm destructive only:
|
|
|
119
124
|
}
|
|
120
125
|
```
|
|
121
126
|
|
|
127
|
+
Notify only:
|
|
128
|
+
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"packages": [
|
|
132
|
+
{
|
|
133
|
+
"source": "npm:@diegopetrucci/pi-extensions",
|
|
134
|
+
"extensions": ["extensions/notify/index.ts"]
|
|
135
|
+
}
|
|
136
|
+
]
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
122
140
|
## npm publishing
|
|
123
141
|
|
|
124
142
|
The repo is set up to support both:
|
|
125
143
|
|
|
126
144
|
- the collection package: `@diegopetrucci/pi-extensions`
|
|
127
|
-
- standalone extension packages like `@diegopetrucci/pi-minimal-footer`, `@diegopetrucci/pi-oracle`, `@diegopetrucci/pi-permission-gate`,
|
|
145
|
+
- standalone extension packages like `@diegopetrucci/pi-minimal-footer`, `@diegopetrucci/pi-oracle`, `@diegopetrucci/pi-permission-gate`, `@diegopetrucci/pi-confirm-destructive`, and `@diegopetrucci/pi-notify`
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# notify
|
|
2
|
+
|
|
3
|
+
A pi extension that sends notifications when the agent finishes and is waiting for input.
|
|
4
|
+
|
|
5
|
+
This started from the original `notify.ts` example in [`badlogic/pi-mono`](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/examples/extensions/notify.ts), but now supports multiple notification channels and JSON configuration.
|
|
6
|
+
|
|
7
|
+
## Supported notification channels
|
|
8
|
+
|
|
9
|
+
### Terminal notifications
|
|
10
|
+
|
|
11
|
+
- OSC 777: Ghostty, iTerm2, WezTerm, rxvt-unicode
|
|
12
|
+
- OSC 99: Kitty
|
|
13
|
+
|
|
14
|
+
### Desktop notifications
|
|
15
|
+
|
|
16
|
+
- macOS Notification Center via `osascript`
|
|
17
|
+
- Linux desktop notifications via `notify-send`
|
|
18
|
+
- Windows toast notifications via `powershell.exe` / Windows Terminal / WSL
|
|
19
|
+
|
|
20
|
+
### Bells and sounds
|
|
21
|
+
|
|
22
|
+
- terminal bell (`\a`)
|
|
23
|
+
- macOS sound playback via `afplay`
|
|
24
|
+
- Linux sound playback via `canberra-gtk-play` or `paplay`
|
|
25
|
+
- Windows beep via `powershell.exe`
|
|
26
|
+
|
|
27
|
+
By default, all channels are enabled:
|
|
28
|
+
|
|
29
|
+
- terminal notification
|
|
30
|
+
- desktop notification
|
|
31
|
+
- bell
|
|
32
|
+
- sound
|
|
33
|
+
|
|
34
|
+
The extension automatically picks the appropriate backend for the current environment.
|
|
35
|
+
|
|
36
|
+
## Install
|
|
37
|
+
|
|
38
|
+
### Standalone npm package
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pi install npm:@diegopetrucci/pi-notify
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Collection package
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pi install npm:@diegopetrucci/pi-extensions
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### GitHub package
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pi install git:github.com/diegopetrucci/pi-extensions
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Then reload pi:
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
/reload
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Configuration
|
|
63
|
+
|
|
64
|
+
Config files are merged, with project config overriding global config:
|
|
65
|
+
|
|
66
|
+
- `~/.pi/agent/extensions/notify.json`
|
|
67
|
+
- `<project>/.pi/notify.json`
|
|
68
|
+
|
|
69
|
+
A ready-to-copy sample file is included at [`notify.example.json`](./notify.example.json).
|
|
70
|
+
|
|
71
|
+
Example:
|
|
72
|
+
|
|
73
|
+
```json
|
|
74
|
+
{
|
|
75
|
+
"enabled": true,
|
|
76
|
+
"onlyWhenInteractive": true,
|
|
77
|
+
"title": "Pi",
|
|
78
|
+
"body": "Ready for input",
|
|
79
|
+
"channels": {
|
|
80
|
+
"terminal": true,
|
|
81
|
+
"desktop": true,
|
|
82
|
+
"bell": true,
|
|
83
|
+
"sound": true
|
|
84
|
+
},
|
|
85
|
+
"terminal": {
|
|
86
|
+
"backend": "auto"
|
|
87
|
+
},
|
|
88
|
+
"desktop": {
|
|
89
|
+
"backend": "auto"
|
|
90
|
+
},
|
|
91
|
+
"sound": {
|
|
92
|
+
"backend": "auto",
|
|
93
|
+
"name": "Glass",
|
|
94
|
+
"linuxSoundId": "complete",
|
|
95
|
+
"frequencyHz": 1000,
|
|
96
|
+
"durationMs": 250,
|
|
97
|
+
"command": ""
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Config fields
|
|
103
|
+
|
|
104
|
+
- `enabled`: master on/off switch
|
|
105
|
+
- `onlyWhenInteractive`: skip notifications in print / non-UI mode
|
|
106
|
+
- `title`: notification title
|
|
107
|
+
- `body`: notification body
|
|
108
|
+
- `channels.terminal`: enable terminal notification output
|
|
109
|
+
- `channels.desktop`: enable OS desktop notifications
|
|
110
|
+
- `channels.bell`: enable terminal bell
|
|
111
|
+
- `channels.sound`: enable sound playback
|
|
112
|
+
- `terminal.backend`: `auto`, `osc777`, `osc99`, `none`
|
|
113
|
+
- `desktop.backend`: `auto`, `macos`, `linux`, `windows-toast`, `none`
|
|
114
|
+
- `sound.backend`: `auto`, `macos`, `linux`, `windows-beep`, `command`, `none`
|
|
115
|
+
- `sound.name`: macOS system sound name, like `Glass` or `Hero`
|
|
116
|
+
- `sound.linuxSoundId`: freedesktop sound id, like `complete`
|
|
117
|
+
- `sound.frequencyHz`: Windows beep frequency
|
|
118
|
+
- `sound.durationMs`: Windows beep duration
|
|
119
|
+
- `sound.command`: custom shell command when `sound.backend` is `command`
|
|
120
|
+
|
|
121
|
+
## Notes
|
|
122
|
+
|
|
123
|
+
- Hooks the `agent_end` event.
|
|
124
|
+
- Default message is `Pi` / `Ready for input`.
|
|
125
|
+
- Terminal, desktop, bell, and sound channels can be enabled independently.
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pi Notify Extension
|
|
3
|
+
*
|
|
4
|
+
* Sends notifications when Pi agent is done and waiting for input.
|
|
5
|
+
* Supports multiple channels:
|
|
6
|
+
* - terminal notifications: OSC 777 and OSC 99
|
|
7
|
+
* - desktop notifications: macOS Notification Center, Linux notify-send, Windows toast
|
|
8
|
+
* - terminal bell
|
|
9
|
+
* - sound playback
|
|
10
|
+
*
|
|
11
|
+
* Config files (project overrides global):
|
|
12
|
+
* - ~/.pi/agent/extensions/notify.json
|
|
13
|
+
* - <cwd>/.pi/notify.json
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { execFile } from "node:child_process";
|
|
17
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
|
20
|
+
import { getAgentDir } from "@mariozechner/pi-coding-agent";
|
|
21
|
+
|
|
22
|
+
type TerminalBackend = "auto" | "osc777" | "osc99" | "none";
|
|
23
|
+
type DesktopBackend = "auto" | "macos" | "linux" | "windows-toast" | "none";
|
|
24
|
+
type SoundBackend = "auto" | "macos" | "linux" | "windows-beep" | "command" | "none";
|
|
25
|
+
|
|
26
|
+
interface NotifyConfig {
|
|
27
|
+
enabled: boolean;
|
|
28
|
+
onlyWhenInteractive: boolean;
|
|
29
|
+
title: string;
|
|
30
|
+
body: string;
|
|
31
|
+
channels: {
|
|
32
|
+
terminal: boolean;
|
|
33
|
+
desktop: boolean;
|
|
34
|
+
bell: boolean;
|
|
35
|
+
sound: boolean;
|
|
36
|
+
};
|
|
37
|
+
terminal: {
|
|
38
|
+
backend: TerminalBackend;
|
|
39
|
+
};
|
|
40
|
+
desktop: {
|
|
41
|
+
backend: DesktopBackend;
|
|
42
|
+
};
|
|
43
|
+
sound: {
|
|
44
|
+
backend: SoundBackend;
|
|
45
|
+
name: string;
|
|
46
|
+
linuxSoundId: string;
|
|
47
|
+
frequencyHz: number;
|
|
48
|
+
durationMs: number;
|
|
49
|
+
command: string;
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const DEFAULT_CONFIG: NotifyConfig = {
|
|
54
|
+
enabled: true,
|
|
55
|
+
onlyWhenInteractive: true,
|
|
56
|
+
title: "Pi",
|
|
57
|
+
body: "Ready for input",
|
|
58
|
+
channels: {
|
|
59
|
+
terminal: true,
|
|
60
|
+
desktop: true,
|
|
61
|
+
bell: true,
|
|
62
|
+
sound: true,
|
|
63
|
+
},
|
|
64
|
+
terminal: {
|
|
65
|
+
backend: "auto",
|
|
66
|
+
},
|
|
67
|
+
desktop: {
|
|
68
|
+
backend: "auto",
|
|
69
|
+
},
|
|
70
|
+
sound: {
|
|
71
|
+
backend: "auto",
|
|
72
|
+
name: "Glass",
|
|
73
|
+
linuxSoundId: "complete",
|
|
74
|
+
frequencyHz: 1000,
|
|
75
|
+
durationMs: 250,
|
|
76
|
+
command: "",
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
function readConfigFile(path: string): Partial<NotifyConfig> {
|
|
81
|
+
if (!existsSync(path)) return {};
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
return JSON.parse(readFileSync(path, "utf-8")) as Partial<NotifyConfig>;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error(`Warning: Could not parse ${path}: ${error}`);
|
|
87
|
+
return {};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function mergeConfig(base: NotifyConfig, overrides: Partial<NotifyConfig>): NotifyConfig {
|
|
92
|
+
return {
|
|
93
|
+
...base,
|
|
94
|
+
...overrides,
|
|
95
|
+
channels: {
|
|
96
|
+
...base.channels,
|
|
97
|
+
...overrides.channels,
|
|
98
|
+
},
|
|
99
|
+
terminal: {
|
|
100
|
+
...base.terminal,
|
|
101
|
+
...overrides.terminal,
|
|
102
|
+
},
|
|
103
|
+
desktop: {
|
|
104
|
+
...base.desktop,
|
|
105
|
+
...overrides.desktop,
|
|
106
|
+
},
|
|
107
|
+
sound: {
|
|
108
|
+
...base.sound,
|
|
109
|
+
...overrides.sound,
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function loadConfig(cwd: string): NotifyConfig {
|
|
115
|
+
const globalConfig = readConfigFile(join(getAgentDir(), "extensions", "notify.json"));
|
|
116
|
+
const projectConfig = readConfigFile(join(cwd, ".pi", "notify.json"));
|
|
117
|
+
return mergeConfig(mergeConfig(DEFAULT_CONFIG, globalConfig), projectConfig);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function powershellString(value: string): string {
|
|
121
|
+
return `'${value.replace(/'/g, "''")}'`;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function windowsToastScript(title: string, body: string): string {
|
|
125
|
+
const type = "Windows.UI.Notifications";
|
|
126
|
+
const mgr = `[${type}.ToastNotificationManager, ${type}, ContentType = WindowsRuntime]`;
|
|
127
|
+
const template = `[${type}.ToastTemplateType]::ToastText01`;
|
|
128
|
+
const toast = `[${type}.ToastNotification]::new($xml)`;
|
|
129
|
+
return [
|
|
130
|
+
`${mgr} > $null`,
|
|
131
|
+
`$xml = [${type}.ToastNotificationManager]::GetTemplateContent(${template})`,
|
|
132
|
+
`$xml.GetElementsByTagName('text')[0].AppendChild($xml.CreateTextNode(${powershellString(body)})) > $null`,
|
|
133
|
+
`[${type}.ToastNotificationManager]::CreateToastNotifier(${powershellString(title)}).Show(${toast})`,
|
|
134
|
+
].join("; ");
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function notifyOSC777(title: string, body: string): void {
|
|
138
|
+
process.stdout.write(`\x1b]777;notify;${title};${body}\x07`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function notifyOSC99(title: string, body: string): void {
|
|
142
|
+
process.stdout.write(`\x1b]99;i=1:d=0;${title}\x1b\\`);
|
|
143
|
+
process.stdout.write(`\x1b]99;i=1:p=body;${body}\x1b\\`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function ringBell(): void {
|
|
147
|
+
process.stdout.write("\x07");
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
function runCommand(command: string, args: string[]): Promise<boolean> {
|
|
151
|
+
return new Promise((resolve) => {
|
|
152
|
+
execFile(command, args, (error) => resolve(!error));
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function runShellCommand(command: string): Promise<boolean> {
|
|
157
|
+
if (process.platform === "win32") {
|
|
158
|
+
return runCommand("cmd.exe", ["/d", "/s", "/c", command]);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
return runCommand(process.env.SHELL || "/bin/sh", ["-lc", command]);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
function detectTerminalBackend(config: NotifyConfig): Exclude<TerminalBackend, "auto"> {
|
|
165
|
+
if (config.terminal.backend !== "auto") return config.terminal.backend;
|
|
166
|
+
if (process.env.KITTY_WINDOW_ID) return "osc99";
|
|
167
|
+
return "osc777";
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function detectDesktopBackend(config: NotifyConfig): Exclude<DesktopBackend, "auto"> {
|
|
171
|
+
if (config.desktop.backend !== "auto") return config.desktop.backend;
|
|
172
|
+
if (process.env.WT_SESSION || process.env.WSL_DISTRO_NAME) return "windows-toast";
|
|
173
|
+
if (process.platform === "darwin") return "macos";
|
|
174
|
+
if (process.platform === "linux") return "linux";
|
|
175
|
+
if (process.platform === "win32") return "windows-toast";
|
|
176
|
+
return "none";
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function detectSoundBackend(config: NotifyConfig): Exclude<SoundBackend, "auto"> {
|
|
180
|
+
if (config.sound.backend !== "auto") return config.sound.backend;
|
|
181
|
+
if (process.env.WT_SESSION || process.platform === "win32" || process.env.WSL_DISTRO_NAME) return "windows-beep";
|
|
182
|
+
if (process.platform === "darwin") return "macos";
|
|
183
|
+
if (process.platform === "linux") return "linux";
|
|
184
|
+
return "none";
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function sendTerminalNotification(title: string, body: string, backend: Exclude<TerminalBackend, "auto">): void {
|
|
188
|
+
if (backend === "osc99") {
|
|
189
|
+
notifyOSC99(title, body);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
if (backend === "osc777") {
|
|
193
|
+
notifyOSC777(title, body);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function appleScriptString(value: string): string {
|
|
198
|
+
return JSON.stringify(value);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
function sendDesktopNotification(
|
|
202
|
+
title: string,
|
|
203
|
+
body: string,
|
|
204
|
+
backend: Exclude<DesktopBackend, "auto">,
|
|
205
|
+
): Promise<boolean> {
|
|
206
|
+
if (backend === "windows-toast") {
|
|
207
|
+
return runCommand("powershell.exe", ["-NoProfile", "-Command", windowsToastScript(title, body)]);
|
|
208
|
+
}
|
|
209
|
+
if (backend === "macos") {
|
|
210
|
+
return runCommand("osascript", ["-e", `display notification ${appleScriptString(body)} with title ${appleScriptString(title)}`]);
|
|
211
|
+
}
|
|
212
|
+
if (backend === "linux") {
|
|
213
|
+
return runCommand("notify-send", [title, body]);
|
|
214
|
+
}
|
|
215
|
+
return Promise.resolve(false);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function playSound(config: NotifyConfig, backend: Exclude<SoundBackend, "auto">): Promise<boolean> {
|
|
219
|
+
if (backend === "command") {
|
|
220
|
+
if (!config.sound.command.trim()) return false;
|
|
221
|
+
return runShellCommand(config.sound.command);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (backend === "windows-beep") {
|
|
225
|
+
return runCommand("powershell.exe", [
|
|
226
|
+
"-NoProfile",
|
|
227
|
+
"-Command",
|
|
228
|
+
`[console]::beep(${config.sound.frequencyHz}, ${config.sound.durationMs})`,
|
|
229
|
+
]);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
if (backend === "macos") {
|
|
233
|
+
return runCommand("afplay", [`/System/Library/Sounds/${config.sound.name}.aiff`]);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
if (backend === "linux") {
|
|
237
|
+
const soundId = config.sound.linuxSoundId;
|
|
238
|
+
const viaCanberra = await runCommand("canberra-gtk-play", ["-i", soundId]);
|
|
239
|
+
if (viaCanberra) return true;
|
|
240
|
+
return runCommand("paplay", [`/usr/share/sounds/freedesktop/stereo/${soundId}.oga`]);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export default function notifyExtension(pi: ExtensionAPI) {
|
|
247
|
+
pi.on("agent_end", async (_event, ctx) => {
|
|
248
|
+
const config = loadConfig(ctx.cwd);
|
|
249
|
+
if (!config.enabled) return;
|
|
250
|
+
if (config.onlyWhenInteractive && !ctx.hasUI) return;
|
|
251
|
+
|
|
252
|
+
const tasks: Array<Promise<unknown>> = [];
|
|
253
|
+
|
|
254
|
+
if (config.channels.terminal) {
|
|
255
|
+
sendTerminalNotification(config.title, config.body, detectTerminalBackend(config));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
if (config.channels.desktop) {
|
|
259
|
+
tasks.push(sendDesktopNotification(config.title, config.body, detectDesktopBackend(config)));
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (config.channels.bell) {
|
|
263
|
+
ringBell();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (config.channels.sound) {
|
|
267
|
+
tasks.push(playSound(config, detectSoundBackend(config)));
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (tasks.length > 0) {
|
|
271
|
+
await Promise.allSettled(tasks);
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"enabled": true,
|
|
3
|
+
"onlyWhenInteractive": true,
|
|
4
|
+
"title": "Pi",
|
|
5
|
+
"body": "Ready for input",
|
|
6
|
+
"channels": {
|
|
7
|
+
"terminal": true,
|
|
8
|
+
"desktop": true,
|
|
9
|
+
"bell": true,
|
|
10
|
+
"sound": true
|
|
11
|
+
},
|
|
12
|
+
"terminal": {
|
|
13
|
+
"backend": "auto"
|
|
14
|
+
},
|
|
15
|
+
"desktop": {
|
|
16
|
+
"backend": "auto"
|
|
17
|
+
},
|
|
18
|
+
"sound": {
|
|
19
|
+
"backend": "auto",
|
|
20
|
+
"name": "Glass",
|
|
21
|
+
"linuxSoundId": "complete",
|
|
22
|
+
"frequencyHz": 1000,
|
|
23
|
+
"durationMs": 250,
|
|
24
|
+
"command": ""
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@diegopetrucci/pi-notify",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A pi extension that sends a notification when the agent is ready for input.",
|
|
5
|
+
"keywords": ["pi-package", "pi", "notification", "terminal"],
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/diegopetrucci/pi-extensions.git",
|
|
10
|
+
"directory": "extensions/notify"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"index.ts",
|
|
14
|
+
"README.md",
|
|
15
|
+
"notify.example.json"
|
|
16
|
+
],
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"pi": {
|
|
21
|
+
"extensions": [
|
|
22
|
+
"index.ts"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"@mariozechner/pi-coding-agent": "*"
|
|
27
|
+
}
|
|
28
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-extensions",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "A collection of pi extensions, including a minimal custom footer, an Amp-style oracle, a permission gate for dangerous bash commands,
|
|
3
|
+
"version": "0.1.9",
|
|
4
|
+
"description": "A collection of pi extensions, including a minimal custom footer, an Amp-style oracle, a permission gate for dangerous bash commands, confirm-before-destructive session actions, and terminal notifications when pi is ready for input.",
|
|
5
5
|
"keywords": ["pi-package", "pi", "terminal", "agent"],
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"./extensions/minimal-footer/index.ts",
|
|
30
30
|
"./extensions/oracle/index.ts",
|
|
31
31
|
"./extensions/permission-gate/index.ts",
|
|
32
|
-
"./extensions/confirm-destructive/index.ts"
|
|
32
|
+
"./extensions/confirm-destructive/index.ts",
|
|
33
|
+
"./extensions/notify/index.ts"
|
|
33
34
|
],
|
|
34
35
|
"image": "https://raw.githubusercontent.com/diegopetrucci/pi-extensions/main/assets/oracle-preview.svg"
|
|
35
36
|
}
|