ccpoke 1.3.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 (91) hide show
  1. package/LICENSE +21 -0
  2. package/README.en.md +158 -0
  3. package/README.md +158 -0
  4. package/dist/channel/telegram/telegram-channel.d.ts +18 -0
  5. package/dist/channel/telegram/telegram-channel.js +148 -0
  6. package/dist/channel/telegram/telegram-channel.js.map +1 -0
  7. package/dist/channel/telegram/telegram-sender.d.ts +2 -0
  8. package/dist/channel/telegram/telegram-sender.js +72 -0
  9. package/dist/channel/telegram/telegram-sender.js.map +1 -0
  10. package/dist/channel/types.d.ts +20 -0
  11. package/dist/channel/types.js +2 -0
  12. package/dist/channel/types.js.map +1 -0
  13. package/dist/commands/help.d.ts +1 -0
  14. package/dist/commands/help.js +19 -0
  15. package/dist/commands/help.js.map +1 -0
  16. package/dist/commands/setup.d.ts +1 -0
  17. package/dist/commands/setup.js +112 -0
  18. package/dist/commands/setup.js.map +1 -0
  19. package/dist/commands/uninstall.d.ts +1 -0
  20. package/dist/commands/uninstall.js +43 -0
  21. package/dist/commands/uninstall.js.map +1 -0
  22. package/dist/commands/update.d.ts +1 -0
  23. package/dist/commands/update.js +136 -0
  24. package/dist/commands/update.js.map +1 -0
  25. package/dist/config-manager.d.ts +20 -0
  26. package/dist/config-manager.js +94 -0
  27. package/dist/config-manager.js.map +1 -0
  28. package/dist/hook/hook-handler.d.ts +10 -0
  29. package/dist/hook/hook-handler.js +79 -0
  30. package/dist/hook/hook-handler.js.map +1 -0
  31. package/dist/hook/hook-installer.d.ts +9 -0
  32. package/dist/hook/hook-installer.js +110 -0
  33. package/dist/hook/hook-installer.js.map +1 -0
  34. package/dist/hook/hook-server.d.ts +13 -0
  35. package/dist/hook/hook-server.js +65 -0
  36. package/dist/hook/hook-server.js.map +1 -0
  37. package/dist/hook/response-store.d.ts +8 -0
  38. package/dist/hook/response-store.js +18 -0
  39. package/dist/i18n/index.d.ts +9 -0
  40. package/dist/i18n/index.js +55 -0
  41. package/dist/i18n/index.js.map +1 -0
  42. package/dist/i18n/locales/en.d.ts +2 -0
  43. package/dist/i18n/locales/en.js +127 -0
  44. package/dist/i18n/locales/en.js.map +1 -0
  45. package/dist/i18n/locales/vi.d.ts +2 -0
  46. package/dist/i18n/locales/vi.js +127 -0
  47. package/dist/i18n/locales/vi.js.map +1 -0
  48. package/dist/i18n/locales/zh.d.ts +2 -0
  49. package/dist/i18n/locales/zh.js +127 -0
  50. package/dist/i18n/locales/zh.js.map +1 -0
  51. package/dist/i18n/types.d.ts +126 -0
  52. package/dist/i18n/types.js +2 -0
  53. package/dist/i18n/types.js.map +1 -0
  54. package/dist/index.d.ts +2 -0
  55. package/dist/index.js +87 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/monitor/git-collector.d.ts +2 -0
  58. package/dist/monitor/git-collector.js +88 -0
  59. package/dist/monitor/git-collector.js.map +1 -0
  60. package/dist/monitor/transcript-parser.d.ts +10 -0
  61. package/dist/monitor/transcript-parser.js +77 -0
  62. package/dist/monitor/transcript-parser.js.map +1 -0
  63. package/dist/setup.d.ts +1 -0
  64. package/dist/setup.js +130 -0
  65. package/dist/telegram/bot.d.ts +20 -0
  66. package/dist/telegram/bot.js +130 -0
  67. package/dist/telegram/message-formatter.d.ts +18 -0
  68. package/dist/telegram/message-formatter.js +56 -0
  69. package/dist/telegram/message-sender.d.ts +2 -0
  70. package/dist/telegram/message-sender.js +76 -0
  71. package/dist/utils/constants.d.ts +44 -0
  72. package/dist/utils/constants.js +41 -0
  73. package/dist/utils/constants.js.map +1 -0
  74. package/dist/utils/error-utils.d.ts +1 -0
  75. package/dist/utils/error-utils.js +3 -0
  76. package/dist/utils/install-detection.d.ts +5 -0
  77. package/dist/utils/install-detection.js +42 -0
  78. package/dist/utils/install-detection.js.map +1 -0
  79. package/dist/utils/log.d.ts +2 -0
  80. package/dist/utils/log.js +18 -0
  81. package/dist/utils/log.js.map +1 -0
  82. package/dist/utils/paths.d.ts +15 -0
  83. package/dist/utils/paths.js +38 -0
  84. package/dist/utils/paths.js.map +1 -0
  85. package/dist/utils/response-store.d.ts +29 -0
  86. package/dist/utils/response-store.js +100 -0
  87. package/dist/utils/response-store.js.map +1 -0
  88. package/dist/utils/tunnel.d.ts +7 -0
  89. package/dist/utils/tunnel.js +53 -0
  90. package/dist/utils/tunnel.js.map +1 -0
  91. package/package.json +88 -0
@@ -0,0 +1,112 @@
1
+ import * as p from "@clack/prompts";
2
+ import { ConfigManager } from "../config-manager.js";
3
+ import { HookInstaller } from "../hook/hook-installer.js";
4
+ import { detectCliPrefix } from "../utils/install-detection.js";
5
+ import { t, setLocale, SUPPORTED_LOCALES, LOCALE_LABELS } from "../i18n/index.js";
6
+ import { DEFAULT_HOOK_PORT } from "../utils/constants.js";
7
+ export async function runSetup() {
8
+ p.intro(t("setup.intro"));
9
+ let existing = null;
10
+ try {
11
+ existing = ConfigManager.load();
12
+ }
13
+ catch {
14
+ // first-time setup, no existing config
15
+ }
16
+ const locale = await promptLanguage(existing);
17
+ setLocale(locale);
18
+ const credentials = await promptCredentials(existing);
19
+ const config = buildConfig(credentials, existing, locale);
20
+ saveConfig(config);
21
+ installHook(config);
22
+ registerChatId(config.user_id);
23
+ const startCommand = detectCliPrefix();
24
+ p.outro(t("setup.complete", { command: startCommand }));
25
+ }
26
+ async function promptLanguage(existing) {
27
+ const result = await p.select({
28
+ message: t("setup.languageMessage"),
29
+ initialValue: existing?.locale ?? "en",
30
+ options: SUPPORTED_LOCALES.map((loc) => ({
31
+ value: loc,
32
+ label: LOCALE_LABELS[loc],
33
+ })),
34
+ });
35
+ if (p.isCancel(result)) {
36
+ p.cancel(t("setup.cancelled"));
37
+ process.exit(0);
38
+ }
39
+ return result;
40
+ }
41
+ async function promptCredentials(existing) {
42
+ const result = await p.group({
43
+ token: () => p.text({
44
+ message: t("setup.tokenMessage"),
45
+ placeholder: t("setup.tokenPlaceholder"),
46
+ initialValue: existing?.telegram_bot_token ?? "",
47
+ validate(value) {
48
+ if (!value || !value.trim())
49
+ return t("setup.tokenRequired");
50
+ if (!value.includes(":"))
51
+ return t("setup.tokenInvalidFormat");
52
+ },
53
+ }),
54
+ userId: () => p.text({
55
+ message: t("setup.userIdMessage"),
56
+ placeholder: t("setup.userIdPlaceholder"),
57
+ initialValue: existing?.user_id?.toString() ?? "",
58
+ validate(value) {
59
+ if (!value || !value.trim())
60
+ return t("setup.userIdRequired");
61
+ if (isNaN(parseInt(value, 10)))
62
+ return t("setup.userIdMustBeNumber");
63
+ },
64
+ }),
65
+ }, {
66
+ onCancel: () => {
67
+ p.cancel(t("setup.cancelled"));
68
+ process.exit(0);
69
+ },
70
+ });
71
+ return {
72
+ token: result.token.trim(),
73
+ userId: parseInt(result.userId.trim(), 10),
74
+ };
75
+ }
76
+ function buildConfig(credentials, existing, locale) {
77
+ return {
78
+ telegram_bot_token: credentials.token,
79
+ user_id: credentials.userId,
80
+ hook_port: existing?.hook_port || DEFAULT_HOOK_PORT,
81
+ hook_secret: existing?.hook_secret || ConfigManager.generateSecret(),
82
+ locale,
83
+ };
84
+ }
85
+ function saveConfig(config) {
86
+ ConfigManager.save(config);
87
+ p.log.success(t("setup.configSaved"));
88
+ }
89
+ function installHook(config) {
90
+ if (HookInstaller.isInstalled()) {
91
+ p.log.step(t("setup.hookAlreadyInstalled"));
92
+ return;
93
+ }
94
+ try {
95
+ HookInstaller.install(config.hook_port, config.hook_secret);
96
+ p.log.success(t("setup.hookInstalled"));
97
+ }
98
+ catch (err) {
99
+ p.log.error(t("setup.hookFailed", { error: err instanceof Error ? err.message : String(err) }));
100
+ throw err;
101
+ }
102
+ }
103
+ function registerChatId(userId) {
104
+ const state = ConfigManager.loadChatState();
105
+ if (state.chat_id === userId) {
106
+ return;
107
+ }
108
+ state.chat_id = userId;
109
+ ConfigManager.saveChatState(state);
110
+ p.log.success(t("setup.chatIdRegistered"));
111
+ }
112
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function runUninstall(): void;
@@ -0,0 +1,43 @@
1
+ import * as p from "@clack/prompts";
2
+ import { rmSync } from "node:fs";
3
+ import { HookInstaller } from "../hook/hook-installer.js";
4
+ import { detectInstallMethod } from "../utils/install-detection.js";
5
+ import { InstallMethod } from "../utils/constants.js";
6
+ import { t } from "../i18n/index.js";
7
+ import { paths } from "../utils/paths.js";
8
+ export function runUninstall() {
9
+ p.intro(t("uninstall.intro"));
10
+ removeHook();
11
+ removeConfigDirectory();
12
+ printPostUninstallHint();
13
+ p.outro(t("uninstall.done"));
14
+ }
15
+ function removeHook() {
16
+ try {
17
+ HookInstaller.uninstall();
18
+ p.log.success(t("uninstall.hookRemoved"));
19
+ }
20
+ catch {
21
+ p.log.warn(t("uninstall.hookNotFound"));
22
+ }
23
+ }
24
+ function removeConfigDirectory() {
25
+ const ccpokeDir = paths.ccpokeDir;
26
+ try {
27
+ rmSync(ccpokeDir, { recursive: true, force: true });
28
+ p.log.success(t("uninstall.configRemoved"));
29
+ }
30
+ catch {
31
+ p.log.warn(t("uninstall.configNotFound"));
32
+ }
33
+ }
34
+ function printPostUninstallHint() {
35
+ const method = detectInstallMethod();
36
+ if (method === InstallMethod.Global) {
37
+ p.log.info(t("uninstall.removeGlobal"));
38
+ }
39
+ else if (method === InstallMethod.GitClone) {
40
+ p.log.info(t("uninstall.removeGitClone"));
41
+ }
42
+ }
43
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../../src/commands/uninstall.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,gBAAgB,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,CAAC,EAAE,MAAM,kBAAkB,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAE1C,MAAM,UAAU,YAAY;IAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;IAE9B,UAAU,EAAE,CAAC;IACb,qBAAqB,EAAE,CAAC;IAExB,sBAAsB,EAAE,CAAC;IAEzB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,aAAa,CAAC,SAAS,EAAE,CAAC;QAC1B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,qBAAqB;IAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;IAClC,IAAI,CAAC;QACH,MAAM,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB;IAC7B,MAAM,MAAM,GAAG,mBAAmB,EAAE,CAAC;IAErC,IAAI,MAAM,KAAK,aAAa,CAAC,MAAM,EAAE,CAAC;QACpC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,MAAM,KAAK,aAAa,CAAC,QAAQ,EAAE,CAAC;QAC7C,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function runUpdate(): void;
@@ -0,0 +1,136 @@
1
+ import * as p from "@clack/prompts";
2
+ import { execSync } from "node:child_process";
3
+ import { existsSync } from "node:fs";
4
+ import { join, dirname } from "node:path";
5
+ import { detectInstallMethod, getGitRepoRoot } from "../utils/install-detection.js";
6
+ import { InstallMethod, PackageManager } from "../utils/constants.js";
7
+ import { t } from "../i18n/index.js";
8
+ import { getPackageVersion } from "../utils/paths.js";
9
+ export function runUpdate() {
10
+ const method = detectInstallMethod();
11
+ switch (method) {
12
+ case InstallMethod.Npx:
13
+ p.intro(t("update.intro"));
14
+ p.log.step(t("update.npxAlreadyLatest"));
15
+ p.outro(t("update.npxDone"));
16
+ break;
17
+ case InstallMethod.Global:
18
+ updateGlobal();
19
+ break;
20
+ case InstallMethod.GitClone:
21
+ updateGitClone();
22
+ break;
23
+ }
24
+ }
25
+ function detectGlobalPackageManager() {
26
+ const scriptPath = process.argv[1] ?? "";
27
+ if (scriptPath.includes(PackageManager.Pnpm))
28
+ return PackageManager.Pnpm;
29
+ if (scriptPath.includes(PackageManager.Yarn))
30
+ return PackageManager.Yarn;
31
+ if (scriptPath.includes(PackageManager.Bun))
32
+ return PackageManager.Bun;
33
+ return PackageManager.Npm;
34
+ }
35
+ function updateGlobal() {
36
+ const pm = detectGlobalPackageManager();
37
+ const pkg = "ccpoke";
38
+ p.intro(t("update.intro"));
39
+ const s = p.spinner();
40
+ s.start(t("update.checking"));
41
+ const currentVersion = getPackageVersion();
42
+ let latestVersion = "unknown";
43
+ try {
44
+ const cmd = pm === PackageManager.Yarn ? `yarn info ${pkg} version --silent` : `npm view ${pkg} version`;
45
+ latestVersion = execSync(cmd, { stdio: "pipe" }).toString().trim();
46
+ }
47
+ catch {
48
+ // ignore
49
+ }
50
+ if (currentVersion !== "unknown" &&
51
+ latestVersion !== "unknown" &&
52
+ currentVersion === latestVersion) {
53
+ s.stop(t("update.alreadyLatestNpm", { version: currentVersion }));
54
+ p.outro(t("update.noUpdateNeeded"));
55
+ return;
56
+ }
57
+ const updateMsg = currentVersion !== "unknown" && latestVersion !== "unknown"
58
+ ? t("update.updatingNpm", { pm, from: currentVersion, to: latestVersion })
59
+ : t("update.updating", { pm });
60
+ s.message(updateMsg);
61
+ const cmd = pm === PackageManager.Yarn ? `yarn global add ${pkg}` : `${pm} install -g ${pkg}@latest`;
62
+ try {
63
+ execSync(cmd, { stdio: "pipe" });
64
+ s.stop(t("update.updateSuccess", { from: currentVersion, to: latestVersion }));
65
+ p.outro(t("update.updateComplete"));
66
+ }
67
+ catch {
68
+ s.stop(t("update.updateFailed"));
69
+ p.log.error(t("update.updateManualGlobal", { cmd }));
70
+ process.exit(1);
71
+ }
72
+ }
73
+ function updateGitClone() {
74
+ const scriptPath = process.argv[1] ?? "";
75
+ const scriptDir = dirname(scriptPath);
76
+ const repoRoot = getGitRepoRoot(scriptDir);
77
+ if (!repoRoot) {
78
+ p.log.error(t("update.gitRepoNotFound"));
79
+ process.exit(1);
80
+ }
81
+ p.intro(t("update.intro"));
82
+ const s = p.spinner();
83
+ try {
84
+ let currentHash = "unknown";
85
+ try {
86
+ currentHash = execSync("git rev-parse --short HEAD", { cwd: repoRoot, stdio: "pipe" })
87
+ .toString()
88
+ .trim();
89
+ }
90
+ catch {
91
+ // git command may fail if not a clean repo
92
+ }
93
+ s.start(t("update.pulling"));
94
+ execSync("git pull", { cwd: repoRoot, stdio: "pipe" });
95
+ let latestHash = "unknown";
96
+ try {
97
+ latestHash = execSync("git rev-parse --short HEAD", { cwd: repoRoot, stdio: "pipe" })
98
+ .toString()
99
+ .trim();
100
+ }
101
+ catch {
102
+ // git command may fail
103
+ }
104
+ if (currentHash !== "unknown" && currentHash === latestHash) {
105
+ s.stop(t("update.alreadyLatestGit", { hash: currentHash }));
106
+ p.outro(t("update.noUpdateNeeded"));
107
+ return;
108
+ }
109
+ if (currentHash !== "unknown" && latestHash !== "unknown" && currentHash !== latestHash) {
110
+ s.stop(t("update.pulledGit", { from: currentHash, to: latestHash }));
111
+ }
112
+ else {
113
+ s.stop(t("update.pulled"));
114
+ }
115
+ const pm = existsSync(join(repoRoot, "pnpm-lock.yaml"))
116
+ ? PackageManager.Pnpm
117
+ : existsSync(join(repoRoot, "yarn.lock"))
118
+ ? PackageManager.Yarn
119
+ : existsSync(join(repoRoot, "bun.lockb"))
120
+ ? PackageManager.Bun
121
+ : PackageManager.Npm;
122
+ s.start(t("update.installingDeps"));
123
+ execSync(`${pm} install`, { cwd: repoRoot, stdio: "pipe" });
124
+ s.stop(t("update.depsInstalled"));
125
+ s.start(t("update.building"));
126
+ execSync(`${pm} run build`, { cwd: repoRoot, stdio: "pipe" });
127
+ s.stop(t("update.buildComplete"));
128
+ p.outro(t("update.updateComplete"));
129
+ }
130
+ catch {
131
+ s.stop(t("update.updateFailed"));
132
+ p.log.error(t("update.updateManualGit"));
133
+ process.exit(1);
134
+ }
135
+ }
136
+ //# sourceMappingURL=update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type Locale } from "./i18n/index.js";
2
+ export interface Config {
3
+ telegram_bot_token: string;
4
+ user_id: number;
5
+ hook_port: number;
6
+ hook_secret: string;
7
+ locale: Locale;
8
+ }
9
+ export interface ChatState {
10
+ chat_id: number | null;
11
+ }
12
+ export declare class ConfigManager {
13
+ static load(): Config;
14
+ static save(cfg: Config): void;
15
+ static isOwner(cfg: Config, userId: number): boolean;
16
+ static generateSecret(): string;
17
+ static loadChatState(): ChatState;
18
+ static saveChatState(state: ChatState): void;
19
+ private static validate;
20
+ }
@@ -0,0 +1,94 @@
1
+ import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { randomBytes } from "node:crypto";
3
+ import { isValidLocale, setLocale } from "./i18n/index.js";
4
+ import { t } from "./i18n/index.js";
5
+ import { paths } from "./utils/paths.js";
6
+ import { DEFAULT_HOOK_PORT } from "./utils/constants.js";
7
+ export class ConfigManager {
8
+ static load() {
9
+ let data;
10
+ try {
11
+ data = readFileSync(paths.configFile, "utf-8");
12
+ }
13
+ catch (err) {
14
+ if (err instanceof Error &&
15
+ "code" in err &&
16
+ err.code === "ENOENT") {
17
+ throw new Error(t("config.notFound"), { cause: err });
18
+ }
19
+ throw err;
20
+ }
21
+ const raw = JSON.parse(data);
22
+ const cfg = ConfigManager.validate(raw);
23
+ if (cfg.hook_secret !== raw.hook_secret) {
24
+ ConfigManager.save(cfg);
25
+ }
26
+ setLocale(cfg.locale);
27
+ return cfg;
28
+ }
29
+ static save(cfg) {
30
+ mkdirSync(paths.ccpokeDir, { recursive: true });
31
+ writeFileSync(paths.configFile, JSON.stringify(cfg, null, 2), { mode: 0o600 });
32
+ }
33
+ static isOwner(cfg, userId) {
34
+ return cfg.user_id === userId;
35
+ }
36
+ static generateSecret() {
37
+ return randomBytes(32).toString("hex");
38
+ }
39
+ static loadChatState() {
40
+ try {
41
+ const data = readFileSync(paths.stateFile, "utf-8");
42
+ return JSON.parse(data);
43
+ }
44
+ catch {
45
+ return { chat_id: null };
46
+ }
47
+ }
48
+ static saveChatState(state) {
49
+ mkdirSync(paths.ccpokeDir, { recursive: true });
50
+ writeFileSync(paths.stateFile, JSON.stringify(state, null, 2), { mode: 0o600 });
51
+ }
52
+ static validate(data) {
53
+ if (typeof data !== "object" || data === null) {
54
+ throw new Error(t("config.mustBeObject"));
55
+ }
56
+ const obj = data;
57
+ if (typeof obj.telegram_bot_token !== "string" || !obj.telegram_bot_token.includes(":")) {
58
+ throw new Error(t("config.invalidToken"));
59
+ }
60
+ if (typeof obj.user_id !== "number" || !Number.isInteger(obj.user_id)) {
61
+ throw new Error(t("config.invalidUserId"));
62
+ }
63
+ let hookPort = DEFAULT_HOOK_PORT;
64
+ if (obj.hook_port !== undefined) {
65
+ if (typeof obj.hook_port !== "number" ||
66
+ !Number.isInteger(obj.hook_port) ||
67
+ obj.hook_port < 1 ||
68
+ obj.hook_port > 65535) {
69
+ throw new Error(t("config.invalidPort"));
70
+ }
71
+ hookPort = obj.hook_port;
72
+ }
73
+ let hookSecret;
74
+ if (typeof obj.hook_secret === "string" && obj.hook_secret.length > 0) {
75
+ if (!/^[a-f0-9]+$/i.test(obj.hook_secret)) {
76
+ throw new Error(t("config.invalidSecret"));
77
+ }
78
+ hookSecret = obj.hook_secret;
79
+ }
80
+ else {
81
+ hookSecret = ConfigManager.generateSecret();
82
+ }
83
+ const locale = isValidLocale(obj.locale) ? obj.locale : "en";
84
+ const cfg = {
85
+ telegram_bot_token: obj.telegram_bot_token,
86
+ user_id: obj.user_id,
87
+ hook_port: hookPort,
88
+ hook_secret: hookSecret,
89
+ locale,
90
+ };
91
+ return cfg;
92
+ }
93
+ }
94
+ //# sourceMappingURL=config-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-manager.js","sourceRoot":"","sources":["../src/config-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { NotificationChannel } from "../channel/types.js";
2
+ import type { TunnelManager } from "../utils/tunnel.js";
3
+ export declare class HookHandler {
4
+ private channel;
5
+ private hookPort;
6
+ private tunnelManager;
7
+ constructor(channel: NotificationChannel, hookPort: number, tunnelManager: TunnelManager);
8
+ handleStopEvent(event: unknown): Promise<void>;
9
+ private buildResponseUrl;
10
+ }
@@ -0,0 +1,79 @@
1
+ import { parseTranscript } from "../monitor/transcript-parser.js";
2
+ import { collectGitChanges } from "../monitor/git-collector.js";
3
+ import { MINI_APP_BASE_URL, TRANSCRIPT_SETTLE_DELAY_MS, DEFAULT_FALLBACK_DURATION_MS, } from "../utils/constants.js";
4
+ import { t } from "../i18n/index.js";
5
+ import { responseStore } from "../utils/response-store.js";
6
+ import { log, logError } from "../utils/log.js";
7
+ import { extractProjectName } from "../utils/paths.js";
8
+ function isValidStopEvent(data) {
9
+ if (typeof data !== "object" || data === null)
10
+ return false;
11
+ const obj = data;
12
+ return (typeof obj.session_id === "string" &&
13
+ typeof obj.transcript_path === "string" &&
14
+ typeof obj.cwd === "string");
15
+ }
16
+ export class HookHandler {
17
+ channel;
18
+ hookPort;
19
+ tunnelManager;
20
+ constructor(channel, hookPort, tunnelManager) {
21
+ this.channel = channel;
22
+ this.hookPort = hookPort;
23
+ this.tunnelManager = tunnelManager;
24
+ }
25
+ async handleStopEvent(event) {
26
+ if (!isValidStopEvent(event)) {
27
+ log(t("hook.invalidPayload"));
28
+ return;
29
+ }
30
+ log(t("hook.stopEventReceived", { sessionId: event.session_id, cwd: event.cwd }));
31
+ await new Promise((resolve) => setTimeout(resolve, TRANSCRIPT_SETTLE_DELAY_MS));
32
+ let summary = {
33
+ lastAssistantMessage: "",
34
+ durationMs: 0,
35
+ totalCostUSD: 0,
36
+ inputTokens: 0,
37
+ outputTokens: 0,
38
+ cacheCreationTokens: 0,
39
+ cacheReadTokens: 0,
40
+ };
41
+ try {
42
+ summary = parseTranscript(event.transcript_path);
43
+ }
44
+ catch (err) {
45
+ logError(t("hook.transcriptFailed"), err);
46
+ }
47
+ const gitChanges = collectGitChanges(event.cwd);
48
+ let durationMs = Math.max(0, summary.durationMs);
49
+ if (durationMs === 0 && summary.lastAssistantMessage) {
50
+ durationMs = DEFAULT_FALLBACK_DURATION_MS;
51
+ }
52
+ const data = {
53
+ projectName: extractProjectName(event.cwd),
54
+ responseSummary: summary.lastAssistantMessage,
55
+ durationMs,
56
+ gitChanges,
57
+ inputTokens: summary.inputTokens,
58
+ outputTokens: summary.outputTokens,
59
+ cacheCreationTokens: summary.cacheCreationTokens,
60
+ cacheReadTokens: summary.cacheReadTokens,
61
+ };
62
+ const responseUrl = this.buildResponseUrl(data);
63
+ this.channel.sendNotification(data, responseUrl).catch((err) => {
64
+ logError(t("hook.notificationFailed"), err);
65
+ });
66
+ }
67
+ buildResponseUrl(data) {
68
+ const id = responseStore.save(data);
69
+ const apiBase = this.tunnelManager.getPublicUrl() || `http://localhost:${this.hookPort}`;
70
+ const params = new URLSearchParams({
71
+ id,
72
+ api: apiBase,
73
+ p: data.projectName,
74
+ d: String(data.durationMs),
75
+ });
76
+ return `${MINI_APP_BASE_URL}/response/?${params.toString()}`;
77
+ }
78
+ }
79
+ //# sourceMappingURL=hook-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook-handler.js","sourceRoot":"","sources":["../../src/hook/hook-handler.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export declare class HookInstaller {
2
+ static isInstalled(): boolean;
3
+ static install(hookPort: number, hookSecret: string): void;
4
+ static uninstall(): void;
5
+ private static installScript;
6
+ private static removeScript;
7
+ private static removeFromSettings;
8
+ private static readSettings;
9
+ }