@kenkaiiii/ggcoder 5.74.3 → 5.75.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/README.md +1 -1
- package/assets/skills/bulletproof/SKILL.md +1 -1
- package/assets/skills/clarify/SKILL.md +1 -1
- package/assets/skills/code-review/SKILL.md +1 -1
- package/assets/skills/compliance-guard/SKILL.md +1 -1
- package/assets/skills/durable/SKILL.md +1 -1
- package/assets/skills/evidence-led-ui/SKILL.md +1 -1
- package/assets/skills/lean/SKILL.md +1 -1
- package/assets/skills/refactoring/SKILL.md +1 -1
- package/assets/skills/root-cause/SKILL.md +1 -1
- package/assets/skills/shared-language/SKILL.md +1 -1
- package/assets/skills/tdd/SKILL.md +1 -1
- package/dist/app-sidecar/app-settings.d.ts +65 -0
- package/dist/app-sidecar/app-settings.js +147 -0
- package/dist/app-sidecar/app-settings.js.map +1 -0
- package/dist/app-sidecar/attachments.d.ts +11 -0
- package/dist/app-sidecar/attachments.js +47 -0
- package/dist/app-sidecar/attachments.js.map +1 -0
- package/dist/app-sidecar/auth-routes.d.ts +3 -0
- package/dist/app-sidecar/auth-routes.js +290 -0
- package/dist/app-sidecar/auth-routes.js.map +1 -0
- package/dist/app-sidecar/autopilot-runner.d.ts +61 -0
- package/dist/app-sidecar/autopilot-runner.js +367 -0
- package/dist/app-sidecar/autopilot-runner.js.map +1 -0
- package/dist/app-sidecar/file-search.d.ts +15 -0
- package/dist/app-sidecar/file-search.js +103 -0
- package/dist/app-sidecar/file-search.js.map +1 -0
- package/dist/app-sidecar/hf-pull-manager.d.ts +20 -0
- package/dist/app-sidecar/hf-pull-manager.js +224 -0
- package/dist/app-sidecar/hf-pull-manager.js.map +1 -0
- package/dist/app-sidecar/history-routes.d.ts +3 -0
- package/dist/app-sidecar/history-routes.js +375 -0
- package/dist/app-sidecar/history-routes.js.map +1 -0
- package/dist/app-sidecar/history.d.ts +67 -0
- package/dist/app-sidecar/history.js +23 -0
- package/dist/app-sidecar/history.js.map +1 -0
- package/dist/app-sidecar/http.d.ts +5 -0
- package/dist/app-sidecar/http.js +27 -0
- package/dist/app-sidecar/http.js.map +1 -0
- package/dist/app-sidecar/integration-routes.d.ts +3 -0
- package/dist/app-sidecar/integration-routes.js +286 -0
- package/dist/app-sidecar/integration-routes.js.map +1 -0
- package/dist/app-sidecar/json-mode.d.ts +10 -0
- package/dist/app-sidecar/json-mode.js +73 -0
- package/dist/app-sidecar/json-mode.js.map +1 -0
- package/dist/app-sidecar/keep-awake.d.ts +4 -0
- package/dist/app-sidecar/keep-awake.js +5 -0
- package/dist/app-sidecar/keep-awake.js.map +1 -0
- package/dist/app-sidecar/ken-context.d.ts +20 -0
- package/dist/app-sidecar/ken-context.js +55 -0
- package/dist/app-sidecar/ken-context.js.map +1 -0
- package/dist/app-sidecar/mcp-routes.d.ts +3 -0
- package/dist/app-sidecar/mcp-routes.js +185 -0
- package/dist/app-sidecar/mcp-routes.js.map +1 -0
- package/dist/app-sidecar/mcp-rows.d.ts +31 -0
- package/dist/app-sidecar/mcp-rows.js +77 -0
- package/dist/app-sidecar/mcp-rows.js.map +1 -0
- package/dist/app-sidecar/progress-manager.d.ts +10 -0
- package/dist/app-sidecar/progress-manager.js +116 -0
- package/dist/app-sidecar/progress-manager.js.map +1 -0
- package/dist/app-sidecar/prompt-routes.d.ts +3 -0
- package/dist/app-sidecar/prompt-routes.js +354 -0
- package/dist/app-sidecar/prompt-routes.js.map +1 -0
- package/dist/app-sidecar/route-context.d.ts +145 -0
- package/dist/app-sidecar/route-context.js +2 -0
- package/dist/app-sidecar/route-context.js.map +1 -0
- package/dist/app-sidecar/run-control-routes.d.ts +3 -0
- package/dist/app-sidecar/run-control-routes.js +430 -0
- package/dist/app-sidecar/run-control-routes.js.map +1 -0
- package/dist/app-sidecar/session-routes.d.ts +3 -0
- package/dist/app-sidecar/session-routes.js +115 -0
- package/dist/app-sidecar/session-routes.js.map +1 -0
- package/dist/app-sidecar/session-types.d.ts +39 -0
- package/dist/app-sidecar/session-types.js +5 -0
- package/dist/app-sidecar/session-types.js.map +1 -0
- package/dist/app-sidecar/task-routes.d.ts +3 -0
- package/dist/app-sidecar/task-routes.js +149 -0
- package/dist/app-sidecar/task-routes.js.map +1 -0
- package/dist/app-sidecar/usage.d.ts +19 -0
- package/dist/app-sidecar/usage.js +153 -0
- package/dist/app-sidecar/usage.js.map +1 -0
- package/dist/app-sidecar/workspace-routes.d.ts +3 -0
- package/dist/app-sidecar/workspace-routes.js +244 -0
- package/dist/app-sidecar/workspace-routes.js.map +1 -0
- package/dist/app-sidecar.js +440 -3720
- package/dist/app-sidecar.js.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/config.js +1 -1
- package/dist/core/acceptance-checks.js +3 -9
- package/dist/core/acceptance-checks.js.map +1 -1
- package/dist/core/agent-session/helpers.d.ts +26 -0
- package/dist/core/agent-session/helpers.js +47 -0
- package/dist/core/agent-session/helpers.js.map +1 -0
- package/dist/core/agent-session/mcp-tools.d.ts +68 -0
- package/dist/core/agent-session/mcp-tools.js +195 -0
- package/dist/core/agent-session/mcp-tools.js.map +1 -0
- package/dist/core/agent-session/run-loop-monitor.d.ts +63 -0
- package/dist/core/agent-session/run-loop-monitor.js +164 -0
- package/dist/core/agent-session/run-loop-monitor.js.map +1 -0
- package/dist/core/agent-session/transcript-markers.d.ts +57 -0
- package/dist/core/agent-session/transcript-markers.js +166 -0
- package/dist/core/agent-session/transcript-markers.js.map +1 -0
- package/dist/core/agent-session/verification-tracker.d.ts +46 -0
- package/dist/core/agent-session/verification-tracker.js +246 -0
- package/dist/core/agent-session/verification-tracker.js.map +1 -0
- package/dist/core/agent-session.d.ts +21 -87
- package/dist/core/agent-session.js +141 -712
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-providers.js +3 -3
- package/dist/core/auth-providers.js.map +1 -1
- package/dist/core/bundled-agents.js +6 -6
- package/dist/core/bundled-agents.js.map +1 -1
- package/dist/core/checklist-git.d.ts +19 -0
- package/dist/core/checklist-git.js +54 -0
- package/dist/core/checklist-git.js.map +1 -0
- package/dist/core/checklist-items.d.ts +10 -1
- package/dist/core/checklist-items.js +22 -0
- package/dist/core/checklist-items.js.map +1 -1
- package/dist/core/checklist-prompt.d.ts +5 -1
- package/dist/core/checklist-prompt.js +16 -5
- package/dist/core/checklist-prompt.js.map +1 -1
- package/dist/core/checklist-snapshot.d.ts +5 -1
- package/dist/core/checklist-snapshot.js +19 -2
- package/dist/core/checklist-snapshot.js.map +1 -1
- package/dist/core/context-limits.js +1 -1
- package/dist/core/context-limits.js.map +1 -1
- package/dist/core/skills.js +6 -9
- package/dist/core/skills.js.map +1 -1
- package/dist/core/style-packs/index.js +2 -11
- package/dist/core/style-packs/index.js.map +1 -1
- package/dist/core/style-packs/packs.d.ts +3 -12
- package/dist/core/style-packs/packs.js +132 -173
- package/dist/core/style-packs/packs.js.map +1 -1
- package/dist/system-prompt.js +55 -78
- package/dist/system-prompt.js.map +1 -1
- package/dist/tools/ask-user.js +13 -74
- package/dist/tools/ask-user.js.map +1 -1
- package/dist/tools/bash.js +13 -78
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/checklist.d.ts +2 -10
- package/dist/tools/checklist.js +7 -39
- package/dist/tools/checklist.js.map +1 -1
- package/dist/tools/code-nav.js +7 -29
- package/dist/tools/code-nav.js.map +1 -1
- package/dist/tools/edit.d.ts +3 -9
- package/dist/tools/edit.js +66 -65
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/enter-plan.js +2 -7
- package/dist/tools/enter-plan.js.map +1 -1
- package/dist/tools/exit-plan.js +2 -3
- package/dist/tools/exit-plan.js.map +1 -1
- package/dist/tools/find.js +3 -4
- package/dist/tools/find.js.map +1 -1
- package/dist/tools/grep.js +6 -18
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/ls.js +3 -3
- package/dist/tools/ls.js.map +1 -1
- package/dist/tools/prompt-hints.js +34 -47
- package/dist/tools/prompt-hints.js.map +1 -1
- package/dist/tools/read.js +8 -20
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/search-code.js +4 -12
- package/dist/tools/search-code.js.map +1 -1
- package/dist/tools/skill.js +13 -7
- package/dist/tools/skill.js.map +1 -1
- package/dist/tools/subagent-control.js +7 -22
- package/dist/tools/subagent-control.js.map +1 -1
- package/dist/tools/subagent.js +4 -7
- package/dist/tools/subagent.js.map +1 -1
- package/dist/tools/task-output.js +4 -15
- package/dist/tools/task-output.js.map +1 -1
- package/dist/tools/task-send.js +5 -17
- package/dist/tools/task-send.js.map +1 -1
- package/dist/tools/task-stop.js +2 -2
- package/dist/tools/task-stop.js.map +1 -1
- package/dist/tools/tool-search.js +2 -7
- package/dist/tools/tool-search.js.map +1 -1
- package/dist/tools/tool-tiers.d.ts +17 -4
- package/dist/tools/tool-tiers.js +38 -15
- package/dist/tools/tool-tiers.js.map +1 -1
- package/dist/tools/web-fetch.js +7 -33
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/tools/write.js +3 -4
- package/dist/tools/write.js.map +1 -1
- package/dist/ui/components/Footer.js +1 -2
- package/dist/ui/components/Footer.js.map +1 -1
- package/package.json +7 -4
- package/dist/core/api-benchmark.d.ts +0 -63
- package/dist/core/api-benchmark.js +0 -381
- package/dist/core/api-benchmark.js.map +0 -1
- package/dist/core/bash-spawn-benchmark.d.ts +0 -1
- package/dist/core/bash-spawn-benchmark.js +0 -139
- package/dist/core/bash-spawn-benchmark.js.map +0 -1
- package/dist/core/cache-warm-benchmark.d.ts +0 -21
- package/dist/core/cache-warm-benchmark.js +0 -170
- package/dist/core/cache-warm-benchmark.js.map +0 -1
- package/dist/core/fast-apply-benchmark.d.ts +0 -25
- package/dist/core/fast-apply-benchmark.js +0 -284
- package/dist/core/fast-apply-benchmark.js.map +0 -1
- package/dist/core/hashline-edit-benchmark.d.ts +0 -88
- package/dist/core/hashline-edit-benchmark.js +0 -518
- package/dist/core/hashline-edit-benchmark.js.map +0 -1
- package/dist/core/semantic-search-benchmark.d.ts +0 -36
- package/dist/core/semantic-search-benchmark.js +0 -211
- package/dist/core/semantic-search-benchmark.js.map +0 -1
- package/dist/core/speed-benchmark.d.ts +0 -132
- package/dist/core/speed-benchmark.js +0 -410
- package/dist/core/speed-benchmark.js.map +0 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { log } from "../core/logger.js";
|
|
2
|
+
import { addServer, removeServer, getServer, parseMcpAddCommand, MCPClientManager, McpOAuthStore, } from "../core/mcp/index.js";
|
|
3
|
+
import { readBody, json } from "./http.js";
|
|
4
|
+
import { buildMcpRows, probeMcp } from "./mcp-rows.js";
|
|
5
|
+
export function handleMcpRoutes(ctx, req, res, url, method) {
|
|
6
|
+
// ── MCP server management (mirrors `ggcoder mcp`) ──────────────────
|
|
7
|
+
// `targetCwd` (project scope) overrides the window cwd so a server can be
|
|
8
|
+
// added/removed for ANY discovered project, not just this window's. Global
|
|
9
|
+
// scope ignores it (always ~/.gg/mcp.json).
|
|
10
|
+
if (method === "GET" && (url === "/mcp" || url.startsWith("/mcp?"))) {
|
|
11
|
+
const targetCwd = new URL(url, `http://${ctx.host}`).searchParams.get("cwd") ?? ctx.cwd;
|
|
12
|
+
void buildMcpRows(targetCwd, ctx.paths.settingsFile)
|
|
13
|
+
.then((servers) => json(res, 200, { servers }))
|
|
14
|
+
.catch((err) => {
|
|
15
|
+
log("ERROR", "app-sidecar", "buildMcpRows failed", {
|
|
16
|
+
message: err instanceof Error ? err.message : String(err),
|
|
17
|
+
});
|
|
18
|
+
json(res, 200, { servers: [] });
|
|
19
|
+
});
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
if (method === "POST" && url === "/mcp/add") {
|
|
23
|
+
void readBody(req, res).then(async (raw) => {
|
|
24
|
+
if (raw === null)
|
|
25
|
+
return;
|
|
26
|
+
let line;
|
|
27
|
+
let scopeValue;
|
|
28
|
+
let bodyCwd;
|
|
29
|
+
try {
|
|
30
|
+
const body = JSON.parse(raw);
|
|
31
|
+
line = body.line ?? "";
|
|
32
|
+
scopeValue = body.scope ?? "global";
|
|
33
|
+
bodyCwd = body.cwd;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
json(res, 400, { error: "invalid JSON body" });
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const scope = scopeValue === "project" ? "project" : "global";
|
|
40
|
+
if (scope === "project" && !bodyCwd) {
|
|
41
|
+
json(res, 400, { error: "project scope requires a project (cwd)." });
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const targetCwd = bodyCwd ?? ctx.cwd;
|
|
45
|
+
const parsed = parseMcpAddCommand(line);
|
|
46
|
+
if (!parsed.ok) {
|
|
47
|
+
json(res, 400, { error: parsed.error });
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const config = parsed.value.config;
|
|
51
|
+
try {
|
|
52
|
+
// Best-effort probe — never blocks the save. A failed connect is
|
|
53
|
+
// surfaced to the UI but the config is still persisted (mirrors the
|
|
54
|
+
// CLI). probeMcp swallows connect errors; the try/catch guards the
|
|
55
|
+
// persist step so a write failure returns a 500 instead of becoming
|
|
56
|
+
// an unhandled rejection that would crash the sidecar.
|
|
57
|
+
const probe = await probeMcp(config);
|
|
58
|
+
const saved = await addServer(config, scope, targetCwd, true);
|
|
59
|
+
if (!saved.ok) {
|
|
60
|
+
json(res, 400, { error: saved.error });
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Adding a project-scope server is an explicit trust signal — the
|
|
64
|
+
// user chose to put a server in this repo's .gg/mcp.json. Auto-trust
|
|
65
|
+
// the project so all project-scope servers connect on next load.
|
|
66
|
+
if (scope === "project") {
|
|
67
|
+
await ctx.session.trustProject(targetCwd);
|
|
68
|
+
}
|
|
69
|
+
json(res, 200, {
|
|
70
|
+
ok: true,
|
|
71
|
+
name: config.name,
|
|
72
|
+
connected: probe.ok,
|
|
73
|
+
toolCount: probe.toolCount,
|
|
74
|
+
error: probe.error,
|
|
75
|
+
requiresAuth: probe.requiresAuth,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
json(res, 500, {
|
|
80
|
+
error: err instanceof Error ? err.message : String(err),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
if (method === "POST" && url === "/mcp/remove") {
|
|
87
|
+
void readBody(req, res).then(async (raw) => {
|
|
88
|
+
if (raw === null)
|
|
89
|
+
return;
|
|
90
|
+
let name;
|
|
91
|
+
let scopeValue;
|
|
92
|
+
let bodyCwd;
|
|
93
|
+
try {
|
|
94
|
+
const body = JSON.parse(raw);
|
|
95
|
+
name = body.name ?? "";
|
|
96
|
+
scopeValue = body.scope ?? "global";
|
|
97
|
+
bodyCwd = body.cwd;
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
json(res, 400, { error: "invalid JSON body" });
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (!name.trim()) {
|
|
104
|
+
json(res, 400, { error: "missing server name" });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
const scope = scopeValue === "project" ? "project" : "global";
|
|
108
|
+
if (scope === "project" && !bodyCwd) {
|
|
109
|
+
json(res, 400, { error: "project scope requires a project (cwd)." });
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const targetCwd = bodyCwd ?? ctx.cwd;
|
|
113
|
+
const removed = await removeServer(name, scope, targetCwd);
|
|
114
|
+
// Drop any saved OAuth tokens for this server so a re-add starts clean.
|
|
115
|
+
await new McpOAuthStore().clear(name).catch(() => { });
|
|
116
|
+
json(res, 200, { removed });
|
|
117
|
+
});
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
// Interactive OAuth login for a remote (HTTP) MCP server. The browser is
|
|
121
|
+
// opened by the webview in response to the broadcast `mcp_auth_url` event;
|
|
122
|
+
// progress + outcome stream via `mcp_auth_status` / `mcp_auth_done` /
|
|
123
|
+
// `mcp_auth_error`. Responds 202 immediately and runs the flow in the
|
|
124
|
+
// background (the browser round-trip can take a while).
|
|
125
|
+
if (method === "POST" && url === "/mcp/login") {
|
|
126
|
+
void readBody(req, res).then(async (raw) => {
|
|
127
|
+
if (raw === null)
|
|
128
|
+
return;
|
|
129
|
+
let name;
|
|
130
|
+
let scopeValue;
|
|
131
|
+
let bodyCwd;
|
|
132
|
+
try {
|
|
133
|
+
const body = JSON.parse(raw);
|
|
134
|
+
name = body.name ?? "";
|
|
135
|
+
scopeValue = body.scope ?? "global";
|
|
136
|
+
bodyCwd = body.cwd;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
json(res, 400, { error: "invalid JSON body" });
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (!name.trim()) {
|
|
143
|
+
json(res, 400, { error: "missing server name" });
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const scope = scopeValue === "project" ? "project" : "global";
|
|
147
|
+
const targetCwd = bodyCwd ?? ctx.cwd;
|
|
148
|
+
const scoped = await getServer(name, targetCwd);
|
|
149
|
+
if (!scoped || scoped.scope !== scope) {
|
|
150
|
+
json(res, 404, { error: `No "${name}" server found.` });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (!scoped.config.url) {
|
|
154
|
+
json(res, 400, { error: "Login is only supported for HTTP MCP servers." });
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
json(res, 202, { accepted: true });
|
|
158
|
+
ctx.broadcast("mcp_auth_status", { name, message: "Starting login\u2026" });
|
|
159
|
+
const manager = new MCPClientManager();
|
|
160
|
+
try {
|
|
161
|
+
const result = await manager.login(scoped.config, (authUrl) => {
|
|
162
|
+
ctx.broadcast("mcp_auth_url", { name, url: authUrl });
|
|
163
|
+
});
|
|
164
|
+
if (result.ok) {
|
|
165
|
+
ctx.broadcast("mcp_auth_done", { name, toolCount: result.toolCount });
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
ctx.broadcast("mcp_auth_error", { name, message: result.error ?? "Login failed." });
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
ctx.broadcast("mcp_auth_error", {
|
|
173
|
+
name,
|
|
174
|
+
message: err instanceof Error ? err.message : String(err),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
finally {
|
|
178
|
+
await manager.dispose().catch(() => { });
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=mcp-routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-routes.js","sourceRoot":"","sources":["../../src/app-sidecar/mcp-routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type MCPScope, type MCPServerConfig } from "../core/mcp/index.js";
|
|
2
|
+
/** One wire row for the MCP list: a server config joined with its live status. */
|
|
3
|
+
export interface McpWireRow {
|
|
4
|
+
name: string;
|
|
5
|
+
scope: MCPScope;
|
|
6
|
+
ok: boolean;
|
|
7
|
+
toolCount: number;
|
|
8
|
+
error?: string;
|
|
9
|
+
kind: "stdio" | "http";
|
|
10
|
+
summary: string;
|
|
11
|
+
/** True when the server needs an interactive OAuth login before it connects. */
|
|
12
|
+
requiresAuth?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** A short transport summary for display (URL for http/sse, command+args for stdio). */
|
|
15
|
+
export declare function mcpRowSummary(config: MCPServerConfig): string;
|
|
16
|
+
/** Load + connect every server, returning one wire row per server. Mirrors the
|
|
17
|
+
* CLI dashboard's buildRows (connectAllDetailed, then dispose). Empty list
|
|
18
|
+
* short-circuits before spawning any stdio process / opening any HTTP conn.
|
|
19
|
+
* Project-scope servers run repo-controlled commands, so unless the user
|
|
20
|
+
* trusts them (trustProjectMcpServers) they are reported blocked WITHOUT
|
|
21
|
+
* being connected — even a status probe would spawn the process. */
|
|
22
|
+
export declare function buildMcpRows(cwd: string, settingsFile: string): Promise<McpWireRow[]>;
|
|
23
|
+
/** Probe a single server's connection before persisting it. Never throws — a
|
|
24
|
+
* failed probe returns ok:false with a human-readable error so the config can
|
|
25
|
+
* still be saved. Mirrors the CLI's probeServer. */
|
|
26
|
+
export declare function probeMcp(config: MCPServerConfig): Promise<{
|
|
27
|
+
ok: boolean;
|
|
28
|
+
toolCount: number;
|
|
29
|
+
error?: string;
|
|
30
|
+
requiresAuth?: boolean;
|
|
31
|
+
}>;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { loadSavedSettings, projectScopeAllowed } from "../config.js";
|
|
2
|
+
import { loadServers, MCPClientManager, } from "../core/mcp/index.js";
|
|
3
|
+
/** A short transport summary for display (URL for http/sse, command+args for stdio). */
|
|
4
|
+
export function mcpRowSummary(config) {
|
|
5
|
+
if (config.url)
|
|
6
|
+
return config.url;
|
|
7
|
+
return [config.command, ...(config.args ?? [])].filter(Boolean).join(" ");
|
|
8
|
+
}
|
|
9
|
+
/** Load + connect every server, returning one wire row per server. Mirrors the
|
|
10
|
+
* CLI dashboard's buildRows (connectAllDetailed, then dispose). Empty list
|
|
11
|
+
* short-circuits before spawning any stdio process / opening any HTTP conn.
|
|
12
|
+
* Project-scope servers run repo-controlled commands, so unless the user
|
|
13
|
+
* trusts them (trustProjectMcpServers) they are reported blocked WITHOUT
|
|
14
|
+
* being connected — even a status probe would spawn the process. */
|
|
15
|
+
export async function buildMcpRows(cwd, settingsFile) {
|
|
16
|
+
const scoped = await loadServers(cwd);
|
|
17
|
+
if (scoped.length === 0)
|
|
18
|
+
return [];
|
|
19
|
+
const settings = loadSavedSettings(settingsFile);
|
|
20
|
+
const allowProject = projectScopeAllowed(settings.trustProjectMcpServers, settings.trustedProjects, cwd);
|
|
21
|
+
const connectable = scoped.filter((s) => allowProject || s.scope !== "project");
|
|
22
|
+
const blocked = scoped.filter((s) => !allowProject && s.scope === "project");
|
|
23
|
+
const manager = new MCPClientManager();
|
|
24
|
+
try {
|
|
25
|
+
const results = connectable.length > 0
|
|
26
|
+
? await manager.connectAllDetailed(connectable.map((s) => s.config))
|
|
27
|
+
: [];
|
|
28
|
+
return [
|
|
29
|
+
...connectable.map((s) => {
|
|
30
|
+
const result = results.find((r) => r.name === s.config.name);
|
|
31
|
+
return {
|
|
32
|
+
name: s.config.name,
|
|
33
|
+
scope: s.scope,
|
|
34
|
+
ok: result?.ok ?? false,
|
|
35
|
+
toolCount: result?.toolCount ?? 0,
|
|
36
|
+
error: result?.error,
|
|
37
|
+
kind: s.config.url ? "http" : "stdio",
|
|
38
|
+
summary: mcpRowSummary(s.config),
|
|
39
|
+
requiresAuth: result?.requiresAuth,
|
|
40
|
+
};
|
|
41
|
+
}),
|
|
42
|
+
...blocked.map((s) => ({
|
|
43
|
+
name: s.config.name,
|
|
44
|
+
scope: s.scope,
|
|
45
|
+
ok: false,
|
|
46
|
+
toolCount: 0,
|
|
47
|
+
error: "Project-scope server not connected — this repo's .gg/mcp.json runs " +
|
|
48
|
+
"repo-controlled commands. Add or re-add a server in this project via " +
|
|
49
|
+
"the MCP modal to trust it.",
|
|
50
|
+
kind: (s.config.url ? "http" : "stdio"),
|
|
51
|
+
summary: mcpRowSummary(s.config),
|
|
52
|
+
})),
|
|
53
|
+
];
|
|
54
|
+
}
|
|
55
|
+
finally {
|
|
56
|
+
await manager.dispose();
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** Probe a single server's connection before persisting it. Never throws — a
|
|
60
|
+
* failed probe returns ok:false with a human-readable error so the config can
|
|
61
|
+
* still be saved. Mirrors the CLI's probeServer. */
|
|
62
|
+
export async function probeMcp(config) {
|
|
63
|
+
const manager = new MCPClientManager();
|
|
64
|
+
try {
|
|
65
|
+
const result = await manager.probe(config);
|
|
66
|
+
return {
|
|
67
|
+
ok: result.ok,
|
|
68
|
+
toolCount: result.toolCount,
|
|
69
|
+
error: result.error,
|
|
70
|
+
requiresAuth: result.requiresAuth,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
await manager.dispose();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=mcp-rows.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-rows.js","sourceRoot":"","sources":["../../src/app-sidecar/mcp-rows.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ProgressSnapshot } from "../core/progress/types.js";
|
|
2
|
+
export interface ProgressManager {
|
|
3
|
+
/** Current snapshot for GET /progress + the SSE ready path. */
|
|
4
|
+
snapshot: () => ProgressSnapshot;
|
|
5
|
+
/** Award XP for one successfully completed run (prompt + any new commits). */
|
|
6
|
+
awardRun: (cwd: string, runStartedAt: number, originId?: string) => Promise<void>;
|
|
7
|
+
/** Close the ~/.gg fs.watch + clear any pending debounce (leak-free shutdown). */
|
|
8
|
+
dispose: () => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function createProgressManager(agentDir: string, broadcastAll: (snapshot: ProgressSnapshot, originId?: string) => void): Promise<ProgressManager>;
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { watch as fsWatch } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { randomUUID } from "node:crypto";
|
|
4
|
+
import { CHAT_AGENT_IDS, chatAgentSessionsDir } from "../chat-agents/index.js";
|
|
5
|
+
import { log } from "../core/logger.js";
|
|
6
|
+
import { buildSnapshot, levelForXp, rankForLevel } from "../core/progress/ranks.js";
|
|
7
|
+
import { loadProgress, peekProgress, updateProgress } from "../core/progress/store.js";
|
|
8
|
+
import { awardPrompt, awardCommits } from "../core/progress/engine.js";
|
|
9
|
+
import { detectNewCommits, repoKey } from "../core/progress/git-xp.js";
|
|
10
|
+
import { rebuildFromSessions } from "../core/progress/rebuild.js";
|
|
11
|
+
export async function createProgressManager(agentDir, broadcastAll) {
|
|
12
|
+
// Boot: recovery chain main → backup → coding + chat session rebuild → empty.
|
|
13
|
+
const coderSessionsDir = path.join(agentDir, "sessions");
|
|
14
|
+
let file = await loadProgress({
|
|
15
|
+
rebuild: () => rebuildFromSessions([
|
|
16
|
+
coderSessionsDir,
|
|
17
|
+
...CHAT_AGENT_IDS.map((agentId) => chatAgentSessionsDir(coderSessionsDir, agentId)),
|
|
18
|
+
]),
|
|
19
|
+
});
|
|
20
|
+
// Don't re-celebrate an old levelUp event on boot.
|
|
21
|
+
let lastSeenNonce = file.lastEvent?.nonce ?? null;
|
|
22
|
+
log("INFO", "app-sidecar", "progress loaded", {
|
|
23
|
+
xp: String(file.xp),
|
|
24
|
+
level: String(levelForXp(file.xp)),
|
|
25
|
+
});
|
|
26
|
+
function snapshot() {
|
|
27
|
+
return buildSnapshot(file);
|
|
28
|
+
}
|
|
29
|
+
async function awardRun(cwd, runStartedAt, originId) {
|
|
30
|
+
try {
|
|
31
|
+
const now = Date.now();
|
|
32
|
+
const updated = await updateProgress(async (f) => {
|
|
33
|
+
const levelBefore = levelForXp(f.xp);
|
|
34
|
+
awardPrompt(f, now, cwd);
|
|
35
|
+
// Commit XP: probe repo root + HEAD, then score lastHead..HEAD bounded
|
|
36
|
+
// by the run window. First sight of a repo records HEAD, scores nothing.
|
|
37
|
+
const probe = await detectNewCommits(cwd, undefined, runStartedAt);
|
|
38
|
+
if (probe) {
|
|
39
|
+
const key = repoKey(probe.repoRoot);
|
|
40
|
+
const lastHead = f.repos[key]?.lastHead;
|
|
41
|
+
if (lastHead && lastHead !== probe.head) {
|
|
42
|
+
const detected = await detectNewCommits(cwd, lastHead, runStartedAt);
|
|
43
|
+
if (detected && detected.commits.length > 0) {
|
|
44
|
+
awardCommits(f, detected.commits, now, cwd);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
f.repos[key] = { lastHead: probe.head };
|
|
48
|
+
}
|
|
49
|
+
// One combined lastEvent per run so other windows celebrate exactly once.
|
|
50
|
+
const levelAfter = levelForXp(f.xp);
|
|
51
|
+
const levelUp = levelAfter > levelBefore
|
|
52
|
+
? { from: levelBefore, to: levelAfter, rankName: rankForLevel(levelAfter).name }
|
|
53
|
+
: null;
|
|
54
|
+
f.lastEvent = { nonce: randomUUID(), levelUp };
|
|
55
|
+
return { file: f, levelledUp: levelUp !== null };
|
|
56
|
+
});
|
|
57
|
+
file = updated;
|
|
58
|
+
lastSeenNonce = updated.lastEvent?.nonce ?? null;
|
|
59
|
+
broadcastAll(buildSnapshot(updated), originId);
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
log("DEBUG", "app-sidecar", "progress award failed", {
|
|
63
|
+
message: err instanceof Error ? err.message : String(err),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
// Watch ~/.gg (dir watch survives the atomic tmp+rename) for progress.json
|
|
68
|
+
// writes from other daemon processes; debounce, reload read-only, dedupe by nonce.
|
|
69
|
+
let watchDebounce = null;
|
|
70
|
+
let progressWatcher = null;
|
|
71
|
+
try {
|
|
72
|
+
const watcher = fsWatch(agentDir, (_event, filename) => {
|
|
73
|
+
if (filename !== "progress.json")
|
|
74
|
+
return;
|
|
75
|
+
if (watchDebounce)
|
|
76
|
+
clearTimeout(watchDebounce);
|
|
77
|
+
watchDebounce = setTimeout(() => {
|
|
78
|
+
void (async () => {
|
|
79
|
+
const reloaded = await peekProgress();
|
|
80
|
+
if (!reloaded)
|
|
81
|
+
return;
|
|
82
|
+
const nonce = reloaded.lastEvent?.nonce ?? null;
|
|
83
|
+
if (nonce === lastSeenNonce)
|
|
84
|
+
return;
|
|
85
|
+
file = reloaded;
|
|
86
|
+
lastSeenNonce = nonce;
|
|
87
|
+
broadcastAll(buildSnapshot(reloaded));
|
|
88
|
+
})();
|
|
89
|
+
}, 150);
|
|
90
|
+
});
|
|
91
|
+
watcher.unref();
|
|
92
|
+
progressWatcher = watcher;
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
log("DEBUG", "app-sidecar", "progress watch unavailable", {
|
|
96
|
+
message: err instanceof Error ? err.message : String(err),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
// Dispose closes the fs.watch handle (baseline #8: it was previously never
|
|
100
|
+
// closed — a per-daemon leak) and clears any pending debounce timer.
|
|
101
|
+
function dispose() {
|
|
102
|
+
if (watchDebounce) {
|
|
103
|
+
clearTimeout(watchDebounce);
|
|
104
|
+
watchDebounce = null;
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
progressWatcher?.close();
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
// Already closed / never opened — nothing to do.
|
|
111
|
+
}
|
|
112
|
+
progressWatcher = null;
|
|
113
|
+
}
|
|
114
|
+
return { snapshot, awardRun, dispose };
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=progress-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"progress-manager.js","sourceRoot":"","sources":["../../src/app-sidecar/progress-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,OAAO,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/E,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACvF,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAmBlE,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,QAAgB,EAChB,YAAqE;IAErE,8EAA8E;IAC9E,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACzD,IAAI,IAAI,GAAiB,MAAM,YAAY,CAAC;QAC1C,OAAO,EAAE,GAAG,EAAE,CACZ,mBAAmB,CAAC;YAClB,gBAAgB;YAChB,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,oBAAoB,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;SACpF,CAAC;KACL,CAAC,CAAC;IACH,mDAAmD;IACnD,IAAI,aAAa,GAAkB,IAAI,CAAC,SAAS,EAAE,KAAK,IAAI,IAAI,CAAC;IACjE,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,iBAAiB,EAAE;QAC5C,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;KACnC,CAAC,CAAC;IAEH,SAAS,QAAQ;QACf,OAAO,aAAa,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,YAAoB,EAAE,QAAiB;QAC1E,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;gBAC/C,MAAM,WAAW,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACrC,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;gBAEzB,uEAAuE;gBACvE,yEAAyE;gBACzE,MAAM,KAAK,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,SAAS,EAAE,YAAY,CAAC,CAAC;gBACnE,IAAI,KAAK,EAAE,CAAC;oBACV,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACpC,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC;oBACxC,IAAI,QAAQ,IAAI,QAAQ,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;wBACxC,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;wBACrE,IAAI,QAAQ,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAC5C,YAAY,CAAC,CAAC,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;wBAC9C,CAAC;oBACH,CAAC;oBACD,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC1C,CAAC;gBAED,0EAA0E;gBAC1E,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACpC,MAAM,OAAO,GACX,UAAU,GAAG,WAAW;oBACtB,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE;oBAChF,CAAC,CAAC,IAAI,CAAC;gBACX,CAAC,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,CAAC;gBAC/C,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,KAAK,IAAI,EAAE,CAAC;YACnD,CAAC,CAAC,CAAC;YACH,IAAI,GAAG,OAAO,CAAC;YACf,aAAa,GAAG,OAAO,CAAC,SAAS,EAAE,KAAK,IAAI,IAAI,CAAC;YACjD,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE;gBACnD,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aAC1D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,2EAA2E;IAC3E,mFAAmF;IACnF,IAAI,aAAa,GAA0B,IAAI,CAAC;IAChD,IAAI,eAAe,GAAsC,IAAI,CAAC;IAC9D,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE;YACrD,IAAI,QAAQ,KAAK,eAAe;gBAAE,OAAO;YACzC,IAAI,aAAa;gBAAE,YAAY,CAAC,aAAa,CAAC,CAAC;YAC/C,aAAa,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC9B,KAAK,CAAC,KAAK,IAAI,EAAE;oBACf,MAAM,QAAQ,GAAG,MAAM,YAAY,EAAE,CAAC;oBACtC,IAAI,CAAC,QAAQ;wBAAE,OAAO;oBACtB,MAAM,KAAK,GAAG,QAAQ,CAAC,SAAS,EAAE,KAAK,IAAI,IAAI,CAAC;oBAChD,IAAI,KAAK,KAAK,aAAa;wBAAE,OAAO;oBACpC,IAAI,GAAG,QAAQ,CAAC;oBAChB,aAAa,GAAG,KAAK,CAAC;oBACtB,YAAY,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACxC,CAAC,CAAC,EAAE,CAAC;YACP,CAAC,EAAE,GAAG,CAAC,CAAC;QACV,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,eAAe,GAAG,OAAO,CAAC;IAC5B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,OAAO,EAAE,aAAa,EAAE,4BAA4B,EAAE;YACxD,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SAC1D,CAAC,CAAC;IACL,CAAC;IAED,2EAA2E;IAC3E,qEAAqE;IACrE,SAAS,OAAO;QACd,IAAI,aAAa,EAAE,CAAC;YAClB,YAAY,CAAC,aAAa,CAAC,CAAC;YAC5B,aAAa,GAAG,IAAI,CAAC;QACvB,CAAC;QACD,IAAI,CAAC;YACH,eAAe,EAAE,KAAK,EAAE,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,iDAAiD;QACnD,CAAC;QACD,eAAe,GAAG,IAAI,CAAC;IACzB,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC"}
|