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
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createChannelHandlers = createChannelHandlers;
4
+ const events_js_1 = require("../sessions/events.js");
5
+ const tracker_js_1 = require("../sessions/tracker.js");
6
+ const html_js_1 = require("../utils/html.js");
7
+ function createChannelHandlers(channel, injector) {
8
+ const picker = { text: undefined, sessions: undefined };
9
+ async function handleSessionPick(rawText) {
10
+ if (!rawText.startsWith('__session_pick__:') || !picker.text || !picker.sessions) {
11
+ return false;
12
+ }
13
+ const sessionId = rawText.split(':')[1];
14
+ const target = picker.sessions.find(s => s.sessionId === sessionId);
15
+ const text = picker.text;
16
+ picker.text = undefined;
17
+ picker.sessions = undefined;
18
+ if (target) {
19
+ const ok = await injector.sendResponse(target, text, 'idle_prompt');
20
+ console.log(ok
21
+ ? `[daemon] Injected "${text}" into ${target.tmuxPane} (via picker)`
22
+ : `[daemon] Failed to inject via picker`);
23
+ }
24
+ return true;
25
+ }
26
+ async function routeAsFreeTo(sessions, text) {
27
+ if (sessions.length === 0) {
28
+ console.log('[daemon] No active sessions');
29
+ if (channel.sendRaw)
30
+ await channel.sendRaw('No active sessions.');
31
+ return;
32
+ }
33
+ if (sessions.length === 1) {
34
+ const ok = await injector.sendResponse(sessions[0], text, 'idle_prompt');
35
+ console.log(ok
36
+ ? `[daemon] Injected free message into ${sessions[0].tmuxPane}`
37
+ : `[daemon] Failed to inject free message`);
38
+ return;
39
+ }
40
+ // Multiple sessions — send picker if channel supports it
41
+ if (channel.sendSessionPicker) {
42
+ picker.text = text;
43
+ picker.sessions = sessions;
44
+ const choices = sessions.map(s => ({
45
+ id: s.sessionId,
46
+ label: `${s.cwd.split('/').pop()} (${s.tmuxPane})`,
47
+ }));
48
+ await channel.sendSessionPicker(`Which session should receive:\n<pre>${(0, html_js_1.escapeHtml)(text)}</pre>`, choices);
49
+ console.log('[daemon] Session picker sent');
50
+ }
51
+ }
52
+ return {
53
+ onResponse: async (rawText) => {
54
+ if (await handleSessionPick(rawText))
55
+ return;
56
+ console.log(`[daemon] Received response from channel: "${rawText}"`);
57
+ try {
58
+ const resolved = (0, events_js_1.resolveResponse)(rawText);
59
+ if (resolved) {
60
+ const { question, response } = resolved;
61
+ let session = (0, tracker_js_1.getSession)(question.event.sessionId);
62
+ // Fallback: find a session with the same cwd (project)
63
+ if (!session) {
64
+ (0, tracker_js_1.cleanDeadSessions)();
65
+ const byCwd = (0, tracker_js_1.listSessions)().filter(s => s.tmuxPane && s.cwd === question.event.project);
66
+ if (byCwd.length === 1) {
67
+ session = byCwd[0];
68
+ console.log(`[daemon] Session ${question.event.sessionId} not found, matched by cwd → ${session.tmuxPane}`);
69
+ }
70
+ else {
71
+ console.log(`[daemon] Session ${question.event.sessionId} not found (${byCwd.length} cwd matches)`);
72
+ }
73
+ }
74
+ if (session) {
75
+ const canResolve = await injector.resolve(session);
76
+ if (canResolve) {
77
+ const ok = await injector.sendResponse(session, response, question.event.type);
78
+ if (ok) {
79
+ (0, events_js_1.removePending)(question.event.id);
80
+ console.log(`[daemon] Injected "${response}" via ${injector.name}`);
81
+ }
82
+ else {
83
+ console.log(`[daemon] Failed to inject via ${injector.name}`);
84
+ }
85
+ return;
86
+ }
87
+ console.log(`[daemon] Injector cannot resolve session, will try as free message`);
88
+ }
89
+ (0, events_js_1.removePending)(question.event.id);
90
+ }
91
+ // Fallback: treat as free message (strip #eventId prefix if present)
92
+ const cleanText = rawText.replace(/^#[\w-]+\s+/, '').trim();
93
+ if (!cleanText) {
94
+ console.log('[daemon] No text to inject');
95
+ return;
96
+ }
97
+ console.log(`[daemon] Routing as free message: "${cleanText}"`);
98
+ (0, tracker_js_1.cleanDeadSessions)();
99
+ const sessions = (0, tracker_js_1.listSessions)().filter(s => s.tmuxPane);
100
+ await routeAsFreeTo(sessions, cleanText);
101
+ }
102
+ catch (err) {
103
+ console.error('[daemon] Error handling response:', err);
104
+ }
105
+ },
106
+ onFreeMessage: async (msg) => {
107
+ console.log(`[daemon] Free message: "${msg.text}"${msg.sessionId ? ` (session: ${msg.sessionId})` : ''}`);
108
+ try {
109
+ (0, tracker_js_1.cleanDeadSessions)();
110
+ const sessions = (0, tracker_js_1.listSessions)();
111
+ const activeSessions = sessions.filter(s => s.tmuxPane);
112
+ if (activeSessions.length === 0) {
113
+ await msg.replyCallback('No active sessions.');
114
+ return;
115
+ }
116
+ let targetSession;
117
+ // If sessionId is known (reply to a notification), use it directly
118
+ if (msg.sessionId) {
119
+ targetSession = activeSessions.find(s => s.sessionId === msg.sessionId);
120
+ }
121
+ if (!targetSession && activeSessions.length === 1) {
122
+ targetSession = activeSessions[0];
123
+ }
124
+ if (!targetSession && channel.sendSessionPicker) {
125
+ const sessionChoices = activeSessions.map(s => ({
126
+ id: s.sessionId,
127
+ label: `${s.cwd.split('/').pop()} (${s.tmuxPane})`,
128
+ }));
129
+ picker.text = msg.text;
130
+ picker.sessions = activeSessions;
131
+ await channel.sendSessionPicker(`Which session should receive:\n<pre>${(0, html_js_1.escapeHtml)(msg.text)}</pre>`, sessionChoices);
132
+ console.log('[daemon] Session picker sent, waiting for selection...');
133
+ return;
134
+ }
135
+ if (!targetSession) {
136
+ await msg.replyCallback('Could not determine target session.');
137
+ return;
138
+ }
139
+ const ok = await injector.sendResponse(targetSession, msg.text, 'idle_prompt');
140
+ if (ok) {
141
+ console.log(`[daemon] Injected free message into ${targetSession.tmuxPane}`);
142
+ }
143
+ else {
144
+ await msg.replyCallback('Failed to inject message.');
145
+ }
146
+ }
147
+ catch (err) {
148
+ console.error('[daemon] Error handling free message:', err);
149
+ }
150
+ },
151
+ };
152
+ }
153
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/daemon/handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare function isDaemonRunning(): {
2
+ running: boolean;
3
+ pid?: number;
4
+ };
5
+ export declare function startDaemon(): Promise<void>;
6
+ export declare function stopDaemon(): boolean;
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"AAUA,wBAAgB,eAAe,IAAI;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,CAYpE;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAwCjD;AAED,wBAAgB,UAAU,IAAI,OAAO,CAWpC"}
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDaemonRunning = isDaemonRunning;
4
+ exports.startDaemon = startDaemon;
5
+ exports.stopDaemon = stopDaemon;
6
+ const node_fs_1 = require("node:fs");
7
+ const node_path_1 = require("node:path");
8
+ const index_js_1 = require("../config/index.js");
9
+ const factory_js_1 = require("../channels/factory.js");
10
+ const factory_js_2 = require("../injectors/factory.js");
11
+ const server_js_1 = require("./server.js");
12
+ const handlers_js_1 = require("./handlers.js");
13
+ const PID_FILE = () => (0, node_path_1.join)((0, index_js_1.getDataDir)(), 'daemon.pid');
14
+ function isDaemonRunning() {
15
+ const pidFile = PID_FILE();
16
+ if (!(0, node_fs_1.existsSync)(pidFile))
17
+ return { running: false };
18
+ const pid = parseInt((0, node_fs_1.readFileSync)(pidFile, 'utf-8').trim(), 10);
19
+ try {
20
+ process.kill(pid, 0);
21
+ return { running: true, pid };
22
+ }
23
+ catch {
24
+ (0, node_fs_1.unlinkSync)(pidFile);
25
+ return { running: false };
26
+ }
27
+ }
28
+ async function startDaemon() {
29
+ const { running, pid } = isDaemonRunning();
30
+ if (running) {
31
+ console.log(`Daemon already running (PID ${pid})`);
32
+ process.exit(1);
33
+ }
34
+ (0, index_js_1.ensureDataDir)();
35
+ const config = (0, index_js_1.loadConfig)();
36
+ const channel = (0, factory_js_1.createChannel)(config.channel);
37
+ const injector = (0, factory_js_2.createInjector)(config.injector);
38
+ const app = await (0, server_js_1.createServer)({ config, channel, injector });
39
+ // Write PID file
40
+ (0, node_fs_1.writeFileSync)(PID_FILE(), String(process.pid));
41
+ // Start polling for responses from the channel
42
+ const handlers = (0, handlers_js_1.createChannelHandlers)(channel, injector);
43
+ channel.startListening(handlers);
44
+ // Graceful shutdown
45
+ const shutdown = async () => {
46
+ console.log('\nShutting down...');
47
+ channel.stopListening();
48
+ await app.close();
49
+ try {
50
+ (0, node_fs_1.unlinkSync)(PID_FILE());
51
+ }
52
+ catch { /* ignore */ }
53
+ process.exit(0);
54
+ };
55
+ process.on('SIGINT', shutdown);
56
+ process.on('SIGTERM', shutdown);
57
+ try {
58
+ await app.listen({ port: config.port, host: '127.0.0.1' });
59
+ console.log(`claude-pager daemon listening on 127.0.0.1:${config.port}`);
60
+ }
61
+ catch (err) {
62
+ try {
63
+ (0, node_fs_1.unlinkSync)(PID_FILE());
64
+ }
65
+ catch { /* ignore */ }
66
+ throw err;
67
+ }
68
+ }
69
+ function stopDaemon() {
70
+ const { running, pid } = isDaemonRunning();
71
+ if (!running || !pid) {
72
+ console.log('Daemon is not running');
73
+ return false;
74
+ }
75
+ process.kill(pid, 'SIGTERM');
76
+ try {
77
+ (0, node_fs_1.unlinkSync)(PID_FILE());
78
+ }
79
+ catch { /* ignore */ }
80
+ console.log(`Daemon stopped (PID ${pid})`);
81
+ return true;
82
+ }
83
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { RelayConfig } from '../types.js';
2
+ import type { ChannelProvider } from '../channels/channel.js';
3
+ import type { InputInjector } from '../injectors/injector.js';
4
+ interface DaemonDeps {
5
+ config: RelayConfig;
6
+ channel: ChannelProvider;
7
+ injector: InputInjector;
8
+ }
9
+ export declare function createServer(deps: DaemonDeps): Promise<import("fastify").FastifyInstance<import("http").Server<typeof import("http").IncomingMessage, typeof import("http").ServerResponse>, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>>;
10
+ export {};
11
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAc,MAAM,aAAa,CAAC;AAC3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAM9D,UAAU,UAAU;IAClB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,eAAe,CAAC;IACzB,QAAQ,EAAE,aAAa,CAAC;CACzB;AA8BD,wBAAsB,YAAY,CAAC,IAAI,EAAE,UAAU,oUAoGlD"}
@@ -0,0 +1,115 @@
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
+ exports.createServer = createServer;
7
+ const fastify_1 = __importDefault(require("fastify"));
8
+ const events_js_1 = require("../sessions/events.js");
9
+ const tracker_js_1 = require("../sessions/tracker.js");
10
+ const validation_js_1 = require("../utils/validation.js");
11
+ const node_crypto_1 = require("node:crypto");
12
+ // JSON Schemas for Fastify validation
13
+ const eventBodySchema = {
14
+ type: 'object',
15
+ required: ['session_id', 'message'],
16
+ properties: {
17
+ session_id: { type: 'string', minLength: 1 },
18
+ notification_type: { type: 'string' },
19
+ type: { type: 'string' },
20
+ message: { type: 'string', minLength: 1 },
21
+ title: { type: 'string' },
22
+ cwd: { type: 'string' },
23
+ tool_name: { type: 'string' },
24
+ tool_input: { type: 'string' },
25
+ },
26
+ anyOf: [
27
+ { required: ['notification_type'] },
28
+ { required: ['type'] },
29
+ ],
30
+ };
31
+ const respondBodySchema = {
32
+ type: 'object',
33
+ required: ['text'],
34
+ properties: {
35
+ text: { type: 'string', minLength: 1 },
36
+ },
37
+ };
38
+ async function createServer(deps) {
39
+ const { channel, injector } = deps;
40
+ const app = (0, fastify_1.default)({ logger: true });
41
+ // Health check
42
+ app.get('/api/v1/health', async () => {
43
+ return { status: 'ok', channel: channel.name, injector: injector.name };
44
+ });
45
+ // Receive events from hooks
46
+ app.post('/api/v1/events', { schema: { body: eventBodySchema } }, async (request, reply) => {
47
+ const body = request.body;
48
+ const sessionId = body.session_id;
49
+ const type = body.notification_type || body.type;
50
+ const message = body.message;
51
+ if (!(0, validation_js_1.isValidSessionId)(sessionId)) {
52
+ return reply.status(400).send({ error: 'Invalid session_id format' });
53
+ }
54
+ if (!(0, validation_js_1.isValidEventType)(type)) {
55
+ return reply.status(400).send({ error: `Invalid event type: ${type}` });
56
+ }
57
+ const session = (0, tracker_js_1.getSession)(sessionId);
58
+ const project = body.cwd || session?.cwd || 'unknown';
59
+ const event = {
60
+ id: (0, node_crypto_1.randomUUID)(),
61
+ sessionId,
62
+ type,
63
+ message: body.title ? `${body.title}: ${message}` : message,
64
+ toolName: body.tool_name || undefined,
65
+ toolInput: body.tool_input || undefined,
66
+ project,
67
+ timestamp: Date.now(),
68
+ };
69
+ const shortId = (0, events_js_1.addPending)(event);
70
+ const result = await channel.send(event, shortId);
71
+ if (result.success) {
72
+ return { ok: true, eventId: event.id, shortId };
73
+ }
74
+ (0, events_js_1.removePending)(event.id);
75
+ return reply.status(502).send({ error: `Channel send failed: ${result.error}` });
76
+ });
77
+ // Receive raw response text (from channel polling)
78
+ app.post('/api/v1/respond', { schema: { body: respondBodySchema } }, async (request, reply) => {
79
+ const { text } = request.body;
80
+ const resolved = (0, events_js_1.resolveResponse)(text);
81
+ if (!resolved) {
82
+ return reply.status(404).send({ error: 'No pending question to match this response' });
83
+ }
84
+ const { question, response } = resolved;
85
+ let session = (0, tracker_js_1.getSession)(question.event.sessionId);
86
+ if (!session) {
87
+ // Fallback: find by cwd
88
+ (0, tracker_js_1.cleanDeadSessions)();
89
+ const byCwd = (0, tracker_js_1.listSessions)().filter(s => s.tmuxPane && s.cwd === question.event.project);
90
+ if (byCwd.length === 1)
91
+ session = byCwd[0];
92
+ }
93
+ if (!session) {
94
+ (0, events_js_1.removePending)(question.event.id);
95
+ return reply.status(410).send({ error: 'Session no longer active' });
96
+ }
97
+ const ok = await injector.sendResponse(session, response, question.event.type);
98
+ if (!ok) {
99
+ return reply.status(500).send({ error: 'Failed to inject response' });
100
+ }
101
+ (0, events_js_1.removePending)(question.event.id);
102
+ return { ok: true, matched: question.shortId, injected: true };
103
+ });
104
+ // List pending questions
105
+ app.get('/api/v1/pending', async () => {
106
+ return { pending: (0, events_js_1.listPending)() };
107
+ });
108
+ // List active sessions
109
+ app.get('/api/v1/sessions', async () => {
110
+ (0, tracker_js_1.cleanDeadSessions)();
111
+ return { sessions: (0, tracker_js_1.listSessions)() };
112
+ });
113
+ return app;
114
+ }
115
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/daemon/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const node_child_process_1 = require("node:child_process");
5
+ const node_fs_1 = require("node:fs");
6
+ const tracker_js_1 = require("../sessions/tracker.js");
7
+ const index_js_1 = require("../config/index.js");
8
+ // Skip if relay is explicitly disabled (e.g. when working on claude-pager itself)
9
+ if (process.env.CLAUDE_PAGER_DISABLED) {
10
+ process.exit(0);
11
+ }
12
+ async function readStdin() {
13
+ const chunks = [];
14
+ for await (const chunk of process.stdin) {
15
+ chunks.push(chunk);
16
+ }
17
+ return Buffer.concat(chunks).toString('utf-8');
18
+ }
19
+ function getActiveWindowId() {
20
+ try {
21
+ const out = (0, node_child_process_1.execFileSync)('xdotool', ['getactivewindow'], { timeout: 2000 });
22
+ return parseInt(out.toString().trim(), 10) || undefined;
23
+ }
24
+ catch {
25
+ return undefined;
26
+ }
27
+ }
28
+ function extractToolContext(transcriptPath) {
29
+ try {
30
+ const content = (0, node_fs_1.readFileSync)(transcriptPath, 'utf-8');
31
+ const lines = content.trim().split('\n');
32
+ // Read last few lines to find the tool_use block
33
+ for (let i = lines.length - 1; i >= Math.max(0, lines.length - 10); i--) {
34
+ try {
35
+ const entry = JSON.parse(lines[i]);
36
+ // Look for assistant message with tool_use content
37
+ if (entry.type === 'assistant' && Array.isArray(entry.message?.content)) {
38
+ for (const block of entry.message.content) {
39
+ if (block.type === 'tool_use') {
40
+ const input = block.input;
41
+ let toolInput;
42
+ if (input?.command) {
43
+ toolInput = input.command;
44
+ }
45
+ else if (input?.file_path) {
46
+ toolInput = input.file_path;
47
+ }
48
+ else if (input?.content) {
49
+ toolInput = `${input.file_path || ''}\n${String(input.content).slice(0, 150)}`;
50
+ }
51
+ else if (typeof input === 'object') {
52
+ toolInput = JSON.stringify(input).slice(0, 200);
53
+ }
54
+ return { toolName: block.name, toolInput };
55
+ }
56
+ }
57
+ }
58
+ }
59
+ catch {
60
+ // skip unparseable lines
61
+ }
62
+ }
63
+ }
64
+ catch {
65
+ // transcript not readable
66
+ }
67
+ return {};
68
+ }
69
+ function extractLastAssistantMessage(transcriptPath) {
70
+ try {
71
+ const content = (0, node_fs_1.readFileSync)(transcriptPath, 'utf-8');
72
+ const lines = content.trim().split('\n');
73
+ // Read last entries to find the most recent assistant text
74
+ for (let i = lines.length - 1; i >= Math.max(0, lines.length - 20); i--) {
75
+ try {
76
+ const entry = JSON.parse(lines[i]);
77
+ if (entry.type === 'assistant' && Array.isArray(entry.message?.content)) {
78
+ const textBlocks = entry.message.content
79
+ .filter((b) => b.type === 'text' && b.text)
80
+ .map((b) => b.text);
81
+ if (textBlocks.length > 0) {
82
+ const full = textBlocks.join('\n');
83
+ return full.length > 3500 ? full.slice(-3500) : full;
84
+ }
85
+ }
86
+ }
87
+ catch {
88
+ // skip
89
+ }
90
+ }
91
+ }
92
+ catch {
93
+ // transcript not readable
94
+ }
95
+ return undefined;
96
+ }
97
+ async function handleSessionStart() {
98
+ const input = await readStdin();
99
+ const data = JSON.parse(input);
100
+ const info = {
101
+ sessionId: data.session_id,
102
+ pid: process.ppid,
103
+ tty: process.env.TTY || '',
104
+ cwd: data.cwd || process.cwd(),
105
+ windowId: getActiveWindowId(),
106
+ tmuxPane: process.env.TMUX_PANE || undefined,
107
+ timestamp: Date.now(),
108
+ };
109
+ (0, index_js_1.ensureDataDir)();
110
+ (0, tracker_js_1.registerSession)(info);
111
+ }
112
+ async function handleNotification() {
113
+ const input = await readStdin();
114
+ const data = JSON.parse(input);
115
+ // Only forward permission_prompt and idle_prompt
116
+ const type = data.notification_type;
117
+ if (type !== 'permission_prompt' && type !== 'idle_prompt') {
118
+ return;
119
+ }
120
+ let enriched = data;
121
+ if (data.transcript_path) {
122
+ if (type === 'permission_prompt') {
123
+ // Enrich with tool name and input
124
+ const ctx = extractToolContext(data.transcript_path);
125
+ if (ctx.toolName) {
126
+ enriched = { ...data, tool_name: ctx.toolName, tool_input: ctx.toolInput };
127
+ }
128
+ }
129
+ else if (type === 'idle_prompt') {
130
+ // Enrich with last assistant message for context
131
+ const lastMsg = extractLastAssistantMessage(data.transcript_path);
132
+ if (lastMsg) {
133
+ enriched = { ...data, message: lastMsg };
134
+ }
135
+ }
136
+ }
137
+ // Forward to daemon
138
+ const port = process.env.CLAUDE_PAGER_PORT || '17380';
139
+ try {
140
+ const res = await fetch(`http://127.0.0.1:${port}/api/v1/events`, {
141
+ method: 'POST',
142
+ headers: { 'Content-Type': 'application/json' },
143
+ body: JSON.stringify(enriched),
144
+ signal: AbortSignal.timeout(3000),
145
+ });
146
+ if (!res.ok) {
147
+ console.error(`[hook] daemon responded ${res.status}`);
148
+ }
149
+ }
150
+ catch (err) {
151
+ console.error('[hook] daemon unreachable:', err);
152
+ }
153
+ }
154
+ const command = process.argv[2];
155
+ switch (command) {
156
+ case 'session-start':
157
+ handleSessionStart().catch(err => {
158
+ console.error('[hook] session-start error:', err);
159
+ process.exit(1);
160
+ });
161
+ break;
162
+ case 'notification':
163
+ handleNotification().catch(err => {
164
+ console.error('[hook] notification error:', err);
165
+ process.exit(1);
166
+ });
167
+ break;
168
+ default:
169
+ console.error(`Usage: claude-pager-hook <session-start|notification>`);
170
+ process.exit(1);
171
+ }
172
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":";;;AAEA,2DAAkD;AAClD,qCAAuC;AACvC,uDAAyD;AACzD,iDAAmD;AAGnD,kFAAkF;AAClF,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAA,iCAAY,EAAC,SAAS,EAAE,CAAC,iBAAiB,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,OAAO,QAAQ,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,IAAI,SAAS,CAAC;IAC1D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,cAAsB;IAChD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,iDAAiD;QACjD,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACxE,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnC,mDAAmD;gBACnD,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;oBACxE,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;wBAC1C,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;4BAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;4BAC1B,IAAI,SAA6B,CAAC;4BAClC,IAAI,KAAK,EAAE,OAAO,EAAE,CAAC;gCACnB,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC;4BAC5B,CAAC;iCAAM,IAAI,KAAK,EAAE,SAAS,EAAE,CAAC;gCAC5B,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;4BAC9B,CAAC;iCAAM,IAAI,KAAK,EAAE,OAAO,EAAE,CAAC;gCAC1B,SAAS,GAAG,GAAG,KAAK,CAAC,SAAS,IAAI,EAAE,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;4BACjF,CAAC;iCAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gCACrC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;4BAClD,CAAC;4BACD,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC;wBAC7C,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,yBAAyB;YAC3B,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,2BAA2B,CAAC,cAAsB;IACzD,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,sBAAY,EAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,2DAA2D;QAC3D,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACxE,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnC,IAAI,KAAK,CAAC,IAAI,KAAK,WAAW,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,CAAC;oBACxE,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO;yBACrC,MAAM,CAAC,CAAC,CAAkC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC;yBAC3E,GAAG,CAAC,CAAC,CAAmB,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;oBACxC,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBAC1B,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;wBACnC,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACvD,CAAC;gBACH,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE/B,MAAM,IAAI,GAAgB;QACxB,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,GAAG,EAAE,OAAO,CAAC,IAAI;QACjB,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,EAAE;QAC1B,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;QAC9B,QAAQ,EAAE,iBAAiB,EAAE;QAC7B,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,SAAS;QAC5C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC;IAEF,IAAA,wBAAa,GAAE,CAAC;IAChB,IAAA,4BAAe,EAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,MAAM,KAAK,GAAG,MAAM,SAAS,EAAE,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAE/B,iDAAiD;IACjD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,CAAC;IACpC,IAAI,IAAI,KAAK,mBAAmB,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAC3D,OAAO;IACT,CAAC;IAED,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;QACzB,IAAI,IAAI,KAAK,mBAAmB,EAAE,CAAC;YACjC,kCAAkC;YAClC,MAAM,GAAG,GAAG,kBAAkB,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YACrD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;gBACjB,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;YAC7E,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;YAClC,iDAAiD;YACjD,MAAM,OAAO,GAAG,2BAA2B,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAClE,IAAI,OAAO,EAAE,CAAC;gBACZ,QAAQ,GAAG,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,IAAI,gBAAgB,EAAE;YAChE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;YAC9B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,2BAA2B,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;IACnD,CAAC;AACH,CAAC;AAED,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEhC,QAAQ,OAAO,EAAE,CAAC;IAChB,KAAK,eAAe;QAClB,kBAAkB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YAC/B,OAAO,CAAC,KAAK,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;YAClD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,MAAM;IACR,KAAK,cAAc;QACjB,kBAAkB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;YAC/B,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,GAAG,CAAC,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,MAAM;IACR;QACE,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export type { RelayConfig, ChannelConfig, NtfyConfig, TelegramConfig, RelayEvent, SessionInfo, UserResponse } from './types.js';
2
+ export type { ChannelProvider, NotificationResult } from './channels/channel.js';
3
+ export type { InputInjector } from './injectors/injector.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAChI,YAAY,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AACjF,YAAY,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tmux.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmux.test.d.ts","sourceRoot":"","sources":["../../../src/injectors/__tests__/tmux.test.ts"],"names":[],"mappings":""}