Skip to content

Commit c0e69da

Browse files
authored
feat(stations/notify): import agent-notify history (#433)
Preserve the rewritten standalone history and land monorepo CI coverage.
2 parents a0ae2c4 + 308cf4b commit c0e69da

56 files changed

Lines changed: 5161 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ jobs:
1717
outputs:
1818
code_graph: ${{ steps.filter.outputs.code_graph }}
1919
evidence_ledger: ${{ steps.filter.outputs.evidence_ledger }}
20+
notify: ${{ steps.filter.outputs.notify }}
2021
steps:
2122
- uses: actions/checkout@v5
2223
- uses: dorny/paths-filter@v3
@@ -31,6 +32,10 @@ jobs:
3132
- 'engines/evidence-ledger/**'
3233
- 'src/brigade/templates/components/manifest-v1.json'
3334
- '.github/workflows/ci.yml'
35+
notify:
36+
- 'stations/notify/**'
37+
- 'src/brigade/templates/components/manifest-v1.json'
38+
- '.github/workflows/ci.yml'
3439
3540
code-graph-msrv:
3641
name: MSRV (Rust 1.85)
@@ -147,6 +152,61 @@ jobs:
147152
- run: scripts/smoke_mcp.sh
148153
- run: scripts/smoke_http.sh
149154

155+
notify-build-and-test:
156+
name: notify-build-and-test (ubuntu-latest)
157+
needs: changes
158+
if: ${{ needs.changes.outputs.notify == 'true' }}
159+
runs-on: ubuntu-latest
160+
defaults:
161+
run:
162+
working-directory: stations/notify
163+
steps:
164+
- uses: actions/checkout@v5
165+
with:
166+
persist-credentials: false
167+
- uses: actions/setup-go@v5
168+
with:
169+
go-version: '1.22'
170+
cache-dependency-path: stations/notify/go.sum
171+
- name: Build
172+
run: go build ./...
173+
- name: Vet
174+
run: go vet ./...
175+
- name: Test
176+
run: go test -race ./...
177+
- name: Setup stable Go for govulncheck
178+
uses: actions/setup-go@v5
179+
with:
180+
go-version: stable
181+
cache-dependency-path: stations/notify/go.sum
182+
- name: Install govulncheck
183+
run: go install golang.org/x/vuln/cmd/govulncheck@v1.3.0
184+
- name: Vulncheck
185+
run: govulncheck ./...
186+
187+
notify-windows:
188+
name: notify-build-and-test (windows-latest)
189+
needs: changes
190+
if: ${{ needs.changes.outputs.notify == 'true' }}
191+
runs-on: windows-latest
192+
defaults:
193+
run:
194+
working-directory: stations/notify
195+
steps:
196+
- uses: actions/checkout@v5
197+
with:
198+
persist-credentials: false
199+
- uses: actions/setup-go@v5
200+
with:
201+
go-version: '1.22'
202+
cache-dependency-path: stations/notify/go.sum
203+
- name: Build
204+
run: go build ./...
205+
- name: Vet
206+
run: go vet ./...
207+
- name: Test
208+
run: go test -race ./...
209+
150210
lint:
151211
runs-on: ubuntu-latest
152212
steps:
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
name: Bug report
2+
description: Something is broken in agent-notify itself, such as routing, a channel or hook adapter, doctor, status, or the docs.
3+
labels: ["bug"]
4+
body:
5+
- type: textarea
6+
id: what-happened
7+
attributes:
8+
label: What happened
9+
description: What did you run, and what did you expect versus what you got?
10+
placeholder: |
11+
I ran `agent-notify --profile error "5 alerts"` and the Discord channel got nothing.
12+
I expected the message to reach both Telegram and Discord.
13+
validations:
14+
required: true
15+
- type: input
16+
id: version
17+
attributes:
18+
label: agent-notify version
19+
description: Output of `agent-notify version`.
20+
placeholder: agent-notify 0.1.0
21+
validations:
22+
required: true
23+
- type: dropdown
24+
id: channel
25+
attributes:
26+
label: Channel(s) involved
27+
multiple: true
28+
options:
29+
- Discord
30+
- Telegram
31+
- Signal
32+
- Routing / profiles (no specific channel)
33+
- Hook adapter (Claude Code / Codex / custom)
34+
- Other
35+
validations:
36+
required: true
37+
- type: input
38+
id: os
39+
attributes:
40+
label: OS
41+
placeholder: Ubuntu 24.04, macOS 14.5, Windows 11, etc.
42+
validations:
43+
required: true
44+
- type: textarea
45+
id: doctor
46+
attributes:
47+
label: Doctor output
48+
description: Paste `agent-notify doctor` (or `doctor --json`). Redact tokens, webhook URLs, chat IDs, and personal paths first.
49+
render: shell
50+
validations:
51+
required: false
52+
- type: textarea
53+
id: logs
54+
attributes:
55+
label: Full output
56+
description: Paste the full stdout + stderr from the failing command. Keep enough for us to reproduce, but remove any secrets.
57+
render: shell
58+
validations:
59+
required: false
60+
- type: checkboxes
61+
id: scrub
62+
attributes:
63+
label: Pre-flight
64+
options:
65+
- label: I have removed any tokens, webhook URLs, chat IDs, hostnames, and personal paths from this report.
66+
required: true
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Website and docs
4+
url: https://agent-notify.escoffierlabs.dev
5+
about: Project overview, install, and usage. Read here before filing a question.
6+
- name: Security report
7+
url: https://github.com/escoffier-labs/agent-notify/security/policy
8+
about: Do not file security issues publicly. See SECURITY.md for how to report privately.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Feature request
2+
description: Propose a new channel, hook adapter, routing capability, or other enhancement.
3+
labels: ["enhancement"]
4+
body:
5+
- type: textarea
6+
id: problem
7+
attributes:
8+
label: What problem are you trying to solve
9+
description: Describe the user story. What are you doing today, and where does agent-notify fall short?
10+
placeholder: |
11+
I run an agent stack and want notifications to also reach a Slack channel, but agent-notify only supports Discord/Telegram/Signal.
12+
validations:
13+
required: true
14+
- type: textarea
15+
id: proposal
16+
attributes:
17+
label: Proposed change
18+
description: What would you like agent-notify to do? A new channel adapter, a new hook adapter, a routing flag, something else?
19+
validations:
20+
required: true
21+
- type: dropdown
22+
id: kind
23+
attributes:
24+
label: Kind of request
25+
options:
26+
- New channel adapter
27+
- New hook adapter (a different agent's event JSON)
28+
- Routing / profile capability
29+
- Doctor / status check
30+
- Docs
31+
- Other
32+
validations:
33+
required: true
34+
- type: textarea
35+
id: alternatives
36+
attributes:
37+
label: Alternatives you considered
38+
description: A shell wrapper piping JSON to agent-notify, a different tool, etc.
39+
validations:
40+
required: false
41+
- type: checkboxes
42+
id: scope
43+
attributes:
44+
label: Scope check
45+
description: agent-notify is deliberately narrow (no telemetry, no persistence, no runtime deps beyond a TOML parser, no hosted service). See CONTRIBUTING.md.
46+
options:
47+
- label: This request keeps the no-telemetry / no-persistence / single-binary posture, or I have explained why it should not.
48+
required: true
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<!--
2+
Thanks for sending a patch. Keep this short; delete sections that do not apply.
3+
See CONTRIBUTING.md for what lands easily and what needs an issue first.
4+
-->
5+
6+
## What and why
7+
8+
<!-- One or two sentences on the user-visible change and the problem it solves. -->
9+
10+
Closes #
11+
12+
## Type of change
13+
14+
- [ ] Bug fix
15+
- [ ] New channel adapter
16+
- [ ] New hook adapter
17+
- [ ] Docs
18+
- [ ] Refactor with no command-surface change
19+
- [ ] Surface change (message model, config schema, or other public surface) — opened an issue first per CONTRIBUTING.md
20+
21+
## Checklist
22+
23+
- [ ] `go build ./...`, `go vet ./...`, and `go test -race ./...` pass locally
24+
- [ ] Added or updated tests covering the change (including the privacy invariants where relevant)
25+
- [ ] Updated the `Unreleased` section of `CHANGELOG.md` for any user-visible effect
26+
- [ ] No new outbound HTTP except to channel APIs the user configured; no telemetry, update checks, or disk persistence added
27+
- [ ] No personal details, hostnames, real IPs, account names, tokens, or unredacted absolute paths in code, tests, docs, or this PR (use `192.0.2.x` for example IPs and `EXAMPLE` for placeholder tokens)
28+
- [ ] Conventional commit messages, no AI co-authorship trailers
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: ci
2+
on:
3+
push:
4+
paths-ignore:
5+
- 'docs/**'
6+
- '*.md'
7+
- 'LICENSE'
8+
- '.gitignore'
9+
branches: [main]
10+
pull_request:
11+
paths-ignore:
12+
- 'docs/**'
13+
- '*.md'
14+
- 'LICENSE'
15+
- '.gitignore'
16+
branches: [main]
17+
18+
jobs:
19+
test:
20+
runs-on: ubuntu-latest
21+
steps:
22+
- uses: actions/checkout@v6
23+
- uses: actions/setup-go@v6
24+
with:
25+
go-version: "1.22"
26+
- run: go build ./...
27+
- run: go vet ./...
28+
- run: go test -race ./...
29+
30+
test-windows:
31+
runs-on: windows-latest
32+
steps:
33+
- uses: actions/checkout@v6
34+
- uses: actions/setup-go@v6
35+
with:
36+
go-version: "1.22"
37+
- run: go build ./...
38+
- run: go vet ./...
39+
- run: go test -race ./...
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: release
2+
3+
on:
4+
push:
5+
tags:
6+
- "v*"
7+
8+
permissions:
9+
contents: write
10+
id-token: write
11+
attestations: write
12+
13+
jobs:
14+
release:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v6
18+
with:
19+
fetch-depth: 0
20+
21+
- uses: actions/setup-go@v6
22+
with:
23+
go-version: "1.22"
24+
25+
- name: Build release archives
26+
run: make package VERSION="${GITHUB_REF_NAME}"
27+
28+
- name: Generate source SBOM
29+
# Prebuilt syft binary: `go run syft@latest` breaks whenever syft's
30+
# minimum Go version passes the pinned toolchain.
31+
uses: anchore/sbom-action@v0
32+
with:
33+
path: .
34+
format: spdx-json
35+
output-file: dist/agent-notify_${{ github.ref_name }}_source.spdx.json
36+
upload-artifact: false
37+
upload-release-assets: false
38+
39+
- name: Checksum source SBOM
40+
run: |
41+
cd dist
42+
sha256sum "agent-notify_${GITHUB_REF_NAME}_source.spdx.json" >> checksums.txt
43+
44+
- name: Attest release artifacts
45+
uses: actions/attest-build-provenance@v3
46+
with:
47+
subject-path: "dist/*"
48+
49+
- name: Publish GitHub release
50+
env:
51+
GH_TOKEN: ${{ github.token }}
52+
run: |
53+
gh release create "${GITHUB_REF_NAME}" dist/* \
54+
--title "agent-notify ${GITHUB_REF_NAME}" \
55+
--generate-notes

stations/notify/.gitignore

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/agent-notify
2+
/agent-notify-*
3+
/dist/
4+
*.test
5+
*.out
6+
.idea/
7+
.vscode/
8+
.claude/
9+
10+
# Claude Code + research surface
11+
.claude/
12+
.codex/
13+
.learnings/
14+
docs/superpowers/
15+
**/memory-handoffs/
16+
17+
# OpenClaw files
18+
.openclaw/
19+
*.sqlite

stations/notify/CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented in this file.
4+
5+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7+
8+
## [Unreleased]
9+
10+
### Fixed
11+
- Channel transport failures now return bounded provider, stage, status, and cause fields without retaining request URLs or credentials; the dispatcher sanitizes errors again before writing stderr.
12+
13+
### Documentation
14+
- README leads with a what / why / how-it-differs opening, a centered title and badge row, a prominent Website link, a keyword-rich "What it does" section, verified `doctor` and `status` output blocks, and "Why not <alternatives>?" plus "What agent-notify is not" sections.
15+
- Added maintainer-health files: `SECURITY.md` (trust model and report path), `CONTRIBUTING.md` (contribution scope and channel/hook adapter guides), `CODE_OF_CONDUCT.md`, GitHub issue templates (`bug.yml`, `feature.yml`, `config.yml` with blank issues disabled and contact links), a pull request template with a no-PII checklist, and this changelog.
16+
- Added a recorded terminal demo near the top of the README (`docs/assets/agentnotify-wiring.svg`, reproducible from the committed `.cast`): `init` scaffolds a config, `doctor` flags the unconfigured channels, and after the channel env is set `doctor` reports every channel ready, all without sending a notification.
17+
18+
## [0.1.1] - 2026-05
19+
20+
### Fixed
21+
- Codex hook now parses the event JSON from the trailing positional argument that Codex CLI appends, instead of stdin, so an unrelated leading argument cannot corrupt the payload.
22+
- A channel send failure now returns exit code `3` (distinct from the config-error code `2`), with the per-channel failure count logged to stderr.
23+
- Telegram Markdown V2 backslash escaping corrected so message bodies render as intended.
24+
25+
## [0.1.0] - 2026-04
26+
27+
### Added
28+
- Initial release: a single-binary notification dispatcher that fans out to Discord, Telegram, and Signal, best-effort and concurrently.
29+
- Routing precedence (`--to`, `--profile`, default profile, all channels) with `--skip` filtering.
30+
- TOML config with env-var-referenced secrets, plus `init`, `status`, `doctor`, `version`, and `hooks print` subcommands.
31+
- Built-in hook adapters for Claude Code (Stop / Notification), Codex CLI notify, and a custom JSON source.
32+
- Privacy posture: no telemetry, no update checks, no persistent state, outbound HTTP only to configured channel URLs, asserted by `cmd/agent-notify/privacy_test.go`.
33+
34+
[Unreleased]: https://github.com/escoffier-labs/agent-notify/compare/v0.1.1...HEAD
35+
[0.1.1]: https://github.com/escoffier-labs/agent-notify/compare/v0.1.0...v0.1.1
36+
[0.1.0]: https://github.com/escoffier-labs/agent-notify/releases/tag/v0.1.0

0 commit comments

Comments
 (0)