pi-all-notification 1.0.4 → 1.0.5

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.
@@ -18,7 +18,7 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
18
18
  import { join, dirname } from "node:path";
19
19
  import { homedir } from "node:os";
20
20
  import { execSync } from "node:child_process";
21
- import { describeTask, settleNotification } from "./settle.ts";
21
+ import { describeBeforeAgentStart, settleNotification } from "./settle.ts";
22
22
 
23
23
  // ─── Types ────────────────────────────────────────────────────
24
24
 
@@ -763,7 +763,7 @@ export default function (pi: ExtensionAPI) {
763
763
  // Capture the prompt for the completion notification: `agent_settled` carries
764
764
  // no messages, and this is the last point the prompt text is available.
765
765
  pi.on("before_agent_start", (event, _ctx) => {
766
- lastTaskDescription = describeTask((event as { prompt?: unknown }).prompt);
766
+ lastTaskDescription = describeBeforeAgentStart(event);
767
767
  });
768
768
 
769
769
  pi.on("agent_start", (_event, ctx) => {
@@ -22,6 +22,32 @@ export function describeTask(prompt: unknown): string | null {
22
22
  return firstLine.length > 40 ? `${firstLine.slice(0, 37)}...` : firstLine;
23
23
  }
24
24
 
25
+ /**
26
+ * Task text from `before_agent_start`.
27
+ *
28
+ * Pi 1.3 also fires this event for runs started by a custom message, where the
29
+ * event carries `message` instead of `prompt`.
30
+ */
31
+ export function describeBeforeAgentStart(event: unknown): string | null {
32
+ if (!event || typeof event !== "object") return null;
33
+ const { prompt, message } = event as { prompt?: unknown; message?: unknown };
34
+ const fromPrompt = describeTask(prompt);
35
+ if (fromPrompt) return fromPrompt;
36
+ if (!message || typeof message !== "object") return null;
37
+ const content = (message as { content?: unknown }).content;
38
+ if (typeof content === "string") return describeTask(content);
39
+ if (!Array.isArray(content)) return null;
40
+ const text = content
41
+ .map((item) =>
42
+ item && typeof item === "object" && (item as { type?: unknown }).type === "text"
43
+ ? (item as { text?: unknown }).text
44
+ : undefined,
45
+ )
46
+ .filter((item): item is string => typeof item === "string")
47
+ .join("\n");
48
+ return describeTask(text);
49
+ }
50
+
25
51
  /**
26
52
  * The notification for a settled run.
27
53
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-all-notification",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Multi-channel notification for pi: macOS desktop, Bark push, custom webhook",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { describeTask, settleNotification } from "../extensions/settle.ts";
3
+ import { describeBeforeAgentStart, describeTask, settleNotification } from "../extensions/settle.ts";
4
4
 
5
5
  describe("describeTask", () => {
6
6
  it("takes the first line of the prompt", () => {
@@ -22,6 +22,38 @@ describe("describeTask", () => {
22
22
  });
23
23
  });
24
24
 
25
+ describe("describeBeforeAgentStart", () => {
26
+ it("reads the prompt from a user run", () => {
27
+ assert.equal(describeBeforeAgentStart({ messageType: "user", prompt: "Fix the build" }), "Fix the build");
28
+ });
29
+
30
+ it("reads text content from a custom-message run", () => {
31
+ const event = {
32
+ messageType: "custom",
33
+ message: { role: "custom", content: [{ type: "text", text: "Review the release\nand tag it" }] },
34
+ };
35
+ assert.equal(describeBeforeAgentStart(event), "Review the release");
36
+ });
37
+
38
+ it("reads string content from a custom-message run", () => {
39
+ const event = {
40
+ messageType: "custom",
41
+ message: { role: "custom", content: "Review the release" },
42
+ };
43
+ assert.equal(describeBeforeAgentStart(event), "Review the release");
44
+ });
45
+
46
+ it("ignores non-text custom content", () => {
47
+ assert.equal(
48
+ describeBeforeAgentStart({
49
+ messageType: "custom",
50
+ message: { role: "custom", content: [{ type: "image", data: "..." }] },
51
+ }),
52
+ null,
53
+ );
54
+ });
55
+ });
56
+
25
57
  describe("settleNotification", () => {
26
58
  it("reports a natural finish as complete", () => {
27
59
  const note = settleNotification({ aborted: false }, "pi-plugins", "Run the tests");