claude-pager 0.1.0

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.
Files changed (143) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +207 -0
  3. package/dist/channels/channel.d.ts +27 -0
  4. package/dist/channels/channel.d.ts.map +1 -0
  5. package/dist/channels/channel.js +3 -0
  6. package/dist/channels/channel.js.map +1 -0
  7. package/dist/channels/factory.d.ts +4 -0
  8. package/dist/channels/factory.d.ts.map +1 -0
  9. package/dist/channels/factory.js +22 -0
  10. package/dist/channels/factory.js.map +1 -0
  11. package/dist/channels/ntfy/__tests__/provider.test.d.ts +2 -0
  12. package/dist/channels/ntfy/__tests__/provider.test.d.ts.map +1 -0
  13. package/dist/channels/ntfy/__tests__/provider.test.js +29 -0
  14. package/dist/channels/ntfy/__tests__/provider.test.js.map +1 -0
  15. package/dist/channels/ntfy/provider.d.ts +17 -0
  16. package/dist/channels/ntfy/provider.d.ts.map +1 -0
  17. package/dist/channels/ntfy/provider.js +142 -0
  18. package/dist/channels/ntfy/provider.js.map +1 -0
  19. package/dist/channels/telegram/provider.d.ts +27 -0
  20. package/dist/channels/telegram/provider.d.ts.map +1 -0
  21. package/dist/channels/telegram/provider.js +312 -0
  22. package/dist/channels/telegram/provider.js.map +1 -0
  23. package/dist/channels/telegram/voice-handler.d.ts +22 -0
  24. package/dist/channels/telegram/voice-handler.d.ts.map +1 -0
  25. package/dist/channels/telegram/voice-handler.js +68 -0
  26. package/dist/channels/telegram/voice-handler.js.map +1 -0
  27. package/dist/cli/index.d.ts +3 -0
  28. package/dist/cli/index.d.ts.map +1 -0
  29. package/dist/cli/index.js +99 -0
  30. package/dist/cli/index.js.map +1 -0
  31. package/dist/cli/recover.d.ts +2 -0
  32. package/dist/cli/recover.d.ts.map +1 -0
  33. package/dist/cli/recover.js +45 -0
  34. package/dist/cli/recover.js.map +1 -0
  35. package/dist/cli/run.d.ts +2 -0
  36. package/dist/cli/run.d.ts.map +1 -0
  37. package/dist/cli/run.js +32 -0
  38. package/dist/cli/run.js.map +1 -0
  39. package/dist/cli/setup.d.ts +8 -0
  40. package/dist/cli/setup.d.ts.map +1 -0
  41. package/dist/cli/setup.js +238 -0
  42. package/dist/cli/setup.js.map +1 -0
  43. package/dist/config/index.d.ts +6 -0
  44. package/dist/config/index.d.ts.map +1 -0
  45. package/dist/config/index.js +40 -0
  46. package/dist/config/index.js.map +1 -0
  47. package/dist/daemon/__tests__/handlers.test.d.ts +2 -0
  48. package/dist/daemon/__tests__/handlers.test.d.ts.map +1 -0
  49. package/dist/daemon/__tests__/handlers.test.js +99 -0
  50. package/dist/daemon/__tests__/handlers.test.js.map +1 -0
  51. package/dist/daemon/__tests__/server.test.d.ts +2 -0
  52. package/dist/daemon/__tests__/server.test.d.ts.map +1 -0
  53. package/dist/daemon/__tests__/server.test.js +118 -0
  54. package/dist/daemon/__tests__/server.test.js.map +1 -0
  55. package/dist/daemon/handlers.d.ts +4 -0
  56. package/dist/daemon/handlers.d.ts.map +1 -0
  57. package/dist/daemon/handlers.js +153 -0
  58. package/dist/daemon/handlers.js.map +1 -0
  59. package/dist/daemon/index.d.ts +7 -0
  60. package/dist/daemon/index.d.ts.map +1 -0
  61. package/dist/daemon/index.js +83 -0
  62. package/dist/daemon/index.js.map +1 -0
  63. package/dist/daemon/server.d.ts +11 -0
  64. package/dist/daemon/server.d.ts.map +1 -0
  65. package/dist/daemon/server.js +115 -0
  66. package/dist/daemon/server.js.map +1 -0
  67. package/dist/hooks/index.d.ts +3 -0
  68. package/dist/hooks/index.d.ts.map +1 -0
  69. package/dist/hooks/index.js +172 -0
  70. package/dist/hooks/index.js.map +1 -0
  71. package/dist/index.d.ts +4 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +3 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/injectors/__tests__/tmux.test.d.ts +2 -0
  76. package/dist/injectors/__tests__/tmux.test.d.ts.map +1 -0
  77. package/dist/injectors/__tests__/tmux.test.js +38 -0
  78. package/dist/injectors/__tests__/tmux.test.js.map +1 -0
  79. package/dist/injectors/factory.d.ts +3 -0
  80. package/dist/injectors/factory.d.ts.map +1 -0
  81. package/dist/injectors/factory.js +22 -0
  82. package/dist/injectors/factory.js.map +1 -0
  83. package/dist/injectors/injector.d.ts +7 -0
  84. package/dist/injectors/injector.d.ts.map +1 -0
  85. package/dist/injectors/injector.js +3 -0
  86. package/dist/injectors/injector.js.map +1 -0
  87. package/dist/injectors/tmux/injector.d.ts +9 -0
  88. package/dist/injectors/tmux/injector.d.ts.map +1 -0
  89. package/dist/injectors/tmux/injector.js +55 -0
  90. package/dist/injectors/tmux/injector.js.map +1 -0
  91. package/dist/injectors/xdotool/injector.d.ts +9 -0
  92. package/dist/injectors/xdotool/injector.d.ts.map +1 -0
  93. package/dist/injectors/xdotool/injector.js +59 -0
  94. package/dist/injectors/xdotool/injector.js.map +1 -0
  95. package/dist/sessions/__tests__/events.test.d.ts +2 -0
  96. package/dist/sessions/__tests__/events.test.d.ts.map +1 -0
  97. package/dist/sessions/__tests__/events.test.js +103 -0
  98. package/dist/sessions/__tests__/events.test.js.map +1 -0
  99. package/dist/sessions/__tests__/tracker.test.d.ts +2 -0
  100. package/dist/sessions/__tests__/tracker.test.d.ts.map +1 -0
  101. package/dist/sessions/__tests__/tracker.test.js +24 -0
  102. package/dist/sessions/__tests__/tracker.test.js.map +1 -0
  103. package/dist/sessions/events.d.ts +11 -0
  104. package/dist/sessions/events.d.ts.map +1 -0
  105. package/dist/sessions/events.js +73 -0
  106. package/dist/sessions/events.js.map +1 -0
  107. package/dist/sessions/tracker.d.ts +7 -0
  108. package/dist/sessions/tracker.d.ts.map +1 -0
  109. package/dist/sessions/tracker.js +83 -0
  110. package/dist/sessions/tracker.js.map +1 -0
  111. package/dist/types.d.ts +55 -0
  112. package/dist/types.d.ts.map +1 -0
  113. package/dist/types.js +3 -0
  114. package/dist/types.js.map +1 -0
  115. package/dist/utils/__tests__/html.test.d.ts +2 -0
  116. package/dist/utils/__tests__/html.test.d.ts.map +1 -0
  117. package/dist/utils/__tests__/html.test.js +42 -0
  118. package/dist/utils/__tests__/html.test.js.map +1 -0
  119. package/dist/utils/__tests__/json.test.d.ts +2 -0
  120. package/dist/utils/__tests__/json.test.d.ts.map +1 -0
  121. package/dist/utils/__tests__/json.test.js +27 -0
  122. package/dist/utils/__tests__/json.test.js.map +1 -0
  123. package/dist/utils/__tests__/validation.test.d.ts +2 -0
  124. package/dist/utils/__tests__/validation.test.d.ts.map +1 -0
  125. package/dist/utils/__tests__/validation.test.js +38 -0
  126. package/dist/utils/__tests__/validation.test.js.map +1 -0
  127. package/dist/utils/html.d.ts +3 -0
  128. package/dist/utils/html.d.ts.map +1 -0
  129. package/dist/utils/html.js +43 -0
  130. package/dist/utils/html.js.map +1 -0
  131. package/dist/utils/json.d.ts +2 -0
  132. package/dist/utils/json.d.ts.map +1 -0
  133. package/dist/utils/json.js +13 -0
  134. package/dist/utils/json.js.map +1 -0
  135. package/dist/utils/validation.d.ts +4 -0
  136. package/dist/utils/validation.d.ts.map +1 -0
  137. package/dist/utils/validation.js +16 -0
  138. package/dist/utils/validation.js.map +1 -0
  139. package/dist/voice/transcribe.d.ts +7 -0
  140. package/dist/voice/transcribe.d.ts.map +1 -0
  141. package/dist/voice/transcribe.js +66 -0
  142. package/dist/voice/transcribe.js.map +1 -0
  143. package/package.json +50 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Seb Bassompierre / KASEI LABS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,207 @@
1
+ # claude-pager
2
+
3
+ Relay notifications and responses between Claude Code CLI sessions and your phone. When Claude needs your input (permission prompt, idle question) and you're away from the terminal, `claude-pager` sends a notification to your phone and types your response back into the correct tmux pane.
4
+
5
+ ## How it works
6
+
7
+ ```
8
+ ┌─────────────┐ hook → HTTP ┌──────────────┐ Telegram / ntfy ┌──────────┐
9
+ │ Claude Code │ ────────────────► │ claude-pager │ ──────────────────► │ Phone │
10
+ │ (N instances)│ │ daemon │ ◄────────────────── │ (reply) │
11
+ └─────────────┘ └──────┬───────┘ └──────────┘
12
+ │ tmux send-keys
13
+
14
+ ┌──────────────┐
15
+ │ Right terminal│
16
+ └──────────────┘
17
+ ```
18
+
19
+ 1. Claude Code hooks fire when an instance needs user input
20
+ 2. The hook enriches the event (tool name, last assistant message) and sends it to the daemon
21
+ 3. The daemon dispatches a notification to your phone via Telegram or ntfy
22
+ 4. You respond — tap Allow/Deny, type a message, or send a voice note
23
+ 5. The daemon matches the response to the right session and injects it via `tmux send-keys`
24
+
25
+ ## Features
26
+
27
+ - **Multi-session** — run N Claude Code instances in tmux, responses route to the correct pane
28
+ - **Telegram** — inline keyboards (Allow/Deny), reply-to-message routing, voice transcription (Whisper)
29
+ - **ntfy** — self-hosted or ntfy.sh, mobile push notifications
30
+ - **Session recovery** — `claude-pager recover` detects existing Claude sessions in tmux
31
+ - **Smart routing** — `#id response` for explicit targeting, auto-route for single session, session picker for ambiguous cases
32
+ - **Fallback by project** — if a session UUID is no longer registered, matches by `cwd` (project directory)
33
+
34
+ ## Requirements
35
+
36
+ - Node.js >= 20
37
+ - tmux
38
+ - Linux (macOS support planned)
39
+ - A Telegram bot or ntfy server for notifications
40
+
41
+ ## Installation
42
+
43
+ ```bash
44
+ npm install -g claude-pager
45
+ ```
46
+
47
+ ## Setup
48
+
49
+ Interactive configuration — creates `~/.claude-pager/config.json` and installs Claude Code hooks in `~/.claude/settings.json`:
50
+
51
+ ```bash
52
+ claude-pager setup
53
+ ```
54
+
55
+ The setup wizard lets you choose between **Telegram** and **ntfy** as notification channel, and verifies the connection.
56
+
57
+ ### Telegram
58
+
59
+ You need a Telegram bot token (from [@BotFather](https://t.me/BotFather)) and a chat ID. The setup command walks you through obtaining both.
60
+
61
+ ### ntfy
62
+
63
+ Point to your ntfy server (self-hosted or `https://ntfy.sh`) with a topic and optional authentication (user/password or token).
64
+
65
+ ## Usage
66
+
67
+ ### Start the daemon
68
+
69
+ ```bash
70
+ # Foreground (for testing)
71
+ claude-pager start
72
+
73
+ # As a systemd user service (recommended)
74
+ cat > ~/.config/systemd/user/claude-pager.service << 'EOF'
75
+ [Unit]
76
+ Description=Claude Code Relay Daemon
77
+ After=network-online.target
78
+ Wants=network-online.target
79
+
80
+ [Service]
81
+ Type=simple
82
+ ExecStart=%h/.local/bin/claude-pager start
83
+ ExecStop=%h/.local/bin/claude-pager stop
84
+ Restart=on-failure
85
+ RestartSec=5
86
+ Environment=NODE_ENV=production
87
+
88
+ [Install]
89
+ WantedBy=default.target
90
+ EOF
91
+ # If claude-pager is installed via nvm, adjust ExecStart path:
92
+ # ExecStart=/home/you/.nvm/versions/node/v22.x.x/bin/claude-pager start
93
+ systemctl --user daemon-reload
94
+ systemctl --user enable --now claude-pager
95
+ ```
96
+
97
+ ### Launch Claude Code in tmux
98
+
99
+ ```bash
100
+ claude-pager run # opens a new tmux session with claude
101
+ claude-pager run --resume # pass args through to claude
102
+ ```
103
+
104
+ Or just run `claude` directly inside tmux — the `SessionStart` hook registers the session automatically.
105
+
106
+ ### Recover existing sessions
107
+
108
+ If you already have Claude Code running in tmux panes:
109
+
110
+ ```bash
111
+ claude-pager recover
112
+ ```
113
+
114
+ ### Other commands
115
+
116
+ ```bash
117
+ claude-pager status # daemon status + health check
118
+ claude-pager pending # list pending questions
119
+ claude-pager stop # stop the daemon
120
+ ```
121
+
122
+ ## Responding to notifications
123
+
124
+ ### Telegram
125
+
126
+ - **Permission prompts** — tap the inline **Allow** or **Deny** button
127
+ - **Idle prompts** — reply to the notification message with your answer
128
+ - **Voice** — send a voice message, it gets transcribed and injected
129
+ - **Free messages** — send a message without replying; if one session is active it goes there, otherwise a session picker appears
130
+
131
+ ### ntfy
132
+
133
+ - Reply with `#<id> <response>` to target a specific notification
134
+ - If only one question is pending, any reply routes to it
135
+ - `allow` / `deny` auto-route to the most recent permission prompt
136
+
137
+ ## Configuration
138
+
139
+ `~/.claude-pager/config.json`:
140
+
141
+ ```json
142
+ {
143
+ "port": 17380,
144
+ "channel": {
145
+ "type": "telegram",
146
+ "telegram": {
147
+ "botToken": "123456:ABC...",
148
+ "chatId": 12345678
149
+ }
150
+ },
151
+ "injector": "auto"
152
+ }
153
+ ```
154
+
155
+ | Key | Default | Description |
156
+ |-----|---------|-------------|
157
+ | `port` | `17380` | Daemon HTTP port (localhost only) |
158
+ | `channel.type` | `"ntfy"` | `"ntfy"` or `"telegram"` |
159
+ | `injector` | `"auto"` | `"auto"`, `"tmux"`, or `"xdotool"` |
160
+
161
+ The hook port can be overridden with `CLAUDE_PAGER_PORT` environment variable.
162
+
163
+ ## Architecture
164
+
165
+ Strategy + Factory pattern for pluggable components:
166
+
167
+ ```
168
+ src/
169
+ ├── channels/ # Notification channels (ntfy, telegram)
170
+ │ ├── channel.ts # ChannelProvider interface
171
+ │ └── factory.ts
172
+ ├── injectors/ # Terminal input injection (tmux, xdotool)
173
+ │ ├── injector.ts # InputInjector interface
174
+ │ └── factory.ts
175
+ ├── daemon/ # HTTP server + response routing
176
+ │ ├── server.ts # Fastify routes with JSON Schema validation
177
+ │ └── handlers.ts # Channel listener logic (routing, picker)
178
+ ├── sessions/ # Session tracking + pending question store
179
+ ├── hooks/ # Claude Code hook entry point
180
+ ├── utils/ # Shared utilities (html, json, validation)
181
+ ├── cli/ # Commander CLI
182
+ └── voice/ # Telegram voice transcription (Whisper)
183
+ ```
184
+
185
+ See `docs/ARCHITECTURE.md` for the detailed flow.
186
+
187
+ ## Security
188
+
189
+ - HTTP API binds to `127.0.0.1` only — no network exposure
190
+ - Input validation with Fastify JSON Schema + custom validators (`isValidEventType`, `isValidSessionId`)
191
+ - No shell injection — all child processes use `execFileSync` with argument arrays
192
+ - No code content in notifications — only tool names, project names, and question types
193
+ - Memory-bounded maps (capped at 500-1000 entries)
194
+ - Safe JSON parsing with fallbacks for corrupted files
195
+
196
+ ## Development
197
+
198
+ ```bash
199
+ npm run build # TypeScript compilation
200
+ npm test # Run all tests (node:test)
201
+ npm run lint # ESLint with typescript-eslint
202
+ npm run dev # Dev mode (tsx watch)
203
+ ```
204
+
205
+ ## License
206
+
207
+ MIT
@@ -0,0 +1,27 @@
1
+ import type { RelayEvent } from '../types.js';
2
+ export interface NotificationResult {
3
+ messageId?: string;
4
+ success: boolean;
5
+ error?: string;
6
+ }
7
+ export interface FreeMessage {
8
+ text: string;
9
+ sessionId?: string;
10
+ replyCallback: (text: string) => Promise<void>;
11
+ }
12
+ export interface ChannelListeners {
13
+ onResponse: (rawText: string) => void | Promise<void>;
14
+ onFreeMessage?: (msg: FreeMessage) => void | Promise<void>;
15
+ }
16
+ export interface ChannelProvider {
17
+ readonly name: string;
18
+ send(event: RelayEvent, shortId: string): Promise<NotificationResult>;
19
+ sendRaw?(text: string): Promise<void>;
20
+ sendSessionPicker?(text: string, sessions: Array<{
21
+ id: string;
22
+ label: string;
23
+ }>): Promise<number | undefined>;
24
+ startListening(listeners: ChannelListeners): void;
25
+ stopListening(): void;
26
+ }
27
+ //# sourceMappingURL=channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.d.ts","sourceRoot":"","sources":["../../src/channels/channel.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5D;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEtE,OAAO,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAE9G,cAAc,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAElD,aAAa,IAAI,IAAI,CAAC;CACvB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=channel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"channel.js","sourceRoot":"","sources":["../../src/channels/channel.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { ChannelConfig } from '../types.js';
2
+ import type { ChannelProvider } from './channel.js';
3
+ export declare function createChannel(config: ChannelConfig): ChannelProvider;
4
+ //# sourceMappingURL=factory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/channels/factory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAIpD,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,eAAe,CAepE"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createChannel = createChannel;
4
+ const provider_js_1 = require("./ntfy/provider.js");
5
+ const provider_js_2 = require("./telegram/provider.js");
6
+ function createChannel(config) {
7
+ switch (config.type) {
8
+ case 'ntfy':
9
+ if (!config.ntfy) {
10
+ throw new Error('ntfy configuration is required when channel type is "ntfy"');
11
+ }
12
+ return new provider_js_1.NtfyProvider(config.ntfy);
13
+ case 'telegram':
14
+ if (!config.telegram) {
15
+ throw new Error('telegram configuration is required when channel type is "telegram"');
16
+ }
17
+ return new provider_js_2.TelegramProvider(config.telegram);
18
+ default:
19
+ throw new Error(`Unknown channel type: ${config.type}`);
20
+ }
21
+ }
22
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/channels/factory.ts"],"names":[],"mappings":";;AAKA,sCAeC;AAlBD,oDAAkD;AAClD,wDAA0D;AAE1D,SAAgB,aAAa,CAAC,MAAqB;IACjD,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,MAAM;YACT,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACjB,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAC;YAChF,CAAC;YACD,OAAO,IAAI,0BAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,KAAK,UAAU;YACb,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAC;YACxF,CAAC;YACD,OAAO,IAAI,8BAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/C;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=provider.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.test.d.ts","sourceRoot":"","sources":["../../../../src/channels/ntfy/__tests__/provider.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_test_1 = require("node:test");
7
+ const strict_1 = __importDefault(require("node:assert/strict"));
8
+ const provider_js_1 = require("../provider.js");
9
+ (0, node_test_1.describe)('NtfyProvider', () => {
10
+ (0, node_test_1.describe)('send', () => {
11
+ (0, node_test_1.it)('should report error when server is unreachable', async () => {
12
+ const provider = new provider_js_1.NtfyProvider({
13
+ server: 'http://127.0.0.1:19999',
14
+ topic: 'test',
15
+ });
16
+ const result = await provider.send({
17
+ id: 'evt-1',
18
+ sessionId: 'sess-1',
19
+ type: 'permission_prompt',
20
+ message: 'Allow Bash(git status)?',
21
+ project: '/home/user/dev/myproject',
22
+ timestamp: Date.now(),
23
+ }, '1');
24
+ strict_1.default.equal(result.success, false);
25
+ strict_1.default.ok(result.error);
26
+ });
27
+ });
28
+ });
29
+ //# sourceMappingURL=provider.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.test.js","sourceRoot":"","sources":["../../../../src/channels/ntfy/__tests__/provider.test.ts"],"names":[],"mappings":";;;;;AAAA,yCAAyC;AACzC,gEAAwC;AACxC,gDAA8C;AAE9C,IAAA,oBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAA,oBAAQ,EAAC,MAAM,EAAE,GAAG,EAAE;QACpB,IAAA,cAAE,EAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,QAAQ,GAAG,IAAI,0BAAY,CAAC;gBAChC,MAAM,EAAE,wBAAwB;gBAChC,KAAK,EAAE,MAAM;aACd,CAAC,CAAC;YAEH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,IAAI,CAChC;gBACE,EAAE,EAAE,OAAO;gBACX,SAAS,EAAE,QAAQ;gBACnB,IAAI,EAAE,mBAAmB;gBACzB,OAAO,EAAE,yBAAyB;gBAClC,OAAO,EAAE,0BAA0B;gBACnC,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;aACtB,EACD,GAAG,CACJ,CAAC;YAEF,gBAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YACpC,gBAAM,CAAC,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1B,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import type { ChannelProvider, ChannelListeners, NotificationResult } from '../channel.js';
2
+ import type { NtfyConfig, RelayEvent } from '../../types.js';
3
+ export declare class NtfyProvider implements ChannelProvider {
4
+ readonly name = "ntfy";
5
+ private abortController;
6
+ private readonly config;
7
+ private processedIds;
8
+ constructor(config: NtfyConfig);
9
+ private get topicUrl();
10
+ private authHeaders;
11
+ send(event: RelayEvent, shortId: string): Promise<NotificationResult>;
12
+ startListening(listeners: ChannelListeners): void;
13
+ private poll;
14
+ private capSet;
15
+ stopListening(): void;
16
+ }
17
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/channels/ntfy/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAC3F,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE7D,qBAAa,YAAa,YAAW,eAAe;IAClD,QAAQ,CAAC,IAAI,UAAU;IACvB,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,YAAY,CAAqB;gBAE7B,MAAM,EAAE,UAAU;IAI9B,OAAO,KAAK,QAAQ,GAEnB;IAED,OAAO,CAAC,WAAW;IAWb,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAiD3E,cAAc,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;YAMnC,IAAI;IAsDlB,OAAO,CAAC,MAAM;IAOd,aAAa,IAAI,IAAI;CAItB"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NtfyProvider = void 0;
4
+ class NtfyProvider {
5
+ name = 'ntfy';
6
+ abortController = null;
7
+ config;
8
+ processedIds = new Set();
9
+ constructor(config) {
10
+ this.config = config;
11
+ }
12
+ get topicUrl() {
13
+ return `${this.config.server}/${this.config.topic}`;
14
+ }
15
+ authHeaders() {
16
+ if (this.config.token) {
17
+ return { Authorization: `Bearer ${this.config.token}` };
18
+ }
19
+ if (this.config.user && this.config.password) {
20
+ const encoded = Buffer.from(`${this.config.user}:${this.config.password}`).toString('base64');
21
+ return { Authorization: `Basic ${encoded}` };
22
+ }
23
+ return {};
24
+ }
25
+ async send(event, shortId) {
26
+ const projectName = event.project.split('/').pop() || event.project;
27
+ const title = `Claude Code - ${projectName}`;
28
+ const isPermission = event.type === 'permission_prompt';
29
+ const tag = isPermission ? 'robot,lock' : 'robot,question';
30
+ const hint = isPermission ? 'Reply: allow / deny' : 'Reply with your answer';
31
+ const headers = {
32
+ 'Content-Type': 'text/plain',
33
+ Title: title,
34
+ Priority: isPermission ? 'high' : 'default',
35
+ Tags: tag,
36
+ ...this.authHeaders(),
37
+ };
38
+ let body = `#${shortId} ${event.message}`;
39
+ if (event.toolName) {
40
+ body += `\n${event.toolName}`;
41
+ if (event.toolInput) {
42
+ const input = event.toolInput.length > 200 ? event.toolInput.slice(0, 200) + '...' : event.toolInput;
43
+ body += `(${input})`;
44
+ }
45
+ }
46
+ body += `\n\n${hint}`;
47
+ try {
48
+ const res = await fetch(this.topicUrl, {
49
+ method: 'POST',
50
+ headers,
51
+ body,
52
+ });
53
+ if (!res.ok) {
54
+ const text = await res.text();
55
+ return { success: false, error: `ntfy responded ${res.status}: ${text}` };
56
+ }
57
+ const data = (await res.json());
58
+ if (data.id) {
59
+ this.capSet(this.processedIds, 1000);
60
+ this.processedIds.add(data.id);
61
+ }
62
+ return { success: true, messageId: data.id };
63
+ }
64
+ catch (err) {
65
+ return { success: false, error: String(err) };
66
+ }
67
+ }
68
+ startListening(listeners) {
69
+ this.stopListening();
70
+ this.abortController = new AbortController();
71
+ this.poll(listeners.onResponse);
72
+ }
73
+ async poll(onResponse) {
74
+ const signal = this.abortController.signal;
75
+ let pollCount = 0;
76
+ while (!signal.aborted) {
77
+ try {
78
+ pollCount++;
79
+ if (pollCount % 2 === 0)
80
+ console.log(`[ntfy] poll #${pollCount}`);
81
+ const url = `${this.topicUrl}/json?poll=1&since=30s`;
82
+ const res = await fetch(url, {
83
+ headers: this.authHeaders(),
84
+ signal,
85
+ });
86
+ if (res.ok) {
87
+ const text = await res.text();
88
+ for (const line of text.split('\n').filter(Boolean)) {
89
+ try {
90
+ const msg = JSON.parse(line);
91
+ if (msg.event !== 'message' || !msg.message)
92
+ continue;
93
+ if (msg.id && this.processedIds.has(msg.id))
94
+ continue;
95
+ if (msg.id) {
96
+ this.capSet(this.processedIds, 1000);
97
+ this.processedIds.add(msg.id);
98
+ }
99
+ if (/^#\d+ .+\n\nReply[ :]/.test(msg.message))
100
+ continue;
101
+ console.log(`[ntfy] received response: "${msg.message}"`);
102
+ try {
103
+ await Promise.resolve(onResponse(msg.message));
104
+ }
105
+ catch (cbErr) {
106
+ console.error('[ntfy] callback error:', cbErr);
107
+ }
108
+ }
109
+ catch {
110
+ console.debug('[ntfy] skipping malformed line:', line.slice(0, 80));
111
+ }
112
+ }
113
+ }
114
+ }
115
+ catch (err) {
116
+ if (signal.aborted)
117
+ return;
118
+ console.error('[ntfy] poll error:', err);
119
+ }
120
+ // Simple sleep that resolves on abort instead of rejecting
121
+ if (signal.aborted)
122
+ return;
123
+ await new Promise(resolve => {
124
+ const timer = setTimeout(resolve, 5000);
125
+ signal.addEventListener('abort', () => { clearTimeout(timer); resolve(); }, { once: true });
126
+ });
127
+ }
128
+ }
129
+ capSet(set, max) {
130
+ if (set.size >= max) {
131
+ const first = set.values().next().value;
132
+ if (first !== undefined)
133
+ set.delete(first);
134
+ }
135
+ }
136
+ stopListening() {
137
+ this.abortController?.abort();
138
+ this.abortController = null;
139
+ }
140
+ }
141
+ exports.NtfyProvider = NtfyProvider;
142
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/channels/ntfy/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { ChannelProvider, ChannelListeners, NotificationResult } from '../channel.js';
2
+ import type { TelegramConfig, RelayEvent } from '../../types.js';
3
+ export declare class TelegramProvider implements ChannelProvider {
4
+ readonly name = "telegram";
5
+ private abortController;
6
+ private readonly config;
7
+ private lastUpdateId;
8
+ private messageToEvent;
9
+ private messageToSession;
10
+ constructor(config: TelegramConfig);
11
+ private apiUrl;
12
+ send(event: RelayEvent, shortId: string): Promise<NotificationResult>;
13
+ sendRaw(text: string): Promise<void>;
14
+ sendSessionPicker(text: string, sessions: Array<{
15
+ id: string;
16
+ label: string;
17
+ }>): Promise<number | undefined>;
18
+ startListening(listeners: ChannelListeners): void;
19
+ private poll;
20
+ private handleCallback;
21
+ private handleVoice;
22
+ private handleFreeMessage;
23
+ private handleReply;
24
+ private capMap;
25
+ stopListening(): void;
26
+ }
27
+ //# sourceMappingURL=provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../src/channels/telegram/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAe,MAAM,eAAe,CAAC;AACxG,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA2BjE,qBAAa,gBAAiB,YAAW,eAAe;IACtD,QAAQ,CAAC,IAAI,cAAc;IAC3B,OAAO,CAAC,eAAe,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,YAAY,CAAK;IAEzB,OAAO,CAAC,cAAc,CAA6B;IAEnD,OAAO,CAAC,gBAAgB,CAA6B;gBAEzC,MAAM,EAAE,cAAc;IAIlC,OAAO,CAAC,MAAM;IAIR,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IA8DrE,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAapC,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA0BlH,cAAc,CAAC,SAAS,EAAE,gBAAgB,GAAG,IAAI;YAMnC,IAAI;YA6CJ,cAAc;YAwEd,WAAW;YAYX,iBAAiB;YAmBjB,WAAW;IA2CzB,OAAO,CAAC,MAAM;IAOd,aAAa,IAAI,IAAI;CAItB"}