ccbot 1.0.0 → 1.2.1
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/dist/channel/telegram/telegram-channel.d.ts +18 -0
- package/dist/channel/telegram/telegram-channel.js +148 -0
- package/dist/channel/telegram/telegram-channel.js.map +1 -0
- package/dist/channel/telegram/telegram-sender.d.ts +2 -0
- package/dist/channel/telegram/telegram-sender.js +72 -0
- package/dist/channel/telegram/telegram-sender.js.map +1 -0
- package/dist/channel/types.d.ts +20 -0
- package/dist/channel/types.js +2 -0
- package/dist/channel/types.js.map +1 -0
- package/dist/commands/help.js +11 -9
- package/dist/commands/help.js.map +1 -0
- package/dist/commands/setup.js +49 -40
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/uninstall.js +15 -13
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.js +90 -39
- package/dist/commands/update.js.map +1 -0
- package/dist/config-manager.d.ts +7 -2
- package/dist/config-manager.js +44 -21
- package/dist/config-manager.js.map +1 -0
- package/dist/hook/hook-handler.d.ts +8 -7
- package/dist/hook/hook-handler.js +53 -100
- package/dist/hook/hook-handler.js.map +1 -0
- package/dist/hook/hook-installer.d.ts +1 -3
- package/dist/hook/hook-installer.js +46 -33
- package/dist/hook/hook-installer.js.map +1 -0
- package/dist/hook/hook-server.d.ts +2 -1
- package/dist/hook/hook-server.js +32 -9
- package/dist/hook/hook-server.js.map +1 -0
- package/dist/hook/response-store.d.ts +8 -0
- package/dist/hook/response-store.js +18 -0
- package/dist/i18n/index.d.ts +9 -0
- package/dist/i18n/index.js +55 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locales/en.d.ts +2 -0
- package/dist/i18n/locales/en.js +127 -0
- package/dist/i18n/locales/en.js.map +1 -0
- package/dist/i18n/locales/vi.d.ts +2 -0
- package/dist/i18n/locales/vi.js +127 -0
- package/dist/i18n/locales/vi.js.map +1 -0
- package/dist/i18n/locales/zh.d.ts +2 -0
- package/dist/i18n/locales/zh.js +127 -0
- package/dist/i18n/locales/zh.js.map +1 -0
- package/dist/i18n/types.d.ts +126 -0
- package/dist/i18n/types.js +2 -0
- package/dist/i18n/types.js.map +1 -0
- package/dist/index.js +39 -18
- package/dist/index.js.map +1 -0
- package/dist/monitor/git-collector.d.ts +2 -0
- package/dist/monitor/git-collector.js +88 -0
- package/dist/monitor/git-collector.js.map +1 -0
- package/dist/monitor/transcript-parser.d.ts +4 -0
- package/dist/monitor/transcript-parser.js +35 -14
- package/dist/monitor/transcript-parser.js.map +1 -0
- package/dist/telegram/bot.d.ts +8 -3
- package/dist/telegram/bot.js +69 -18
- package/dist/telegram/message-formatter.d.ts +7 -2
- package/dist/telegram/message-formatter.js +26 -23
- package/dist/telegram/message-sender.d.ts +1 -1
- package/dist/telegram/message-sender.js +37 -5
- package/dist/utils/constants.d.ts +44 -0
- package/dist/utils/constants.js +41 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/install-detection.d.ts +2 -1
- package/dist/utils/install-detection.js +11 -9
- package/dist/utils/install-detection.js.map +1 -0
- package/dist/utils/log.d.ts +2 -0
- package/dist/utils/log.js +18 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/paths.d.ts +16 -0
- package/dist/utils/paths.js +39 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/response-store.d.ts +29 -0
- package/dist/utils/response-store.js +100 -0
- package/dist/utils/response-store.js.map +1 -0
- package/dist/utils/tunnel.d.ts +7 -0
- package/dist/utils/tunnel.js +53 -0
- package/dist/utils/tunnel.js.map +1 -0
- package/package.json +30 -12
|
@@ -1,31 +1,39 @@
|
|
|
1
|
-
import { readFileSync, writeFileSync, mkdirSync, unlinkSync,
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync, unlinkSync, rmSync } from "node:fs";
|
|
2
|
+
import { t } from "../i18n/index.js";
|
|
3
|
+
import { paths } from "../utils/paths.js";
|
|
4
|
+
import { ApiRoute } from "../utils/constants.js";
|
|
4
5
|
export class HookInstaller {
|
|
5
|
-
static
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
static isInstalled() {
|
|
7
|
+
try {
|
|
8
|
+
const settings = HookInstaller.readSettings();
|
|
9
|
+
const hooks = (settings.hooks ?? {});
|
|
10
|
+
const existingStop = (hooks.Stop ?? []);
|
|
11
|
+
return existingStop.some((entry) => {
|
|
12
|
+
const entryHooks = entry.hooks;
|
|
13
|
+
return entryHooks?.some((h) => typeof h.command === "string" && h.command.includes("ccbot"));
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
8
20
|
static install(hookPort, hookSecret) {
|
|
9
21
|
if (!Number.isInteger(hookPort) || hookPort < 1 || hookPort > 65535) {
|
|
10
|
-
throw new Error(
|
|
22
|
+
throw new Error(t("config.invalidHookPort", { port: hookPort }));
|
|
11
23
|
}
|
|
12
24
|
const settings = HookInstaller.readSettings();
|
|
13
25
|
const hooks = (settings.hooks ?? {});
|
|
14
26
|
const existingStop = (hooks.Stop ?? []);
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
return entryHooks?.some((h) => typeof h.command === "string" && h.command.includes("ccbot"));
|
|
18
|
-
});
|
|
19
|
-
if (alreadyInstalled) {
|
|
20
|
-
throw new Error("ccbot hook already installed");
|
|
27
|
+
if (HookInstaller.isInstalled()) {
|
|
28
|
+
throw new Error(t("config.hookAlreadyInstalled"));
|
|
21
29
|
}
|
|
22
30
|
existingStop.push({
|
|
23
|
-
hooks: [{ type: "command", command:
|
|
31
|
+
hooks: [{ type: "command", command: paths.hookScript, timeout: 10 }],
|
|
24
32
|
});
|
|
25
33
|
hooks.Stop = existingStop;
|
|
26
34
|
settings.hooks = hooks;
|
|
27
|
-
mkdirSync(
|
|
28
|
-
writeFileSync(
|
|
35
|
+
mkdirSync(paths.claudeDir, { recursive: true });
|
|
36
|
+
writeFileSync(paths.claudeSettings, JSON.stringify(settings, null, 2));
|
|
29
37
|
HookInstaller.installScript(hookPort, hookSecret);
|
|
30
38
|
}
|
|
31
39
|
static uninstall() {
|
|
@@ -33,29 +41,31 @@ export class HookInstaller {
|
|
|
33
41
|
HookInstaller.removeScript();
|
|
34
42
|
}
|
|
35
43
|
static installScript(hookPort, hookSecret) {
|
|
36
|
-
mkdirSync(
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
-H "X-CCBot-Secret: ${hookSecret}"
|
|
41
|
-
|
|
42
|
-
`;
|
|
43
|
-
writeFileSync(HookInstaller.SCRIPT_PATH, script, { mode: 0o755 });
|
|
44
|
+
mkdirSync(paths.hooksDir, { recursive: true });
|
|
45
|
+
const isWindows = process.platform === "win32";
|
|
46
|
+
const script = isWindows
|
|
47
|
+
? `@echo off\ncurl -s -X POST http://localhost:${hookPort}${ApiRoute.HookStop} -H "Content-Type: application/json" -H "X-CCBot-Secret: ${hookSecret}" --data-binary @- > nul 2>&1\n`
|
|
48
|
+
: `#!/bin/bash\ncurl -s -X POST http://localhost:${hookPort}${ApiRoute.HookStop} \\\n -H "Content-Type: application/json" \\\n -H "X-CCBot-Secret: ${hookSecret}" \\\n --data-binary @- > /dev/null 2>&1 || true\n`;
|
|
49
|
+
writeFileSync(paths.hookScript, script, { mode: isWindows ? 0o644 : 0o755 });
|
|
44
50
|
}
|
|
45
51
|
static removeScript() {
|
|
46
52
|
try {
|
|
47
|
-
unlinkSync(
|
|
53
|
+
unlinkSync(paths.hookScript);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
// script file may not exist
|
|
48
57
|
}
|
|
49
|
-
catch { }
|
|
50
58
|
try {
|
|
51
|
-
|
|
59
|
+
rmSync(paths.hooksDir, { recursive: true, force: true });
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// hooks directory may not exist
|
|
52
63
|
}
|
|
53
|
-
catch { }
|
|
54
64
|
}
|
|
55
65
|
static removeFromSettings() {
|
|
56
66
|
let data;
|
|
57
67
|
try {
|
|
58
|
-
data = readFileSync(
|
|
68
|
+
data = readFileSync(paths.claudeSettings, "utf-8");
|
|
59
69
|
}
|
|
60
70
|
catch {
|
|
61
71
|
return;
|
|
@@ -80,18 +90,21 @@ curl -s -X POST http://localhost:${hookPort}/hook/stop \\
|
|
|
80
90
|
if (Object.keys(hooks).length === 0) {
|
|
81
91
|
delete settings.hooks;
|
|
82
92
|
}
|
|
83
|
-
writeFileSync(
|
|
93
|
+
writeFileSync(paths.claudeSettings, JSON.stringify(settings, null, 2));
|
|
84
94
|
}
|
|
85
95
|
static readSettings() {
|
|
86
96
|
try {
|
|
87
|
-
const data = readFileSync(
|
|
97
|
+
const data = readFileSync(paths.claudeSettings, "utf-8");
|
|
88
98
|
return JSON.parse(data);
|
|
89
99
|
}
|
|
90
100
|
catch (err) {
|
|
91
|
-
if (err instanceof Error &&
|
|
101
|
+
if (err instanceof Error &&
|
|
102
|
+
"code" in err &&
|
|
103
|
+
err.code === "ENOENT") {
|
|
92
104
|
return {};
|
|
93
105
|
}
|
|
94
|
-
throw
|
|
106
|
+
throw err;
|
|
95
107
|
}
|
|
96
108
|
}
|
|
97
109
|
}
|
|
110
|
+
//# sourceMappingURL=hook-installer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-installer.js","sourceRoot":"","sources":["../../src/hook/hook-installer.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,7 +5,8 @@ export declare class HookServer {
|
|
|
5
5
|
private port;
|
|
6
6
|
private secret;
|
|
7
7
|
private handler;
|
|
8
|
-
constructor(port: number, secret: string
|
|
8
|
+
constructor(port: number, secret: string);
|
|
9
|
+
setHandler(handler: HookHandler): void;
|
|
9
10
|
start(): void;
|
|
10
11
|
stop(): Promise<void>;
|
|
11
12
|
private createApp;
|
package/dist/hook/hook-server.js
CHANGED
|
@@ -1,19 +1,28 @@
|
|
|
1
|
-
import express from "express";
|
|
1
|
+
import express, {} from "express";
|
|
2
|
+
import { HookHandler } from "./hook-handler.js";
|
|
3
|
+
import { responseStore } from "../utils/response-store.js";
|
|
4
|
+
import { MINI_APP_BASE_URL, ApiRoute } from "../utils/constants.js";
|
|
5
|
+
import { t } from "../i18n/index.js";
|
|
6
|
+
import { log } from "../utils/log.js";
|
|
7
|
+
import { paths } from "../utils/paths.js";
|
|
8
|
+
const ALLOWED_CORS_ORIGIN = new URL(MINI_APP_BASE_URL).origin;
|
|
2
9
|
export class HookServer {
|
|
3
10
|
app;
|
|
4
11
|
server = null;
|
|
5
12
|
port;
|
|
6
13
|
secret;
|
|
7
|
-
handler;
|
|
8
|
-
constructor(port, secret
|
|
14
|
+
handler = null;
|
|
15
|
+
constructor(port, secret) {
|
|
9
16
|
this.port = port;
|
|
10
17
|
this.secret = secret;
|
|
11
|
-
this.handler = handler;
|
|
12
18
|
this.app = this.createApp();
|
|
13
19
|
}
|
|
20
|
+
setHandler(handler) {
|
|
21
|
+
this.handler = handler;
|
|
22
|
+
}
|
|
14
23
|
start() {
|
|
15
24
|
this.server = this.app.listen(this.port, "127.0.0.1", () => {
|
|
16
|
-
|
|
25
|
+
log(t("hook.serverListening", { port: this.port }));
|
|
17
26
|
});
|
|
18
27
|
}
|
|
19
28
|
stop() {
|
|
@@ -28,17 +37,31 @@ export class HookServer {
|
|
|
28
37
|
createApp() {
|
|
29
38
|
const app = express();
|
|
30
39
|
app.use(express.json({ limit: "10mb" }));
|
|
31
|
-
app.
|
|
32
|
-
|
|
40
|
+
app.use(express.static(paths.publicDir));
|
|
41
|
+
app.get(ApiRoute.ResponseData, (req, res) => {
|
|
42
|
+
const requestOrigin = req.headers.origin ?? "";
|
|
43
|
+
const isTunnel = requestOrigin.endsWith(".trycloudflare.com");
|
|
44
|
+
res.header("Access-Control-Allow-Origin", isTunnel ? requestOrigin : ALLOWED_CORS_ORIGIN);
|
|
45
|
+
const data = responseStore.get(req.params.id);
|
|
46
|
+
if (!data) {
|
|
47
|
+
res.status(404).json({ error: "not_found" });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
res.json(data);
|
|
51
|
+
});
|
|
52
|
+
app.post(ApiRoute.HookStop, (req, res) => {
|
|
53
|
+
const receivedSecret = req.headers["x-ccbot-secret"];
|
|
54
|
+
if (receivedSecret !== this.secret) {
|
|
33
55
|
res.status(403).send("forbidden");
|
|
34
56
|
return;
|
|
35
57
|
}
|
|
36
|
-
setImmediate(() => this.handler
|
|
58
|
+
setImmediate(() => this.handler?.handleStopEvent(req.body));
|
|
37
59
|
res.status(200).send("ok");
|
|
38
60
|
});
|
|
39
|
-
app.get(
|
|
61
|
+
app.get(ApiRoute.Health, (_req, res) => {
|
|
40
62
|
res.status(200).send("healthy");
|
|
41
63
|
});
|
|
42
64
|
return app;
|
|
43
65
|
}
|
|
44
66
|
}
|
|
67
|
+
//# sourceMappingURL=hook-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hook-server.js","sourceRoot":"","sources":["../../src/hook/hook-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NotificationData } from "../telegram/message-formatter.js";
|
|
2
|
+
interface StoredResponse extends NotificationData {
|
|
3
|
+
id: string;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function storeResponse(data: NotificationData): string;
|
|
7
|
+
export declare function getResponse(id: string): StoredResponse | undefined;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const MAX_RESPONSES = 50;
|
|
2
|
+
const responses = new Map();
|
|
3
|
+
let counter = 0;
|
|
4
|
+
export function storeResponse(data) {
|
|
5
|
+
const id = `${Date.now()}-${++counter}`;
|
|
6
|
+
const stored = { ...data, id, timestamp: Date.now() };
|
|
7
|
+
responses.set(id, stored);
|
|
8
|
+
// Evict old entries
|
|
9
|
+
if (responses.size > MAX_RESPONSES) {
|
|
10
|
+
const oldest = responses.keys().next().value;
|
|
11
|
+
if (oldest)
|
|
12
|
+
responses.delete(oldest);
|
|
13
|
+
}
|
|
14
|
+
return id;
|
|
15
|
+
}
|
|
16
|
+
export function getResponse(id) {
|
|
17
|
+
return responses.get(id);
|
|
18
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { TranslationKeys } from "./types.js";
|
|
2
|
+
export type Locale = "en" | "vi" | "zh";
|
|
3
|
+
export declare const SUPPORTED_LOCALES: readonly Locale[];
|
|
4
|
+
export declare const LOCALE_LABELS: Record<Locale, string>;
|
|
5
|
+
export declare function setLocale(locale: Locale): void;
|
|
6
|
+
export declare function getLocale(): Locale;
|
|
7
|
+
export declare function isValidLocale(value: unknown): value is Locale;
|
|
8
|
+
export declare function t(key: string, params?: Record<string, string | number>): string;
|
|
9
|
+
export declare function getTranslations(): TranslationKeys;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { en } from "./locales/en.js";
|
|
2
|
+
import { vi } from "./locales/vi.js";
|
|
3
|
+
import { zh } from "./locales/zh.js";
|
|
4
|
+
export const SUPPORTED_LOCALES = ["en", "vi", "zh"];
|
|
5
|
+
export const LOCALE_LABELS = {
|
|
6
|
+
en: "English",
|
|
7
|
+
vi: "Tiếng Việt",
|
|
8
|
+
zh: "中文",
|
|
9
|
+
};
|
|
10
|
+
const localeMap = { en, vi, zh };
|
|
11
|
+
let currentLocale = "en";
|
|
12
|
+
export function setLocale(locale) {
|
|
13
|
+
currentLocale = locale;
|
|
14
|
+
}
|
|
15
|
+
export function getLocale() {
|
|
16
|
+
return currentLocale;
|
|
17
|
+
}
|
|
18
|
+
export function isValidLocale(value) {
|
|
19
|
+
return typeof value === "string" && SUPPORTED_LOCALES.includes(value);
|
|
20
|
+
}
|
|
21
|
+
function resolveKey(translations, key) {
|
|
22
|
+
const parts = key.split(".");
|
|
23
|
+
let result = translations;
|
|
24
|
+
for (const part of parts) {
|
|
25
|
+
if (result === null || result === undefined || typeof result !== "object") {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
result = result[part];
|
|
29
|
+
}
|
|
30
|
+
return result;
|
|
31
|
+
}
|
|
32
|
+
export function t(key, params) {
|
|
33
|
+
let value = resolveKey(localeMap[currentLocale], key);
|
|
34
|
+
if (value === undefined || value === null) {
|
|
35
|
+
value = resolveKey(en, key);
|
|
36
|
+
}
|
|
37
|
+
if (value === undefined || value === null) {
|
|
38
|
+
return key;
|
|
39
|
+
}
|
|
40
|
+
if (typeof value !== "string") {
|
|
41
|
+
return key;
|
|
42
|
+
}
|
|
43
|
+
if (params) {
|
|
44
|
+
let result = value;
|
|
45
|
+
for (const [paramKey, paramValue] of Object.entries(params)) {
|
|
46
|
+
result = result.replaceAll(`{${paramKey}}`, String(paramValue));
|
|
47
|
+
}
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
51
|
+
}
|
|
52
|
+
export function getTranslations() {
|
|
53
|
+
return localeMap[currentLocale];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AACrC,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAIrC,MAAM,CAAC,MAAM,iBAAiB,GAAsB,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAU,CAAC;AAEhF,MAAM,CAAC,MAAM,aAAa,GAA2B;IACnD,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,YAAY;IAChB,EAAE,EAAE,IAAI;CACT,CAAC;AAEF,MAAM,SAAS,GAAoC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;AAElE,IAAI,aAAa,GAAW,IAAI,CAAC;AAEjC,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,aAAa,GAAG,MAAM,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,aAAa,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,iBAAiB,CAAC,QAAQ,CAAC,KAAe,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,UAAU,CAAC,YAA6B,EAAE,GAAW;IAC5D,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,MAAM,GAAY,YAAY,CAAC;IACnC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC1E,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,GAAI,MAAkC,CAAC,IAAI,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,CAAC,CAAC,GAAW,EAAE,MAAwC;IACrE,IAAI,KAAK,GAAG,UAAU,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE,GAAG,CAAC,CAAC;IAEtD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,KAAK,GAAG,UAAU,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1C,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,GAAG,CAAC;IACb,CAAC;IAED,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,MAAM,GAAG,KAAK,CAAC;QACnB,KAAK,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5D,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,QAAQ,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC;QAClE,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,SAAS,CAAC,aAAa,CAAC,CAAC;AAClC,CAAC"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export const en = {
|
|
2
|
+
bot: {
|
|
3
|
+
started: "started (hook port: {port})",
|
|
4
|
+
shuttingDown: "shutting down...",
|
|
5
|
+
telegramStarted: "telegram bot started",
|
|
6
|
+
commandsRegistered: "commands registered",
|
|
7
|
+
commandsRegisterFailed: "failed to register commands",
|
|
8
|
+
menuButtonRegistered: "mini app menu button registered",
|
|
9
|
+
menuButtonFailed: "failed to register menu button",
|
|
10
|
+
noChatId: "no chat ID yet — run 'ccbot setup' or send /start to the bot",
|
|
11
|
+
notificationFailed: "failed to send notification",
|
|
12
|
+
registeredChatId: "registered chat ID {chatId}",
|
|
13
|
+
unauthorizedUser: "unauthorized user {userId} ({username})",
|
|
14
|
+
ready: "✅ *ccbot* is ready\\.\n\nYou will receive notifications when Claude Code completes a response\\.",
|
|
15
|
+
alreadyConnected: "✅ ccbot is already connected — bot is running normally.",
|
|
16
|
+
connectionLost: "⚠️ lost connection to Telegram — retrying...",
|
|
17
|
+
connectionRestored: "✅ reconnected to Telegram",
|
|
18
|
+
commands: {
|
|
19
|
+
start: "Connect bot to this chat",
|
|
20
|
+
},
|
|
21
|
+
viewDetails: "📱 View details",
|
|
22
|
+
dashboard: "📱 Dashboard",
|
|
23
|
+
sendFailed: "send failed, falling back",
|
|
24
|
+
sendFallbackFailed: "fallback also failed",
|
|
25
|
+
},
|
|
26
|
+
setup: {
|
|
27
|
+
intro: "🤖 ccbot setup",
|
|
28
|
+
tokenMessage: "Telegram Bot Token",
|
|
29
|
+
tokenPlaceholder: "Get from @BotFather → /newbot",
|
|
30
|
+
tokenRequired: "Bot token is required",
|
|
31
|
+
tokenInvalidFormat: "Invalid format (expected: 123456:ABC-xxx)",
|
|
32
|
+
userIdMessage: "Your Telegram User ID",
|
|
33
|
+
userIdPlaceholder: "Send /start to @userinfobot",
|
|
34
|
+
userIdRequired: "User ID is required",
|
|
35
|
+
userIdMustBeNumber: "Must be a number",
|
|
36
|
+
cancelled: "Setup cancelled.",
|
|
37
|
+
configSaved: "Config saved",
|
|
38
|
+
hookInstalled: "Hook installed → ~/.claude/settings.json",
|
|
39
|
+
hookAlreadyInstalled: "Hook already installed",
|
|
40
|
+
hookFailed: "Hook installation failed: {error}",
|
|
41
|
+
chatIdRegistered: "Chat ID registered",
|
|
42
|
+
complete: "🎉 Setup complete!\n\n Next steps:\n 1. Start bot: {command}\n 2. Use Claude Code normally → notifications will arrive",
|
|
43
|
+
languageMessage: "Language",
|
|
44
|
+
},
|
|
45
|
+
uninstall: {
|
|
46
|
+
intro: "🗑️ Uninstalling ccbot",
|
|
47
|
+
hookRemoved: "Hook removed from ~/.claude/settings.json",
|
|
48
|
+
hookNotFound: "No hook found (already removed)",
|
|
49
|
+
configRemoved: "Removed ~/.ccbot/ (config, state, hooks)",
|
|
50
|
+
configNotFound: "~/.ccbot/ not found (already removed)",
|
|
51
|
+
removeGlobal: "To also remove the package:\n pnpm remove -g ccbot",
|
|
52
|
+
removeGitClone: "To also remove the source:\n rm -rf <ccbot-directory>",
|
|
53
|
+
done: "ccbot uninstalled",
|
|
54
|
+
},
|
|
55
|
+
update: {
|
|
56
|
+
intro: "📦 ccbot update",
|
|
57
|
+
npxAlreadyLatest: "Installed via npx — always uses latest version, no update needed.",
|
|
58
|
+
npxDone: "Already up to date",
|
|
59
|
+
checking: "Checking version...",
|
|
60
|
+
alreadyLatestNpm: "Already up to date (v{version})",
|
|
61
|
+
alreadyLatestGit: "Already up to date (commit {hash})",
|
|
62
|
+
updatingNpm: "Updating via {pm} (v{from} → v{to})...",
|
|
63
|
+
updating: "Updating via {pm}...",
|
|
64
|
+
updateSuccess: "Updated successfully (v{from} → v{to})",
|
|
65
|
+
updateComplete: "Update complete",
|
|
66
|
+
updateFailed: "Update failed",
|
|
67
|
+
noUpdateNeeded: "✨ No update needed",
|
|
68
|
+
updateManualGlobal: "Try manually: {cmd}",
|
|
69
|
+
pulling: "Pulling latest changes...",
|
|
70
|
+
pulled: "Pulled latest changes",
|
|
71
|
+
pulledGit: "Pulled latest changes ({from} → {to})",
|
|
72
|
+
installingDeps: "Installing dependencies...",
|
|
73
|
+
depsInstalled: "Dependencies installed",
|
|
74
|
+
building: "Building...",
|
|
75
|
+
buildComplete: "Build complete",
|
|
76
|
+
updateManualGit: "Try manually: git pull && npm install && npm run build",
|
|
77
|
+
gitRepoNotFound: "Could not find git repo root.",
|
|
78
|
+
},
|
|
79
|
+
help: {
|
|
80
|
+
intro: "🤖 ccbot — Claude Code ↔ Telegram Notification Bot",
|
|
81
|
+
usage: "Usage: {prefix} [command]",
|
|
82
|
+
commands: "Commands:",
|
|
83
|
+
cmdNone: " (none) Start the bot",
|
|
84
|
+
cmdSetup: " setup Interactive setup (config + hooks)",
|
|
85
|
+
cmdUpdate: " update Update ccbot to latest version",
|
|
86
|
+
cmdUninstall: " uninstall Remove all ccbot data and hooks",
|
|
87
|
+
cmdHelp: " help Show this help message",
|
|
88
|
+
docs: "docs → https://github.com/palooza-kaida/ccbot",
|
|
89
|
+
},
|
|
90
|
+
hook: {
|
|
91
|
+
serverListening: "hook server listening on localhost:{port}",
|
|
92
|
+
invalidPayload: "invalid stop event payload — missing required fields",
|
|
93
|
+
stopEventReceived: "stop event received for session {sessionId} at {cwd}",
|
|
94
|
+
transcriptFailed: "failed to parse transcript",
|
|
95
|
+
notificationFailed: "failed to send notification",
|
|
96
|
+
},
|
|
97
|
+
tunnel: {
|
|
98
|
+
installing: "installing cloudflared binary...",
|
|
99
|
+
installed: "cloudflared binary installed",
|
|
100
|
+
started: "🌐 public URL: {url}",
|
|
101
|
+
failed: "⚠️ tunnel failed, using localhost only",
|
|
102
|
+
disconnected: "⚠️ tunnel disconnected, reconnecting...",
|
|
103
|
+
exited: "tunnel process exited (code {code})",
|
|
104
|
+
timeout: "tunnel connection timeout ({seconds}s)",
|
|
105
|
+
},
|
|
106
|
+
config: {
|
|
107
|
+
notFound: "config not found — run 'ccbot setup' first",
|
|
108
|
+
mustBeObject: "config must be a JSON object",
|
|
109
|
+
invalidToken: "telegram_bot_token must be a string containing ':' — run 'ccbot setup'",
|
|
110
|
+
invalidUserId: "user_id must be an integer — run 'ccbot setup'",
|
|
111
|
+
invalidPort: "hook_port must be an integer between 1 and 65535",
|
|
112
|
+
invalidSecret: "hook_secret must contain only hex characters (a-f, 0-9)",
|
|
113
|
+
invalidHookPort: "invalid hook port: {port} (must be 1-65535)",
|
|
114
|
+
hookAlreadyInstalled: "ccbot hook already installed",
|
|
115
|
+
},
|
|
116
|
+
notification: {
|
|
117
|
+
tokens: "tokens",
|
|
118
|
+
cache: "cache",
|
|
119
|
+
cacheRead: "read",
|
|
120
|
+
cacheWrite: "write",
|
|
121
|
+
},
|
|
122
|
+
common: {
|
|
123
|
+
unknownCommand: "unknown command: {command}",
|
|
124
|
+
setupFailed: "setup failed",
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=en.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../../src/i18n/locales/en.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
export const vi = {
|
|
2
|
+
bot: {
|
|
3
|
+
started: "đã khởi động (hook port: {port})",
|
|
4
|
+
shuttingDown: "đang tắt...",
|
|
5
|
+
telegramStarted: "telegram bot đã khởi động",
|
|
6
|
+
commandsRegistered: "đã đăng ký commands",
|
|
7
|
+
commandsRegisterFailed: "đăng ký commands thất bại",
|
|
8
|
+
menuButtonRegistered: "đã đăng ký mini app menu button",
|
|
9
|
+
menuButtonFailed: "đăng ký menu button thất bại",
|
|
10
|
+
noChatId: "chưa có chat ID — chạy 'ccbot setup' hoặc gửi /start cho bot",
|
|
11
|
+
notificationFailed: "gửi notification thất bại",
|
|
12
|
+
registeredChatId: "đã đăng ký chat ID {chatId}",
|
|
13
|
+
unauthorizedUser: "user không có quyền {userId} ({username})",
|
|
14
|
+
ready: "✅ *ccbot* đã sẵn sàng\\.\n\nBạn sẽ nhận notification khi Claude Code hoàn thành response\\.",
|
|
15
|
+
alreadyConnected: "✅ ccbot đã kết nối rồi — bot đang hoạt động bình thường.",
|
|
16
|
+
connectionLost: "⚠️ mất kết nối tới Telegram — đang thử kết nối lại...",
|
|
17
|
+
connectionRestored: "✅ đã kết nối lại Telegram",
|
|
18
|
+
commands: {
|
|
19
|
+
start: "Kết nối bot với chat này",
|
|
20
|
+
},
|
|
21
|
+
viewDetails: "📱 Xem chi tiết",
|
|
22
|
+
dashboard: "📱 Bảng điều khiển",
|
|
23
|
+
sendFailed: "gửi thất bại, dùng fallback",
|
|
24
|
+
sendFallbackFailed: "fallback cũng thất bại",
|
|
25
|
+
},
|
|
26
|
+
setup: {
|
|
27
|
+
intro: "🤖 ccbot setup",
|
|
28
|
+
tokenMessage: "Telegram Bot Token",
|
|
29
|
+
tokenPlaceholder: "Lấy từ @BotFather → /newbot",
|
|
30
|
+
tokenRequired: "Bot token là bắt buộc",
|
|
31
|
+
tokenInvalidFormat: "Sai định dạng (cần: 123456:ABC-xxx)",
|
|
32
|
+
userIdMessage: "Telegram User ID của bạn",
|
|
33
|
+
userIdPlaceholder: "Gửi /start cho @userinfobot",
|
|
34
|
+
userIdRequired: "User ID là bắt buộc",
|
|
35
|
+
userIdMustBeNumber: "Phải là số",
|
|
36
|
+
cancelled: "Đã hủy setup.",
|
|
37
|
+
configSaved: "Đã lưu config",
|
|
38
|
+
hookInstalled: "Đã cài hook → ~/.claude/settings.json",
|
|
39
|
+
hookAlreadyInstalled: "Hook đã được cài rồi",
|
|
40
|
+
hookFailed: "Cài hook thất bại: {error}",
|
|
41
|
+
chatIdRegistered: "Đã đăng ký Chat ID",
|
|
42
|
+
complete: "🎉 Setup hoàn tất!\n\n Bước tiếp:\n 1. Chạy bot: {command}\n 2. Dùng Claude Code bình thường → notification sẽ đến",
|
|
43
|
+
languageMessage: "Ngôn ngữ",
|
|
44
|
+
},
|
|
45
|
+
uninstall: {
|
|
46
|
+
intro: "🗑️ Gỡ cài đặt ccbot",
|
|
47
|
+
hookRemoved: "Đã xóa hook khỏi ~/.claude/settings.json",
|
|
48
|
+
hookNotFound: "Không tìm thấy hook (đã xóa rồi)",
|
|
49
|
+
configRemoved: "Đã xóa ~/.ccbot/ (config, state, hooks)",
|
|
50
|
+
configNotFound: "Không tìm thấy ~/.ccbot/ (đã xóa rồi)",
|
|
51
|
+
removeGlobal: "Để gỡ package:\n pnpm remove -g ccbot",
|
|
52
|
+
removeGitClone: "Để xóa source:\n rm -rf <ccbot-directory>",
|
|
53
|
+
done: "Đã gỡ ccbot",
|
|
54
|
+
},
|
|
55
|
+
update: {
|
|
56
|
+
intro: "📦 ccbot cập nhật",
|
|
57
|
+
npxAlreadyLatest: "Cài qua npx — luôn dùng bản mới nhất, không cần cập nhật.",
|
|
58
|
+
npxDone: "Đã là phiên bản mới nhất",
|
|
59
|
+
checking: "Đang kiểm tra phiên bản...",
|
|
60
|
+
alreadyLatestNpm: "Đã là phiên bản mới nhất (v{version})",
|
|
61
|
+
alreadyLatestGit: "Đã là phiên bản mới nhất (commit {hash})",
|
|
62
|
+
updatingNpm: "Đang cập nhật qua {pm} (v{from} → v{to})...",
|
|
63
|
+
updating: "Đang cập nhật qua {pm}...",
|
|
64
|
+
updateSuccess: "Cập nhật thành công (v{from} → v{to})",
|
|
65
|
+
updateComplete: "Hoàn tất cập nhật",
|
|
66
|
+
updateFailed: "Cập nhật thất bại",
|
|
67
|
+
noUpdateNeeded: "✨ Không cần cập nhật",
|
|
68
|
+
updateManualGlobal: "Thử thủ công: {cmd}",
|
|
69
|
+
pulling: "Đang pull code mới nhất...",
|
|
70
|
+
pulled: "Đã pull code mới nhất",
|
|
71
|
+
pulledGit: "Đã pull code mới nhất ({from} → {to})",
|
|
72
|
+
installingDeps: "Đang cài dependencies...",
|
|
73
|
+
depsInstalled: "Đã cài dependencies",
|
|
74
|
+
building: "Đang build...",
|
|
75
|
+
buildComplete: "Build xong",
|
|
76
|
+
updateManualGit: "Thử thủ công: git pull && npm install && npm run build",
|
|
77
|
+
gitRepoNotFound: "Không tìm thấy thư mục gốc git repo.",
|
|
78
|
+
},
|
|
79
|
+
help: {
|
|
80
|
+
intro: "🤖 ccbot — Claude Code ↔ Telegram Notification Bot",
|
|
81
|
+
usage: "Usage: {prefix} [command]",
|
|
82
|
+
commands: "Commands:",
|
|
83
|
+
cmdNone: " (none) Chạy bot",
|
|
84
|
+
cmdSetup: " setup Setup tương tác (config + hooks)",
|
|
85
|
+
cmdUpdate: " update Cập nhật ccbot lên bản mới nhất",
|
|
86
|
+
cmdUninstall: " uninstall Xóa toàn bộ dữ liệu và hooks ccbot",
|
|
87
|
+
cmdHelp: " help Hiện hướng dẫn này",
|
|
88
|
+
docs: "docs → https://github.com/palooza-kaida/ccbot",
|
|
89
|
+
},
|
|
90
|
+
hook: {
|
|
91
|
+
serverListening: "hook server đang lắng nghe tại localhost:{port}",
|
|
92
|
+
invalidPayload: "payload stop event không hợp lệ — thiếu trường bắt buộc",
|
|
93
|
+
stopEventReceived: "nhận stop event cho session {sessionId} tại {cwd}",
|
|
94
|
+
transcriptFailed: "parse transcript thất bại",
|
|
95
|
+
notificationFailed: "gửi notification thất bại",
|
|
96
|
+
},
|
|
97
|
+
tunnel: {
|
|
98
|
+
installing: "đang cài đặt cloudflared binary...",
|
|
99
|
+
installed: "đã cài đặt cloudflared binary",
|
|
100
|
+
started: "🌐 URL công khai: {url}",
|
|
101
|
+
failed: "⚠️ tunnel thất bại, chỉ dùng localhost",
|
|
102
|
+
disconnected: "⚠️ tunnel bị ngắt, đang kết nối lại...",
|
|
103
|
+
exited: "tunnel process đã thoát (code {code})",
|
|
104
|
+
timeout: "tunnel connection timeout ({seconds}s)",
|
|
105
|
+
},
|
|
106
|
+
config: {
|
|
107
|
+
notFound: "không tìm thấy config — chạy 'ccbot setup' trước",
|
|
108
|
+
mustBeObject: "config phải là một JSON object",
|
|
109
|
+
invalidToken: "telegram_bot_token phải là string chứa ':' — chạy 'ccbot setup'",
|
|
110
|
+
invalidUserId: "user_id phải là số nguyên — chạy 'ccbot setup'",
|
|
111
|
+
invalidPort: "hook_port phải là số nguyên từ 1 đến 65535",
|
|
112
|
+
invalidSecret: "hook_secret chỉ được chứa ký tự hex (a-f, 0-9)",
|
|
113
|
+
invalidHookPort: "hook port không hợp lệ: {port} (phải từ 1-65535)",
|
|
114
|
+
hookAlreadyInstalled: "ccbot hook đã được cài rồi",
|
|
115
|
+
},
|
|
116
|
+
notification: {
|
|
117
|
+
tokens: "token",
|
|
118
|
+
cache: "cache",
|
|
119
|
+
cacheRead: "đọc",
|
|
120
|
+
cacheWrite: "ghi",
|
|
121
|
+
},
|
|
122
|
+
common: {
|
|
123
|
+
unknownCommand: "lệnh không xác định: {command}",
|
|
124
|
+
setupFailed: "setup thất bại",
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=vi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vi.js","sourceRoot":"","sources":["../../../src/i18n/locales/vi.ts"],"names":[],"mappings":"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"}
|