@kenkaiiii/ggcoder 4.10.1 → 4.11.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.
- package/dist/app-sidecar.d.ts +2 -0
- package/dist/app-sidecar.d.ts.map +1 -0
- package/dist/app-sidecar.js +1201 -0
- package/dist/app-sidecar.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +5 -22
- package/dist/cli.js.map +1 -1
- package/dist/core/agent-session.d.ts +94 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +313 -1
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-providers.d.ts +18 -0
- package/dist/core/auth-providers.d.ts.map +1 -0
- package/dist/core/auth-providers.js +71 -0
- package/dist/core/auth-providers.js.map +1 -0
- package/dist/core/event-bus.d.ts +5 -0
- package/dist/core/event-bus.d.ts.map +1 -1
- package/dist/core/event-bus.js +1 -0
- package/dist/core/event-bus.js.map +1 -1
- package/dist/core/project-discovery.d.ts +41 -0
- package/dist/core/project-discovery.d.ts.map +1 -0
- package/dist/core/project-discovery.js +441 -0
- package/dist/core/project-discovery.js.map +1 -0
- package/dist/core/radio.d.ts +44 -0
- package/dist/core/radio.d.ts.map +1 -0
- package/dist/core/radio.js +250 -0
- package/dist/core/radio.js.map +1 -0
- package/dist/core/settings-manager.d.ts +1 -1
- package/dist/core/shell-path.d.ts +12 -0
- package/dist/core/shell-path.d.ts.map +1 -0
- package/dist/core/shell-path.js +166 -0
- package/dist/core/shell-path.js.map +1 -0
- package/dist/core/telegram-config.d.ts +21 -0
- package/dist/core/telegram-config.d.ts.map +1 -0
- package/dist/core/telegram-config.js +52 -0
- package/dist/core/telegram-config.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/modes/serve-mode.d.ts +24 -0
- package/dist/modes/serve-mode.d.ts.map +1 -1
- package/dist/modes/serve-mode.js +54 -19
- package/dist/modes/serve-mode.js.map +1 -1
- package/dist/tools/tasks.d.ts +1 -1
- package/dist/ui/hooks/useTranscriptHistory.d.ts +2 -0
- package/dist/ui/hooks/useTranscriptHistory.d.ts.map +1 -1
- package/dist/ui/hooks/useTranscriptHistory.js +3 -2
- package/dist/ui/hooks/useTranscriptHistory.js.map +1 -1
- package/dist/ui/render.d.ts.map +1 -1
- package/dist/ui/render.js +60 -8
- package/dist/ui/render.js.map +1 -1
- package/dist/ui/terminal-history-repaint.test.d.ts +2 -0
- package/dist/ui/terminal-history-repaint.test.d.ts.map +1 -0
- package/dist/ui/terminal-history-repaint.test.js +73 -0
- package/dist/ui/terminal-history-repaint.test.js.map +1 -0
- package/dist/ui/terminal-history.d.ts +1 -0
- package/dist/ui/terminal-history.d.ts.map +1 -1
- package/dist/ui/terminal-history.js +31 -2
- package/dist/ui/terminal-history.js.map +1 -1
- package/dist/utils/git.d.ts +6 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +12 -0
- package/dist/utils/git.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { log } from "./logger.js";
|
|
5
|
+
export const RADIO_STATIONS = [
|
|
6
|
+
{
|
|
7
|
+
id: "somafm-groove-salad",
|
|
8
|
+
name: "SomaFM · Groove Salad",
|
|
9
|
+
description: "Chilled downtempo, ambient grooves",
|
|
10
|
+
url: "http://ice1.somafm.com/groovesalad-128-mp3",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
id: "somafm-drone-zone",
|
|
14
|
+
name: "SomaFM · Drone Zone",
|
|
15
|
+
description: "Atmospheric textures with minimal beats",
|
|
16
|
+
url: "http://ice1.somafm.com/dronezone-128-mp3",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: "radio-paradise",
|
|
20
|
+
name: "Radio Paradise",
|
|
21
|
+
description: "Eclectic mix — rock, electronica, jazz",
|
|
22
|
+
url: "http://stream.radioparadise.com/mp3-128",
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
id: "george-fm",
|
|
26
|
+
name: "George FM",
|
|
27
|
+
description: "NZ dance + electronic",
|
|
28
|
+
url: "https://mediaworks.streamguys1.com/george_net_icy",
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
/**
|
|
32
|
+
* Well-known directories where streaming players get installed but which a
|
|
33
|
+
* GUI app's minimal PATH usually omits. macOS apps launched from Finder/Dock
|
|
34
|
+
* inherit only `/usr/bin:/bin:/usr/sbin:/sbin` — not Homebrew (`/opt/homebrew/bin`
|
|
35
|
+
* on Apple Silicon, `/usr/local/bin` on Intel) or MacPorts (`/opt/local/bin`),
|
|
36
|
+
* so `spawn("mpv")` ENOENTs even when mpv is installed. We search these in
|
|
37
|
+
* addition to PATH. Linux dirs cover the common package-manager prefixes.
|
|
38
|
+
*/
|
|
39
|
+
function extraPlayerDirs() {
|
|
40
|
+
switch (process.platform) {
|
|
41
|
+
case "darwin":
|
|
42
|
+
return ["/opt/homebrew/bin", "/usr/local/bin", "/opt/local/bin"];
|
|
43
|
+
case "linux":
|
|
44
|
+
return ["/usr/bin", "/usr/local/bin", "/bin", "/snap/bin"];
|
|
45
|
+
default:
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve a player command to a runnable path. Probes PATH plus the well-known
|
|
51
|
+
* install dirs and returns the first absolute hit, so GUI apps find players in
|
|
52
|
+
* Homebrew/MacPorts dirs their minimal PATH omits. Returns null when the binary
|
|
53
|
+
* isn't found anywhere we look.
|
|
54
|
+
*
|
|
55
|
+
* Windows is left to the OS: executables carry extensions (.exe/.cmd) resolved
|
|
56
|
+
* via PATHEXT, and GUI apps there inherit a usable PATH — so we return `cmd`
|
|
57
|
+
* unchanged and let spawn do its normal lookup (probing bare names here would
|
|
58
|
+
* miss `mpv.exe` and regress Windows).
|
|
59
|
+
*/
|
|
60
|
+
function resolvePlayerPath(cmd) {
|
|
61
|
+
// An explicit path is used as-is.
|
|
62
|
+
if (cmd.includes(path.sep))
|
|
63
|
+
return existsSync(cmd) ? cmd : null;
|
|
64
|
+
// Defer to the OS on Windows (PATHEXT handles the extension).
|
|
65
|
+
if (process.platform === "win32")
|
|
66
|
+
return cmd;
|
|
67
|
+
// 1) PATH (covers terminal launches + any inherited shell environment).
|
|
68
|
+
const pathDirs = (process.env.PATH ?? "").split(path.delimiter).filter(Boolean);
|
|
69
|
+
// 2) Well-known dirs a GUI PATH typically omits.
|
|
70
|
+
for (const dir of [...pathDirs, ...extraPlayerDirs()]) {
|
|
71
|
+
const candidate = path.join(dir, cmd);
|
|
72
|
+
if (existsSync(candidate))
|
|
73
|
+
return candidate;
|
|
74
|
+
}
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Streaming-capable players in priority order. Each gets its quietest flag
|
|
79
|
+
* combination — radio runs in the background, we don't want stdout/stderr
|
|
80
|
+
* spam. Stdio is also redirected to "ignore" at spawn time.
|
|
81
|
+
*/
|
|
82
|
+
const PLAYERS = [
|
|
83
|
+
{ cmd: "mpv", args: (u) => ["--really-quiet", "--no-video", "--no-terminal", u] },
|
|
84
|
+
{ cmd: "ffplay", args: (u) => ["-nodisp", "-autoexit", "-loglevel", "quiet", u] },
|
|
85
|
+
{ cmd: "mpg123", args: (u) => ["-q", u] },
|
|
86
|
+
{ cmd: "cvlc", args: (u) => ["--play-and-exit", "--quiet", u] },
|
|
87
|
+
];
|
|
88
|
+
let currentChild = null;
|
|
89
|
+
let currentStationId = null;
|
|
90
|
+
export function getCurrentStation() {
|
|
91
|
+
return currentStationId;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Stop whatever's currently playing. Idempotent — safe to call when nothing
|
|
95
|
+
* is playing. Sends SIGTERM (graceful), child cleans up the audio device.
|
|
96
|
+
*/
|
|
97
|
+
export function stopRadio() {
|
|
98
|
+
if (!currentChild)
|
|
99
|
+
return;
|
|
100
|
+
try {
|
|
101
|
+
// Detached children sit in their own process group on POSIX; kill the
|
|
102
|
+
// whole group so any helper threads/forks die too. On Windows there's no
|
|
103
|
+
// process group concept — kill() targets the child only.
|
|
104
|
+
if (process.platform !== "win32" && currentChild.pid) {
|
|
105
|
+
try {
|
|
106
|
+
process.kill(-currentChild.pid, "SIGTERM");
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
currentChild.kill("SIGTERM");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
currentChild.kill("SIGTERM");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Already exited — nothing to do.
|
|
118
|
+
}
|
|
119
|
+
currentChild = null;
|
|
120
|
+
currentStationId = null;
|
|
121
|
+
log("INFO", "radio", "stopped");
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* On WSL2, native Linux audio binaries can't reach the Windows audio device
|
|
125
|
+
* through WSLg's bridge in any useful way for streaming — detect WSL and route
|
|
126
|
+
* through the Windows host instead.
|
|
127
|
+
*/
|
|
128
|
+
function isWsl() {
|
|
129
|
+
if (process.platform !== "linux")
|
|
130
|
+
return false;
|
|
131
|
+
return !!process.env.WSL_DISTRO_NAME || existsSync("/proc/sys/fs/binfmt_misc/WSLInterop");
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Stream a station through powershell.exe + WPF MediaPlayer on the Windows host
|
|
135
|
+
* instead of a Linux binary. Returns the ChildProcess or null on spawn failure.
|
|
136
|
+
* The URL is allowlist-checked, scheme-enforced, and passed via env (never
|
|
137
|
+
* interpolated into the -Command string).
|
|
138
|
+
*/
|
|
139
|
+
function tryPlayOnWindowsHost(station) {
|
|
140
|
+
const allowedUrls = new Set(RADIO_STATIONS.map((s) => s.url));
|
|
141
|
+
if (!allowedUrls.has(station.url))
|
|
142
|
+
return null;
|
|
143
|
+
if (!/^https?:\/\//i.test(station.url))
|
|
144
|
+
return null;
|
|
145
|
+
const psScript = [
|
|
146
|
+
"Add-Type -AssemblyName presentationCore;",
|
|
147
|
+
"Add-Type -AssemblyName WindowsBase;",
|
|
148
|
+
"$p = New-Object System.Windows.Media.MediaPlayer;",
|
|
149
|
+
"$p.Open([uri]$env:GG_RADIO_URL);",
|
|
150
|
+
"$p.Play();",
|
|
151
|
+
"[System.Windows.Threading.Dispatcher]::Run();",
|
|
152
|
+
].join(" ");
|
|
153
|
+
try {
|
|
154
|
+
return spawn("powershell.exe", ["-NoProfile", "-WindowStyle", "Hidden", "-Command", psScript], {
|
|
155
|
+
detached: true,
|
|
156
|
+
stdio: "ignore",
|
|
157
|
+
env: {
|
|
158
|
+
...process.env,
|
|
159
|
+
GG_RADIO_URL: station.url,
|
|
160
|
+
WSLENV: (process.env.WSLENV ? process.env.WSLENV + ":" : "") + "GG_RADIO_URL",
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Spawn a streaming player for the given station. If one is already playing,
|
|
170
|
+
* it's killed first. Returns ok=false with a hint if no compatible player is
|
|
171
|
+
* installed — caller should surface the error to the user.
|
|
172
|
+
*/
|
|
173
|
+
export function playRadio(stationId) {
|
|
174
|
+
const station = RADIO_STATIONS.find((s) => s.id === stationId);
|
|
175
|
+
if (!station)
|
|
176
|
+
return { ok: false, error: `Unknown station: ${stationId}` };
|
|
177
|
+
// Always stop the previous stream before starting a new one.
|
|
178
|
+
stopRadio();
|
|
179
|
+
if (isWsl()) {
|
|
180
|
+
const child = tryPlayOnWindowsHost(station);
|
|
181
|
+
if (child) {
|
|
182
|
+
let errored = false;
|
|
183
|
+
child.once("error", () => {
|
|
184
|
+
errored = true;
|
|
185
|
+
});
|
|
186
|
+
if (child.pid && !errored) {
|
|
187
|
+
currentChild = child;
|
|
188
|
+
currentStationId = stationId;
|
|
189
|
+
log("INFO", "radio", "playing", {
|
|
190
|
+
station: station.id,
|
|
191
|
+
player: "powershell.exe (wsl→host)",
|
|
192
|
+
url: station.url,
|
|
193
|
+
});
|
|
194
|
+
child.unref();
|
|
195
|
+
return { ok: true };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
for (const player of PLAYERS) {
|
|
200
|
+
// Resolve to an absolute path first so we find players in Homebrew/MacPorts
|
|
201
|
+
// dirs that a GUI app's minimal PATH omits. Skip when not installed.
|
|
202
|
+
const bin = resolvePlayerPath(player.cmd);
|
|
203
|
+
if (!bin)
|
|
204
|
+
continue;
|
|
205
|
+
try {
|
|
206
|
+
const child = spawn(bin, player.args(station.url), {
|
|
207
|
+
detached: process.platform !== "win32",
|
|
208
|
+
stdio: "ignore",
|
|
209
|
+
});
|
|
210
|
+
let errored = false;
|
|
211
|
+
child.once("error", () => {
|
|
212
|
+
errored = true;
|
|
213
|
+
});
|
|
214
|
+
if (child.pid && !errored) {
|
|
215
|
+
currentChild = child;
|
|
216
|
+
currentStationId = stationId;
|
|
217
|
+
log("INFO", "radio", "playing", {
|
|
218
|
+
station: station.id,
|
|
219
|
+
player: player.cmd,
|
|
220
|
+
url: station.url,
|
|
221
|
+
});
|
|
222
|
+
child.unref();
|
|
223
|
+
return { ok: true };
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// ENOENT or permission — try the next player.
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
log("WARN", "radio", "no compatible player found", { platform: process.platform });
|
|
231
|
+
return { ok: false, error: buildInstallHint() };
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Platform-specific one-line install hint so the user can copy-paste rather
|
|
235
|
+
* than reading generic suggestions.
|
|
236
|
+
*/
|
|
237
|
+
function buildInstallHint() {
|
|
238
|
+
const base = "Radio needs a streaming player. Install one of: mpv (recommended), ffplay, mpg123, or vlc.";
|
|
239
|
+
switch (process.platform) {
|
|
240
|
+
case "darwin":
|
|
241
|
+
return `${base} On macOS: \`brew install mpv\` (or \`brew install ffmpeg\` for ffplay).`;
|
|
242
|
+
case "linux":
|
|
243
|
+
return `${base} On Linux (Debian/Ubuntu): \`sudo apt install mpv\`. Fedora: \`sudo dnf install mpv\`. Arch: \`sudo pacman -S mpv\`.`;
|
|
244
|
+
case "win32":
|
|
245
|
+
return `${base} On Windows: \`winget install mpv.mpv\` (or download from https://mpv.io).`;
|
|
246
|
+
default:
|
|
247
|
+
return `${base} See https://mpv.io for platform installation instructions.`;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
//# sourceMappingURL=radio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"radio.js","sourceRoot":"","sources":["../../src/core/radio.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,8 +24,8 @@ declare const SettingsSchema: z.ZodObject<{
|
|
|
24
24
|
max: "max";
|
|
25
25
|
}>>;
|
|
26
26
|
theme: z.ZodDefault<z.ZodEnum<{
|
|
27
|
-
light: "light";
|
|
28
27
|
dark: "dark";
|
|
28
|
+
light: "light";
|
|
29
29
|
"dark-ansi": "dark-ansi";
|
|
30
30
|
"light-ansi": "light-ansi";
|
|
31
31
|
"dark-daltonized": "dark-daltonized";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compute the enriched PATH (login shell ∪ current ∪ existing well-known dirs).
|
|
3
|
+
* Cached after first call. Order is preserved and duplicates removed.
|
|
4
|
+
*/
|
|
5
|
+
export declare function resolveEnrichedPath(currentPath?: string): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Enrich `process.env.PATH` in place so every later spawn/execFile (the bash
|
|
8
|
+
* tool, background tasks, LSP servers, git helpers) inherits a working PATH.
|
|
9
|
+
* Idempotent and safe to call once at startup. No-op on Windows.
|
|
10
|
+
*/
|
|
11
|
+
export declare function enrichProcessPath(): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=shell-path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-path.d.ts","sourceRoot":"","sources":["../../src/core/shell-path.ts"],"names":[],"mappings":"AA4HA;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,GAAE,MAA+B,GAAG,OAAO,CAAC,MAAM,CAAC,CAqBvG;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAUvD"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import os from "node:os";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { log } from "./logger.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve a usable PATH for shelling out to developer tools.
|
|
8
|
+
*
|
|
9
|
+
* GUI apps launched from Finder/Dock (the packaged desktop app) inherit a
|
|
10
|
+
* minimal PATH — on macOS just `/usr/bin:/bin:/usr/sbin:/sbin` — which omits
|
|
11
|
+
* Homebrew (`/opt/homebrew/bin`, `/usr/local/bin`), Cargo (`~/.cargo/bin`),
|
|
12
|
+
* version managers (nvm/asdf/pyenv), and most toolchains. A coding agent that
|
|
13
|
+
* can't find `node`, `npm`, `git`, `python3`, `rg`, `cargo`, … is useless, so
|
|
14
|
+
* we enrich the process PATH once at sidecar startup.
|
|
15
|
+
*
|
|
16
|
+
* Strategy (union, de-duped, order-preserving):
|
|
17
|
+
* 1. The user's real login-shell PATH (captures nvm/asdf/pyenv/custom dirs).
|
|
18
|
+
* 2. The current process PATH (whatever we were launched with).
|
|
19
|
+
* 3. Well-known install dirs that exist on disk (fallback when 1 fails).
|
|
20
|
+
*
|
|
21
|
+
* No-op on Windows, where GUI apps inherit a usable PATH and there's no
|
|
22
|
+
* equivalent login-shell concept.
|
|
23
|
+
*/
|
|
24
|
+
/** Well-known bin dirs a GUI PATH commonly omits, by platform. */
|
|
25
|
+
function wellKnownBinDirs() {
|
|
26
|
+
const home = os.homedir();
|
|
27
|
+
if (process.platform === "darwin") {
|
|
28
|
+
return [
|
|
29
|
+
"/opt/homebrew/bin",
|
|
30
|
+
"/opt/homebrew/sbin",
|
|
31
|
+
"/usr/local/bin",
|
|
32
|
+
"/usr/local/sbin",
|
|
33
|
+
"/opt/local/bin", // MacPorts
|
|
34
|
+
"/opt/local/sbin",
|
|
35
|
+
path.join(home, ".local", "bin"),
|
|
36
|
+
path.join(home, ".cargo", "bin"),
|
|
37
|
+
path.join(home, "go", "bin"),
|
|
38
|
+
path.join(home, ".deno", "bin"),
|
|
39
|
+
path.join(home, ".bun", "bin"),
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
if (process.platform === "linux") {
|
|
43
|
+
return [
|
|
44
|
+
"/usr/local/bin",
|
|
45
|
+
"/usr/local/sbin",
|
|
46
|
+
"/usr/bin",
|
|
47
|
+
"/bin",
|
|
48
|
+
"/usr/sbin",
|
|
49
|
+
"/sbin",
|
|
50
|
+
"/snap/bin",
|
|
51
|
+
path.join(home, ".local", "bin"),
|
|
52
|
+
path.join(home, ".cargo", "bin"),
|
|
53
|
+
path.join(home, "go", "bin"),
|
|
54
|
+
path.join(home, ".deno", "bin"),
|
|
55
|
+
path.join(home, ".bun", "bin"),
|
|
56
|
+
];
|
|
57
|
+
}
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
const DELIMITER = "_GG_SHELL_ENV_DELIMITER_";
|
|
61
|
+
/**
|
|
62
|
+
* Ask the user's login shell for its PATH. Best-effort: resolves to null on any
|
|
63
|
+
* error/timeout so the caller falls back to the well-known dirs. Mirrors the
|
|
64
|
+
* approach used by `shell-env`/`fix-path` (delimited echo, detached to dodge a
|
|
65
|
+
* zsh hang, oh-my-zsh auto-update disabled).
|
|
66
|
+
*/
|
|
67
|
+
function loginShellPath() {
|
|
68
|
+
if (process.platform === "win32")
|
|
69
|
+
return Promise.resolve(null);
|
|
70
|
+
const shell = process.env.SHELL || "/bin/zsh";
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
let settled = false;
|
|
73
|
+
const finish = (value) => {
|
|
74
|
+
if (settled)
|
|
75
|
+
return;
|
|
76
|
+
settled = true;
|
|
77
|
+
resolve(value);
|
|
78
|
+
};
|
|
79
|
+
try {
|
|
80
|
+
const child = spawn(shell, ["-ilc", `echo -n "${DELIMITER}"; printf "%s" "$PATH"; echo -n "${DELIMITER}"; exit`], {
|
|
81
|
+
// zsh can hang on stdin without detaching; matches shell-env's fix.
|
|
82
|
+
detached: true,
|
|
83
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
84
|
+
env: { ...process.env, DISABLE_AUTO_UPDATE: "true" },
|
|
85
|
+
});
|
|
86
|
+
let out = "";
|
|
87
|
+
child.stdout?.on("data", (d) => {
|
|
88
|
+
out += d.toString("utf-8");
|
|
89
|
+
});
|
|
90
|
+
child.once("error", () => finish(null));
|
|
91
|
+
child.once("close", () => {
|
|
92
|
+
const start = out.indexOf(DELIMITER);
|
|
93
|
+
const end = out.lastIndexOf(DELIMITER);
|
|
94
|
+
if (start === -1 || end === -1 || end <= start) {
|
|
95
|
+
finish(null);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const value = out.slice(start + DELIMITER.length, end).trim();
|
|
99
|
+
finish(value || null);
|
|
100
|
+
});
|
|
101
|
+
// Hard cap: some shells (slow rc files) can stall; don't block startup.
|
|
102
|
+
const timer = setTimeout(() => {
|
|
103
|
+
try {
|
|
104
|
+
if (child.pid)
|
|
105
|
+
process.kill(-child.pid, "SIGKILL");
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
child.kill("SIGKILL");
|
|
109
|
+
}
|
|
110
|
+
finish(null);
|
|
111
|
+
}, 5000);
|
|
112
|
+
timer.unref();
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
finish(null);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
let cached;
|
|
120
|
+
/**
|
|
121
|
+
* Compute the enriched PATH (login shell ∪ current ∪ existing well-known dirs).
|
|
122
|
+
* Cached after first call. Order is preserved and duplicates removed.
|
|
123
|
+
*/
|
|
124
|
+
export async function resolveEnrichedPath(currentPath = process.env.PATH ?? "") {
|
|
125
|
+
if (cached !== undefined)
|
|
126
|
+
return cached;
|
|
127
|
+
const parts = [];
|
|
128
|
+
const seen = new Set();
|
|
129
|
+
const add = (dir) => {
|
|
130
|
+
const d = dir.trim();
|
|
131
|
+
if (d && !seen.has(d)) {
|
|
132
|
+
seen.add(d);
|
|
133
|
+
parts.push(d);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
const login = await loginShellPath();
|
|
137
|
+
if (login)
|
|
138
|
+
for (const d of login.split(path.delimiter))
|
|
139
|
+
add(d);
|
|
140
|
+
for (const d of currentPath.split(path.delimiter))
|
|
141
|
+
add(d);
|
|
142
|
+
// Only append fallback dirs that actually exist, so PATH stays clean.
|
|
143
|
+
for (const d of wellKnownBinDirs())
|
|
144
|
+
if (existsSync(d))
|
|
145
|
+
add(d);
|
|
146
|
+
cached = parts.join(path.delimiter);
|
|
147
|
+
return cached;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Enrich `process.env.PATH` in place so every later spawn/execFile (the bash
|
|
151
|
+
* tool, background tasks, LSP servers, git helpers) inherits a working PATH.
|
|
152
|
+
* Idempotent and safe to call once at startup. No-op on Windows.
|
|
153
|
+
*/
|
|
154
|
+
export async function enrichProcessPath() {
|
|
155
|
+
if (process.platform === "win32")
|
|
156
|
+
return;
|
|
157
|
+
const before = process.env.PATH ?? "";
|
|
158
|
+
const enriched = await resolveEnrichedPath(before);
|
|
159
|
+
if (enriched && enriched !== before) {
|
|
160
|
+
process.env.PATH = enriched;
|
|
161
|
+
log("INFO", "shell-path", "enriched PATH for tools", {
|
|
162
|
+
added: enriched.length - before.length,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=shell-path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shell-path.js","sourceRoot":"","sources":["../../src/core/shell-path.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface TelegramConfig {
|
|
2
|
+
botToken: string;
|
|
3
|
+
userId: number;
|
|
4
|
+
}
|
|
5
|
+
/** Read the saved Telegram config, or null when unset/incomplete. */
|
|
6
|
+
export declare function loadTelegramConfig(): Promise<TelegramConfig | null>;
|
|
7
|
+
/** Persist the Telegram config with owner-only permissions (0600). */
|
|
8
|
+
export declare function saveTelegramConfig(config: TelegramConfig): Promise<void>;
|
|
9
|
+
/** Rough bot-token shape check (`123456789:ABCdef...`). */
|
|
10
|
+
export declare function isValidBotTokenFormat(token: string): boolean;
|
|
11
|
+
export interface BotVerification {
|
|
12
|
+
ok: boolean;
|
|
13
|
+
username?: string;
|
|
14
|
+
firstName?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Verify a bot token against Telegram's getMe. Returns `{ ok: false }` when the
|
|
18
|
+
* token is malformed or Telegram rejects it (never throws on a bad token).
|
|
19
|
+
*/
|
|
20
|
+
export declare function verifyBotToken(botToken: string): Promise<BotVerification>;
|
|
21
|
+
//# sourceMappingURL=telegram-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-config.d.ts","sourceRoot":"","sources":["../../src/core/telegram-config.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qEAAqE;AACrE,wBAAsB,kBAAkB,IAAI,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CASzE;AAED,sEAAsE;AACtE,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAM9E;AAED,2DAA2D;AAC3D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAa/E"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Telegram bot configuration: the `~/.gg/telegram.json` store (bot token
|
|
3
|
+
* + authorized user id) plus bot-token verification. Used by the CLI
|
|
4
|
+
* (`ggcoder telegram` / `ggcoder serve`) and the desktop app sidecar so both
|
|
5
|
+
* read/write the same file with the same validation.
|
|
6
|
+
*/
|
|
7
|
+
import fs from "node:fs/promises";
|
|
8
|
+
import { ensureAppDirs, getAppPaths } from "../config.js";
|
|
9
|
+
/** Read the saved Telegram config, or null when unset/incomplete. */
|
|
10
|
+
export async function loadTelegramConfig() {
|
|
11
|
+
try {
|
|
12
|
+
const raw = await fs.readFile(getAppPaths().telegramFile, "utf-8");
|
|
13
|
+
const data = JSON.parse(raw);
|
|
14
|
+
if (data.botToken && data.userId)
|
|
15
|
+
return data;
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Persist the Telegram config with owner-only permissions (0600). */
|
|
23
|
+
export async function saveTelegramConfig(config) {
|
|
24
|
+
const paths = await ensureAppDirs();
|
|
25
|
+
await fs.writeFile(paths.telegramFile, JSON.stringify(config, null, 2), {
|
|
26
|
+
encoding: "utf-8",
|
|
27
|
+
mode: 0o600,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
/** Rough bot-token shape check (`123456789:ABCdef...`). */
|
|
31
|
+
export function isValidBotTokenFormat(token) {
|
|
32
|
+
return /^\d+:[A-Za-z0-9_-]+$/.test(token);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Verify a bot token against Telegram's getMe. Returns `{ ok: false }` when the
|
|
36
|
+
* token is malformed or Telegram rejects it (never throws on a bad token).
|
|
37
|
+
*/
|
|
38
|
+
export async function verifyBotToken(botToken) {
|
|
39
|
+
if (!isValidBotTokenFormat(botToken))
|
|
40
|
+
return { ok: false };
|
|
41
|
+
try {
|
|
42
|
+
const res = await fetch(`https://api.telegram.org/bot${botToken}/getMe`, { method: "POST" });
|
|
43
|
+
const data = (await res.json());
|
|
44
|
+
if (!data.ok || !data.result)
|
|
45
|
+
return { ok: false };
|
|
46
|
+
return { ok: true, username: data.result.username, firstName: data.result.first_name };
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return { ok: false };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=telegram-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram-config.js","sourceRoot":"","sources":["../../src/core/telegram-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAO1D,qEAAqE;AACrE,MAAM,CAAC,KAAK,UAAU,kBAAkB;IACtC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;QAC/C,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,MAAsB;IAC7D,MAAM,KAAK,GAAG,MAAM,aAAa,EAAE,CAAC;IACpC,MAAM,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QACtE,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED,2DAA2D;AAC3D,MAAM,UAAU,qBAAqB,CAAC,KAAa;IACjD,OAAO,sBAAsB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5C,CAAC;AAQD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAgB;IACnD,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,+BAA+B,QAAQ,QAAQ,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;QAC7F,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAG7B,CAAC;QACF,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;IACzF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { EventBus, AgentSession, SessionManager, SettingsManager, AuthStorage, S
|
|
|
5
5
|
export { runPrintMode } from "./modes/index.js";
|
|
6
6
|
export { renderApp } from "./ui/render.js";
|
|
7
7
|
export { APP_NAME, VERSION, getAppPaths, ensureAppDirs } from "./config.js";
|
|
8
|
+
export { discoverProjects, listRecentSessions, type DiscoveredProject, type ProjectSource, type RecentSession, } from "./core/project-discovery.js";
|
|
8
9
|
export type { CliConfig, SessionHeader as LegacySessionHeader, SessionMessageEntry, SessionEntry as LegacySessionEntry, SessionInfo as LegacySessionInfo, } from "./types.js";
|
|
9
10
|
export type { AgentSessionOptions, AgentSessionState, BusEventMap, ContextWindowOptions, ModelInfo, Settings, SlashCommand, SlashCommandContext, Skill, Extension, ExtensionContext, CompactionResult, SessionEntry, SessionInfo, SessionHeader, } from "./core/index.js";
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,MAAM,EACN,QAAQ,EACR,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,aAAa,EACb,OAAO,EACP,cAAc,EACd,cAAc,EACd,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5E,YAAY,EACV,SAAS,EACT,aAAa,IAAI,mBAAmB,EACpC,mBAAmB,EACnB,YAAY,IAAI,kBAAkB,EAClC,WAAW,IAAI,iBAAiB,GACjC,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,iBAAiB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAGvD,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,MAAM,EACN,QAAQ,EACR,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,aAAa,EACb,OAAO,EACP,cAAc,EACd,cAAc,EACd,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAG3C,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5E,OAAO,EACL,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,aAAa,GACnB,MAAM,6BAA6B,CAAC;AAGrC,YAAY,EACV,SAAS,EACT,aAAa,IAAI,mBAAmB,EACpC,mBAAmB,EACnB,YAAY,IAAI,kBAAkB,EAClC,WAAW,IAAI,iBAAiB,GACjC,MAAM,YAAY,CAAC;AAEpB,YAAY,EACV,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,oBAAoB,EACpB,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,mBAAmB,EACnB,KAAK,EACL,SAAS,EACT,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -12,4 +12,6 @@ export { runPrintMode } from "./modes/index.js";
|
|
|
12
12
|
export { renderApp } from "./ui/render.js";
|
|
13
13
|
// Config
|
|
14
14
|
export { APP_NAME, VERSION, getAppPaths, ensureAppDirs } from "./config.js";
|
|
15
|
+
// Project discovery (shared with gg-boss + gg-app sidecar)
|
|
16
|
+
export { discoverProjects, listRecentSessions, } from "./core/project-discovery.js";
|
|
15
17
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,gBAAgB;AAChB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,kCAAkC;AAClC,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO;AACP,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,MAAM,EACN,QAAQ,EACR,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,aAAa,EACb,OAAO,EACP,cAAc,EACd,cAAc,EACd,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,WAAW;AACX,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,SAAS;AACT,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,QAAQ;AACR,OAAO,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,cAAc,EACd,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAE1B,gBAAgB;AAChB,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,kCAAkC;AAClC,OAAO,EACL,aAAa,EACb,WAAW,EACX,YAAY,EACZ,oBAAoB,EACpB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,OAAO;AACP,OAAO,EACL,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,eAAe,EACf,WAAW,EACX,oBAAoB,EACpB,eAAe,EACf,MAAM,EACN,QAAQ,EACR,oBAAoB,EACpB,eAAe,EACf,gBAAgB,EAChB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,0BAA0B,EAC1B,wBAAwB,EACxB,aAAa,EACb,OAAO,EACP,cAAc,EACd,cAAc,EACd,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AAEzB,QAAQ;AACR,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAEhD,WAAW;AACX,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,SAAS;AACT,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5E,2DAA2D;AAC3D,OAAO,EACL,gBAAgB,EAChB,kBAAkB,GAInB,MAAM,6BAA6B,CAAC"}
|
|
@@ -9,6 +9,17 @@ export interface ServeModeOptions {
|
|
|
9
9
|
botToken: string;
|
|
10
10
|
userId: number;
|
|
11
11
|
};
|
|
12
|
+
/**
|
|
13
|
+
* Embedded mode (desktop app): skip the terminal banner/console output and
|
|
14
|
+
* don't register process signal handlers — the host process owns those. The
|
|
15
|
+
* bot polls in the background and the caller stops it via the returned
|
|
16
|
+
* controller. Defaults to false (the CLI's blocking, banner-printing flow).
|
|
17
|
+
*/
|
|
18
|
+
embedded?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/** Handle for an embedded serve session: stop polling + dispose all sessions. */
|
|
21
|
+
export interface ServeController {
|
|
22
|
+
stop: () => Promise<void>;
|
|
12
23
|
}
|
|
13
24
|
/**
|
|
14
25
|
* Serve mode: run ggcoder controlled via Telegram.
|
|
@@ -17,5 +28,18 @@ export interface ServeModeOptions {
|
|
|
17
28
|
* - Groups → linked projects via /link <path>
|
|
18
29
|
* - Each chat gets its own AgentSession, tools, context
|
|
19
30
|
*/
|
|
31
|
+
/**
|
|
32
|
+
* Build a serve session: wire the Telegram bot to per-chat AgentSessions and
|
|
33
|
+
* start long-polling in the background. Returns a controller to stop it.
|
|
34
|
+
*
|
|
35
|
+
* Shared by the CLI (`ggcoder serve`, via {@link runServeMode}) and the desktop
|
|
36
|
+
* app sidecar. In `embedded` mode it stays silent and leaves process-signal
|
|
37
|
+
* handling to the host.
|
|
38
|
+
*/
|
|
39
|
+
export declare function startServeMode(options: ServeModeOptions): Promise<ServeController>;
|
|
40
|
+
/**
|
|
41
|
+
* CLI serve flow (`ggcoder serve`): prints the banner, starts the bot, wires
|
|
42
|
+
* SIGINT/SIGTERM to a graceful shutdown, then blocks until the process exits.
|
|
43
|
+
*/
|
|
20
44
|
export declare function runServeMode(options: ServeModeOptions): Promise<void>;
|
|
21
45
|
//# sourceMappingURL=serve-mode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serve-mode.d.ts","sourceRoot":"","sources":["../../src/modes/serve-mode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"serve-mode.d.ts","sourceRoot":"","sources":["../../src/modes/serve-mode.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAgBhE,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,QAAQ,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,QAAQ,EAAE;QACR,QAAQ,EAAE,MAAM,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AA2ED;;;;;;GAMG;AACH;;;;;;;GAOG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CA+rBxF;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB3E"}
|