@selucas12/cheesy 2.0.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.
- package/.env.example +22 -0
- package/CHANGELOG.md +268 -0
- package/LICENSE +21 -0
- package/README.md +394 -0
- package/ccgram.service +24 -0
- package/config/channels.json +58 -0
- package/config/default.json +27 -0
- package/config/defaults/config.json +16 -0
- package/config/defaults/i18n.json +32 -0
- package/config/email-template.json +31 -0
- package/config/test-with-subagent.json +16 -0
- package/config/user.json +27 -0
- package/dist/claude-hook-notify.d.ts +7 -0
- package/dist/claude-hook-notify.d.ts.map +1 -0
- package/dist/claude-hook-notify.js +154 -0
- package/dist/claude-hook-notify.js.map +1 -0
- package/dist/claude-remote.d.ts +50 -0
- package/dist/claude-remote.d.ts.map +1 -0
- package/dist/claude-remote.js +927 -0
- package/dist/claude-remote.js.map +1 -0
- package/dist/elicitation-notify.d.ts +20 -0
- package/dist/elicitation-notify.d.ts.map +1 -0
- package/dist/elicitation-notify.js +241 -0
- package/dist/elicitation-notify.js.map +1 -0
- package/dist/enhanced-hook-notify.d.ts +23 -0
- package/dist/enhanced-hook-notify.d.ts.map +1 -0
- package/dist/enhanced-hook-notify.js +402 -0
- package/dist/enhanced-hook-notify.js.map +1 -0
- package/dist/permission-denied-notify.d.ts +11 -0
- package/dist/permission-denied-notify.d.ts.map +1 -0
- package/dist/permission-denied-notify.js +193 -0
- package/dist/permission-denied-notify.js.map +1 -0
- package/dist/permission-hook.d.ts +15 -0
- package/dist/permission-hook.d.ts.map +1 -0
- package/dist/permission-hook.js +386 -0
- package/dist/permission-hook.js.map +1 -0
- package/dist/pre-compact-notify.d.ts +13 -0
- package/dist/pre-compact-notify.d.ts.map +1 -0
- package/dist/pre-compact-notify.js +197 -0
- package/dist/pre-compact-notify.js.map +1 -0
- package/dist/prompt-bridge.d.ts +50 -0
- package/dist/prompt-bridge.d.ts.map +1 -0
- package/dist/prompt-bridge.js +173 -0
- package/dist/prompt-bridge.js.map +1 -0
- package/dist/question-notify.d.ts +17 -0
- package/dist/question-notify.d.ts.map +1 -0
- package/dist/question-notify.js +356 -0
- package/dist/question-notify.js.map +1 -0
- package/dist/setup.d.ts +10 -0
- package/dist/setup.d.ts.map +1 -0
- package/dist/setup.js +649 -0
- package/dist/setup.js.map +1 -0
- package/dist/smart-monitor.d.ts +7 -0
- package/dist/smart-monitor.d.ts.map +1 -0
- package/dist/smart-monitor.js +256 -0
- package/dist/smart-monitor.js.map +1 -0
- package/dist/src/automation/clipboard-automation.d.ts +35 -0
- package/dist/src/automation/clipboard-automation.d.ts.map +1 -0
- package/dist/src/automation/clipboard-automation.js +242 -0
- package/dist/src/automation/clipboard-automation.js.map +1 -0
- package/dist/src/channels/base/channel.d.ts +60 -0
- package/dist/src/channels/base/channel.d.ts.map +1 -0
- package/dist/src/channels/base/channel.js +96 -0
- package/dist/src/channels/base/channel.js.map +1 -0
- package/dist/src/channels/email/smtp.d.ts +74 -0
- package/dist/src/channels/email/smtp.d.ts.map +1 -0
- package/dist/src/channels/email/smtp.js +605 -0
- package/dist/src/channels/email/smtp.js.map +1 -0
- package/dist/src/channels/line/line.d.ts +36 -0
- package/dist/src/channels/line/line.d.ts.map +1 -0
- package/dist/src/channels/line/line.js +180 -0
- package/dist/src/channels/line/line.js.map +1 -0
- package/dist/src/channels/line/webhook.d.ts +55 -0
- package/dist/src/channels/line/webhook.d.ts.map +1 -0
- package/dist/src/channels/line/webhook.js +191 -0
- package/dist/src/channels/line/webhook.js.map +1 -0
- package/dist/src/channels/local/desktop.d.ts +30 -0
- package/dist/src/channels/local/desktop.d.ts.map +1 -0
- package/dist/src/channels/local/desktop.js +161 -0
- package/dist/src/channels/local/desktop.js.map +1 -0
- package/dist/src/channels/telegram/telegram.d.ts +43 -0
- package/dist/src/channels/telegram/telegram.d.ts.map +1 -0
- package/dist/src/channels/telegram/telegram.js +223 -0
- package/dist/src/channels/telegram/telegram.js.map +1 -0
- package/dist/src/channels/telegram/webhook.d.ts +75 -0
- package/dist/src/channels/telegram/webhook.d.ts.map +1 -0
- package/dist/src/channels/telegram/webhook.js +278 -0
- package/dist/src/channels/telegram/webhook.js.map +1 -0
- package/dist/src/cli.d.ts +9 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +99 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/commands/hooks.d.ts +10 -0
- package/dist/src/commands/hooks.d.ts.map +1 -0
- package/dist/src/commands/hooks.js +50 -0
- package/dist/src/commands/hooks.js.map +1 -0
- package/dist/src/commands/init.d.ts +20 -0
- package/dist/src/commands/init.d.ts.map +1 -0
- package/dist/src/commands/init.js +173 -0
- package/dist/src/commands/init.js.map +1 -0
- package/dist/src/commands/license.d.ts +15 -0
- package/dist/src/commands/license.d.ts.map +1 -0
- package/dist/src/commands/license.js +107 -0
- package/dist/src/commands/license.js.map +1 -0
- package/dist/src/commands/start.d.ts +17 -0
- package/dist/src/commands/start.d.ts.map +1 -0
- package/dist/src/commands/start.js +150 -0
- package/dist/src/commands/start.js.map +1 -0
- package/dist/src/commands/status.d.ts +8 -0
- package/dist/src/commands/status.d.ts.map +1 -0
- package/dist/src/commands/status.js +95 -0
- package/dist/src/commands/status.js.map +1 -0
- package/dist/src/commands/stop.d.ts +8 -0
- package/dist/src/commands/stop.d.ts.map +1 -0
- package/dist/src/commands/stop.js +64 -0
- package/dist/src/commands/stop.js.map +1 -0
- package/dist/src/config-manager.d.ts +16 -0
- package/dist/src/config-manager.d.ts.map +1 -0
- package/dist/src/config-manager.js +152 -0
- package/dist/src/config-manager.js.map +1 -0
- package/dist/src/core/config.d.ts +28 -0
- package/dist/src/core/config.d.ts.map +1 -0
- package/dist/src/core/config.js +248 -0
- package/dist/src/core/config.js.map +1 -0
- package/dist/src/core/logger.d.ts +19 -0
- package/dist/src/core/logger.d.ts.map +1 -0
- package/dist/src/core/logger.js +47 -0
- package/dist/src/core/logger.js.map +1 -0
- package/dist/src/core/notifier.d.ts +45 -0
- package/dist/src/core/notifier.d.ts.map +1 -0
- package/dist/src/core/notifier.js +189 -0
- package/dist/src/core/notifier.js.map +1 -0
- package/dist/src/lib/license-validator.d.ts +120 -0
- package/dist/src/lib/license-validator.d.ts.map +1 -0
- package/dist/src/lib/license-validator.js +294 -0
- package/dist/src/lib/license-validator.js.map +1 -0
- package/dist/src/lib/preflight.d.ts +28 -0
- package/dist/src/lib/preflight.d.ts.map +1 -0
- package/dist/src/lib/preflight.js +90 -0
- package/dist/src/lib/preflight.js.map +1 -0
- package/dist/src/relay/claude-command-bridge.d.ts +57 -0
- package/dist/src/relay/claude-command-bridge.d.ts.map +1 -0
- package/dist/src/relay/claude-command-bridge.js +188 -0
- package/dist/src/relay/claude-command-bridge.js.map +1 -0
- package/dist/src/relay/email-listener.d.ts +65 -0
- package/dist/src/relay/email-listener.d.ts.map +1 -0
- package/dist/src/relay/email-listener.js +460 -0
- package/dist/src/relay/email-listener.js.map +1 -0
- package/dist/src/relay/relay-pty.d.ts +21 -0
- package/dist/src/relay/relay-pty.d.ts.map +1 -0
- package/dist/src/relay/relay-pty.js +696 -0
- package/dist/src/relay/relay-pty.js.map +1 -0
- package/dist/src/relay/smart-injector.d.ts +30 -0
- package/dist/src/relay/smart-injector.d.ts.map +1 -0
- package/dist/src/relay/smart-injector.js +233 -0
- package/dist/src/relay/smart-injector.js.map +1 -0
- package/dist/src/relay/tmux-injector.d.ts +46 -0
- package/dist/src/relay/tmux-injector.d.ts.map +1 -0
- package/dist/src/relay/tmux-injector.js +413 -0
- package/dist/src/relay/tmux-injector.js.map +1 -0
- package/dist/src/tools/config-manager.d.ts +33 -0
- package/dist/src/tools/config-manager.d.ts.map +1 -0
- package/dist/src/tools/config-manager.js +448 -0
- package/dist/src/tools/config-manager.js.map +1 -0
- package/dist/src/tools/installer.d.ts +38 -0
- package/dist/src/tools/installer.d.ts.map +1 -0
- package/dist/src/tools/installer.js +222 -0
- package/dist/src/tools/installer.js.map +1 -0
- package/dist/src/types/callbacks.d.ts +53 -0
- package/dist/src/types/callbacks.d.ts.map +1 -0
- package/dist/src/types/callbacks.js +7 -0
- package/dist/src/types/callbacks.js.map +1 -0
- package/dist/src/types/config.d.ts +56 -0
- package/dist/src/types/config.d.ts.map +1 -0
- package/dist/src/types/config.js +6 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/hooks.d.ts +47 -0
- package/dist/src/types/hooks.d.ts.map +1 -0
- package/dist/src/types/hooks.js +6 -0
- package/dist/src/types/hooks.js.map +1 -0
- package/dist/src/types/index.d.ts +7 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +23 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/ipc.d.ts +43 -0
- package/dist/src/types/ipc.d.ts.map +1 -0
- package/dist/src/types/ipc.js +7 -0
- package/dist/src/types/ipc.js.map +1 -0
- package/dist/src/types/session.d.ts +87 -0
- package/dist/src/types/session.d.ts.map +1 -0
- package/dist/src/types/session.js +9 -0
- package/dist/src/types/session.js.map +1 -0
- package/dist/src/types/telegram.d.ts +58 -0
- package/dist/src/types/telegram.d.ts.map +1 -0
- package/dist/src/types/telegram.js +6 -0
- package/dist/src/types/telegram.js.map +1 -0
- package/dist/src/utils/active-check.d.ts +20 -0
- package/dist/src/utils/active-check.d.ts.map +1 -0
- package/dist/src/utils/active-check.js +42 -0
- package/dist/src/utils/active-check.js.map +1 -0
- package/dist/src/utils/callback-parser.d.ts +23 -0
- package/dist/src/utils/callback-parser.d.ts.map +1 -0
- package/dist/src/utils/callback-parser.js +85 -0
- package/dist/src/utils/callback-parser.js.map +1 -0
- package/dist/src/utils/controller-injector.d.ts +21 -0
- package/dist/src/utils/controller-injector.d.ts.map +1 -0
- package/dist/src/utils/controller-injector.js +108 -0
- package/dist/src/utils/controller-injector.js.map +1 -0
- package/dist/src/utils/conversation-tracker.d.ts +32 -0
- package/dist/src/utils/conversation-tracker.d.ts.map +1 -0
- package/dist/src/utils/conversation-tracker.js +119 -0
- package/dist/src/utils/conversation-tracker.js.map +1 -0
- package/dist/src/utils/deep-link.d.ts +22 -0
- package/dist/src/utils/deep-link.d.ts.map +1 -0
- package/dist/src/utils/deep-link.js +43 -0
- package/dist/src/utils/deep-link.js.map +1 -0
- package/dist/src/utils/ghostty-session-manager.d.ts +81 -0
- package/dist/src/utils/ghostty-session-manager.d.ts.map +1 -0
- package/dist/src/utils/ghostty-session-manager.js +370 -0
- package/dist/src/utils/ghostty-session-manager.js.map +1 -0
- package/dist/src/utils/hook-definitions.d.ts +25 -0
- package/dist/src/utils/hook-definitions.d.ts.map +1 -0
- package/dist/src/utils/hook-definitions.js +36 -0
- package/dist/src/utils/hook-definitions.js.map +1 -0
- package/dist/src/utils/http-request.d.ts +25 -0
- package/dist/src/utils/http-request.d.ts.map +1 -0
- package/dist/src/utils/http-request.js +66 -0
- package/dist/src/utils/http-request.js.map +1 -0
- package/dist/src/utils/optional-require.d.ts +13 -0
- package/dist/src/utils/optional-require.d.ts.map +1 -0
- package/dist/src/utils/optional-require.js +37 -0
- package/dist/src/utils/optional-require.js.map +1 -0
- package/dist/src/utils/paths.d.ts +13 -0
- package/dist/src/utils/paths.d.ts.map +1 -0
- package/dist/src/utils/paths.js +30 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/src/utils/pty-session-manager.d.ts +43 -0
- package/dist/src/utils/pty-session-manager.d.ts.map +1 -0
- package/dist/src/utils/pty-session-manager.js +183 -0
- package/dist/src/utils/pty-session-manager.js.map +1 -0
- package/dist/src/utils/subagent-tracker.d.ts +64 -0
- package/dist/src/utils/subagent-tracker.d.ts.map +1 -0
- package/dist/src/utils/subagent-tracker.js +191 -0
- package/dist/src/utils/subagent-tracker.js.map +1 -0
- package/dist/src/utils/tmux-monitor.d.ts +102 -0
- package/dist/src/utils/tmux-monitor.d.ts.map +1 -0
- package/dist/src/utils/tmux-monitor.js +642 -0
- package/dist/src/utils/tmux-monitor.js.map +1 -0
- package/dist/src/utils/trace-capture.d.ts +42 -0
- package/dist/src/utils/trace-capture.d.ts.map +1 -0
- package/dist/src/utils/trace-capture.js +102 -0
- package/dist/src/utils/trace-capture.js.map +1 -0
- package/dist/src/utils/transcript-reader.d.ts +57 -0
- package/dist/src/utils/transcript-reader.d.ts.map +1 -0
- package/dist/src/utils/transcript-reader.js +229 -0
- package/dist/src/utils/transcript-reader.js.map +1 -0
- package/dist/start-all-webhooks.d.ts +7 -0
- package/dist/start-all-webhooks.d.ts.map +1 -0
- package/dist/start-all-webhooks.js +98 -0
- package/dist/start-all-webhooks.js.map +1 -0
- package/dist/start-line-webhook.d.ts +7 -0
- package/dist/start-line-webhook.d.ts.map +1 -0
- package/dist/start-line-webhook.js +59 -0
- package/dist/start-line-webhook.js.map +1 -0
- package/dist/start-relay-pty.d.ts +7 -0
- package/dist/start-relay-pty.d.ts.map +1 -0
- package/dist/start-relay-pty.js +173 -0
- package/dist/start-relay-pty.js.map +1 -0
- package/dist/start-telegram-webhook.d.ts +7 -0
- package/dist/start-telegram-webhook.d.ts.map +1 -0
- package/dist/start-telegram-webhook.js +80 -0
- package/dist/start-telegram-webhook.js.map +1 -0
- package/dist/user-prompt-hook.d.ts +13 -0
- package/dist/user-prompt-hook.d.ts.map +1 -0
- package/dist/user-prompt-hook.js +45 -0
- package/dist/user-prompt-hook.js.map +1 -0
- package/dist/workspace-router.d.ts +114 -0
- package/dist/workspace-router.d.ts.map +1 -0
- package/dist/workspace-router.js +572 -0
- package/dist/workspace-router.js.map +1 -0
- package/dist/workspace-telegram-bot.d.ts +3 -0
- package/dist/workspace-telegram-bot.d.ts.map +1 -0
- package/dist/workspace-telegram-bot.js +1847 -0
- package/dist/workspace-telegram-bot.js.map +1 -0
- package/package.json +85 -0
- package/src/types/callbacks.ts +73 -0
- package/src/types/config.ts +63 -0
- package/src/types/hooks.ts +50 -0
- package/src/types/index.ts +6 -0
- package/src/types/ipc.ts +55 -0
- package/src/types/session.ts +91 -0
- package/src/types/telegram.ts +66 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-hook.d.ts","sourceRoot":"","sources":["../permission-hook.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;GAWG"}
|
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Permission Hook — Called by Claude Code's PermissionRequest hook.
|
|
5
|
+
*
|
|
6
|
+
* Blocking approach:
|
|
7
|
+
* 1. Sends a Telegram message with inline keyboard buttons
|
|
8
|
+
* 2. Polls for a response file written by the bot's callback handler
|
|
9
|
+
* 3. Outputs the permission decision via stdout
|
|
10
|
+
* 4. Exits cleanly
|
|
11
|
+
*
|
|
12
|
+
* Stdin JSON: { tool_name, tool_input, cwd, session_id, hook_event_name }
|
|
13
|
+
* Stdout JSON: { hookSpecificOutput: { hookEventName, decision: { behavior } } }
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
const path_1 = __importDefault(require("path"));
|
|
20
|
+
const paths_1 = require("./src/utils/paths");
|
|
21
|
+
require('dotenv').config({ path: path_1.default.join(paths_1.PROJECT_ROOT, '.env'), quiet: true });
|
|
22
|
+
const fs_1 = __importDefault(require("fs"));
|
|
23
|
+
const https_1 = __importDefault(require("https"));
|
|
24
|
+
const child_process_1 = require("child_process");
|
|
25
|
+
const workspace_router_1 = require("./workspace-router");
|
|
26
|
+
const prompt_bridge_1 = require("./prompt-bridge");
|
|
27
|
+
const active_check_1 = require("./src/utils/active-check");
|
|
28
|
+
const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
29
|
+
const CHAT_ID = process.env.TELEGRAM_CHAT_ID;
|
|
30
|
+
const POLL_INTERVAL_MS = 500;
|
|
31
|
+
const POLL_TIMEOUT_MS = 90000; // 90 seconds max wait
|
|
32
|
+
// Debug logging to file (since stdout is for Claude Code)
|
|
33
|
+
const LOG_FILE = path_1.default.join(paths_1.PROJECT_ROOT, 'logs', 'permission-hook-debug.log');
|
|
34
|
+
function debugLog(msg) {
|
|
35
|
+
const ts = new Date().toISOString();
|
|
36
|
+
try {
|
|
37
|
+
fs_1.default.appendFileSync(LOG_FILE, `${ts} ${msg}\n`);
|
|
38
|
+
}
|
|
39
|
+
catch { }
|
|
40
|
+
}
|
|
41
|
+
// ── Main ────────────────────────────────────────────────────────
|
|
42
|
+
async function main() {
|
|
43
|
+
const raw = await readStdin();
|
|
44
|
+
let payload;
|
|
45
|
+
try {
|
|
46
|
+
payload = JSON.parse(raw);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return; // Can't parse — exit without decision
|
|
50
|
+
}
|
|
51
|
+
const toolName = payload.tool_name || 'Unknown';
|
|
52
|
+
// AskUserQuestion: exit silently so Claude Code shows the interactive
|
|
53
|
+
// question/permission UI in the terminal. The question-notify.js PreToolUse
|
|
54
|
+
// hook sends the Telegram notification. Clicking an option injects arrow
|
|
55
|
+
// keys + Enter which both selects the answer AND grants permission.
|
|
56
|
+
if (toolName === 'AskUserQuestion') {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// If user is actively at the terminal AND this wasn't injected from Telegram,
|
|
60
|
+
// exit without a decision so Claude Code shows its own permission UI locally.
|
|
61
|
+
// Uses the same 120s (2 min) Cheesyboy threshold as notification hooks.
|
|
62
|
+
// If user stepped away more than 2 min ago, Telegram handles the permission
|
|
63
|
+
// so Claude isn't left stuck waiting with no way to respond.
|
|
64
|
+
const typingActivePath = path_1.default.join(paths_1.PROJECT_ROOT, 'src/data', 'typing-active');
|
|
65
|
+
const isTelegramInjected = fs_1.default.existsSync(typingActivePath);
|
|
66
|
+
if (!isTelegramInjected && (0, active_check_1.isUserActiveAtTerminal)()) {
|
|
67
|
+
debugLog(`[skip] User is at terminal (within 2 min) — deferring to Claude Code's own permission UI`);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const toolInput = (payload.tool_input || {});
|
|
71
|
+
const cwd = payload.cwd || process.cwd();
|
|
72
|
+
const workspace = (0, workspace_router_1.extractWorkspaceName)(cwd);
|
|
73
|
+
const sessionTitle = payload.session_title || null; // v2.1.94+
|
|
74
|
+
const promptId = (0, prompt_bridge_1.generatePromptId)();
|
|
75
|
+
const tmuxSession = detectSessionName(cwd);
|
|
76
|
+
const isPlan = toolName === 'ExitPlanMode';
|
|
77
|
+
// Build Telegram message and keyboard
|
|
78
|
+
let messageText;
|
|
79
|
+
let keyboard;
|
|
80
|
+
if (isPlan) {
|
|
81
|
+
// Plan approval — try to capture plan content from tmux
|
|
82
|
+
let planContent = '';
|
|
83
|
+
if (tmuxSession) {
|
|
84
|
+
try {
|
|
85
|
+
const paneOutput = (0, child_process_1.execSync)(`tmux capture-pane -t ${tmuxSession} -p -S -50 2>/dev/null`, { encoding: 'utf8', timeout: 3000 });
|
|
86
|
+
planContent = cleanPlanOutput(paneOutput);
|
|
87
|
+
}
|
|
88
|
+
catch { }
|
|
89
|
+
}
|
|
90
|
+
messageText = `\u{1F4CB} *Plan Approval* — ${escapeMarkdown(workspace)}`;
|
|
91
|
+
if (planContent) {
|
|
92
|
+
const truncated = planContent.length > 2500
|
|
93
|
+
? planContent.slice(0, 2497) + '...'
|
|
94
|
+
: planContent;
|
|
95
|
+
messageText += `\n\n${truncated}`;
|
|
96
|
+
}
|
|
97
|
+
keyboard = {
|
|
98
|
+
inline_keyboard: [
|
|
99
|
+
[
|
|
100
|
+
{ text: '\u2705 Yes', callback_data: `perm:${promptId}:yes` },
|
|
101
|
+
{ text: '\u2705 Yes, stop asking', callback_data: `perm:${promptId}:yes_stop` },
|
|
102
|
+
{ text: '\u274C No', callback_data: `perm:${promptId}:no` },
|
|
103
|
+
{ text: '\u{1F4AC} Explain', callback_data: `perm:${promptId}:explain` },
|
|
104
|
+
],
|
|
105
|
+
],
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// Tool permission request
|
|
110
|
+
const toolDescription = formatToolDescription(toolName, toolInput);
|
|
111
|
+
// Include session title if available (v2.1.94+)
|
|
112
|
+
const titleSuffix = sessionTitle ? ` (${escapeMarkdown(sessionTitle)})` : '';
|
|
113
|
+
messageText = `\u{1F510} *Permission* — ${escapeMarkdown(workspace)}${titleSuffix}\n\n*Tool:* ${escapeMarkdown(toolName)}`;
|
|
114
|
+
if (toolDescription) {
|
|
115
|
+
const truncated = toolDescription.length > 2500
|
|
116
|
+
? toolDescription.slice(0, 2497) + '...'
|
|
117
|
+
: toolDescription;
|
|
118
|
+
messageText += `\n${truncated}`;
|
|
119
|
+
}
|
|
120
|
+
keyboard = {
|
|
121
|
+
inline_keyboard: [
|
|
122
|
+
[
|
|
123
|
+
{ text: '\u2705 Yes', callback_data: `perm:${promptId}:yes` },
|
|
124
|
+
{ text: '\u2705 Yes, stop asking', callback_data: `perm:${promptId}:yes_stop` },
|
|
125
|
+
{ text: '\u274C No', callback_data: `perm:${promptId}:no` },
|
|
126
|
+
{ text: '\u{1F4AC} Explain', callback_data: `perm:${promptId}:explain` },
|
|
127
|
+
],
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
// Write pending file so bot callback handler can write the response
|
|
132
|
+
(0, prompt_bridge_1.writePending)(promptId, {
|
|
133
|
+
type: isPlan ? 'plan' : 'permission',
|
|
134
|
+
workspace,
|
|
135
|
+
toolName,
|
|
136
|
+
toolInput,
|
|
137
|
+
tmuxSession,
|
|
138
|
+
});
|
|
139
|
+
// Send Telegram message with inline keyboard
|
|
140
|
+
debugLog(`[${promptId}] Sending Telegram message for ${toolName}...`);
|
|
141
|
+
try {
|
|
142
|
+
const result = await sendTelegramWithKeyboard(messageText, keyboard);
|
|
143
|
+
debugLog(`[${promptId}] Telegram message sent`);
|
|
144
|
+
if (result && result.message_id) {
|
|
145
|
+
(0, workspace_router_1.trackNotificationMessage)(result.message_id, workspace, 'permission');
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
catch (err) {
|
|
149
|
+
debugLog(`[${promptId}] Telegram send failed: ${err.message}`);
|
|
150
|
+
process.stderr.write(`[permission-hook] Telegram send failed: ${err.message}\n`);
|
|
151
|
+
(0, prompt_bridge_1.cleanPrompt)(promptId);
|
|
152
|
+
return; // Can't notify — exit without decision
|
|
153
|
+
}
|
|
154
|
+
// Poll for response file
|
|
155
|
+
debugLog(`[${promptId}] Starting to poll for response...`);
|
|
156
|
+
const response = await pollForResponse(promptId);
|
|
157
|
+
if (response) {
|
|
158
|
+
const action = response.action || 'allow';
|
|
159
|
+
debugLog(`[${promptId}] Got response: action=${action}`);
|
|
160
|
+
// Handle defer action — pause the session so user can resume later
|
|
161
|
+
if (action === 'defer') {
|
|
162
|
+
// For PermissionRequest, defer means deny but with a message suggesting resume
|
|
163
|
+
const output = {
|
|
164
|
+
hookSpecificOutput: {
|
|
165
|
+
hookEventName: 'PermissionRequest',
|
|
166
|
+
decision: {
|
|
167
|
+
behavior: 'deny',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
systemMessage: 'Session paused via Telegram. Resume with: claude --resume',
|
|
171
|
+
};
|
|
172
|
+
const outputStr = JSON.stringify(output);
|
|
173
|
+
debugLog(`[${promptId}] Writing defer (as deny) to stdout: ${outputStr}`);
|
|
174
|
+
process.stdout.write(outputStr + '\n');
|
|
175
|
+
debugLog(`[${promptId}] Stdout written`);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
// New 4-button vocab: yes / yes_stop / no / explain.
|
|
179
|
+
// Legacy: allow / deny / always.
|
|
180
|
+
// "explain" is treated as deny so Claude is prompted to give context and re-ask.
|
|
181
|
+
let decision;
|
|
182
|
+
if (action === 'no' || action === 'deny' || action === 'explain') {
|
|
183
|
+
decision = 'deny';
|
|
184
|
+
}
|
|
185
|
+
else {
|
|
186
|
+
// yes, yes_stop, allow, always → allow
|
|
187
|
+
decision = 'allow';
|
|
188
|
+
}
|
|
189
|
+
const output = {
|
|
190
|
+
hookSpecificOutput: {
|
|
191
|
+
hookEventName: 'PermissionRequest',
|
|
192
|
+
decision: {
|
|
193
|
+
behavior: decision,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
systemMessage: `Decision received via Telegram: user ${decision}ed (${action})`,
|
|
197
|
+
};
|
|
198
|
+
const outputStr = JSON.stringify(output);
|
|
199
|
+
debugLog(`[${promptId}] Writing to stdout: ${outputStr}`);
|
|
200
|
+
process.stdout.write(outputStr + '\n');
|
|
201
|
+
debugLog(`[${promptId}] Stdout written`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
debugLog(`[${promptId}] No response received (timed out or error)`);
|
|
206
|
+
}
|
|
207
|
+
// Clean up
|
|
208
|
+
(0, prompt_bridge_1.cleanPrompt)(promptId);
|
|
209
|
+
debugLog(`[${promptId}] Cleaned up, letting process exit naturally`);
|
|
210
|
+
}
|
|
211
|
+
// ── Polling ─────────────────────────────────────────────────────
|
|
212
|
+
function pollForResponse(promptId) {
|
|
213
|
+
return new Promise((resolve) => {
|
|
214
|
+
const responseFile = path_1.default.join(prompt_bridge_1.PROMPTS_DIR, `response-${promptId}.json`);
|
|
215
|
+
const startTime = Date.now();
|
|
216
|
+
const interval = setInterval(() => {
|
|
217
|
+
// Check timeout
|
|
218
|
+
if (Date.now() - startTime > POLL_TIMEOUT_MS) {
|
|
219
|
+
clearInterval(interval);
|
|
220
|
+
process.stderr.write(`[permission-hook] Timed out waiting for response\n`);
|
|
221
|
+
resolve(null);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
// Check for response file
|
|
225
|
+
try {
|
|
226
|
+
if (fs_1.default.existsSync(responseFile)) {
|
|
227
|
+
const raw = fs_1.default.readFileSync(responseFile, 'utf8');
|
|
228
|
+
const data = JSON.parse(raw);
|
|
229
|
+
clearInterval(interval);
|
|
230
|
+
resolve(data);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
// File not ready yet or parse error — keep polling
|
|
235
|
+
}
|
|
236
|
+
}, POLL_INTERVAL_MS);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
// ── Telegram ────────────────────────────────────────────────────
|
|
240
|
+
function sendTelegramWithKeyboard(text, replyMarkup) {
|
|
241
|
+
return new Promise((resolve, reject) => {
|
|
242
|
+
const body = JSON.stringify({
|
|
243
|
+
chat_id: CHAT_ID,
|
|
244
|
+
text,
|
|
245
|
+
parse_mode: 'Markdown',
|
|
246
|
+
reply_markup: replyMarkup,
|
|
247
|
+
});
|
|
248
|
+
const options = {
|
|
249
|
+
hostname: 'api.telegram.org',
|
|
250
|
+
path: `/bot${BOT_TOKEN}/sendMessage`,
|
|
251
|
+
method: 'POST',
|
|
252
|
+
headers: {
|
|
253
|
+
'Content-Type': 'application/json',
|
|
254
|
+
'Content-Length': Buffer.byteLength(body),
|
|
255
|
+
},
|
|
256
|
+
timeout: 5000,
|
|
257
|
+
};
|
|
258
|
+
const req = https_1.default.request(options, (res) => {
|
|
259
|
+
let data = '';
|
|
260
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
261
|
+
res.on('end', () => {
|
|
262
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
263
|
+
try {
|
|
264
|
+
const parsed = JSON.parse(data);
|
|
265
|
+
resolve(parsed.result || null);
|
|
266
|
+
}
|
|
267
|
+
catch {
|
|
268
|
+
resolve(null);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
reject(new Error(`Telegram API ${res.statusCode}: ${data}`));
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
req.on('error', reject);
|
|
277
|
+
req.on('timeout', () => {
|
|
278
|
+
req.destroy();
|
|
279
|
+
reject(new Error('Telegram request timed out'));
|
|
280
|
+
});
|
|
281
|
+
req.write(body);
|
|
282
|
+
req.end();
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
// ── Helpers ──────────────────────────────────────────────────────
|
|
286
|
+
function readStdin() {
|
|
287
|
+
return new Promise((resolve) => {
|
|
288
|
+
let data = '';
|
|
289
|
+
let resolved = false;
|
|
290
|
+
process.stdin.setEncoding('utf8');
|
|
291
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
292
|
+
process.stdin.on('end', () => {
|
|
293
|
+
if (!resolved) {
|
|
294
|
+
resolved = true;
|
|
295
|
+
resolve(data);
|
|
296
|
+
}
|
|
297
|
+
});
|
|
298
|
+
setTimeout(() => {
|
|
299
|
+
if (!resolved) {
|
|
300
|
+
resolved = true;
|
|
301
|
+
process.stdin.destroy();
|
|
302
|
+
resolve(data || '{}');
|
|
303
|
+
}
|
|
304
|
+
}, 500);
|
|
305
|
+
});
|
|
306
|
+
}
|
|
307
|
+
function detectSessionName(cwd) {
|
|
308
|
+
// 1. Try tmux (existing behaviour)
|
|
309
|
+
if (process.env.TMUX) {
|
|
310
|
+
try {
|
|
311
|
+
return (0, child_process_1.execSync)('tmux display-message -p "#S"', { encoding: 'utf8' }).trim();
|
|
312
|
+
}
|
|
313
|
+
catch { }
|
|
314
|
+
}
|
|
315
|
+
// 2. Derive from CWD — apply the same sanitization /new uses for session names
|
|
316
|
+
// (dots, colons, spaces → hyphens) so the name matches the PTY handle key
|
|
317
|
+
const raw = (0, workspace_router_1.extractWorkspaceName)(cwd);
|
|
318
|
+
if (!raw)
|
|
319
|
+
return null;
|
|
320
|
+
return raw.replace(/[.:\s]/g, '-');
|
|
321
|
+
}
|
|
322
|
+
function formatToolDescription(toolName, toolInput) {
|
|
323
|
+
if (toolName === 'Bash' && toolInput.command) {
|
|
324
|
+
const cmd = toolInput.command;
|
|
325
|
+
const truncated = cmd.length > 500 ? cmd.slice(0, 497) + '...' : cmd;
|
|
326
|
+
return `*Command:* \`${escapeMarkdown(truncated)}\``;
|
|
327
|
+
}
|
|
328
|
+
if (toolName === 'Edit' && toolInput.file_path) {
|
|
329
|
+
const filePath = escapeMarkdown(toolInput.file_path);
|
|
330
|
+
if (toolInput.old_string && toolInput.new_string) {
|
|
331
|
+
const maxLines = 12;
|
|
332
|
+
const oldLines = toolInput.old_string.split('\n');
|
|
333
|
+
const newLines = toolInput.new_string.split('\n');
|
|
334
|
+
const oldTrunc = oldLines.length > maxLines;
|
|
335
|
+
const newTrunc = newLines.length > maxLines;
|
|
336
|
+
const oldStr = oldLines.slice(0, maxLines).map(l => `- ${l}`).join('\n') + (oldTrunc ? '\n ...' : '');
|
|
337
|
+
const newStr = newLines.slice(0, maxLines).map(l => `+ ${l}`).join('\n') + (newTrunc ? '\n ...' : '');
|
|
338
|
+
return `*File:* \`${filePath}\`\n\`\`\`\n${oldStr}\n${newStr}\n\`\`\``;
|
|
339
|
+
}
|
|
340
|
+
return `*File:* \`${filePath}\``;
|
|
341
|
+
}
|
|
342
|
+
if (toolName === 'Write' && toolInput.file_path) {
|
|
343
|
+
return `*File:* \`${escapeMarkdown(toolInput.file_path)}\``;
|
|
344
|
+
}
|
|
345
|
+
if (toolName === 'Read' && toolInput.file_path) {
|
|
346
|
+
return `*File:* \`${escapeMarkdown(toolInput.file_path)}\``;
|
|
347
|
+
}
|
|
348
|
+
const keys = Object.keys(toolInput);
|
|
349
|
+
if (keys.length > 0) {
|
|
350
|
+
const key = keys[0];
|
|
351
|
+
const val = String(toolInput[key]).slice(0, 200);
|
|
352
|
+
return `*${escapeMarkdown(key)}:* \`${escapeMarkdown(val)}\``;
|
|
353
|
+
}
|
|
354
|
+
return '';
|
|
355
|
+
}
|
|
356
|
+
function cleanPlanOutput(raw) {
|
|
357
|
+
let lines = raw.split('\n');
|
|
358
|
+
lines = lines.map(l => l
|
|
359
|
+
.replace(/\x1B\[[0-9;]*[a-zA-Z]/g, '')
|
|
360
|
+
.replace(/\x1B\][^\x07]*\x07/g, ''));
|
|
361
|
+
while (lines.length && !lines[lines.length - 1].trim())
|
|
362
|
+
lines.pop();
|
|
363
|
+
while (lines.length && !lines[0].trim())
|
|
364
|
+
lines.shift();
|
|
365
|
+
lines = lines.filter(l => {
|
|
366
|
+
const t = l.trim();
|
|
367
|
+
if (!t)
|
|
368
|
+
return true;
|
|
369
|
+
if (/^[\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F]/.test(t))
|
|
370
|
+
return false;
|
|
371
|
+
if (/^(Clauding|Working|Waiting|Processing)/i.test(t))
|
|
372
|
+
return false;
|
|
373
|
+
if (/^.+\|.+\|.+\|.+\$/.test(t))
|
|
374
|
+
return false;
|
|
375
|
+
return true;
|
|
376
|
+
});
|
|
377
|
+
return lines.join('\n').trim();
|
|
378
|
+
}
|
|
379
|
+
function escapeMarkdown(text) {
|
|
380
|
+
return text.replace(/([_*`\[])/g, '\\$1');
|
|
381
|
+
}
|
|
382
|
+
// ── Run ─────────────────────────────────────────────────────────
|
|
383
|
+
main().catch((err) => {
|
|
384
|
+
process.stderr.write(`[permission-hook] Fatal: ${err.message}\n`);
|
|
385
|
+
});
|
|
386
|
+
//# sourceMappingURL=permission-hook.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission-hook.js","sourceRoot":"","sources":["../permission-hook.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Pre-Compact Notify — Called by Claude Code's PreCompact hook.
|
|
4
|
+
*
|
|
5
|
+
* BLOCKING mode: Notifies user before context compaction, allows them to
|
|
6
|
+
* block it if they want to preserve context.
|
|
7
|
+
*
|
|
8
|
+
* Stdin JSON: { cwd, session_id, tokens_current, ... }
|
|
9
|
+
* Stdout: { hookSpecificOutput: { decision: "block" } } — to prevent compaction
|
|
10
|
+
* (or exit silently to allow compaction)
|
|
11
|
+
*/
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=pre-compact-notify.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-compact-notify.d.ts","sourceRoot":"","sources":["../pre-compact-notify.ts"],"names":[],"mappings":";AAEA;;;;;;;;;GASG"}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Pre-Compact Notify — Called by Claude Code's PreCompact hook.
|
|
5
|
+
*
|
|
6
|
+
* BLOCKING mode: Notifies user before context compaction, allows them to
|
|
7
|
+
* block it if they want to preserve context.
|
|
8
|
+
*
|
|
9
|
+
* Stdin JSON: { cwd, session_id, tokens_current, ... }
|
|
10
|
+
* Stdout: { hookSpecificOutput: { decision: "block" } } — to prevent compaction
|
|
11
|
+
* (or exit silently to allow compaction)
|
|
12
|
+
*/
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
const path_1 = __importDefault(require("path"));
|
|
18
|
+
const paths_1 = require("./src/utils/paths");
|
|
19
|
+
require('dotenv').config({ path: path_1.default.join(paths_1.PROJECT_ROOT, '.env'), quiet: true });
|
|
20
|
+
const fs_1 = __importDefault(require("fs"));
|
|
21
|
+
const https_1 = __importDefault(require("https"));
|
|
22
|
+
const workspace_router_1 = require("./workspace-router");
|
|
23
|
+
const prompt_bridge_1 = require("./prompt-bridge");
|
|
24
|
+
const active_check_1 = require("./src/utils/active-check");
|
|
25
|
+
const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
26
|
+
const CHAT_ID = process.env.TELEGRAM_CHAT_ID;
|
|
27
|
+
// Polling configuration
|
|
28
|
+
const POLL_INTERVAL_MS = 500;
|
|
29
|
+
const POLL_TIMEOUT_MS = 30000; // 30 seconds to decide
|
|
30
|
+
// ── Main ────────────────────────────────────────────────────────
|
|
31
|
+
async function main() {
|
|
32
|
+
const raw = await readStdin();
|
|
33
|
+
// Skip Telegram notification if user is at terminal AND this wasn't Telegram-injected
|
|
34
|
+
const typingActivePath = path_1.default.join(paths_1.PROJECT_ROOT, 'src/data', 'typing-active');
|
|
35
|
+
const isTelegramInjected = fs_1.default.existsSync(typingActivePath);
|
|
36
|
+
if (!isTelegramInjected && (0, active_check_1.isUserActiveAtTerminal)()) {
|
|
37
|
+
// User is at terminal — let compaction proceed automatically
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
let payload;
|
|
41
|
+
try {
|
|
42
|
+
payload = JSON.parse(raw);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const cwd = payload.cwd || process.cwd();
|
|
48
|
+
const workspace = (0, workspace_router_1.extractWorkspaceName)(cwd);
|
|
49
|
+
const tokensCurrent = payload.tokens_current;
|
|
50
|
+
const promptId = (0, prompt_bridge_1.generatePromptId)();
|
|
51
|
+
let messageText = `\u{1F4E6} *Context Compaction* — ${escapeMarkdown(workspace)}\n\n`;
|
|
52
|
+
messageText += `Context is getting large and will be compacted.`;
|
|
53
|
+
if (tokensCurrent) {
|
|
54
|
+
messageText += `\n\n_Current tokens: ${tokensCurrent.toLocaleString()}_`;
|
|
55
|
+
}
|
|
56
|
+
// Build inline keyboard with Proceed/Block buttons
|
|
57
|
+
const keyboard = [
|
|
58
|
+
[
|
|
59
|
+
{ text: '\u2705 Proceed', callback_data: `pre-compact:${promptId}:proceed` },
|
|
60
|
+
{ text: '\u{1F6D1} Block', callback_data: `pre-compact:${promptId}:block` },
|
|
61
|
+
],
|
|
62
|
+
];
|
|
63
|
+
// Write pending file
|
|
64
|
+
(0, prompt_bridge_1.writePending)(promptId, {
|
|
65
|
+
type: 'pre-compact',
|
|
66
|
+
workspace,
|
|
67
|
+
tokensCurrent,
|
|
68
|
+
});
|
|
69
|
+
// Send Telegram message
|
|
70
|
+
try {
|
|
71
|
+
const result = await sendTelegramWithKeyboard(messageText, { inline_keyboard: keyboard });
|
|
72
|
+
if (result && result.message_id) {
|
|
73
|
+
(0, workspace_router_1.trackNotificationMessage)(result.message_id, workspace, 'pre-compact');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
process.stderr.write(`[pre-compact-notify] Telegram send failed: ${err.message}\n`);
|
|
78
|
+
(0, prompt_bridge_1.cleanPrompt)(promptId);
|
|
79
|
+
return; // Let compaction proceed on send failure
|
|
80
|
+
}
|
|
81
|
+
// Poll for response
|
|
82
|
+
const response = await pollForResponse(promptId);
|
|
83
|
+
(0, prompt_bridge_1.cleanPrompt)(promptId);
|
|
84
|
+
if (response && response.action === 'block') {
|
|
85
|
+
const output = {
|
|
86
|
+
decision: 'block',
|
|
87
|
+
reason: 'User blocked compaction via Telegram to preserve context',
|
|
88
|
+
hookSpecificOutput: {
|
|
89
|
+
hookEventName: 'PreCompact',
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
process.stdout.write(JSON.stringify(output) + '\n');
|
|
93
|
+
}
|
|
94
|
+
// If proceed or timeout, exit silently — compaction proceeds
|
|
95
|
+
}
|
|
96
|
+
// ── Polling ─────────────────────────────────────────────────────
|
|
97
|
+
function pollForResponse(promptId) {
|
|
98
|
+
return new Promise((resolve) => {
|
|
99
|
+
const responseFile = path_1.default.join(prompt_bridge_1.PROMPTS_DIR, `response-${promptId}.json`);
|
|
100
|
+
const startTime = Date.now();
|
|
101
|
+
const interval = setInterval(() => {
|
|
102
|
+
if (Date.now() - startTime > POLL_TIMEOUT_MS) {
|
|
103
|
+
clearInterval(interval);
|
|
104
|
+
process.stderr.write(`[pre-compact-notify] Timed out — allowing compaction\n`);
|
|
105
|
+
resolve(null);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
if (fs_1.default.existsSync(responseFile)) {
|
|
110
|
+
const raw = fs_1.default.readFileSync(responseFile, 'utf8');
|
|
111
|
+
const data = JSON.parse(raw);
|
|
112
|
+
clearInterval(interval);
|
|
113
|
+
resolve(data);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// File not ready yet or parse error — keep polling
|
|
118
|
+
}
|
|
119
|
+
}, POLL_INTERVAL_MS);
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// ── Telegram ────────────────────────────────────────────────────
|
|
123
|
+
function sendTelegramWithKeyboard(text, replyMarkup) {
|
|
124
|
+
return new Promise((resolve, reject) => {
|
|
125
|
+
const body = JSON.stringify({
|
|
126
|
+
chat_id: CHAT_ID,
|
|
127
|
+
text,
|
|
128
|
+
parse_mode: 'Markdown',
|
|
129
|
+
reply_markup: replyMarkup,
|
|
130
|
+
});
|
|
131
|
+
const options = {
|
|
132
|
+
hostname: 'api.telegram.org',
|
|
133
|
+
path: `/bot${BOT_TOKEN}/sendMessage`,
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: {
|
|
136
|
+
'Content-Type': 'application/json',
|
|
137
|
+
'Content-Length': Buffer.byteLength(body),
|
|
138
|
+
},
|
|
139
|
+
timeout: 5000,
|
|
140
|
+
};
|
|
141
|
+
const req = https_1.default.request(options, (res) => {
|
|
142
|
+
let data = '';
|
|
143
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
144
|
+
res.on('end', () => {
|
|
145
|
+
if (res.statusCode >= 200 && res.statusCode < 300) {
|
|
146
|
+
try {
|
|
147
|
+
const parsed = JSON.parse(data);
|
|
148
|
+
resolve(parsed.result || null);
|
|
149
|
+
}
|
|
150
|
+
catch {
|
|
151
|
+
resolve(null);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
reject(new Error(`Telegram API ${res.statusCode}: ${data}`));
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
req.on('error', reject);
|
|
160
|
+
req.on('timeout', () => {
|
|
161
|
+
req.destroy();
|
|
162
|
+
reject(new Error('Telegram request timed out'));
|
|
163
|
+
});
|
|
164
|
+
req.write(body);
|
|
165
|
+
req.end();
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
// ── Helpers ──────────────────────────────────────────────────────
|
|
169
|
+
function readStdin() {
|
|
170
|
+
return new Promise((resolve) => {
|
|
171
|
+
let data = '';
|
|
172
|
+
let resolved = false;
|
|
173
|
+
process.stdin.setEncoding('utf8');
|
|
174
|
+
process.stdin.on('data', (chunk) => { data += chunk; });
|
|
175
|
+
process.stdin.on('end', () => {
|
|
176
|
+
if (!resolved) {
|
|
177
|
+
resolved = true;
|
|
178
|
+
resolve(data);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
setTimeout(() => {
|
|
182
|
+
if (!resolved) {
|
|
183
|
+
resolved = true;
|
|
184
|
+
process.stdin.destroy();
|
|
185
|
+
resolve(data || '{}');
|
|
186
|
+
}
|
|
187
|
+
}, 500);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
function escapeMarkdown(text) {
|
|
191
|
+
return text.replace(/([_*`\[])/g, '\\$1');
|
|
192
|
+
}
|
|
193
|
+
// ── Run ─────────────────────────────────────────────────────────
|
|
194
|
+
main().catch((err) => {
|
|
195
|
+
process.stderr.write(`[pre-compact-notify] Fatal: ${err.message}\n`);
|
|
196
|
+
});
|
|
197
|
+
//# sourceMappingURL=pre-compact-notify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pre-compact-notify.js","sourceRoot":"","sources":["../pre-compact-notify.ts"],"names":[],"mappings":"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"}
|