remoat 0.2.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 (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +297 -0
  3. package/dist/bin/cli.d.ts +2 -0
  4. package/dist/bin/cli.js +80 -0
  5. package/dist/bin/cli.js.map +1 -0
  6. package/dist/bin/commands/doctor.d.ts +1 -0
  7. package/dist/bin/commands/doctor.js +211 -0
  8. package/dist/bin/commands/doctor.js.map +1 -0
  9. package/dist/bin/commands/open.d.ts +1 -0
  10. package/dist/bin/commands/open.js +187 -0
  11. package/dist/bin/commands/open.js.map +1 -0
  12. package/dist/bin/commands/setup.d.ts +1 -0
  13. package/dist/bin/commands/setup.js +267 -0
  14. package/dist/bin/commands/setup.js.map +1 -0
  15. package/dist/bin/commands/start.d.ts +2 -0
  16. package/dist/bin/commands/start.js +39 -0
  17. package/dist/bin/commands/start.js.map +1 -0
  18. package/dist/bot/index.d.ts +2 -0
  19. package/dist/bot/index.js +1393 -0
  20. package/dist/bot/index.js.map +1 -0
  21. package/dist/commands/chatCommandHandler.d.ts +20 -0
  22. package/dist/commands/chatCommandHandler.js +30 -0
  23. package/dist/commands/chatCommandHandler.js.map +1 -0
  24. package/dist/commands/cleanupCommandHandler.d.ts +21 -0
  25. package/dist/commands/cleanupCommandHandler.js +40 -0
  26. package/dist/commands/cleanupCommandHandler.js.map +1 -0
  27. package/dist/commands/joinCommandHandler.d.ts +19 -0
  28. package/dist/commands/joinCommandHandler.js +27 -0
  29. package/dist/commands/joinCommandHandler.js.map +1 -0
  30. package/dist/commands/messageParser.d.ts +7 -0
  31. package/dist/commands/messageParser.js +29 -0
  32. package/dist/commands/messageParser.js.map +1 -0
  33. package/dist/commands/slashCommandHandler.d.ts +21 -0
  34. package/dist/commands/slashCommandHandler.js +105 -0
  35. package/dist/commands/slashCommandHandler.js.map +1 -0
  36. package/dist/commands/workspaceCommandHandler.d.ts +16 -0
  37. package/dist/commands/workspaceCommandHandler.js +29 -0
  38. package/dist/commands/workspaceCommandHandler.js.map +1 -0
  39. package/dist/database/chatSessionRepository.d.ts +59 -0
  40. package/dist/database/chatSessionRepository.js +110 -0
  41. package/dist/database/chatSessionRepository.js.map +1 -0
  42. package/dist/database/scheduleRepository.d.ts +60 -0
  43. package/dist/database/scheduleRepository.js +106 -0
  44. package/dist/database/scheduleRepository.js.map +1 -0
  45. package/dist/database/templateRepository.d.ts +51 -0
  46. package/dist/database/templateRepository.js +90 -0
  47. package/dist/database/templateRepository.js.map +1 -0
  48. package/dist/database/workspaceBindingRepository.d.ts +48 -0
  49. package/dist/database/workspaceBindingRepository.js +92 -0
  50. package/dist/database/workspaceBindingRepository.js.map +1 -0
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.js +11 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/middleware/auth.d.ts +5 -0
  55. package/dist/middleware/auth.js +14 -0
  56. package/dist/middleware/auth.js.map +1 -0
  57. package/dist/middleware/sanitize.d.ts +1 -0
  58. package/dist/middleware/sanitize.js +18 -0
  59. package/dist/middleware/sanitize.js.map +1 -0
  60. package/dist/services/antigravityLauncher.d.ts +7 -0
  61. package/dist/services/antigravityLauncher.js +94 -0
  62. package/dist/services/antigravityLauncher.js.map +1 -0
  63. package/dist/services/approvalDetector.d.ts +97 -0
  64. package/dist/services/approvalDetector.js +394 -0
  65. package/dist/services/approvalDetector.js.map +1 -0
  66. package/dist/services/assistantDomExtractor.d.ts +49 -0
  67. package/dist/services/assistantDomExtractor.js +340 -0
  68. package/dist/services/assistantDomExtractor.js.map +1 -0
  69. package/dist/services/autoAcceptService.d.ts +14 -0
  70. package/dist/services/autoAcceptService.js +81 -0
  71. package/dist/services/autoAcceptService.js.map +1 -0
  72. package/dist/services/cdpBridgeManager.d.ts +50 -0
  73. package/dist/services/cdpBridgeManager.js +355 -0
  74. package/dist/services/cdpBridgeManager.js.map +1 -0
  75. package/dist/services/cdpConnectionPool.d.ts +88 -0
  76. package/dist/services/cdpConnectionPool.js +235 -0
  77. package/dist/services/cdpConnectionPool.js.map +1 -0
  78. package/dist/services/cdpService.d.ts +214 -0
  79. package/dist/services/cdpService.js +1423 -0
  80. package/dist/services/cdpService.js.map +1 -0
  81. package/dist/services/chatSessionService.d.ts +89 -0
  82. package/dist/services/chatSessionService.js +738 -0
  83. package/dist/services/chatSessionService.js.map +1 -0
  84. package/dist/services/errorPopupDetector.d.ts +89 -0
  85. package/dist/services/errorPopupDetector.js +274 -0
  86. package/dist/services/errorPopupDetector.js.map +1 -0
  87. package/dist/services/modeService.d.ts +44 -0
  88. package/dist/services/modeService.js +74 -0
  89. package/dist/services/modeService.js.map +1 -0
  90. package/dist/services/modelService.d.ts +36 -0
  91. package/dist/services/modelService.js +64 -0
  92. package/dist/services/modelService.js.map +1 -0
  93. package/dist/services/planningDetector.d.ts +87 -0
  94. package/dist/services/planningDetector.js +321 -0
  95. package/dist/services/planningDetector.js.map +1 -0
  96. package/dist/services/processManager.d.ts +18 -0
  97. package/dist/services/processManager.js +62 -0
  98. package/dist/services/processManager.js.map +1 -0
  99. package/dist/services/progressSender.d.ts +20 -0
  100. package/dist/services/progressSender.js +65 -0
  101. package/dist/services/progressSender.js.map +1 -0
  102. package/dist/services/promptDispatcher.d.ts +38 -0
  103. package/dist/services/promptDispatcher.js +42 -0
  104. package/dist/services/promptDispatcher.js.map +1 -0
  105. package/dist/services/quotaService.d.ts +21 -0
  106. package/dist/services/quotaService.js +191 -0
  107. package/dist/services/quotaService.js.map +1 -0
  108. package/dist/services/responseMonitor.d.ts +129 -0
  109. package/dist/services/responseMonitor.js +996 -0
  110. package/dist/services/responseMonitor.js.map +1 -0
  111. package/dist/services/scheduleService.d.ts +58 -0
  112. package/dist/services/scheduleService.js +135 -0
  113. package/dist/services/scheduleService.js.map +1 -0
  114. package/dist/services/screenshotService.d.ts +55 -0
  115. package/dist/services/screenshotService.js +86 -0
  116. package/dist/services/screenshotService.js.map +1 -0
  117. package/dist/services/telegramTopicManager.d.ts +40 -0
  118. package/dist/services/telegramTopicManager.js +103 -0
  119. package/dist/services/telegramTopicManager.js.map +1 -0
  120. package/dist/services/titleGeneratorService.d.ts +32 -0
  121. package/dist/services/titleGeneratorService.js +114 -0
  122. package/dist/services/titleGeneratorService.js.map +1 -0
  123. package/dist/services/updateCheckService.d.ts +16 -0
  124. package/dist/services/updateCheckService.js +148 -0
  125. package/dist/services/updateCheckService.js.map +1 -0
  126. package/dist/services/userMessageDetector.d.ts +57 -0
  127. package/dist/services/userMessageDetector.js +222 -0
  128. package/dist/services/userMessageDetector.js.map +1 -0
  129. package/dist/services/workspaceService.d.ts +33 -0
  130. package/dist/services/workspaceService.js +65 -0
  131. package/dist/services/workspaceService.js.map +1 -0
  132. package/dist/ui/autoAcceptUi.d.ts +6 -0
  133. package/dist/ui/autoAcceptUi.js +22 -0
  134. package/dist/ui/autoAcceptUi.js.map +1 -0
  135. package/dist/ui/modeUi.d.ts +12 -0
  136. package/dist/ui/modeUi.js +40 -0
  137. package/dist/ui/modeUi.js.map +1 -0
  138. package/dist/ui/modelsUi.d.ts +12 -0
  139. package/dist/ui/modelsUi.js +101 -0
  140. package/dist/ui/modelsUi.js.map +1 -0
  141. package/dist/ui/projectListUi.d.ts +11 -0
  142. package/dist/ui/projectListUi.js +59 -0
  143. package/dist/ui/projectListUi.js.map +1 -0
  144. package/dist/ui/screenshotUi.d.ts +6 -0
  145. package/dist/ui/screenshotUi.js +28 -0
  146. package/dist/ui/screenshotUi.js.map +1 -0
  147. package/dist/ui/sessionPickerUi.d.ts +8 -0
  148. package/dist/ui/sessionPickerUi.js +32 -0
  149. package/dist/ui/sessionPickerUi.js.map +1 -0
  150. package/dist/ui/templateUi.d.ts +5 -0
  151. package/dist/ui/templateUi.js +44 -0
  152. package/dist/ui/templateUi.js.map +1 -0
  153. package/dist/utils/cdpPorts.d.ts +2 -0
  154. package/dist/utils/cdpPorts.js +6 -0
  155. package/dist/utils/cdpPorts.js.map +1 -0
  156. package/dist/utils/config.d.ts +14 -0
  157. package/dist/utils/config.js +12 -0
  158. package/dist/utils/config.js.map +1 -0
  159. package/dist/utils/configLoader.d.ts +23 -0
  160. package/dist/utils/configLoader.js +153 -0
  161. package/dist/utils/configLoader.js.map +1 -0
  162. package/dist/utils/htmlToTelegramMarkdown.d.ts +6 -0
  163. package/dist/utils/htmlToTelegramMarkdown.js +189 -0
  164. package/dist/utils/htmlToTelegramMarkdown.js.map +1 -0
  165. package/dist/utils/i18n.d.ts +3 -0
  166. package/dist/utils/i18n.js +78 -0
  167. package/dist/utils/i18n.js.map +1 -0
  168. package/dist/utils/imageHandler.d.ts +35 -0
  169. package/dist/utils/imageHandler.js +155 -0
  170. package/dist/utils/imageHandler.js.map +1 -0
  171. package/dist/utils/lockfile.d.ts +7 -0
  172. package/dist/utils/lockfile.js +117 -0
  173. package/dist/utils/lockfile.js.map +1 -0
  174. package/dist/utils/logger.d.ts +23 -0
  175. package/dist/utils/logger.js +85 -0
  176. package/dist/utils/logger.js.map +1 -0
  177. package/dist/utils/logo.d.ts +1 -0
  178. package/dist/utils/logo.js +14 -0
  179. package/dist/utils/logo.js.map +1 -0
  180. package/dist/utils/metadataExtractor.d.ts +5 -0
  181. package/dist/utils/metadataExtractor.js +16 -0
  182. package/dist/utils/metadataExtractor.js.map +1 -0
  183. package/dist/utils/pathUtils.d.ts +23 -0
  184. package/dist/utils/pathUtils.js +58 -0
  185. package/dist/utils/pathUtils.js.map +1 -0
  186. package/dist/utils/processLogBuffer.d.ts +17 -0
  187. package/dist/utils/processLogBuffer.js +108 -0
  188. package/dist/utils/processLogBuffer.js.map +1 -0
  189. package/dist/utils/streamMessageFormatter.d.ts +18 -0
  190. package/dist/utils/streamMessageFormatter.js +91 -0
  191. package/dist/utils/streamMessageFormatter.js.map +1 -0
  192. package/dist/utils/telegramFormatter.d.ts +37 -0
  193. package/dist/utils/telegramFormatter.js +445 -0
  194. package/dist/utils/telegramFormatter.js.map +1 -0
  195. package/dist/utils/voiceHandler.d.ts +23 -0
  196. package/dist/utils/voiceHandler.js +169 -0
  197. package/dist/utils/voiceHandler.js.map +1 -0
  198. package/locales/en.json +85 -0
  199. package/locales/ja.json +109 -0
  200. package/package.json +84 -0
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ConfigLoader = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
39
+ const path = __importStar(require("path"));
40
+ const dotenv = __importStar(require("dotenv"));
41
+ dotenv.config();
42
+ const CONFIG_DIR_NAME = '.remoat';
43
+ const CONFIG_FILE_NAME = 'config.json';
44
+ const DEFAULT_DB_NAME = 'antigravity.db';
45
+ function getConfigDir() {
46
+ return path.join(os.homedir(), CONFIG_DIR_NAME);
47
+ }
48
+ function getConfigFilePath() {
49
+ return path.join(getConfigDir(), CONFIG_FILE_NAME);
50
+ }
51
+ function getDefaultDbPath() {
52
+ return path.join(getConfigDir(), DEFAULT_DB_NAME);
53
+ }
54
+ function expandTilde(raw) {
55
+ if (raw === '~')
56
+ return os.homedir();
57
+ if (raw.startsWith('~/'))
58
+ return path.join(os.homedir(), raw.slice(2));
59
+ return raw;
60
+ }
61
+ function readPersistedConfig(filePath) {
62
+ if (!fs.existsSync(filePath))
63
+ return {};
64
+ const raw = fs.readFileSync(filePath, 'utf-8');
65
+ try {
66
+ return JSON.parse(raw);
67
+ }
68
+ catch {
69
+ throw new Error(`Failed to parse config file at ${filePath}. Check for syntax errors.`);
70
+ }
71
+ }
72
+ function mergeConfig(persisted) {
73
+ const token = process.env.TELEGRAM_BOT_TOKEN ?? persisted.telegramBotToken;
74
+ if (!token) {
75
+ throw new Error('Missing required config: TELEGRAM_BOT_TOKEN');
76
+ }
77
+ const allowedUserIds = resolveAllowedUserIds(persisted);
78
+ if (allowedUserIds.length === 0) {
79
+ throw new Error('Missing required config: ALLOWED_USER_IDS');
80
+ }
81
+ const defaultDir = path.join(os.homedir(), 'Code');
82
+ const rawDir = process.env.WORKSPACE_BASE_DIR ?? persisted.workspaceBaseDir ?? defaultDir;
83
+ const workspaceBaseDir = expandTilde(rawDir);
84
+ const autoApproveFileEdits = resolveBoolean(process.env.AUTO_APPROVE_FILE_EDITS, persisted.autoApproveFileEdits, false);
85
+ const logLevel = resolveLogLevel(process.env.LOG_LEVEL, persisted.logLevel);
86
+ const extractionMode = resolveExtractionMode(process.env.EXTRACTION_MODE, persisted.extractionMode);
87
+ const useTopics = resolveBoolean(process.env.USE_TOPICS, persisted.useTopics, true);
88
+ return {
89
+ telegramBotToken: token,
90
+ allowedUserIds,
91
+ workspaceBaseDir,
92
+ autoApproveFileEdits,
93
+ logLevel,
94
+ extractionMode,
95
+ useTopics,
96
+ };
97
+ }
98
+ function resolveAllowedUserIds(persisted) {
99
+ const envValue = process.env.ALLOWED_USER_IDS;
100
+ if (envValue) {
101
+ return envValue
102
+ .split(',')
103
+ .map((id) => id.trim())
104
+ .filter((id) => id.length > 0);
105
+ }
106
+ if (persisted.allowedUserIds && persisted.allowedUserIds.length > 0) {
107
+ return [...persisted.allowedUserIds];
108
+ }
109
+ return [];
110
+ }
111
+ const VALID_LOG_LEVELS = ['debug', 'info', 'warn', 'error', 'none'];
112
+ function resolveLogLevel(envValue, persistedValue) {
113
+ const raw = envValue?.toLowerCase() ?? persistedValue;
114
+ if (raw && VALID_LOG_LEVELS.includes(raw)) {
115
+ return raw;
116
+ }
117
+ return 'info';
118
+ }
119
+ function resolveExtractionMode(envValue, persistedValue) {
120
+ const raw = envValue ?? persistedValue;
121
+ if (raw === 'legacy')
122
+ return 'legacy';
123
+ return 'structured';
124
+ }
125
+ function resolveBoolean(envValue, persistedValue, defaultValue) {
126
+ if (envValue !== undefined)
127
+ return envValue.toLowerCase() === 'true';
128
+ if (persistedValue !== undefined)
129
+ return persistedValue;
130
+ return defaultValue;
131
+ }
132
+ exports.ConfigLoader = {
133
+ getConfigDir,
134
+ getConfigFilePath,
135
+ getDefaultDbPath,
136
+ configExists() {
137
+ return fs.existsSync(getConfigFilePath());
138
+ },
139
+ load(persistedOverride) {
140
+ const persisted = persistedOverride ?? readPersistedConfig(getConfigFilePath());
141
+ return mergeConfig(persisted);
142
+ },
143
+ save(config) {
144
+ const dir = getConfigDir();
145
+ if (!fs.existsSync(dir)) {
146
+ fs.mkdirSync(dir, { recursive: true });
147
+ }
148
+ const existing = readPersistedConfig(getConfigFilePath());
149
+ const merged = { ...existing, ...config };
150
+ fs.writeFileSync(getConfigFilePath(), JSON.stringify(merged, null, 2) + '\n', 'utf-8');
151
+ },
152
+ };
153
+ //# sourceMappingURL=configLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"configLoader.js","sourceRoot":"","sources":["../../src/utils/configLoader.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * HTML-to-Telegram-HTML converter.
3
+ * Converts common HTML tags to Telegram-compatible HTML formatting.
4
+ * Telegram supports: <b>, <i>, <code>, <pre>, <a href="">, <s>, <u>, <blockquote>.
5
+ */
6
+ export declare function htmlToTelegramHtml(html: string): string;
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ /**
3
+ * HTML-to-Telegram-HTML converter.
4
+ * Converts common HTML tags to Telegram-compatible HTML formatting.
5
+ * Telegram supports: <b>, <i>, <code>, <pre>, <a href="">, <s>, <u>, <blockquote>.
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.htmlToTelegramHtml = htmlToTelegramHtml;
9
+ function htmlToTelegramHtml(html) {
10
+ if (!html)
11
+ return '';
12
+ let result = html;
13
+ // Remove non-visible elements
14
+ result = result.replace(/<style[^>]*>[\s\S]*?<\/style>/gi, '');
15
+ result = result.replace(/<script[^>]*>[\s\S]*?<\/script>/gi, '');
16
+ // Line breaks and separators
17
+ result = result.replace(/<br\s*\/?>/gi, '\n');
18
+ result = result.replace(/<hr\s*\/?>/gi, '\n---\n');
19
+ // Headings (all levels → bold)
20
+ result = result.replace(/<h[1-6][^>]*>([\s\S]*?)<\/h[1-6]>/gi, (_m, content) => `\n<b>${stripTags(content).trim()}</b>\n`);
21
+ // Code blocks: <pre><code> (must come before inline code)
22
+ result = result.replace(/<pre[^>]*>\s*<code(?:\s+class="language-([^"]*)")?[^>]*>([\s\S]*?)<\/code>\s*<\/pre>/gi, (_m, lang, content) => lang
23
+ ? `\n<pre><code class="language-${lang}">${content}</code></pre>\n`
24
+ : `\n<pre>${content}</pre>\n`);
25
+ // Inline code
26
+ result = result.replace(/<code[^>]*>([\s\S]*?)<\/code>/gi, '<code>$1</code>');
27
+ // Bold
28
+ result = result.replace(/<(?:strong|b)(?:\s[^>]*)?>((?: |\s|[^<]|<(?!\/(?:strong|b)>))*)<\/(?:strong|b)>/gi, '<b>$1</b>');
29
+ // Italic
30
+ result = result.replace(/<(?:em|i)(?:\s[^>]*)?>((?: |\s|[^<]|<(?!\/(?:em|i)>))*)<\/(?:em|i)>/gi, '<i>$1</i>');
31
+ // Strikethrough: <del>, <strike>, <s> → <s>
32
+ result = result.replace(/<(?:del|strike|s)(?:\s[^>]*)?>([\s\S]*?)<\/(?:del|strike|s)>/gi, '<s>$1</s>');
33
+ // Underline: <ins>, <u> → <u>
34
+ result = result.replace(/<(?:ins|u)(?:\s[^>]*)?>([\s\S]*?)<\/(?:ins|u)>/gi, '<u>$1</u>');
35
+ // Highlight/mark → bold fallback
36
+ result = result.replace(/<mark[^>]*>([\s\S]*?)<\/mark>/gi, '<b>$1</b>');
37
+ // Links: preserve <a href="...">text</a>
38
+ result = result.replace(/<a\s+[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi, (_m, href, text) => {
39
+ const linkText = stripTags(text).trim();
40
+ if (!href || href.startsWith('#') || href.startsWith('javascript:')) {
41
+ return linkText;
42
+ }
43
+ return `<a href="${href}">${linkText}</a>`;
44
+ });
45
+ // Blockquote → Telegram <blockquote>
46
+ result = result.replace(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/gi, (_m, content) => `\n<blockquote>${stripTags(content).trim()}</blockquote>\n`);
47
+ // Context-scope mentions (Antigravity-specific)
48
+ result = result.replace(/<span[^>]*class="[^"]*context-scope-mention[^"]*"[^>]*>([\s\S]*?)<\/span>/gi, (_m, text) => `<code>${stripTags(text).trim()}</code>`);
49
+ // Elements with title attributes (file paths)
50
+ result = result.replace(/<(?:div|span|a)[^>]*\btitle="([^"]*)"[^>]*>([\s\S]*?)<\/(?:div|span|a)>/gi, (_m, title, text) => {
51
+ if (looksLikeFilePath(title)) {
52
+ return `${title}${stripTags(text).trim()}`;
53
+ }
54
+ return stripTags(text);
55
+ });
56
+ // Images → show alt text
57
+ result = result.replace(/<img[^>]*alt="([^"]*)"[^>]*\/?>/gi, (_m, alt) => alt ? `[${alt}]` : '');
58
+ result = result.replace(/<img[^>]*\/?>/gi, '');
59
+ // Details/summary → show as expandable content
60
+ result = result.replace(/<details[^>]*>\s*<summary[^>]*>([\s\S]*?)<\/summary>([\s\S]*?)<\/details>/gi, (_m, summary, content) => {
61
+ const summaryText = stripTags(summary).trim();
62
+ const contentText = stripTags(content).trim();
63
+ return contentText
64
+ ? `\n<b>${summaryText}</b>\n${contentText}\n`
65
+ : `\n<b>${summaryText}</b>\n`;
66
+ });
67
+ // Figure/figcaption → show caption
68
+ result = result.replace(/<figure[^>]*>([\s\S]*?)<figcaption[^>]*>([\s\S]*?)<\/figcaption>[\s\S]*?<\/figure>/gi, (_m, content, caption) => `${stripTags(content).trim()}\n<i>${stripTags(caption).trim()}</i>\n`);
69
+ result = result.replace(/<figure[^>]*>([\s\S]*?)<\/figure>/gi, '$1');
70
+ // Convert HTML tables to monospace ASCII tables inside <pre>
71
+ result = result.replace(/<table[^>]*>([\s\S]*?)<\/table>/gi, (_m, tableContent) => {
72
+ const rows = [];
73
+ const rowRegex = /<tr[^>]*>([\s\S]*?)<\/tr>/gi;
74
+ let rowMatch;
75
+ while ((rowMatch = rowRegex.exec(tableContent)) !== null) {
76
+ const cells = [];
77
+ const cellRegex = /<(?:td|th)[^>]*>([\s\S]*?)<\/(?:td|th)>/gi;
78
+ let cellMatch;
79
+ while ((cellMatch = cellRegex.exec(rowMatch[1])) !== null) {
80
+ cells.push(stripTags(cellMatch[1]).trim());
81
+ }
82
+ if (cells.length > 0)
83
+ rows.push(cells);
84
+ }
85
+ if (rows.length === 0)
86
+ return '';
87
+ const colCount = Math.max(...rows.map(r => r.length));
88
+ const colWidths = [];
89
+ for (let c = 0; c < colCount; c++) {
90
+ colWidths[c] = Math.max(...rows.map(r => (r[c] || '').length), 1);
91
+ }
92
+ const lines = [];
93
+ for (let ri = 0; ri < rows.length; ri++) {
94
+ const row = rows[ri];
95
+ const cells = row.map((cell, ci) => cell.padEnd(colWidths[ci]));
96
+ lines.push('| ' + cells.join(' | ') + ' |');
97
+ if (ri === 0) {
98
+ lines.push('|' + colWidths.map(w => '-'.repeat(w + 2)).join('|') + '|');
99
+ }
100
+ }
101
+ return `\n<pre>${lines.join('\n')}</pre>\n`;
102
+ });
103
+ // Definition lists: <dl>, <dt>, <dd>
104
+ result = result.replace(/<dl[^>]*>([\s\S]*?)<\/dl>/gi, (_m, content) => {
105
+ let output = '\n';
106
+ output = content.replace(/<dt[^>]*>([\s\S]*?)<\/dt>/gi, (_dm, text) => `<b>${stripTags(text).trim()}</b>\n`);
107
+ output = output.replace(/<dd[^>]*>([\s\S]*?)<\/dd>/gi, (_ddm, text) => ` ${stripTags(text).trim()}\n`);
108
+ return `\n${output}`;
109
+ });
110
+ // Superscript/subscript → inline text
111
+ result = result.replace(/<sup[^>]*>([\s\S]*?)<\/sup>/gi, (_m, text) => `^${stripTags(text).trim()}`);
112
+ result = result.replace(/<sub[^>]*>([\s\S]*?)<\/sub>/gi, (_m, text) => `_${stripTags(text).trim()}`);
113
+ // Block-level elements
114
+ result = result.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, '$1\n\n');
115
+ result = result.replace(/<div[^>]*>([\s\S]*?)<\/div>/gi, '$1\n');
116
+ // Lists (iterative for nested lists)
117
+ for (let iteration = 0; iteration < 5; iteration++) {
118
+ if (!/<(?:ul|ol)\b/i.test(result))
119
+ break;
120
+ result = result.replace(/<ul[^>]*>((?:(?!<\/?(?:ul|ol)\b)[\s\S])*?)<\/ul>/gi, (_m, content) => {
121
+ const items = content.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_lm, text) => `- ${stripTags(text).trim()}\n`);
122
+ return `\n${items}`;
123
+ });
124
+ result = result.replace(/<ol[^>]*>((?:(?!<\/?(?:ul|ol)\b)[\s\S])*?)<\/ol>/gi, (_m, content) => {
125
+ let counter = 0;
126
+ const items = content.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, (_lm, text) => {
127
+ counter++;
128
+ return `${counter}. ${stripTags(text).trim()}\n`;
129
+ });
130
+ return `\n${items}`;
131
+ });
132
+ }
133
+ // Strip remaining HTML tags except the Telegram-supported ones
134
+ result = stripUnsupportedTags(result);
135
+ result = decodeSafeEntities(result);
136
+ result = result.replace(/\n{3,}/g, '\n\n');
137
+ result = result.trim();
138
+ return result;
139
+ }
140
+ function looksLikeFilePath(value) {
141
+ if (!value)
142
+ return false;
143
+ return /^[a-zA-Z0-9._\-/]+\.[a-zA-Z0-9]+$/.test(value) && value.includes('/');
144
+ }
145
+ function stripTags(html) {
146
+ return html.replace(/<[^>]+>/g, '');
147
+ }
148
+ /** Strip HTML tags except the ones Telegram supports */
149
+ function stripUnsupportedTags(html) {
150
+ const allowed = /^\/?(b|i|u|s|code|pre|a|blockquote)(\s|>|\/|$)/i;
151
+ return html.replace(/<\/?[^>]+>/g, (tag) => {
152
+ const inner = tag.replace(/^<\/?/, '').replace(/>$/, '');
153
+ return allowed.test(inner) ? tag : '';
154
+ });
155
+ }
156
+ /**
157
+ * Decode HTML entities that are safe for Telegram HTML mode.
158
+ * Preserves &amp; &lt; &gt; as-is since Telegram requires them escaped.
159
+ */
160
+ function decodeSafeEntities(text) {
161
+ return text
162
+ .replace(/&quot;/g, '"')
163
+ .replace(/&#39;/g, "'")
164
+ .replace(/&#x27;/g, "'")
165
+ .replace(/&nbsp;/g, ' ')
166
+ .replace(/&#x([0-9a-fA-F]+);/g, (_m, hex) => {
167
+ const cp = parseInt(hex, 16);
168
+ const ch = String.fromCodePoint(cp);
169
+ if (ch === '&')
170
+ return '&amp;';
171
+ if (ch === '<')
172
+ return '&lt;';
173
+ if (ch === '>')
174
+ return '&gt;';
175
+ return ch;
176
+ })
177
+ .replace(/&#(\d+);/g, (_m, dec) => {
178
+ const cp = parseInt(dec, 10);
179
+ const ch = String.fromCodePoint(cp);
180
+ if (ch === '&')
181
+ return '&amp;';
182
+ if (ch === '<')
183
+ return '&lt;';
184
+ if (ch === '>')
185
+ return '&gt;';
186
+ return ch;
187
+ });
188
+ }
189
+ //# sourceMappingURL=htmlToTelegramMarkdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"htmlToTelegramMarkdown.js","sourceRoot":"","sources":["../../src/utils/htmlToTelegramMarkdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export type Language = 'en' | 'ja';
2
+ export declare function initI18n(lang?: Language): void;
3
+ export declare function t(key: string, variables?: Record<string, any>): string;
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.initI18n = initI18n;
37
+ exports.t = t;
38
+ const logger_1 = require("./logger");
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ let currentLanguage = 'en';
42
+ let translations = {};
43
+ function initI18n(lang = 'en') {
44
+ currentLanguage = lang;
45
+ loadTranslations();
46
+ }
47
+ function loadTranslations() {
48
+ try {
49
+ const enPath = path.join(__dirname, '../../locales/en.json');
50
+ const jaPath = path.join(__dirname, '../../locales/ja.json');
51
+ if (fs.existsSync(enPath)) {
52
+ translations['en'] = JSON.parse(fs.readFileSync(enPath, 'utf8'));
53
+ }
54
+ else {
55
+ translations['en'] = {};
56
+ }
57
+ if (fs.existsSync(jaPath)) {
58
+ translations['ja'] = JSON.parse(fs.readFileSync(jaPath, 'utf8'));
59
+ }
60
+ else {
61
+ translations['ja'] = {};
62
+ }
63
+ }
64
+ catch (error) {
65
+ logger_1.logger.error('Failed to load translations:', error);
66
+ }
67
+ }
68
+ function t(key, variables) {
69
+ const langDict = translations[currentLanguage] || translations['en'];
70
+ let text = langDict?.[key] || translations['en']?.[key] || key;
71
+ if (variables) {
72
+ for (const [vKey, vValue] of Object.entries(variables)) {
73
+ text = text.replaceAll(`{{${vKey}}}`, String(vValue));
74
+ }
75
+ }
76
+ return text;
77
+ }
78
+ //# sourceMappingURL=i18n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.js","sourceRoot":"","sources":["../../src/utils/i18n.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,4BAGC;AAuBD,cAWC;AA9CD,qCAAkC;AAClC,uCAAyB;AACzB,2CAA6B;AAI7B,IAAI,eAAe,GAAa,IAAI,CAAC;AACrC,IAAI,YAAY,GAA2C,EAAE,CAAC;AAE9D,SAAgB,QAAQ,CAAC,OAAiB,IAAI;IAC1C,eAAe,GAAG,IAAI,CAAC;IACvB,gBAAgB,EAAE,CAAC;AACvB,CAAC;AAED,SAAS,gBAAgB;IACrB,IAAI,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;QAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,CAAC;QAE7D,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACJ,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,CAAC;QAED,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACJ,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5B,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,eAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;IACxD,CAAC;AACL,CAAC;AAED,SAAgB,CAAC,CAAC,GAAW,EAAE,SAA+B;IAC1D,MAAM,QAAQ,GAAG,YAAY,CAAC,eAAe,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,CAAC;IACrE,IAAI,IAAI,GAAG,QAAQ,EAAE,CAAC,GAAG,CAAC,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;IAE/D,IAAI,SAAS,EAAE,CAAC;QACZ,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YACrD,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1D,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC"}
@@ -0,0 +1,35 @@
1
+ import { ExtractedResponseImage } from '../services/cdpService';
2
+ export interface InboundImageAttachment {
3
+ localPath: string;
4
+ url: string;
5
+ name: string;
6
+ mimeType: string;
7
+ }
8
+ export interface TelegramPhotoInfo {
9
+ file_id: string;
10
+ file_unique_id: string;
11
+ width: number;
12
+ height: number;
13
+ file_size?: number;
14
+ }
15
+ export declare function isImageAttachment(contentType: string | null | undefined, fileName: string | null | undefined): boolean;
16
+ export declare function mimeTypeToExtension(mimeType: string): string;
17
+ export declare function sanitizeFileName(fileName: string): string;
18
+ export declare function buildPromptWithAttachmentUrls(prompt: string, attachments: InboundImageAttachment[]): string;
19
+ /**
20
+ * Download image attachments from a Telegram message via bot API.
21
+ */
22
+ export declare function downloadTelegramImages(botApi: {
23
+ getFile: (fileId: string) => Promise<any>;
24
+ }, botToken: string, photos: Array<{
25
+ file_id: string;
26
+ file_size?: number;
27
+ }>, messageId: string | number): Promise<InboundImageAttachment[]>;
28
+ export declare function cleanupInboundImageAttachments(attachments: InboundImageAttachment[]): Promise<void>;
29
+ /**
30
+ * Convert an extracted response image to a Buffer + filename for sending via Telegram.
31
+ */
32
+ export declare function toTelegramInputFile(image: ExtractedResponseImage, index: number): Promise<{
33
+ buffer: Buffer;
34
+ name: string;
35
+ } | null>;
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isImageAttachment = isImageAttachment;
37
+ exports.mimeTypeToExtension = mimeTypeToExtension;
38
+ exports.sanitizeFileName = sanitizeFileName;
39
+ exports.buildPromptWithAttachmentUrls = buildPromptWithAttachmentUrls;
40
+ exports.downloadTelegramImages = downloadTelegramImages;
41
+ exports.cleanupInboundImageAttachments = cleanupInboundImageAttachments;
42
+ exports.toTelegramInputFile = toTelegramInputFile;
43
+ const fs = __importStar(require("fs/promises"));
44
+ const os = __importStar(require("os"));
45
+ const path = __importStar(require("path"));
46
+ const logger_1 = require("./logger");
47
+ const MAX_INBOUND_IMAGE_ATTACHMENTS = 4;
48
+ const IMAGE_EXT_PATTERN = /\.(png|jpe?g|webp|gif|bmp)$/i;
49
+ const TEMP_IMAGE_DIR = path.join(os.tmpdir(), 'remoat-images');
50
+ function isImageAttachment(contentType, fileName) {
51
+ if ((contentType || '').toLowerCase().startsWith('image/'))
52
+ return true;
53
+ return IMAGE_EXT_PATTERN.test(fileName || '');
54
+ }
55
+ function mimeTypeToExtension(mimeType) {
56
+ const normalized = (mimeType || '').toLowerCase();
57
+ if (normalized.includes('jpeg') || normalized.includes('jpg'))
58
+ return 'jpg';
59
+ if (normalized.includes('webp'))
60
+ return 'webp';
61
+ if (normalized.includes('gif'))
62
+ return 'gif';
63
+ if (normalized.includes('bmp'))
64
+ return 'bmp';
65
+ return 'png';
66
+ }
67
+ function sanitizeFileName(fileName) {
68
+ const sanitized = fileName.replace(/[^a-zA-Z0-9._-]/g, '-').replace(/-+/g, '-').replace(/^-+|-+$/g, '');
69
+ return sanitized || `image-${Date.now()}.png`;
70
+ }
71
+ function buildPromptWithAttachmentUrls(prompt, attachments) {
72
+ const base = prompt.trim() || 'Please review the attached images and respond accordingly.';
73
+ if (attachments.length === 0)
74
+ return base;
75
+ const lines = attachments.map((image, index) => `${index + 1}. ${image.name}\nURL: ${image.url}`);
76
+ return `${base}\n\n[Telegram Attached Images]\n${lines.join('\n\n')}\n\nPlease refer to the attached images above in your response.`;
77
+ }
78
+ /**
79
+ * Download image attachments from a Telegram message via bot API.
80
+ */
81
+ async function downloadTelegramImages(botApi, botToken, photos, messageId) {
82
+ const imageAttachments = photos.slice(0, MAX_INBOUND_IMAGE_ATTACHMENTS);
83
+ if (imageAttachments.length === 0)
84
+ return [];
85
+ await fs.mkdir(TEMP_IMAGE_DIR, { recursive: true });
86
+ const downloaded = [];
87
+ let index = 0;
88
+ for (const photo of imageAttachments) {
89
+ try {
90
+ const file = await botApi.getFile(photo.file_id);
91
+ const filePath = file.file_path;
92
+ if (!filePath)
93
+ continue;
94
+ const url = `https://api.telegram.org/file/bot${botToken}/${filePath}`;
95
+ const response = await fetch(url);
96
+ if (!response.ok) {
97
+ logger_1.logger.warn(`[ImageBridge] Telegram image download failed (status=${response.status})`);
98
+ continue;
99
+ }
100
+ const bytes = Buffer.from(await response.arrayBuffer());
101
+ if (bytes.length === 0)
102
+ continue;
103
+ const ext = path.extname(filePath) || '.png';
104
+ const name = sanitizeFileName(`telegram-image-${index + 1}${ext}`);
105
+ const localPath = path.join(TEMP_IMAGE_DIR, `${Date.now()}-${messageId}-${index}-${name}`);
106
+ await fs.writeFile(localPath, bytes);
107
+ const mimeExt = ext.slice(1).toLowerCase() === 'jpg' ? 'jpeg' : ext.slice(1).toLowerCase();
108
+ downloaded.push({ localPath, url: `[local file: ${name}]`, name, mimeType: `image/${mimeExt}` });
109
+ index += 1;
110
+ }
111
+ catch (error) {
112
+ logger_1.logger.warn(`[ImageBridge] Telegram image processing failed`, error?.message || error);
113
+ }
114
+ }
115
+ return downloaded;
116
+ }
117
+ async function cleanupInboundImageAttachments(attachments) {
118
+ for (const image of attachments) {
119
+ await fs.unlink(image.localPath).catch(() => { });
120
+ }
121
+ }
122
+ /**
123
+ * Convert an extracted response image to a Buffer + filename for sending via Telegram.
124
+ */
125
+ async function toTelegramInputFile(image, index) {
126
+ let buffer = null;
127
+ let mimeType = image.mimeType || 'image/png';
128
+ if (image.base64Data) {
129
+ try {
130
+ buffer = Buffer.from(image.base64Data, 'base64');
131
+ }
132
+ catch {
133
+ buffer = null;
134
+ }
135
+ }
136
+ else if (image.url && /^https?:\/\//i.test(image.url)) {
137
+ try {
138
+ const response = await fetch(image.url);
139
+ if (response.ok) {
140
+ buffer = Buffer.from(await response.arrayBuffer());
141
+ mimeType = response.headers.get('content-type') || mimeType;
142
+ }
143
+ }
144
+ catch {
145
+ buffer = null;
146
+ }
147
+ }
148
+ if (!buffer || buffer.length === 0)
149
+ return null;
150
+ const fallbackExt = mimeTypeToExtension(mimeType);
151
+ const baseName = sanitizeFileName(image.name || `generated-image-${index + 1}.${fallbackExt}`);
152
+ const finalName = IMAGE_EXT_PATTERN.test(baseName) ? baseName : `${baseName}.${fallbackExt}`;
153
+ return { buffer, name: finalName };
154
+ }
155
+ //# sourceMappingURL=imageHandler.js.map