@kenkaiiii/ggcoder 4.3.242 → 4.4.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 (87) hide show
  1. package/dist/cli/shared.d.ts.map +1 -1
  2. package/dist/cli/shared.js +27 -5
  3. package/dist/cli/shared.js.map +1 -1
  4. package/dist/config.d.ts +3 -14
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +4 -17
  7. package/dist/config.js.map +1 -1
  8. package/dist/core/auth-storage.d.ts +1 -40
  9. package/dist/core/auth-storage.d.ts.map +1 -1
  10. package/dist/core/auth-storage.js +3 -200
  11. package/dist/core/auth-storage.js.map +1 -1
  12. package/dist/core/auto-update.d.ts +4 -26
  13. package/dist/core/auto-update.d.ts.map +1 -1
  14. package/dist/core/auto-update.js +12 -237
  15. package/dist/core/auto-update.js.map +1 -1
  16. package/dist/core/claude-code-version.d.ts +1 -9
  17. package/dist/core/claude-code-version.d.ts.map +1 -1
  18. package/dist/core/claude-code-version.js +2 -105
  19. package/dist/core/claude-code-version.js.map +1 -1
  20. package/dist/core/file-lock.d.ts +1 -5
  21. package/dist/core/file-lock.d.ts.map +1 -1
  22. package/dist/core/file-lock.js +2 -75
  23. package/dist/core/file-lock.js.map +1 -1
  24. package/dist/core/logger.d.ts +4 -17
  25. package/dist/core/logger.d.ts.map +1 -1
  26. package/dist/core/logger.js +21 -110
  27. package/dist/core/logger.js.map +1 -1
  28. package/dist/core/model-registry.d.ts +1 -54
  29. package/dist/core/model-registry.d.ts.map +1 -1
  30. package/dist/core/model-registry.js +4 -296
  31. package/dist/core/model-registry.js.map +1 -1
  32. package/dist/core/oauth/anthropic.d.ts +1 -3
  33. package/dist/core/oauth/anthropic.d.ts.map +1 -1
  34. package/dist/core/oauth/anthropic.js +2 -96
  35. package/dist/core/oauth/anthropic.js.map +1 -1
  36. package/dist/core/oauth/gemini.d.ts +1 -3
  37. package/dist/core/oauth/gemini.d.ts.map +1 -1
  38. package/dist/core/oauth/gemini.js +2 -379
  39. package/dist/core/oauth/gemini.js.map +1 -1
  40. package/dist/core/oauth/openai.d.ts +1 -3
  41. package/dist/core/oauth/openai.d.ts.map +1 -1
  42. package/dist/core/oauth/openai.js +2 -187
  43. package/dist/core/oauth/openai.js.map +1 -1
  44. package/dist/core/oauth/pkce.d.ts +1 -4
  45. package/dist/core/oauth/pkce.d.ts.map +1 -1
  46. package/dist/core/oauth/pkce.js +2 -16
  47. package/dist/core/oauth/pkce.js.map +1 -1
  48. package/dist/core/oauth/types.d.ts +1 -13
  49. package/dist/core/oauth/types.d.ts.map +1 -1
  50. package/dist/core/telegram.d.ts +1 -112
  51. package/dist/core/telegram.d.ts.map +1 -1
  52. package/dist/core/telegram.js +2 -251
  53. package/dist/core/telegram.js.map +1 -1
  54. package/dist/core/thinking-level.d.ts +1 -4
  55. package/dist/core/thinking-level.d.ts.map +1 -1
  56. package/dist/core/thinking-level.js +3 -58
  57. package/dist/core/thinking-level.js.map +1 -1
  58. package/dist/core/voice-transcriber.d.ts +1 -32
  59. package/dist/core/voice-transcriber.d.ts.map +1 -1
  60. package/dist/core/voice-transcriber.js +3 -112
  61. package/dist/core/voice-transcriber.js.map +1 -1
  62. package/dist/ui/App.d.ts.map +1 -1
  63. package/dist/ui/App.js +27 -5
  64. package/dist/ui/App.js.map +1 -1
  65. package/dist/utils/plan-steps.d.ts +18 -0
  66. package/dist/utils/plan-steps.d.ts.map +1 -1
  67. package/dist/utils/plan-steps.js +32 -0
  68. package/dist/utils/plan-steps.js.map +1 -1
  69. package/dist/utils/plan-steps.test.js +57 -1
  70. package/dist/utils/plan-steps.test.js.map +1 -1
  71. package/package.json +4 -3
  72. package/dist/core/model-registry.test.d.ts +0 -2
  73. package/dist/core/model-registry.test.d.ts.map +0 -1
  74. package/dist/core/model-registry.test.js +0 -95
  75. package/dist/core/model-registry.test.js.map +0 -1
  76. package/dist/core/oauth/gemini.test.d.ts +0 -2
  77. package/dist/core/oauth/gemini.test.d.ts.map +0 -1
  78. package/dist/core/oauth/gemini.test.js +0 -154
  79. package/dist/core/oauth/gemini.test.js.map +0 -1
  80. package/dist/core/thinking-level.test.d.ts +0 -2
  81. package/dist/core/thinking-level.test.d.ts.map +0 -1
  82. package/dist/core/thinking-level.test.js +0 -38
  83. package/dist/core/thinking-level.test.js.map +0 -1
  84. package/dist/core/voice-transcriber.test.d.ts +0 -2
  85. package/dist/core/voice-transcriber.test.d.ts.map +0 -1
  86. package/dist/core/voice-transcriber.test.js +0 -88
  87. package/dist/core/voice-transcriber.test.js.map +0 -1
@@ -1,188 +1,3 @@
1
- import http from "node:http";
2
- import crypto from "node:crypto";
3
- import { generatePKCE } from "./pkce.js";
4
- const CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
5
- const AUTHORIZE_URL = "https://auth.openai.com/oauth/authorize";
6
- const TOKEN_URL = "https://auth.openai.com/oauth/token";
7
- const REDIRECT_URI = "http://localhost:1455/auth/callback";
8
- const SCOPE = "openid profile email offline_access api.connectors.read api.connectors.invoke";
9
- const JWT_CLAIM_PATH = "https://api.openai.com/auth";
10
- export async function loginOpenAI(callbacks) {
11
- const { verifier, challenge } = await generatePKCE();
12
- const state = crypto.randomBytes(16).toString("hex");
13
- const url = new URL(AUTHORIZE_URL);
14
- url.searchParams.set("response_type", "code");
15
- url.searchParams.set("client_id", CLIENT_ID);
16
- url.searchParams.set("redirect_uri", REDIRECT_URI);
17
- url.searchParams.set("scope", SCOPE);
18
- url.searchParams.set("code_challenge", challenge);
19
- url.searchParams.set("code_challenge_method", "S256");
20
- url.searchParams.set("state", state);
21
- url.searchParams.set("id_token_add_organizations", "true");
22
- url.searchParams.set("codex_cli_simplified_flow", "true");
23
- url.searchParams.set("originator", "ggcoder");
24
- let code;
25
- try {
26
- code = await loginWithServer(url.toString(), state, callbacks);
27
- }
28
- catch {
29
- // Fallback: manual code paste
30
- callbacks.onOpenUrl(url.toString());
31
- const raw = await callbacks.onPromptCode("Could not start local server. Paste the callback URL or code from the browser:");
32
- const parsed = parseAuthorizationInput(raw);
33
- if (!parsed.code) {
34
- throw new Error("No authorization code found in input.");
35
- }
36
- code = parsed.code;
37
- }
38
- const creds = await exchangeOpenAICode(code, verifier);
39
- const accountId = getAccountId(creds.accessToken);
40
- if (!accountId) {
41
- throw new Error("Failed to extract accountId from OpenAI token.");
42
- }
43
- creds.accountId = accountId;
44
- return creds;
45
- }
46
- function parseAuthorizationInput(input) {
47
- const value = input.trim();
48
- if (!value)
49
- return {};
50
- // Full URL
51
- try {
52
- const url = new URL(value);
53
- return {
54
- code: url.searchParams.get("code") ?? undefined,
55
- state: url.searchParams.get("state") ?? undefined,
56
- };
57
- }
58
- catch {
59
- // not a URL
60
- }
61
- // code#state
62
- if (value.includes("#")) {
63
- const [code, state] = value.split("#", 2);
64
- return { code, state };
65
- }
66
- // Query string with code=
67
- if (value.includes("code=")) {
68
- const params = new URLSearchParams(value);
69
- return {
70
- code: params.get("code") ?? undefined,
71
- state: params.get("state") ?? undefined,
72
- };
73
- }
74
- // Raw code
75
- return { code: value };
76
- }
77
- function decodeJwt(token) {
78
- try {
79
- const parts = token.split(".");
80
- if (parts.length !== 3)
81
- return null;
82
- const decoded = atob(parts[1]);
83
- return JSON.parse(decoded);
84
- }
85
- catch {
86
- return null;
87
- }
88
- }
89
- function getAccountId(accessToken) {
90
- const payload = decodeJwt(accessToken);
91
- const auth = payload?.[JWT_CLAIM_PATH];
92
- const accountId = auth?.chatgpt_account_id;
93
- return typeof accountId === "string" && accountId.length > 0 ? accountId : null;
94
- }
95
- async function loginWithServer(authUrl, expectedState, callbacks) {
96
- return new Promise((resolve, reject) => {
97
- let receivedCode = null;
98
- const server = http.createServer((req, res) => {
99
- const url = new URL(req.url || "", "http://localhost");
100
- if (url.pathname !== "/auth/callback") {
101
- res.statusCode = 404;
102
- res.end("Not found");
103
- return;
104
- }
105
- if (url.searchParams.get("state") !== expectedState) {
106
- res.statusCode = 400;
107
- res.end("State mismatch");
108
- return;
109
- }
110
- receivedCode = url.searchParams.get("code");
111
- res.writeHead(200, { "Content-Type": "text/html" });
112
- res.end("<html><body><h1>Login successful!</h1><p>You can close this tab.</p></body></html>");
113
- server.close();
114
- });
115
- server.on("error", (err) => {
116
- reject(err);
117
- });
118
- server.listen(1455, "127.0.0.1", () => {
119
- callbacks.onOpenUrl(authUrl);
120
- callbacks.onStatus("Waiting for browser callback...");
121
- });
122
- const timeout = setTimeout(() => {
123
- if (!receivedCode) {
124
- server.close();
125
- }
126
- }, 120_000);
127
- timeout.unref();
128
- server.on("close", () => {
129
- clearTimeout(timeout);
130
- if (receivedCode) {
131
- resolve(receivedCode);
132
- }
133
- else {
134
- reject(new Error("Server closed without receiving code"));
135
- }
136
- });
137
- });
138
- }
139
- async function exchangeOpenAICode(code, verifier) {
140
- const response = await fetch(TOKEN_URL, {
141
- method: "POST",
142
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
143
- body: new URLSearchParams({
144
- grant_type: "authorization_code",
145
- client_id: CLIENT_ID,
146
- code,
147
- redirect_uri: REDIRECT_URI,
148
- code_verifier: verifier,
149
- }),
150
- });
151
- if (!response.ok) {
152
- const text = await response.text();
153
- throw new Error(`OpenAI token exchange failed (${response.status}): ${text}`);
154
- }
155
- const data = (await response.json());
156
- return {
157
- accessToken: data.access_token,
158
- refreshToken: data.refresh_token,
159
- expiresAt: Date.now() + data.expires_in * 1000,
160
- };
161
- }
162
- export async function refreshOpenAIToken(refreshToken) {
163
- const response = await fetch(TOKEN_URL, {
164
- method: "POST",
165
- headers: { "Content-Type": "application/x-www-form-urlencoded" },
166
- body: new URLSearchParams({
167
- grant_type: "refresh_token",
168
- refresh_token: refreshToken,
169
- client_id: CLIENT_ID,
170
- }),
171
- });
172
- if (!response.ok) {
173
- const text = await response.text();
174
- throw new Error(`OpenAI token refresh failed (${response.status}): ${text}`);
175
- }
176
- const data = (await response.json());
177
- const creds = {
178
- accessToken: data.access_token,
179
- refreshToken: data.refresh_token,
180
- expiresAt: Date.now() + data.expires_in * 1000,
181
- };
182
- const accountId = getAccountId(creds.accessToken);
183
- if (accountId) {
184
- creds.accountId = accountId;
185
- }
186
- return creds;
187
- }
1
+ // Moved to @kenkaiiii/gg-core.
2
+ export { loginOpenAI, refreshOpenAIToken } from "@kenkaiiii/gg-core";
188
3
  //# sourceMappingURL=openai.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/core/oauth/openai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/core/oauth/openai.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,5 +1,2 @@
1
- export declare function generatePKCE(): Promise<{
2
- verifier: string;
3
- challenge: string;
4
- }>;
1
+ export { generatePKCE } from "@kenkaiiii/gg-core";
5
2
  //# sourceMappingURL=pkce.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../../src/core/oauth/pkce.ts"],"names":[],"mappings":"AAQA,wBAAsB,YAAY,IAAI,OAAO,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,CAAC,CAUrF"}
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../../src/core/oauth/pkce.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,17 +1,3 @@
1
- function base64urlEncode(bytes) {
2
- let binary = "";
3
- for (const byte of bytes) {
4
- binary += String.fromCharCode(byte);
5
- }
6
- return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
7
- }
8
- export async function generatePKCE() {
9
- const verifierBytes = new Uint8Array(32);
10
- crypto.getRandomValues(verifierBytes);
11
- const verifier = base64urlEncode(verifierBytes);
12
- const data = new TextEncoder().encode(verifier);
13
- const hashBuffer = await crypto.subtle.digest("SHA-256", data);
14
- const challenge = base64urlEncode(new Uint8Array(hashBuffer));
15
- return { verifier, challenge };
16
- }
1
+ // Moved to @kenkaiiii/gg-core.
2
+ export { generatePKCE } from "@kenkaiiii/gg-core";
17
3
  //# sourceMappingURL=pkce.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../../src/core/oauth/pkce.ts"],"names":[],"mappings":"AAAA,SAAS,eAAe,CAAC,KAAiB;IACxC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,aAAa,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,eAAe,CAAC,aAAa,CAAC,CAAC;IAEhD,MAAM,IAAI,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,UAAU,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/D,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;IAE9D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
1
+ {"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../../src/core/oauth/pkce.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,14 +1,2 @@
1
- export interface OAuthCredentials {
2
- accessToken: string;
3
- refreshToken: string;
4
- expiresAt: number;
5
- accountId?: string;
6
- projectId?: string;
7
- baseUrl?: string;
8
- }
9
- export interface OAuthLoginCallbacks {
10
- onOpenUrl: (url: string) => void;
11
- onPromptCode: (message: string) => Promise<string>;
12
- onStatus: (message: string) => void;
13
- }
1
+ export type { OAuthCredentials, OAuthLoginCallbacks } from "@kenkaiiii/gg-core";
14
2
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/oauth/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/core/oauth/types.ts"],"names":[],"mappings":"AAEA,YAAY,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
@@ -1,113 +1,2 @@
1
- /**
2
- * Minimal Telegram Bot API client using raw fetch().
3
- * Supports long polling, markdown messages, inline keyboards, and message splitting.
4
- */
5
- export interface TelegramConfig {
6
- botToken: string;
7
- /** Only accept messages from this Telegram user ID. */
8
- allowedUserId: number;
9
- }
10
- export interface TelegramUpdate {
11
- update_id: number;
12
- message?: {
13
- message_id: number;
14
- from: {
15
- id: number;
16
- first_name: string;
17
- };
18
- chat: {
19
- id: number;
20
- type: string;
21
- title?: string;
22
- };
23
- text?: string;
24
- voice?: {
25
- file_id: string;
26
- duration: number;
27
- mime_type?: string;
28
- file_size?: number;
29
- };
30
- };
31
- callback_query?: {
32
- id: string;
33
- from: {
34
- id: number;
35
- };
36
- message: {
37
- chat: {
38
- id: number;
39
- };
40
- };
41
- data: string;
42
- };
43
- my_chat_member?: {
44
- chat: {
45
- id: number;
46
- type: string;
47
- title?: string;
48
- };
49
- from: {
50
- id: number;
51
- };
52
- new_chat_member: {
53
- status: string;
54
- };
55
- };
56
- }
57
- export interface InlineButton {
58
- text: string;
59
- callback_data: string;
60
- }
61
- /** Incoming message with chat context. */
62
- export interface TelegramMessage {
63
- text: string;
64
- chatId: number;
65
- chatType: "private" | "group" | "supergroup" | "channel";
66
- chatTitle?: string;
67
- }
68
- /** Incoming voice note with chat context. */
69
- export interface TelegramVoiceMessage {
70
- fileId: string;
71
- duration: number;
72
- chatId: number;
73
- chatType: "private" | "group" | "supergroup" | "channel";
74
- chatTitle?: string;
75
- }
76
- export declare class TelegramBot {
77
- private token;
78
- private allowedUserId;
79
- private offset;
80
- private running;
81
- private onMessage;
82
- private onVoiceMessage;
83
- private onCallback;
84
- private onBotAdded;
85
- private onBotRemoved;
86
- constructor(config: TelegramConfig);
87
- /** Register handler for incoming text messages. */
88
- onText(handler: (msg: TelegramMessage) => void): void;
89
- /** Register handler for incoming voice notes. */
90
- onVoice(handler: (msg: TelegramVoiceMessage) => void): void;
91
- /** Register handler for inline keyboard button presses. */
92
- onCallbackQuery(handler: (data: string, chatId: number) => void): void;
93
- /** Register handler for when the bot is added to a group. */
94
- onAddedToGroup(handler: (chatId: number, chatTitle?: string) => void): void;
95
- /** Register handler for when the bot is removed from a group. */
96
- onRemovedFromGroup(handler: (chatId: number) => void): void;
97
- /** Start long polling. Blocks until stop() is called. */
98
- start(): Promise<void>;
99
- /** Stop long polling. */
100
- stop(): void;
101
- /** Send a text message to a specific chat. Converts markdown and splits long messages. */
102
- send(chatId: number, text: string, buttons?: InlineButton[][]): Promise<void>;
103
- /** Send a plain text message (no markdown parsing) to a specific chat. */
104
- sendPlain(chatId: number, text: string): Promise<void>;
105
- /** Send a typing indicator to a specific chat. */
106
- sendTyping(chatId: number): Promise<void>;
107
- /** Get a direct download URL for a Telegram file. */
108
- getFileUrl(fileId: string): Promise<string>;
109
- private getUpdates;
110
- private handleUpdate;
111
- private apiCall;
112
- }
1
+ export { TelegramBot, type TelegramConfig, type TelegramUpdate, type InlineButton, type TelegramMessage, type TelegramVoiceMessage, } from "@kenkaiiii/gg-core";
113
2
  //# sourceMappingURL=telegram.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../src/core/telegram.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"telegram.d.ts","sourceRoot":"","sources":["../../src/core/telegram.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,eAAe,EACpB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAC"}
@@ -1,252 +1,3 @@
1
- /**
2
- * Minimal Telegram Bot API client using raw fetch().
3
- * Supports long polling, markdown messages, inline keyboards, and message splitting.
4
- */
5
- const TELEGRAM_API = "https://api.telegram.org";
6
- const MAX_MESSAGE_LENGTH = 4096;
7
- export class TelegramBot {
8
- token;
9
- allowedUserId;
10
- offset = 0;
11
- running = false;
12
- onMessage = null;
13
- onVoiceMessage = null;
14
- onCallback = null;
15
- onBotAdded = null;
16
- onBotRemoved = null;
17
- constructor(config) {
18
- this.token = config.botToken;
19
- this.allowedUserId = config.allowedUserId;
20
- }
21
- /** Register handler for incoming text messages. */
22
- onText(handler) {
23
- this.onMessage = handler;
24
- }
25
- /** Register handler for incoming voice notes. */
26
- onVoice(handler) {
27
- this.onVoiceMessage = handler;
28
- }
29
- /** Register handler for inline keyboard button presses. */
30
- onCallbackQuery(handler) {
31
- this.onCallback = handler;
32
- }
33
- /** Register handler for when the bot is added to a group. */
34
- onAddedToGroup(handler) {
35
- this.onBotAdded = handler;
36
- }
37
- /** Register handler for when the bot is removed from a group. */
38
- onRemovedFromGroup(handler) {
39
- this.onBotRemoved = handler;
40
- }
41
- /** Start long polling. Blocks until stop() is called. */
42
- async start() {
43
- this.running = true;
44
- // Verify bot token works
45
- const me = await this.apiCall("getMe");
46
- if (!me.ok) {
47
- throw new Error(`Invalid bot token: ${JSON.stringify(me)}`);
48
- }
49
- while (this.running) {
50
- try {
51
- const updates = await this.getUpdates();
52
- for (const update of updates) {
53
- await this.handleUpdate(update);
54
- }
55
- }
56
- catch (err) {
57
- if (!this.running)
58
- break;
59
- console.error(`[telegram] Poll error: ${err instanceof Error ? err.message : err}`);
60
- await sleep(3000);
61
- }
62
- }
63
- }
64
- /** Stop long polling. */
65
- stop() {
66
- this.running = false;
67
- }
68
- /** Send a text message to a specific chat. Converts markdown and splits long messages. */
69
- async send(chatId, text, buttons) {
70
- const converted = toTelegramMarkdown(text);
71
- const chunks = splitMessage(converted);
72
- for (let i = 0; i < chunks.length; i++) {
73
- const isLast = i === chunks.length - 1;
74
- const replyMarkup = isLast && buttons
75
- ? {
76
- inline_keyboard: buttons.map((row) => row.map((b) => ({ text: b.text, callback_data: b.callback_data }))),
77
- }
78
- : undefined;
79
- await this.apiCall("sendMessage", {
80
- chat_id: chatId,
81
- text: chunks[i],
82
- parse_mode: "Markdown",
83
- ...(replyMarkup ? { reply_markup: replyMarkup } : {}),
84
- });
85
- }
86
- }
87
- /** Send a plain text message (no markdown parsing) to a specific chat. */
88
- async sendPlain(chatId, text) {
89
- const chunks = splitMessage(text);
90
- for (const chunk of chunks) {
91
- await this.apiCall("sendMessage", {
92
- chat_id: chatId,
93
- text: chunk,
94
- });
95
- }
96
- }
97
- /** Send a typing indicator to a specific chat. */
98
- async sendTyping(chatId) {
99
- await this.apiCall("sendChatAction", {
100
- chat_id: chatId,
101
- action: "typing",
102
- });
103
- }
104
- /** Get a direct download URL for a Telegram file. */
105
- async getFileUrl(fileId) {
106
- const result = await this.apiCall("getFile", { file_id: fileId });
107
- if (!result.ok)
108
- throw new Error(`Failed to get file: ${JSON.stringify(result)}`);
109
- const filePath = result.result.file_path;
110
- return `${TELEGRAM_API}/file/bot${this.token}/${filePath}`;
111
- }
112
- // ── Private ───────────────────────────────────────────
113
- async getUpdates() {
114
- const result = await this.apiCall("getUpdates", {
115
- offset: this.offset,
116
- timeout: 30,
117
- allowed_updates: ["message", "callback_query", "my_chat_member"],
118
- });
119
- if (!result.ok || !Array.isArray(result.result))
120
- return [];
121
- const updates = result.result;
122
- if (updates.length > 0) {
123
- this.offset = updates[updates.length - 1].update_id + 1;
124
- }
125
- return updates;
126
- }
127
- async handleUpdate(update) {
128
- if (update.message) {
129
- const msg = update.message;
130
- // Auth check
131
- if (msg.from.id !== this.allowedUserId) {
132
- return;
133
- }
134
- if (msg.text && this.onMessage) {
135
- this.onMessage({
136
- text: msg.text,
137
- chatId: msg.chat.id,
138
- chatType: msg.chat.type,
139
- chatTitle: msg.chat.title,
140
- });
141
- }
142
- else if (msg.voice && this.onVoiceMessage) {
143
- this.onVoiceMessage({
144
- fileId: msg.voice.file_id,
145
- duration: msg.voice.duration,
146
- chatId: msg.chat.id,
147
- chatType: msg.chat.type,
148
- chatTitle: msg.chat.title,
149
- });
150
- }
151
- }
152
- // Bot membership changed in a group
153
- if (update.my_chat_member) {
154
- const member = update.my_chat_member;
155
- const status = member.new_chat_member.status;
156
- if ((status === "member" || status === "administrator") && this.onBotAdded) {
157
- this.onBotAdded(member.chat.id, member.chat.title);
158
- }
159
- else if ((status === "left" || status === "kicked") && this.onBotRemoved) {
160
- this.onBotRemoved(member.chat.id);
161
- }
162
- }
163
- if (update.callback_query) {
164
- const cb = update.callback_query;
165
- if (cb.from.id !== this.allowedUserId)
166
- return;
167
- await this.apiCall("answerCallbackQuery", { callback_query_id: cb.id });
168
- if (cb.data && this.onCallback) {
169
- this.onCallback(cb.data, cb.message.chat.id);
170
- }
171
- }
172
- }
173
- async apiCall(method, body) {
174
- const url = `${TELEGRAM_API}/bot${this.token}/${method}`;
175
- const response = await fetch(url, {
176
- method: "POST",
177
- headers: { "Content-Type": "application/json" },
178
- body: body ? JSON.stringify(body) : undefined,
179
- });
180
- if (!response.ok) {
181
- return { ok: false };
182
- }
183
- return response.json();
184
- }
185
- }
186
- // ── Markdown Conversion ──────────────────────────────────
187
- /**
188
- * Convert GitHub-flavored markdown to Telegram-compatible Markdown.
189
- *
190
- * Telegram supports: *bold*, _italic_, `code`, ```pre```, [link](url)
191
- * Does NOT support: headings, horizontal rules, tables, HTML tags, images
192
- */
193
- function toTelegramMarkdown(text) {
194
- const lines = text.split("\n");
195
- const result = [];
196
- let inCodeBlock = false;
197
- for (const line of lines) {
198
- if (line.trimStart().startsWith("```")) {
199
- inCodeBlock = !inCodeBlock;
200
- result.push(line);
201
- continue;
202
- }
203
- if (inCodeBlock) {
204
- result.push(line);
205
- continue;
206
- }
207
- let transformed = line;
208
- // Headings → bold text
209
- const headingMatch = transformed.match(/^(#{1,6})\s+(.+)$/);
210
- if (headingMatch) {
211
- transformed = `*${headingMatch[2]}*`;
212
- result.push(transformed);
213
- continue;
214
- }
215
- // Horizontal rules → empty line
216
- if (/^(-{3,}|_{3,}|\*{3,})$/.test(transformed.trim())) {
217
- result.push("");
218
- continue;
219
- }
220
- // **bold** → *bold*
221
- transformed = transformed.replace(/\*\*(.+?)\*\*/g, "*$1*");
222
- result.push(transformed);
223
- }
224
- return result.join("\n");
225
- }
226
- // ── Helpers ───────────────────────────────────────────────
227
- function splitMessage(text) {
228
- if (text.length <= MAX_MESSAGE_LENGTH)
229
- return [text];
230
- const chunks = [];
231
- let remaining = text;
232
- while (remaining.length > 0) {
233
- if (remaining.length <= MAX_MESSAGE_LENGTH) {
234
- chunks.push(remaining);
235
- break;
236
- }
237
- let splitAt = remaining.lastIndexOf("\n", MAX_MESSAGE_LENGTH);
238
- if (splitAt === -1 || splitAt < MAX_MESSAGE_LENGTH * 0.5) {
239
- splitAt = remaining.lastIndexOf(" ", MAX_MESSAGE_LENGTH);
240
- }
241
- if (splitAt === -1 || splitAt < MAX_MESSAGE_LENGTH * 0.5) {
242
- splitAt = MAX_MESSAGE_LENGTH;
243
- }
244
- chunks.push(remaining.slice(0, splitAt));
245
- remaining = remaining.slice(splitAt).trimStart();
246
- }
247
- return chunks;
248
- }
249
- function sleep(ms) {
250
- return new Promise((r) => setTimeout(r, ms));
251
- }
1
+ // Moved to @kenkaiiii/gg-core. Shim keeps `../core/telegram.js` imports working.
2
+ export { TelegramBot, } from "@kenkaiiii/gg-core";
252
3
  //# sourceMappingURL=telegram.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/core/telegram.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/core/telegram.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,OAAO,EACL,WAAW,GAMZ,MAAM,oBAAoB,CAAC"}