@diegopetrucci/pi-brrr 0.1.5 → 0.1.8
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/.pi-fleet-tested-version +1 -1
- package/README.md +5 -5
- package/index.ts +26 -6
- package/package.json +5 -1
package/.pi-fleet-tested-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.80.
|
|
1
|
+
0.80.6
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# brrr
|
|
2
2
|
|
|
3
|
-
A pi extension that sends [brrr](https://brrr.now) push notifications when pi
|
|
3
|
+
A pi extension that sends [brrr](https://brrr.now) push notifications when pi has fully settled and is ready for input.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -32,10 +32,10 @@ Then reload pi:
|
|
|
32
32
|
|
|
33
33
|
Config files are merged, with project config overriding global config:
|
|
34
34
|
|
|
35
|
-
-
|
|
36
|
-
- `<project
|
|
35
|
+
- `~/<pi-config-dir>/agent/extensions/brrr.json`
|
|
36
|
+
- `<project>/<pi-config-dir>/brrr.json`
|
|
37
37
|
|
|
38
|
-
Project config is only read after Pi reports that the project is trusted.
|
|
38
|
+
Here `<pi-config-dir>` is Pi's runtime config directory name (`CONFIG_DIR_NAME`; `.pi` by default). Project config is only read after Pi reports that the project is trusted.
|
|
39
39
|
|
|
40
40
|
The default config expects your webhook in `BRRR_WEBHOOK_URL`:
|
|
41
41
|
|
|
@@ -81,6 +81,6 @@ Example:
|
|
|
81
81
|
|
|
82
82
|
## Notes
|
|
83
83
|
|
|
84
|
-
- Hooks the `
|
|
84
|
+
- Hooks the `agent_settled` event so automatic retries, compaction retries, and queued follow-ups do not trigger intermediate notifications.
|
|
85
85
|
- The extension sends directly to the brrr webhook; it does not require the `brrr` CLI at runtime.
|
|
86
86
|
- By default, notifications are skipped unless the Mac has been idle for at least 20 seconds.
|
package/index.ts
CHANGED
|
@@ -5,18 +5,17 @@
|
|
|
5
5
|
* for more input.
|
|
6
6
|
*
|
|
7
7
|
* Config files (project overrides global):
|
|
8
|
-
* -
|
|
9
|
-
* - <cwd
|
|
8
|
+
* - ~/<pi-config-dir>/agent/extensions/brrr.json
|
|
9
|
+
* - <cwd>/<pi-config-dir>/brrr.json, when the project is trusted
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { execFile } from "node:child_process";
|
|
13
13
|
import { existsSync, readFileSync } from "node:fs";
|
|
14
14
|
import { basename, join } from "node:path";
|
|
15
15
|
import { promisify } from "node:util";
|
|
16
|
-
import { getAgentDir, type ExtensionAPI, type ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
16
|
+
import { CONFIG_DIR_NAME, getAgentDir, type ExtensionAPI, type ExtensionCommandContext, type SessionEntry } from "@earendil-works/pi-coding-agent";
|
|
17
17
|
|
|
18
18
|
const execFileAsync = promisify(execFile);
|
|
19
|
-
const CONFIG_DIR_NAME = ".pi";
|
|
20
19
|
|
|
21
20
|
interface BrrrConfig {
|
|
22
21
|
enabled: boolean;
|
|
@@ -180,6 +179,25 @@ function lastAssistantMessage(messages: readonly unknown[]): string | undefined
|
|
|
180
179
|
return undefined;
|
|
181
180
|
}
|
|
182
181
|
|
|
182
|
+
type SessionMessageSource = {
|
|
183
|
+
buildContextEntries(): SessionEntry[];
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
function sessionMessages(sessionManager: SessionMessageSource | undefined): readonly unknown[] {
|
|
187
|
+
if (!sessionManager) return [];
|
|
188
|
+
|
|
189
|
+
return sessionManager
|
|
190
|
+
.buildContextEntries()
|
|
191
|
+
.flatMap((entry: SessionEntry) => (entry.type === "message" ? [entry.message] : []));
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function resolveAssistantMessage(
|
|
195
|
+
sessionManager: SessionMessageSource | undefined,
|
|
196
|
+
fallbackMessages: readonly unknown[],
|
|
197
|
+
): string | undefined {
|
|
198
|
+
return lastAssistantMessage(sessionMessages(sessionManager)) ?? lastAssistantMessage(fallbackMessages);
|
|
199
|
+
}
|
|
200
|
+
|
|
183
201
|
function truncateMessage(value: string): string {
|
|
184
202
|
const trimmed = value.trim();
|
|
185
203
|
if (trimmed.length <= 800) return trimmed;
|
|
@@ -237,7 +255,7 @@ export default function brrrExtension(pi: ExtensionAPI) {
|
|
|
237
255
|
},
|
|
238
256
|
});
|
|
239
257
|
|
|
240
|
-
pi.on("
|
|
258
|
+
pi.on("agent_settled", async (event, ctx) => {
|
|
241
259
|
const config = loadConfig(ctx);
|
|
242
260
|
if (!config.enabled) return;
|
|
243
261
|
if (config.onlyWhenInteractive && !ctx.hasUI) return;
|
|
@@ -246,7 +264,9 @@ export default function brrrExtension(pi: ExtensionAPI) {
|
|
|
246
264
|
if (!webhook || !isBrrrWebhookUrl(webhook)) return;
|
|
247
265
|
if (await shouldSkipForIdleThreshold(config.idleSeconds)) return;
|
|
248
266
|
|
|
249
|
-
const assistantMessage = config.includeLastAssistantMessage
|
|
267
|
+
const assistantMessage = config.includeLastAssistantMessage
|
|
268
|
+
? resolveAssistantMessage(ctx.sessionManager, (event as { messages?: readonly unknown[] }).messages ?? [])
|
|
269
|
+
: undefined;
|
|
250
270
|
const message = truncateMessage(assistantMessage || formatTemplate(config.message, ctx.cwd));
|
|
251
271
|
const result = await sendBrrr(webhook, {
|
|
252
272
|
title: formatTemplate(config.title, ctx.cwd),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@diegopetrucci/pi-brrr",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"description": "A pi extension that sends brrr push notifications when pi is ready for input.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -31,5 +31,9 @@
|
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"@earendil-works/pi-coding-agent": "*"
|
|
34
|
+
},
|
|
35
|
+
"type": "module",
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=22.19.0"
|
|
34
38
|
}
|
|
35
39
|
}
|