@kenkaiiii/ggcoder 4.2.27 → 4.2.29
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/cli.js +212 -0
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +18 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +68 -3
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +47 -12
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/compaction/token-estimator.d.ts +5 -0
- package/dist/core/compaction/token-estimator.d.ts.map +1 -1
- package/dist/core/compaction/token-estimator.js +41 -2
- package/dist/core/compaction/token-estimator.js.map +1 -1
- package/dist/core/compaction/token-estimator.test.js +43 -21
- package/dist/core/compaction/token-estimator.test.js.map +1 -1
- package/dist/core/event-bus.d.ts +4 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/file-lock.d.ts +6 -0
- package/dist/core/file-lock.d.ts.map +1 -0
- package/dist/core/file-lock.js +76 -0
- package/dist/core/file-lock.js.map +1 -0
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/session-manager.d.ts +25 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +46 -2
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts +4 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +22 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/telegram.d.ts +92 -0
- package/dist/core/telegram.d.ts.map +1 -0
- package/dist/core/telegram.js +217 -0
- package/dist/core/telegram.js.map +1 -0
- package/dist/modes/index.d.ts +1 -0
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -0
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/rpc-mode.d.ts +28 -0
- package/dist/modes/rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc-mode.js +145 -0
- package/dist/modes/rpc-mode.js.map +1 -0
- package/dist/modes/serve-mode.d.ts +20 -0
- package/dist/modes/serve-mode.d.ts.map +1 -0
- package/dist/modes/serve-mode.js +553 -0
- package/dist/modes/serve-mode.js.map +1 -0
- package/dist/tools/bash.d.ts +2 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +3 -3
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +2 -1
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +4 -4
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/grep.d.ts +2 -1
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +7 -8
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/index.d.ts +4 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +9 -6
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/ls.d.ts +2 -1
- package/dist/tools/ls.d.ts.map +1 -1
- package/dist/tools/ls.js +4 -4
- package/dist/tools/ls.js.map +1 -1
- package/dist/tools/operations.d.ts +39 -0
- package/dist/tools/operations.d.ts.map +1 -0
- package/dist/tools/operations.js +27 -0
- package/dist/tools/operations.js.map +1 -0
- package/dist/tools/read.d.ts +2 -1
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +4 -4
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/subagent.d.ts.map +1 -1
- package/dist/tools/subagent.js +41 -1
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/write.d.ts +2 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +4 -6
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +7 -20
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/components/AnimationContext.d.ts +22 -0
- package/dist/ui/components/AnimationContext.d.ts.map +1 -0
- package/dist/ui/components/AnimationContext.js +35 -0
- package/dist/ui/components/AnimationContext.js.map +1 -0
- package/dist/ui/components/CompactionNotice.d.ts.map +1 -1
- package/dist/ui/components/CompactionNotice.js +4 -8
- package/dist/ui/components/CompactionNotice.js.map +1 -1
- package/dist/ui/components/Footer.d.ts.map +1 -1
- package/dist/ui/components/Footer.js.map +1 -1
- package/dist/ui/components/InputArea.d.ts.map +1 -1
- package/dist/ui/components/InputArea.js +6 -22
- package/dist/ui/components/InputArea.js.map +1 -1
- package/dist/ui/components/Spinner.d.ts.map +1 -1
- package/dist/ui/components/Spinner.js +4 -8
- package/dist/ui/components/Spinner.js.map +1 -1
- package/dist/ui/components/StreamingArea.d.ts.map +1 -1
- package/dist/ui/components/StreamingArea.js +4 -2
- package/dist/ui/components/StreamingArea.js.map +1 -1
- package/dist/ui/components/SubAgentPanel.d.ts.map +1 -1
- package/dist/ui/components/SubAgentPanel.js +11 -12
- package/dist/ui/components/SubAgentPanel.js.map +1 -1
- package/dist/ui/components/ThinkingIndicator.d.ts.map +1 -1
- package/dist/ui/components/ThinkingIndicator.js +8 -33
- package/dist/ui/components/ThinkingIndicator.js.map +1 -1
- package/dist/ui/components/ToolExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolExecution.js +6 -23
- package/dist/ui/components/ToolExecution.js.map +1 -1
- package/dist/ui/components/ToolGroupExecution.d.ts.map +1 -1
- package/dist/ui/components/ToolGroupExecution.js +6 -2
- package/dist/ui/components/ToolGroupExecution.js.map +1 -1
- package/dist/ui/components/index.d.ts +1 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +1 -0
- package/dist/ui/components/index.js.map +1 -1
- package/dist/ui/hooks/useTerminalSize.d.ts.map +1 -1
- package/dist/ui/hooks/useTerminalSize.js +4 -2
- package/dist/ui/hooks/useTerminalSize.js.map +1 -1
- package/dist/ui/hooks/useTerminalTitle.d.ts.map +1 -1
- package/dist/ui/hooks/useTerminalTitle.js +5 -13
- package/dist/ui/hooks/useTerminalTitle.js.map +1 -1
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +19 -10
- package/dist/ui/render.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,553 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { AgentSession } from "../core/agent-session.js";
|
|
4
|
+
import { TelegramBot } from "../core/telegram.js";
|
|
5
|
+
import chalk from "chalk";
|
|
6
|
+
import { formatUserError } from "../utils/error-handler.js";
|
|
7
|
+
import { log, closeLogger } from "../core/logger.js";
|
|
8
|
+
import { getAppPaths } from "../config.js";
|
|
9
|
+
import { MODELS, getContextWindow } from "../core/model-registry.js";
|
|
10
|
+
import { estimateConversationTokens } from "../core/compaction/token-estimator.js";
|
|
11
|
+
function getConfigPath() {
|
|
12
|
+
return path.join(getAppPaths().agentDir, "serve.json");
|
|
13
|
+
}
|
|
14
|
+
async function loadConfig() {
|
|
15
|
+
try {
|
|
16
|
+
const content = await fs.readFile(getConfigPath(), "utf-8");
|
|
17
|
+
const raw = JSON.parse(content);
|
|
18
|
+
return { chats: raw.chats ?? {} };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { chats: {} };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function saveConfig(config) {
|
|
25
|
+
const configPath = getConfigPath();
|
|
26
|
+
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
|
27
|
+
await fs.writeFile(configPath, JSON.stringify(config, null, 2), "utf-8");
|
|
28
|
+
}
|
|
29
|
+
// ── Project Discovery ──────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Scan ~/.gg/sessions/ to find all project directories that have sessions.
|
|
32
|
+
* Returns decoded absolute paths sorted alphabetically.
|
|
33
|
+
*/
|
|
34
|
+
async function discoverProjects() {
|
|
35
|
+
const sessionsDir = getAppPaths().sessionsDir;
|
|
36
|
+
try {
|
|
37
|
+
const entries = await fs.readdir(sessionsDir);
|
|
38
|
+
const projects = [];
|
|
39
|
+
for (const entry of entries) {
|
|
40
|
+
// Decode: reverse of encodeCwd (replace _ back to /)
|
|
41
|
+
// encodeCwd: replace /\\ with _, remove :, strip leading _
|
|
42
|
+
// Decoding is imperfect but works for display — we reconstruct the path
|
|
43
|
+
const decoded = "/" + entry.replace(/_/g, "/");
|
|
44
|
+
// Verify the decoded path has session files
|
|
45
|
+
const dir = path.join(sessionsDir, entry);
|
|
46
|
+
const stat = await fs.stat(dir);
|
|
47
|
+
if (stat.isDirectory()) {
|
|
48
|
+
const files = await fs.readdir(dir);
|
|
49
|
+
if (files.some((f) => f.endsWith(".jsonl"))) {
|
|
50
|
+
projects.push(decoded);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return projects.sort();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return [];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Serve mode: run ggcoder controlled via Telegram.
|
|
62
|
+
*
|
|
63
|
+
* - DMs to bot → default project (CWD where serve was started)
|
|
64
|
+
* - Groups → linked projects via /link <path>
|
|
65
|
+
* - Each chat gets its own AgentSession, tools, context
|
|
66
|
+
*/
|
|
67
|
+
export async function runServeMode(options) {
|
|
68
|
+
const bot = new TelegramBot({
|
|
69
|
+
botToken: options.telegram.botToken,
|
|
70
|
+
allowedUserId: options.telegram.userId,
|
|
71
|
+
});
|
|
72
|
+
const config = await loadConfig();
|
|
73
|
+
const chatStates = new Map();
|
|
74
|
+
/** Chats waiting for a number selection after /link showed the project list. */
|
|
75
|
+
const pendingLinkSelections = new Map();
|
|
76
|
+
// ── Session lifecycle ──────────────────────────────────
|
|
77
|
+
async function getOrCreateChat(chatId, cwd) {
|
|
78
|
+
const existing = chatStates.get(chatId);
|
|
79
|
+
if (existing)
|
|
80
|
+
return existing;
|
|
81
|
+
const ac = new AbortController();
|
|
82
|
+
const session = new AgentSession({
|
|
83
|
+
provider: options.provider,
|
|
84
|
+
model: options.model,
|
|
85
|
+
cwd,
|
|
86
|
+
thinkingLevel: options.thinkingLevel,
|
|
87
|
+
signal: ac.signal,
|
|
88
|
+
});
|
|
89
|
+
await session.initialize();
|
|
90
|
+
log("INFO", "serve", `Session initialized for chat ${chatId}`, { cwd });
|
|
91
|
+
const state = {
|
|
92
|
+
chatId,
|
|
93
|
+
cwd,
|
|
94
|
+
session,
|
|
95
|
+
ac,
|
|
96
|
+
textBuffer: "",
|
|
97
|
+
activeTools: new Map(),
|
|
98
|
+
isProcessing: false,
|
|
99
|
+
typingInterval: null,
|
|
100
|
+
};
|
|
101
|
+
chatStates.set(chatId, state);
|
|
102
|
+
wireSessionEvents(state);
|
|
103
|
+
return state;
|
|
104
|
+
}
|
|
105
|
+
function resolveProjectPath(chatId) {
|
|
106
|
+
return config.chats[String(chatId)] ?? options.cwd;
|
|
107
|
+
}
|
|
108
|
+
// ── Per-chat typing ────────────────────────────────────
|
|
109
|
+
function startTyping(state) {
|
|
110
|
+
if (state.typingInterval)
|
|
111
|
+
return;
|
|
112
|
+
bot.sendTyping(state.chatId).catch(() => { });
|
|
113
|
+
state.typingInterval = setInterval(() => {
|
|
114
|
+
bot.sendTyping(state.chatId).catch(() => { });
|
|
115
|
+
}, 4000);
|
|
116
|
+
}
|
|
117
|
+
function stopTyping(state) {
|
|
118
|
+
if (state.typingInterval) {
|
|
119
|
+
clearInterval(state.typingInterval);
|
|
120
|
+
state.typingInterval = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function flushText(state) {
|
|
124
|
+
const text = state.textBuffer.trim();
|
|
125
|
+
state.textBuffer = "";
|
|
126
|
+
if (text) {
|
|
127
|
+
return bot.send(state.chatId, text);
|
|
128
|
+
}
|
|
129
|
+
return Promise.resolve();
|
|
130
|
+
}
|
|
131
|
+
// ── Agent → Telegram bridge (per chat) ─────────────────
|
|
132
|
+
function wireSessionEvents(state) {
|
|
133
|
+
const { session, chatId } = state;
|
|
134
|
+
session.eventBus.on("text_delta", ({ text }) => {
|
|
135
|
+
state.textBuffer += text;
|
|
136
|
+
});
|
|
137
|
+
session.eventBus.on("thinking_delta", () => {
|
|
138
|
+
// Thinking not displayed in Telegram
|
|
139
|
+
});
|
|
140
|
+
session.eventBus.on("tool_call_start", ({ toolCallId, name, args }) => {
|
|
141
|
+
state.activeTools.set(toolCallId, { name, startTime: Date.now(), args });
|
|
142
|
+
});
|
|
143
|
+
session.eventBus.on("tool_call_end", ({ toolCallId, isError, durationMs }) => {
|
|
144
|
+
const tool = state.activeTools.get(toolCallId);
|
|
145
|
+
state.activeTools.delete(toolCallId);
|
|
146
|
+
if (tool) {
|
|
147
|
+
const icon = isError ? "✗" : "✓";
|
|
148
|
+
const argsStr = formatArgs(tool.args);
|
|
149
|
+
bot
|
|
150
|
+
.send(chatId, `${icon} \`${tool.name}\` ${argsStr} _${formatDuration(durationMs)}_`)
|
|
151
|
+
.catch(() => { });
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
session.eventBus.on("turn_end", () => {
|
|
155
|
+
// Don't flush — let agent_done send response + summary as one message
|
|
156
|
+
});
|
|
157
|
+
session.eventBus.on("agent_done", ({ totalTurns, totalUsage }) => {
|
|
158
|
+
stopTyping(state);
|
|
159
|
+
state.isProcessing = false;
|
|
160
|
+
const total = totalUsage.inputTokens + totalUsage.outputTokens;
|
|
161
|
+
const tokens = total >= 1000 ? `${(total / 1000).toFixed(1)}k` : `${total}`;
|
|
162
|
+
const turns = totalTurns === 1 ? "1 turn" : `${totalTurns} turns`;
|
|
163
|
+
// Context usage percentage
|
|
164
|
+
const modelId = session.getState().model;
|
|
165
|
+
const contextWindow = getContextWindow(modelId);
|
|
166
|
+
const contextTokens = estimateConversationTokens(session.getMessages());
|
|
167
|
+
const contextPctRaw = (contextTokens / contextWindow) * 100;
|
|
168
|
+
const contextStr = contextPctRaw > 0 && contextPctRaw < 1 ? "<1" : String(Math.round(contextPctRaw));
|
|
169
|
+
state.textBuffer += `\n\n_${tokens} tokens · ${turns} · ${contextStr}% context_`;
|
|
170
|
+
flushText(state).catch(() => { });
|
|
171
|
+
});
|
|
172
|
+
session.eventBus.on("error", ({ error }) => {
|
|
173
|
+
stopTyping(state);
|
|
174
|
+
state.isProcessing = false;
|
|
175
|
+
bot.send(chatId, `✗ *Error*\n${error.message}`).catch(() => { });
|
|
176
|
+
});
|
|
177
|
+
session.eventBus.on("compaction_end", ({ originalCount, newCount }) => {
|
|
178
|
+
bot.send(chatId, `✓ *Compacted* — ${originalCount} → ${newCount} messages`).catch(() => { });
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
// ── Telegram command handlers ──────────────────────────
|
|
182
|
+
const TELEGRAM_COMMANDS = new Set([
|
|
183
|
+
"help",
|
|
184
|
+
"status",
|
|
185
|
+
"cancel",
|
|
186
|
+
"link",
|
|
187
|
+
"unlink",
|
|
188
|
+
"start",
|
|
189
|
+
"m",
|
|
190
|
+
"model",
|
|
191
|
+
]);
|
|
192
|
+
/** Chats waiting for a model number selection. */
|
|
193
|
+
const pendingModelSelections = new Map();
|
|
194
|
+
function buildHelpText(chatId) {
|
|
195
|
+
const projectPath = resolveProjectPath(chatId);
|
|
196
|
+
const linked = config.chats[String(chatId)];
|
|
197
|
+
const state = chatStates.get(chatId);
|
|
198
|
+
const currentModel = state?.session.getState().model ?? options.model;
|
|
199
|
+
const modelInfo = MODELS.find((m) => m.id === currentModel);
|
|
200
|
+
let text = `*ggcoder* — remote coding agent\n\n`;
|
|
201
|
+
text += `Project: \`${path.basename(projectPath)}\`\n`;
|
|
202
|
+
text += `Model: *${modelInfo?.name ?? currentModel}*\n\n`;
|
|
203
|
+
text += `*Commands*\n`;
|
|
204
|
+
text += `/m — switch model\n`;
|
|
205
|
+
text += `/link — switch project\n`;
|
|
206
|
+
text += `/status — current state\n`;
|
|
207
|
+
text += `/compact — compress context\n`;
|
|
208
|
+
text += `/branch — fork conversation\n`;
|
|
209
|
+
text += `/new — fresh session\n`;
|
|
210
|
+
text += `/cancel — abort current task\n`;
|
|
211
|
+
text += `/help — this message\n`;
|
|
212
|
+
if (!linked) {
|
|
213
|
+
text += `\n_Tip: send /link to connect this chat to a specific project._`;
|
|
214
|
+
}
|
|
215
|
+
text += `\n\nSend any message to start coding.`;
|
|
216
|
+
return text;
|
|
217
|
+
}
|
|
218
|
+
async function linkChat(chatId, projectPath, chatTitle) {
|
|
219
|
+
config.chats[String(chatId)] = projectPath;
|
|
220
|
+
await saveConfig(config);
|
|
221
|
+
// Dispose existing session if switching projects
|
|
222
|
+
const existing = chatStates.get(chatId);
|
|
223
|
+
if (existing && existing.cwd !== projectPath) {
|
|
224
|
+
await existing.session.dispose();
|
|
225
|
+
chatStates.delete(chatId);
|
|
226
|
+
}
|
|
227
|
+
const name = chatTitle ?? path.basename(projectPath);
|
|
228
|
+
await bot.send(chatId, `Linked *${name}* → \`${projectPath}\``);
|
|
229
|
+
}
|
|
230
|
+
bot.onAddedToGroup(async (chatId, chatTitle) => {
|
|
231
|
+
const groupName = chatTitle ?? "this group";
|
|
232
|
+
await bot.send(chatId, `*ggcoder* joined *${groupName}*\n\n` +
|
|
233
|
+
`Send /link to connect to a project\n` +
|
|
234
|
+
`Send /help for all commands`);
|
|
235
|
+
log("INFO", "serve", `Bot added to group ${chatId}`, { title: chatTitle ?? "unknown" });
|
|
236
|
+
});
|
|
237
|
+
bot.onRemovedFromGroup(async (chatId) => {
|
|
238
|
+
// Clean up config and session when bot is removed from a group
|
|
239
|
+
const existing = chatStates.get(chatId);
|
|
240
|
+
if (existing) {
|
|
241
|
+
stopTyping(existing);
|
|
242
|
+
await existing.session.dispose();
|
|
243
|
+
chatStates.delete(chatId);
|
|
244
|
+
}
|
|
245
|
+
if (config.chats[String(chatId)]) {
|
|
246
|
+
delete config.chats[String(chatId)];
|
|
247
|
+
await saveConfig(config);
|
|
248
|
+
}
|
|
249
|
+
log("INFO", "serve", `Bot removed from group ${chatId} — unlinked`);
|
|
250
|
+
});
|
|
251
|
+
bot.onText(async (msg) => {
|
|
252
|
+
const { text, chatId } = msg;
|
|
253
|
+
// Check for pending selections (user sent a number after /link or /m)
|
|
254
|
+
const pendingProjects = pendingLinkSelections.get(chatId);
|
|
255
|
+
if (pendingProjects) {
|
|
256
|
+
pendingLinkSelections.delete(chatId);
|
|
257
|
+
const num = parseInt(text.trim(), 10);
|
|
258
|
+
if (isNaN(num) || num < 1 || num > pendingProjects.length) {
|
|
259
|
+
await bot.send(chatId, "Invalid selection. Send /link to try again.");
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
const selected = pendingProjects[num - 1];
|
|
263
|
+
await linkChat(chatId, selected, msg.chatTitle);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const pendingModels = pendingModelSelections.get(chatId);
|
|
267
|
+
if (pendingModels) {
|
|
268
|
+
pendingModelSelections.delete(chatId);
|
|
269
|
+
const num = parseInt(text.trim(), 10);
|
|
270
|
+
if (isNaN(num) || num < 1 || num > pendingModels.length) {
|
|
271
|
+
await bot.send(chatId, "Invalid selection. Send /m to try again.");
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
const selected = pendingModels[num - 1];
|
|
275
|
+
const projectPath = resolveProjectPath(chatId);
|
|
276
|
+
const chatState = await getOrCreateChat(chatId, projectPath);
|
|
277
|
+
await chatState.session.switchModel(selected.provider, selected.id);
|
|
278
|
+
await bot.send(chatId, `Switched to *${selected.name}*`);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
if (!text.startsWith("/")) {
|
|
282
|
+
await handlePrompt(chatId, text);
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const parts = text.trim().split(/\s+/);
|
|
286
|
+
const cmd = parts[0].slice(1).toLowerCase().replace(/@\w+$/, ""); // strip /cmd@botname
|
|
287
|
+
const args = parts.slice(1).join(" ");
|
|
288
|
+
// ── Telegram-specific commands ──
|
|
289
|
+
if (cmd === "help") {
|
|
290
|
+
await bot.send(chatId, buildHelpText(chatId));
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
if (cmd === "status") {
|
|
294
|
+
const projectPath = resolveProjectPath(chatId);
|
|
295
|
+
const state = chatStates.get(chatId);
|
|
296
|
+
const linked = config.chats[String(chatId)];
|
|
297
|
+
const projectName = linked ? path.basename(projectPath) : "default";
|
|
298
|
+
if (!state) {
|
|
299
|
+
await bot.send(chatId, `*${projectName}*\n\n` +
|
|
300
|
+
`Path \`${projectPath}\`\n` +
|
|
301
|
+
`Session _not started_\n\n` +
|
|
302
|
+
`_Send a message to initialize._`);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
const sessionState = state.session.getState();
|
|
306
|
+
const modelInfo = MODELS.find((m) => m.id === sessionState.model);
|
|
307
|
+
const contextWindow = getContextWindow(sessionState.model);
|
|
308
|
+
const contextTokens = estimateConversationTokens(state.session.getMessages());
|
|
309
|
+
const statusPctRaw = (contextTokens / contextWindow) * 100;
|
|
310
|
+
const statusContextStr = statusPctRaw > 0 && statusPctRaw < 1 ? "<1" : String(Math.round(statusPctRaw));
|
|
311
|
+
await bot.send(chatId, `*${projectName}*\n\n` +
|
|
312
|
+
`Model *${modelInfo?.name ?? sessionState.model}*\n` +
|
|
313
|
+
`Messages ${sessionState.messageCount}\n` +
|
|
314
|
+
`Context ${statusContextStr}%\n` +
|
|
315
|
+
`Status ${state.isProcessing ? "_working..._" : "_idle_"}\n\n` +
|
|
316
|
+
`\`${sessionState.cwd}\``);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
if (cmd === "cancel") {
|
|
320
|
+
const state = chatStates.get(chatId);
|
|
321
|
+
if (state?.isProcessing) {
|
|
322
|
+
state.ac.abort();
|
|
323
|
+
await bot.send(chatId, "Cancelled.");
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
await bot.send(chatId, "_Nothing to cancel._");
|
|
327
|
+
}
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
if (cmd === "link") {
|
|
331
|
+
if (args && path.isAbsolute(args.trim())) {
|
|
332
|
+
// Direct path provided — link immediately
|
|
333
|
+
const projectPath = args.trim();
|
|
334
|
+
await linkChat(chatId, projectPath, msg.chatTitle);
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
// No path — show project picker
|
|
338
|
+
const projects = await discoverProjects();
|
|
339
|
+
if (projects.length === 0) {
|
|
340
|
+
await bot.send(chatId, "_No projects found._\n\nUse /link `<path>` to link manually.");
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
343
|
+
const current = config.chats[String(chatId)];
|
|
344
|
+
const lines = projects.map((p, i) => {
|
|
345
|
+
const name = path.basename(p);
|
|
346
|
+
const active = p === current ? " _current_" : "";
|
|
347
|
+
return `*${i + 1}.* *${name}*${active}\n \`${p}\``;
|
|
348
|
+
});
|
|
349
|
+
pendingLinkSelections.set(chatId, projects);
|
|
350
|
+
await bot.send(chatId, `*Select a project*\n\n${lines.join("\n\n")}\n\nSend the number to link.`);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
if (cmd === "unlink") {
|
|
354
|
+
if (!config.chats[String(chatId)]) {
|
|
355
|
+
await bot.send(chatId, "_This chat isn't linked to a project._");
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const existing = chatStates.get(chatId);
|
|
359
|
+
if (existing) {
|
|
360
|
+
await existing.session.dispose();
|
|
361
|
+
chatStates.delete(chatId);
|
|
362
|
+
}
|
|
363
|
+
delete config.chats[String(chatId)];
|
|
364
|
+
await saveConfig(config);
|
|
365
|
+
await bot.send(chatId, `✓ *Unlinked*\n\nDefault project: \`${path.basename(options.cwd)}\``);
|
|
366
|
+
return;
|
|
367
|
+
}
|
|
368
|
+
if (cmd === "start") {
|
|
369
|
+
await bot.send(chatId, buildHelpText(chatId));
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
if (cmd === "m" || cmd === "model") {
|
|
373
|
+
const state = chatStates.get(chatId);
|
|
374
|
+
const currentModel = state?.session.getState().model;
|
|
375
|
+
if (args) {
|
|
376
|
+
// Direct switch: /m 3 (number) or /m opus (name fragment)
|
|
377
|
+
const num = parseInt(args, 10);
|
|
378
|
+
if (!isNaN(num) && num >= 1 && num <= MODELS.length) {
|
|
379
|
+
const selected = MODELS[num - 1];
|
|
380
|
+
const projectPath = resolveProjectPath(chatId);
|
|
381
|
+
const chatState = await getOrCreateChat(chatId, projectPath);
|
|
382
|
+
await chatState.session.switchModel(selected.provider, selected.id);
|
|
383
|
+
await bot.send(chatId, `Switched to *${selected.name}*`);
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
// Try matching by name fragment
|
|
387
|
+
const lower = args.toLowerCase();
|
|
388
|
+
const match = MODELS.find((m) => m.name.toLowerCase().includes(lower) || m.id.toLowerCase().includes(lower));
|
|
389
|
+
if (match) {
|
|
390
|
+
const projectPath = resolveProjectPath(chatId);
|
|
391
|
+
const chatState = await getOrCreateChat(chatId, projectPath);
|
|
392
|
+
await chatState.session.switchModel(match.provider, match.id);
|
|
393
|
+
await bot.send(chatId, `Switched to *${match.name}*`);
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
await bot.send(chatId, `No model matching "${args}". Send /m to see the list.`);
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
// No args — show numbered list grouped by provider
|
|
400
|
+
let listText = "*Models*\n";
|
|
401
|
+
let lastProvider = "";
|
|
402
|
+
const modelList = [...MODELS];
|
|
403
|
+
modelList.forEach((m, i) => {
|
|
404
|
+
if (m.provider !== lastProvider) {
|
|
405
|
+
lastProvider = m.provider;
|
|
406
|
+
const providerName = m.provider === "anthropic"
|
|
407
|
+
? "Anthropic"
|
|
408
|
+
: m.provider === "openai"
|
|
409
|
+
? "OpenAI"
|
|
410
|
+
: m.provider === "glm"
|
|
411
|
+
? "Z.AI"
|
|
412
|
+
: "Moonshot";
|
|
413
|
+
listText += `\n_${providerName}_\n`;
|
|
414
|
+
}
|
|
415
|
+
const active = m.id === currentModel ? " ←" : "";
|
|
416
|
+
listText += ` *${i + 1}.* ${m.name}${active}\n`;
|
|
417
|
+
});
|
|
418
|
+
pendingModelSelections.set(chatId, modelList);
|
|
419
|
+
listText += `\nSend number or name to switch.`;
|
|
420
|
+
await bot.send(chatId, listText);
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
// ── Forward to ggcoder slash commands ──
|
|
424
|
+
if (!TELEGRAM_COMMANDS.has(cmd)) {
|
|
425
|
+
const projectPath = resolveProjectPath(chatId);
|
|
426
|
+
const state = await getOrCreateChat(chatId, projectPath);
|
|
427
|
+
if (state.isProcessing) {
|
|
428
|
+
await bot.send(chatId, "_Working..._ send /cancel to interrupt.");
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
431
|
+
try {
|
|
432
|
+
state.textBuffer = "";
|
|
433
|
+
await state.session.prompt(text.trim());
|
|
434
|
+
await flushText(state);
|
|
435
|
+
}
|
|
436
|
+
catch (err) {
|
|
437
|
+
await bot.send(chatId, `Command failed: ${formatUserError(err)}`);
|
|
438
|
+
}
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
// ── Prompt handler ──────────────────────────────────
|
|
443
|
+
async function handlePrompt(chatId, text) {
|
|
444
|
+
const projectPath = resolveProjectPath(chatId);
|
|
445
|
+
const state = await getOrCreateChat(chatId, projectPath);
|
|
446
|
+
if (state.isProcessing) {
|
|
447
|
+
await bot.send(chatId, "_Working..._ send /cancel to interrupt.");
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
state.isProcessing = true;
|
|
451
|
+
startTyping(state);
|
|
452
|
+
state.textBuffer = "";
|
|
453
|
+
state.activeTools = new Map();
|
|
454
|
+
try {
|
|
455
|
+
await state.session.prompt(text);
|
|
456
|
+
}
|
|
457
|
+
catch (err) {
|
|
458
|
+
stopTyping(state);
|
|
459
|
+
state.isProcessing = false;
|
|
460
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
461
|
+
await bot.send(chatId, "Cancelled.");
|
|
462
|
+
}
|
|
463
|
+
else {
|
|
464
|
+
await bot.send(chatId, `Error: ${formatUserError(err)}`);
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
// ── Initialize and start ─────────────────────────────
|
|
469
|
+
try {
|
|
470
|
+
// Clear terminal
|
|
471
|
+
process.stdout.write("\x1b[2J\x1b[3J\x1b[H");
|
|
472
|
+
const linkedCount = Object.keys(config.chats).length;
|
|
473
|
+
const modelInfo = MODELS.find((m) => m.id === options.model);
|
|
474
|
+
const modelName = modelInfo?.name ?? options.model;
|
|
475
|
+
const home = process.env.HOME ?? "";
|
|
476
|
+
const displayPath = home && options.cwd.startsWith(home) ? "~" + options.cwd.slice(home.length) : options.cwd;
|
|
477
|
+
// GG logo with gradient
|
|
478
|
+
const LOGO = [" ▄▀▀▀ ▄▀▀▀", " █ ▀█ █ ▀█", " ▀▄▄▀ ▀▄▄▀"];
|
|
479
|
+
const GRADIENT = ["#60a5fa", "#7a9df7", "#9495f3", "#a78bfa"];
|
|
480
|
+
function gradientText(text) {
|
|
481
|
+
let colorIdx = 0;
|
|
482
|
+
return text
|
|
483
|
+
.split("")
|
|
484
|
+
.map((ch) => {
|
|
485
|
+
if (ch === " ")
|
|
486
|
+
return ch;
|
|
487
|
+
const color = GRADIENT[colorIdx++ % GRADIENT.length];
|
|
488
|
+
return chalk.hex(color)(ch);
|
|
489
|
+
})
|
|
490
|
+
.join("");
|
|
491
|
+
}
|
|
492
|
+
const GAP = " ";
|
|
493
|
+
console.log();
|
|
494
|
+
console.log(` ${gradientText(LOGO[0])}${GAP}` +
|
|
495
|
+
chalk.hex("#60a5fa").bold("GG Coder") +
|
|
496
|
+
chalk.hex("#6b7280")(" · serve"));
|
|
497
|
+
console.log(` ${gradientText(LOGO[1])}${GAP}` + chalk.hex("#a78bfa")(modelName));
|
|
498
|
+
console.log(` ${gradientText(LOGO[2])}${GAP}` + chalk.hex("#6b7280")(displayPath));
|
|
499
|
+
console.log();
|
|
500
|
+
console.log(chalk.hex("#6b7280")(" User ") +
|
|
501
|
+
chalk.white(String(options.telegram.userId)) +
|
|
502
|
+
(linkedCount > 0 ? chalk.hex("#6b7280")(` · ${linkedCount} linked chat(s)`) : ""));
|
|
503
|
+
console.log();
|
|
504
|
+
console.log(chalk.hex("#4ade80")(" Ready. ") +
|
|
505
|
+
chalk.hex("#6b7280")("Open Telegram and message your bot."));
|
|
506
|
+
console.log();
|
|
507
|
+
console.log(chalk.hex("#6b7280")(" /help ") +
|
|
508
|
+
chalk.hex("#6b7280")("all commands") +
|
|
509
|
+
chalk.hex("#6b7280")(" /link ") +
|
|
510
|
+
chalk.hex("#6b7280")("switch project") +
|
|
511
|
+
chalk.hex("#6b7280")(" /m ") +
|
|
512
|
+
chalk.hex("#6b7280")("switch model"));
|
|
513
|
+
console.log();
|
|
514
|
+
// Handle graceful shutdown
|
|
515
|
+
const shutdown = async () => {
|
|
516
|
+
console.log("\nShutting down...");
|
|
517
|
+
bot.stop();
|
|
518
|
+
for (const state of chatStates.values()) {
|
|
519
|
+
stopTyping(state);
|
|
520
|
+
await state.session.dispose();
|
|
521
|
+
}
|
|
522
|
+
closeLogger();
|
|
523
|
+
process.exit(0);
|
|
524
|
+
};
|
|
525
|
+
process.on("SIGINT", shutdown);
|
|
526
|
+
process.on("SIGTERM", shutdown);
|
|
527
|
+
await bot.start();
|
|
528
|
+
}
|
|
529
|
+
catch (err) {
|
|
530
|
+
console.error(`Failed to start: ${formatUserError(err)}`);
|
|
531
|
+
for (const state of chatStates.values()) {
|
|
532
|
+
await state.session.dispose();
|
|
533
|
+
}
|
|
534
|
+
closeLogger();
|
|
535
|
+
process.exit(1);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
// ── Helpers ───────────────────────────────────────────────
|
|
539
|
+
function formatArgs(args) {
|
|
540
|
+
const entries = Object.entries(args);
|
|
541
|
+
if (entries.length === 0)
|
|
542
|
+
return "";
|
|
543
|
+
const [_key, value] = entries[0];
|
|
544
|
+
const str = typeof value === "string" ? value : JSON.stringify(value);
|
|
545
|
+
const truncated = str.length > 60 ? str.slice(0, 57) + "..." : str;
|
|
546
|
+
return `\`${truncated}\``;
|
|
547
|
+
}
|
|
548
|
+
function formatDuration(ms) {
|
|
549
|
+
if (ms < 1000)
|
|
550
|
+
return `${ms}ms`;
|
|
551
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
552
|
+
}
|
|
553
|
+
//# sourceMappingURL=serve-mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-mode.js","sourceRoot":"","sources":["../../src/modes/serve-mode.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/bash.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import type { AgentTool } from "@kenkaiiii/gg-agent";
|
|
3
3
|
import type { ProcessManager } from "../core/process-manager.js";
|
|
4
|
+
import { type ToolOperations } from "./operations.js";
|
|
4
5
|
declare const BashParams: z.ZodObject<{
|
|
5
6
|
command: z.ZodString;
|
|
6
7
|
timeout: z.ZodOptional<z.ZodNumber>;
|
|
7
8
|
run_in_background: z.ZodOptional<z.ZodBoolean>;
|
|
8
9
|
}, z.core.$strip>;
|
|
9
|
-
export declare function createBashTool(cwd: string, processManager: ProcessManager): AgentTool<typeof BashParams>;
|
|
10
|
+
export declare function createBashTool(cwd: string, processManager: ProcessManager, ops?: ToolOperations): AgentTool<typeof BashParams>;
|
|
10
11
|
export {};
|
|
11
12
|
//# sourceMappingURL=bash.d.ts.map
|
package/dist/tools/bash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../src/tools/bash.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGjE,OAAO,EAAmB,KAAK,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAwDvE,QAAA,MAAM,UAAU;;;;iBAed,CAAC;AAEH,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,cAAc,EAAE,cAAc,EAC9B,GAAG,GAAE,cAAgC,GACpC,SAAS,CAAC,OAAO,UAAU,CAAC,CAuG9B"}
|
package/dist/tools/bash.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
1
|
import fs from "node:fs/promises";
|
|
3
2
|
import os from "node:os";
|
|
4
3
|
import path from "node:path";
|
|
5
4
|
import { z } from "zod";
|
|
6
5
|
import { killProcessTree } from "../utils/process.js";
|
|
7
6
|
import { truncateTail } from "./truncate.js";
|
|
7
|
+
import { localOperations } from "./operations.js";
|
|
8
8
|
const DEFAULT_TIMEOUT = 120_000; // 120 seconds
|
|
9
9
|
const MAX_OUTPUT_BYTES = 10 * 1024 * 1024; // 10 MB — cap buffered output to prevent OOM
|
|
10
10
|
/** Environment variables safe to inherit. Everything else is stripped to prevent leaking secrets to LLM. */
|
|
@@ -71,7 +71,7 @@ const BashParams = z.object({
|
|
|
71
71
|
.describe("Run the command in the background. Returns a process ID immediately. " +
|
|
72
72
|
"Use task_output to read output and task_stop to stop it."),
|
|
73
73
|
});
|
|
74
|
-
export function createBashTool(cwd, processManager) {
|
|
74
|
+
export function createBashTool(cwd, processManager, ops = localOperations) {
|
|
75
75
|
return {
|
|
76
76
|
name: "bash",
|
|
77
77
|
description: "Execute a bash command. The shell's working directory is already set to the project root — " +
|
|
@@ -93,7 +93,7 @@ export function createBashTool(cwd, processManager) {
|
|
|
93
93
|
}
|
|
94
94
|
const effectiveTimeout = timeoutMs ?? DEFAULT_TIMEOUT;
|
|
95
95
|
return new Promise((resolve) => {
|
|
96
|
-
const child = spawn("bash", ["-c", command], {
|
|
96
|
+
const child = ops.spawn("bash", ["-c", command], {
|
|
97
97
|
cwd,
|
|
98
98
|
detached: true,
|
|
99
99
|
stdio: ["ignore", "pipe", "pipe"],
|