mirror of
https://bitbucket.org/siakitem/my-pi.git
synced 2026-08-28 07:23:06 +00:00
107 lines
3.2 KiB
TypeScript
107 lines
3.2 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { afterEach, describe, it } from "node:test";
|
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
import { getConfig, shouldNotify } from "../src/config.ts";
|
|
|
|
const envKeys = [
|
|
"PI_NOTIFY_ENABLED",
|
|
"PI_NOTIFY_TITLE",
|
|
"PI_NOTIFY_BODY",
|
|
"PI_NOTIFY_MESSAGE_SOURCE",
|
|
"PI_NOTIFY_MESSAGE_MAX",
|
|
"PI_NOTIFY_MIN_SECONDS",
|
|
"PI_NOTIFY_VISIBILITY",
|
|
"PI_NOTIFY_ACTION",
|
|
"PI_NOTIFY_SOUND_CMD",
|
|
] as const;
|
|
|
|
const savedEnv = new Map(envKeys.map((key) => [key, process.env[key]]));
|
|
|
|
afterEach(() => {
|
|
for (const key of envKeys) {
|
|
const value = savedEnv.get(key);
|
|
if (value === undefined) delete process.env[key];
|
|
else process.env[key] = value;
|
|
}
|
|
});
|
|
|
|
function context(): ExtensionContext {
|
|
return {
|
|
cwd: "/tmp/pi-notify",
|
|
model: { provider: "openai", id: "gpt-4.1" },
|
|
} as ExtensionContext;
|
|
}
|
|
|
|
const runtime = { notificationId: "pi-session", toolErrorCount: 0 };
|
|
|
|
describe("config", () => {
|
|
it("builds safe Kitty defaults from the settled assistant output", () => {
|
|
const config = getConfig(
|
|
context(),
|
|
800,
|
|
[
|
|
{ role: "user", content: "please fix this" },
|
|
{ role: "assistant", content: "fixed it" },
|
|
],
|
|
runtime,
|
|
5_000,
|
|
);
|
|
|
|
assert.deepEqual(config, {
|
|
enabled: true,
|
|
title: "π - pi-notify",
|
|
body: "fixed it",
|
|
durationMs: 4_200,
|
|
minDurationMs: 3_000,
|
|
notificationId: "pi-session",
|
|
visibility: "always",
|
|
action: "focus",
|
|
soundCommand: undefined,
|
|
});
|
|
assert.equal(shouldNotify(config), true);
|
|
});
|
|
|
|
it("supports privacy, threshold, focus, and status template settings", () => {
|
|
process.env.PI_NOTIFY_ENABLED = "off";
|
|
process.env.PI_NOTIFY_TITLE = "{status_icon} {status} {tool_error_count}";
|
|
process.env.PI_NOTIFY_BODY = "{message}";
|
|
process.env.PI_NOTIFY_MESSAGE_SOURCE = "none";
|
|
process.env.PI_NOTIFY_MIN_SECONDS = "10.5";
|
|
process.env.PI_NOTIFY_VISIBILITY = "invisible";
|
|
process.env.PI_NOTIFY_ACTION = "none";
|
|
process.env.PI_NOTIFY_SOUND_CMD = " say done ";
|
|
|
|
const config = getConfig(context(), 1_000, [{ role: "assistant", content: "secret" }], {
|
|
notificationId: "pi-session",
|
|
toolErrorCount: 2,
|
|
}, 2_000);
|
|
|
|
assert.equal(config.title, "⚠ ready · 2 tool errors 2");
|
|
assert.equal(config.body, "Ready for input");
|
|
assert.equal(config.enabled, false);
|
|
assert.equal(config.minDurationMs, 10_500);
|
|
assert.equal(config.visibility, "invisible");
|
|
assert.equal(config.action, "none");
|
|
assert.equal(config.soundCommand, "say done");
|
|
assert.equal(shouldNotify(config), false);
|
|
assert.equal(shouldNotify(config, true), false, "the minimum duration still applies to command overrides");
|
|
});
|
|
|
|
it("applies selected-message truncation and a session override", () => {
|
|
process.env.PI_NOTIFY_MESSAGE_SOURCE = "user";
|
|
process.env.PI_NOTIFY_MESSAGE_MAX = "5";
|
|
process.env.PI_NOTIFY_MIN_SECONDS = "0";
|
|
const config = getConfig(
|
|
context(),
|
|
1_000,
|
|
[{ role: "user", content: "hello world" }],
|
|
runtime,
|
|
2_000,
|
|
);
|
|
|
|
assert.equal(config.body, "hell…");
|
|
assert.equal(shouldNotify(config, false), false);
|
|
assert.equal(shouldNotify(config, true), true);
|
|
});
|
|
});
|