4 Commits
Author SHA1 Message Date
杨豪 a4efba3f1f chore: bump version to 1.0.2
Publish pi-ntfy to npm / publish (push) Successful in 16s
2026-09-17 11:14:30 +08:00
杨豪 2f9f865d17 docs: document configurable notification templates 2026-09-17 11:05:32 +08:00
杨豪 4628ee02d7 fix: use agent config directory 2026-09-17 10:05:45 +08:00
杨豪 42b20c42d6 fix: use fixed pi-ntfy config path 2026-09-17 10:02:28 +08:00
7 changed files with 64 additions and 54 deletions
+54 -17
View File
@@ -15,33 +15,54 @@ Pi coding agent 的 NTFY 专用通知插件,适合并行开发时区分项目
## 安装
```bash
pi remove /home/yanghao05/Workspace/pi-push
pi install /home/yanghao05/Workspace/pi-push
pi install npm:pi-ntfy
```
不要同时安装或启用旧版 `npm:pi-agent-push`
卸载:
```bash
pi remove npm:pi-ntfy
```
## 配置
```bash
cp config.example.json config.json
插件固定从以下路径读取配置,不再通过环境变量选择配置文件:
```text
~/.pi/agent/pi-ntfy.json
```
默认配置
如果文件不存在,插件保持静默;可直接创建该文件,或使用 `/ntfy set``/ntfy enable` 等命令生成和修改配置
示例配置:
```json
{
"enabled": true,
"modes": ["tui"],
"titleTemplate": "[{{project}}] {{status}} · {{session}}",
"template": "项目: {{project}}\\n会话: {{session}}\\n任务: {{task}}\\n状态: {{status}}\\n原因: {{reason}}\\n摘要: {{summary}}\\n耗时: {{duration}}\\n模型: {{model}}\\n主机: {{host}}\\n时间: {{date}} {{time}}\\n工具: {{tools}}",
"channels": [
{
"type": "ntfy",
"name": "Agent",
"enabled": true,
"topic": "Agent",
"server": "https://n.ipao.vip",
"token": "$NTFY_TOKEN"
}
]
}
```
`token` 可以使用 `$NTFY_TOKEN``${NTFY_TOKEN}` 引用环境变量;配置文件路径本身不受环境变量影响。
配置字段:
```json
{
"titleTemplate": "[{{project}}] {{status}} · {{session}}",
"template": "项目: {{project}}\n会话: {{session}}\n任务: {{task}}\n状态: {{status}}\n原因: {{reason}}\n摘要: {{summary}}\n耗时: {{duration}}\n模型: {{model}}\n主机: {{host}}\n时间: {{date}} {{time}}\n工具: {{tools}}",
"channels": [
{
"type": "ntfy",
"enabled": true,
"topic": "$NTFY_TOPIC",
"server": "$NTFY_HOST",
"token": "$NTFY_TOKEN"
}
]
"template": "项目: {{project}}\\n会话: {{session}}\\n任务: {{task}}\\n状态: {{status}}\\n原因: {{reason}}\\n摘要: {{summary}}\\n耗时: {{duration}}\\n模型: {{model}}\\n主机: {{host}}\\n时间: {{date}} {{time}}\\n工具: {{tools}}"
}
```
@@ -69,4 +90,20 @@ cp config.example.json config.json
/ntfy off
```
旧的 `/push` 命令不再使用。
## 发布
版本发布由 Gitea Actions 完成。推送 `v*` 标签或手动运行 `Publish pi-ntfy to npm` workflow 即可发布到 npm。
workflow 使用账户级 Secret
```text
NPM_PACKAGE_TOKEN
```
例如:
```bash
npm version patch
git push
git push --tags
```
+1 -1
View File
@@ -8,7 +8,7 @@
import { httpRequest, localFailure, type HttpResult } from "../http.ts";
import type { NotifyPayload, NtfyChannel } from "../types.ts";
const DEFAULT_SERVER = "https://ntfy.sh";
const DEFAULT_SERVER = "https://n.ipao.vip";
function eventTagFor(event: NotifyPayload["event"]): string {
switch (event) {
+2 -2
View File
@@ -23,8 +23,8 @@
"type": "ntfy",
"name": "手机 ntfy",
"enabled": true,
"topic": "$NTFY_TOPIC",
"server": "$NTFY_HOST",
"topic": "Agent",
"server": "https://n.ipao.vip",
"token": "$NTFY_TOKEN",
"priority": "default",
"tags": "pi,computer"
+4 -18
View File
@@ -9,35 +9,21 @@ import {
} from "node:fs";
import { homedir } from "node:os";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
import type { ChannelConfig, NotifyConfig, NtfyChannel } from "./types.ts";
function resolveExtensionDir(): string {
try {
return dirname(fileURLToPath(import.meta.url));
} catch {
return join(homedir(), ".pi", "agent", "extensions", "pi-ntfy");
}
}
export const EXTENSION_DIR = resolveExtensionDir();
const CONFIG_PATH = join(homedir(), ".pi", "agent", "pi-ntfy.json");
export function configPath(): string {
const override =
process.env.PI_NTFY_CONFIG?.trim() ||
process.env.PI_AGENT_PUSH_CONFIG?.trim() ||
process.env.PI_PUSH_CONFIG?.trim();
return override ? override : join(EXTENSION_DIR, "config.json");
return CONFIG_PATH;
}
export function logPath(): string {
// Next to the config file, so PI_AGENT_PUSH_CONFIG keeps everything together.
return join(dirname(configPath()), "push.log");
return join(dirname(configPath()), "pi-ntfy.log");
}
export const KNOWN_TYPES = ["ntfy"] as const;
export type KnownChannelType = (typeof KNOWN_TYPES)[number];
/** Whole-value reference: "$BARK_KEY" */
/** Whole-value reference: "$NTFY_TOKEN" */
const ENV_REF = /^\$([A-Za-z_][A-Za-z0-9_]*)$/;
/** Embedded reference: "Bearer ${MY_TOKEN}" */
const ENV_INTERPOLATION = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g;
+1 -7
View File
@@ -1,10 +1,4 @@
/**
* pi-agent-push — HTTP transport.
*
* Every request carries its own `AbortSignal.timeout`. It must never use the
* agent's `ctx.signal`: on the "interrupted" path that signal is already
* aborted, so the notification about the cancellation would cancel itself.
*/
/** pi-ntfy HTTP transport. */
import type { ChannelResult } from "./types.ts";
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "pi-ntfy",
"version": "1.0.0",
"version": "1.0.2",
"description": "Project and session-aware NTFY notifications for the pi coding agent.",
"type": "module",
"license": "MIT",
+1 -8
View File
@@ -1,11 +1,4 @@
/**
* pi-agent-push — `{{placeholder}}` substitution.
*
* Escaping matters: a raw string template that lands inside JSON must have its
* values JSON-escaped, otherwise a quote or newline in an error message
* produces an invalid request body. Object templates avoid the problem
* entirely (substitute first, stringify after) and are the recommended form.
*/
/** pi-ntfy template rendering. */
const PLACEHOLDER = /\{\{\s*([a-zA-Z0-9_]+)\s*\}\}/g;