Files

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);
});
});