@diegopetrucci/pi-brrr 0.1.4 → 0.1.7
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 +3 -3
- package/index.ts +30 -9
- package/package.json +1 -1
package/.pi-fleet-tested-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.
|
|
1
|
+
0.80.6
|
package/README.md
CHANGED
|
@@ -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
|
|
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;
|
|
@@ -159,8 +158,9 @@ function extractTextContent(content: unknown): string {
|
|
|
159
158
|
}
|
|
160
159
|
if (typeof part !== "object" || part === null) continue;
|
|
161
160
|
|
|
162
|
-
const
|
|
163
|
-
if (
|
|
161
|
+
const typedPart = part as { type?: unknown; text?: unknown };
|
|
162
|
+
if (typedPart.type !== undefined && typedPart.type !== "text") continue;
|
|
163
|
+
if (typeof typedPart.text === "string") parts.push(typedPart.text);
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
return parts.join("\n");
|
|
@@ -173,12 +173,31 @@ function lastAssistantMessage(messages: readonly unknown[]): string | undefined
|
|
|
173
173
|
if ((message as { role?: unknown }).role !== "assistant") continue;
|
|
174
174
|
|
|
175
175
|
const text = extractTextContent((message as { content?: unknown }).content).trim();
|
|
176
|
-
|
|
176
|
+
return text || undefined;
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
return undefined;
|
|
180
180
|
}
|
|
181
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
|
+
|
|
182
201
|
function truncateMessage(value: string): string {
|
|
183
202
|
const trimmed = value.trim();
|
|
184
203
|
if (trimmed.length <= 800) return trimmed;
|
|
@@ -236,7 +255,7 @@ export default function brrrExtension(pi: ExtensionAPI) {
|
|
|
236
255
|
},
|
|
237
256
|
});
|
|
238
257
|
|
|
239
|
-
pi.on("
|
|
258
|
+
pi.on("agent_settled", async (event, ctx) => {
|
|
240
259
|
const config = loadConfig(ctx);
|
|
241
260
|
if (!config.enabled) return;
|
|
242
261
|
if (config.onlyWhenInteractive && !ctx.hasUI) return;
|
|
@@ -245,7 +264,9 @@ export default function brrrExtension(pi: ExtensionAPI) {
|
|
|
245
264
|
if (!webhook || !isBrrrWebhookUrl(webhook)) return;
|
|
246
265
|
if (await shouldSkipForIdleThreshold(config.idleSeconds)) return;
|
|
247
266
|
|
|
248
|
-
const assistantMessage = config.includeLastAssistantMessage
|
|
267
|
+
const assistantMessage = config.includeLastAssistantMessage
|
|
268
|
+
? resolveAssistantMessage(ctx.sessionManager, (event as { messages?: readonly unknown[] }).messages ?? [])
|
|
269
|
+
: undefined;
|
|
249
270
|
const message = truncateMessage(assistantMessage || formatTemplate(config.message, ctx.cwd));
|
|
250
271
|
const result = await sendBrrr(webhook, {
|
|
251
272
|
title: formatTemplate(config.title, ctx.cwd),
|