@kenkaiiii/ggcoder 5.19.4 → 5.19.6
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.js +69 -10
- package/dist/app-sidecar.js.map +1 -1
- package/dist/core/sidecar-error-reporter.d.ts +12 -0
- package/dist/core/sidecar-error-reporter.d.ts.map +1 -0
- package/dist/core/sidecar-error-reporter.js +57 -0
- package/dist/core/sidecar-error-reporter.js.map +1 -0
- package/dist/core/sidecar-error-reporter.test.d.ts +2 -0
- package/dist/core/sidecar-error-reporter.test.d.ts.map +1 -0
- package/dist/core/sidecar-error-reporter.test.js +61 -0
- package/dist/core/sidecar-error-reporter.test.js.map +1 -0
- package/dist/modes/json-mode.d.ts.map +1 -1
- package/dist/modes/json-mode.js +6 -0
- package/dist/modes/json-mode.js.map +1 -1
- package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
- package/dist/modes/subagent-worker-mode.js +10 -0
- package/dist/modes/subagent-worker-mode.js.map +1 -1
- package/dist/tools/subagent-shared.d.ts +1 -1
- package/dist/tools/subagent-shared.d.ts.map +1 -1
- package/dist/tools/subagent-shared.js +4 -1
- package/dist/tools/subagent-shared.js.map +1 -1
- package/dist/tools/subagent-shared.test.js +6 -1
- package/dist/tools/subagent-shared.test.js.map +1 -1
- package/package.json +4 -4
package/dist/app-sidecar.js
CHANGED
|
@@ -64,6 +64,7 @@ import { loadProgress, peekProgress, updateProgress } from "./core/progress/stor
|
|
|
64
64
|
import { awardPrompt, awardCommits } from "./core/progress/engine.js";
|
|
65
65
|
import { detectNewCommits, repoKey } from "./core/progress/git-xp.js";
|
|
66
66
|
import { rebuildFromSessions } from "./core/progress/rebuild.js";
|
|
67
|
+
import { captureSidecarError, flushSidecarErrors, shouldCaptureToolFailure, shouldCaptureUsagePollingError, wrapSidecarHandler, } from "./core/sidecar-error-reporter.js";
|
|
67
68
|
const ALL_PROVIDERS = [
|
|
68
69
|
// US
|
|
69
70
|
"anthropic",
|
|
@@ -169,6 +170,7 @@ async function persistModelSelection(settingsFile, provider, model) {
|
|
|
169
170
|
await sm.set("defaultModel", model);
|
|
170
171
|
}
|
|
171
172
|
catch (err) {
|
|
173
|
+
captureSidecarError(err, "app-sidecar.settings.persist-model");
|
|
172
174
|
log("WARN", "app-sidecar", "failed to persist model selection", { err: String(err) });
|
|
173
175
|
}
|
|
174
176
|
}
|
|
@@ -185,6 +187,7 @@ async function persistThinkingLevel(settingsFile, level) {
|
|
|
185
187
|
await sm.set("thinkingLevel", level);
|
|
186
188
|
}
|
|
187
189
|
catch (err) {
|
|
190
|
+
captureSidecarError(err, "app-sidecar.settings.persist-thinking");
|
|
188
191
|
log("WARN", "app-sidecar", "failed to persist thinking level", { err: String(err) });
|
|
189
192
|
}
|
|
190
193
|
}
|
|
@@ -452,7 +455,11 @@ async function runJsonModeIfRequested() {
|
|
|
452
455
|
maxTurns: maxTurnsRaw ? parseInt(maxTurnsRaw, 10) : undefined,
|
|
453
456
|
allowedTools,
|
|
454
457
|
promptCacheKey: values["prompt-cache-key"],
|
|
455
|
-
}).catch((err) => {
|
|
458
|
+
}).catch(async (err) => {
|
|
459
|
+
captureSidecarError(err, "app-sidecar.json-mode", {
|
|
460
|
+
provider: String(values.provider ?? "anthropic"),
|
|
461
|
+
});
|
|
462
|
+
await flushSidecarErrors();
|
|
456
463
|
process.stderr.write((err instanceof Error ? err.message : String(err)) + "\n");
|
|
457
464
|
process.exit(1);
|
|
458
465
|
});
|
|
@@ -590,6 +597,9 @@ async function main() {
|
|
|
590
597
|
}
|
|
591
598
|
catch (error) {
|
|
592
599
|
const message = error instanceof Error ? error.message : String(error);
|
|
600
|
+
if (shouldCaptureUsagePollingError(error)) {
|
|
601
|
+
captureSidecarError(error, "app-sidecar.usage.fetch", { provider });
|
|
602
|
+
}
|
|
593
603
|
log("WARN", "app-sidecar", "subscription usage fetch failed", { provider, message });
|
|
594
604
|
if (error instanceof SubscriptionUsageError && error.status === 429) {
|
|
595
605
|
usageRateLimitedUntil.set(provider, Date.now() + USAGE_RATE_LIMIT_BACKOFF_MS);
|
|
@@ -649,7 +659,7 @@ async function main() {
|
|
|
649
659
|
return null;
|
|
650
660
|
}
|
|
651
661
|
}
|
|
652
|
-
const server = http.createServer((req, res) => {
|
|
662
|
+
const server = http.createServer(wrapSidecarHandler((req, res) => {
|
|
653
663
|
const url = req.url ?? "/";
|
|
654
664
|
const method = req.method ?? "GET";
|
|
655
665
|
// CORS preflight — the webview origin differs from 127.0.0.1.
|
|
@@ -693,6 +703,7 @@ async function main() {
|
|
|
693
703
|
}
|
|
694
704
|
catch (err) {
|
|
695
705
|
const message = err instanceof Error ? err.message : String(err);
|
|
706
|
+
captureSidecarError(err, "app-sidecar.session.create");
|
|
696
707
|
log("ERROR", "app-sidecar", "session create failed", { message });
|
|
697
708
|
daemonJson(res, 500, { error: message });
|
|
698
709
|
}
|
|
@@ -729,6 +740,7 @@ async function main() {
|
|
|
729
740
|
}
|
|
730
741
|
daemonJson(res, 200, await subscriptionUsage(provider));
|
|
731
742
|
})().catch((error) => {
|
|
743
|
+
captureSidecarError(error, "app-sidecar.usage.request");
|
|
732
744
|
log("ERROR", "app-sidecar", "subscription usage request failed", {
|
|
733
745
|
message: error instanceof Error ? error.message : String(error),
|
|
734
746
|
});
|
|
@@ -744,7 +756,7 @@ async function main() {
|
|
|
744
756
|
return;
|
|
745
757
|
}
|
|
746
758
|
ctx.handle(req, res, url, method);
|
|
747
|
-
});
|
|
759
|
+
}, "app-sidecar.http"));
|
|
748
760
|
server.listen(port, host, () => {
|
|
749
761
|
const addr = server.address();
|
|
750
762
|
// The Rust shell reads this line to learn the daemon port.
|
|
@@ -889,6 +901,7 @@ async function createProgressManager(agentDir, broadcastAll) {
|
|
|
889
901
|
broadcastAll(buildSnapshot(updated), originId);
|
|
890
902
|
}
|
|
891
903
|
catch (err) {
|
|
904
|
+
captureSidecarError(err, "app-sidecar.progress.award");
|
|
892
905
|
log("DEBUG", "app-sidecar", "progress award failed", {
|
|
893
906
|
message: err instanceof Error ? err.message : String(err),
|
|
894
907
|
});
|
|
@@ -920,6 +933,7 @@ async function createProgressManager(agentDir, broadcastAll) {
|
|
|
920
933
|
watcher.unref();
|
|
921
934
|
}
|
|
922
935
|
catch (err) {
|
|
936
|
+
captureSidecarError(err, "app-sidecar.progress.watch");
|
|
923
937
|
log("DEBUG", "app-sidecar", "progress watch unavailable", {
|
|
924
938
|
message: err instanceof Error ? err.message : String(err),
|
|
925
939
|
});
|
|
@@ -1010,6 +1024,11 @@ async function createSession(deps, opts) {
|
|
|
1010
1024
|
const f = formatError(err);
|
|
1011
1025
|
const message = f.message ? desktopGuidance(f.message) : undefined;
|
|
1012
1026
|
const guidance = desktopGuidance(f.guidance);
|
|
1027
|
+
captureSidecarError(err, `app-sidecar.${logLabel.replaceAll(" ", "-")}`, {
|
|
1028
|
+
scope: type,
|
|
1029
|
+
...(f.provider ? { provider: f.provider } : {}),
|
|
1030
|
+
...(f.statusCode != null ? { status: String(f.statusCode) } : {}),
|
|
1031
|
+
});
|
|
1013
1032
|
log("ERROR", "app-sidecar", logLabel, {
|
|
1014
1033
|
headline: f.headline,
|
|
1015
1034
|
source: f.source,
|
|
@@ -1067,6 +1086,7 @@ async function createSession(deps, opts) {
|
|
|
1067
1086
|
chatAgent = nextAgent;
|
|
1068
1087
|
broadcast("chat_agent_change", { chatAgent: nextAgent });
|
|
1069
1088
|
await session.persistAppMarker("agent_handoff", { chatAgent: nextAgent }).catch((error) => {
|
|
1089
|
+
captureSidecarError(error, "app-sidecar.chat-agent.persist-handoff");
|
|
1070
1090
|
log("WARN", "app-sidecar", "agent handoff marker persist failed", {
|
|
1071
1091
|
message: error instanceof Error ? error.message : String(error),
|
|
1072
1092
|
});
|
|
@@ -1185,6 +1205,7 @@ async function createSession(deps, opts) {
|
|
|
1185
1205
|
.catch(() => false)
|
|
1186
1206
|
.then(() => syncApprovedPlanProgress(generation))
|
|
1187
1207
|
.catch((error) => {
|
|
1208
|
+
captureSidecarError(error, "app-sidecar.plan.refresh-progress");
|
|
1188
1209
|
log("WARN", "app-sidecar", "plan progress refresh failed", {
|
|
1189
1210
|
message: error instanceof Error ? error.message : String(error),
|
|
1190
1211
|
});
|
|
@@ -1239,6 +1260,11 @@ async function createSession(deps, opts) {
|
|
|
1239
1260
|
session.eventBus.on("tool_call_end", (d) => {
|
|
1240
1261
|
const name = toolCallNames.get(d.toolCallId) ?? "unknown";
|
|
1241
1262
|
toolCallNames.delete(d.toolCallId);
|
|
1263
|
+
if (d.isError && shouldCaptureToolFailure(name, d.result)) {
|
|
1264
|
+
// Expected model-correctable validation failures stay in the local log and
|
|
1265
|
+
// conversation. Unexpected failures are reported without private result data.
|
|
1266
|
+
captureSidecarError(new Error(`Tool ${name} failed`), `tool.${name}`, { tool: name });
|
|
1267
|
+
}
|
|
1242
1268
|
log(d.isError ? "ERROR" : "INFO", "tool", `Tool call ended: ${name}`, {
|
|
1243
1269
|
id: d.toolCallId,
|
|
1244
1270
|
durationMs: String(d.durationMs),
|
|
@@ -1579,6 +1605,7 @@ async function createSession(deps, opts) {
|
|
|
1579
1605
|
catch (error) {
|
|
1580
1606
|
// Keep tracking when prompt cleanup fails; hiding the widget here
|
|
1581
1607
|
// would claim completion while the approved-plan contract remained.
|
|
1608
|
+
captureSidecarError(error, "app-sidecar.plan.cleanup");
|
|
1582
1609
|
log("WARN", "app-sidecar", "completed plan cleanup failed", {
|
|
1583
1610
|
message: error instanceof Error ? error.message : String(error),
|
|
1584
1611
|
});
|
|
@@ -2058,7 +2085,10 @@ async function createSession(deps, opts) {
|
|
|
2058
2085
|
void memoryStore
|
|
2059
2086
|
.snapshot()
|
|
2060
2087
|
.then((snapshot) => json(res, 200, snapshot))
|
|
2061
|
-
.catch((error) =>
|
|
2088
|
+
.catch((error) => {
|
|
2089
|
+
captureSidecarError(error, "app-sidecar.memory.snapshot");
|
|
2090
|
+
json(res, 500, { error: error instanceof Error ? error.message : String(error) });
|
|
2091
|
+
});
|
|
2062
2092
|
return;
|
|
2063
2093
|
}
|
|
2064
2094
|
if (method === "DELETE" && url.startsWith("/memories/")) {
|
|
@@ -2071,14 +2101,20 @@ async function createSession(deps, opts) {
|
|
|
2071
2101
|
.forget(id)
|
|
2072
2102
|
.then(() => memoryStore.snapshot())
|
|
2073
2103
|
.then((snapshot) => json(res, 200, snapshot))
|
|
2074
|
-
.catch((error) =>
|
|
2104
|
+
.catch((error) => {
|
|
2105
|
+
captureSidecarError(error, "app-sidecar.memory.forget");
|
|
2106
|
+
json(res, 500, { error: error instanceof Error ? error.message : String(error) });
|
|
2107
|
+
});
|
|
2075
2108
|
return;
|
|
2076
2109
|
}
|
|
2077
2110
|
if (method === "GET" && url === "/jiwa") {
|
|
2078
2111
|
void jiwaStore
|
|
2079
2112
|
.snapshot()
|
|
2080
2113
|
.then((snapshot) => json(res, 200, snapshot))
|
|
2081
|
-
.catch((error) =>
|
|
2114
|
+
.catch((error) => {
|
|
2115
|
+
captureSidecarError(error, "app-sidecar.jiwa.snapshot");
|
|
2116
|
+
json(res, 500, { error: error instanceof Error ? error.message : String(error) });
|
|
2117
|
+
});
|
|
2082
2118
|
return;
|
|
2083
2119
|
}
|
|
2084
2120
|
if (method === "DELETE" && url.startsWith("/jiwa/")) {
|
|
@@ -2091,7 +2127,10 @@ async function createSession(deps, opts) {
|
|
|
2091
2127
|
.forget(id)
|
|
2092
2128
|
.then(() => jiwaStore.snapshot())
|
|
2093
2129
|
.then((snapshot) => json(res, 200, snapshot))
|
|
2094
|
-
.catch((error) =>
|
|
2130
|
+
.catch((error) => {
|
|
2131
|
+
captureSidecarError(error, "app-sidecar.jiwa.forget");
|
|
2132
|
+
json(res, 500, { error: error instanceof Error ? error.message : String(error) });
|
|
2133
|
+
});
|
|
2095
2134
|
return;
|
|
2096
2135
|
}
|
|
2097
2136
|
if (method === "GET" && (url === "/events" || url.startsWith("/events?"))) {
|
|
@@ -2204,6 +2243,7 @@ async function createSession(deps, opts) {
|
|
|
2204
2243
|
json(res, 200, { path: dir });
|
|
2205
2244
|
}
|
|
2206
2245
|
catch (err) {
|
|
2246
|
+
captureSidecarError(err, "app-sidecar.project.create");
|
|
2207
2247
|
json(res, 500, { error: err instanceof Error ? err.message : String(err) });
|
|
2208
2248
|
}
|
|
2209
2249
|
});
|
|
@@ -2214,6 +2254,7 @@ async function createSession(deps, opts) {
|
|
|
2214
2254
|
void discoverProjects()
|
|
2215
2255
|
.then((projects) => json(res, 200, { projects }))
|
|
2216
2256
|
.catch((err) => {
|
|
2257
|
+
captureSidecarError(err, "app-sidecar.projects.discover");
|
|
2217
2258
|
log("ERROR", "app-sidecar", "discoverProjects failed", {
|
|
2218
2259
|
message: err instanceof Error ? err.message : String(err),
|
|
2219
2260
|
});
|
|
@@ -2247,7 +2288,10 @@ async function createSession(deps, opts) {
|
|
|
2247
2288
|
.map(({ item }) => item);
|
|
2248
2289
|
json(res, 200, { sessions: recent });
|
|
2249
2290
|
})
|
|
2250
|
-
.catch(() =>
|
|
2291
|
+
.catch((error) => {
|
|
2292
|
+
captureSidecarError(error, "app-sidecar.sessions.list-chat");
|
|
2293
|
+
json(res, 200, { sessions: [] });
|
|
2294
|
+
});
|
|
2251
2295
|
return;
|
|
2252
2296
|
}
|
|
2253
2297
|
// The picker may be served by a sidecar currently running in Chat mode.
|
|
@@ -2258,7 +2302,10 @@ async function createSession(deps, opts) {
|
|
|
2258
2302
|
: paths.sessionsDir;
|
|
2259
2303
|
void listRecentSessions(target, 5, sessionsDir)
|
|
2260
2304
|
.then((sessions) => json(res, 200, { sessions }))
|
|
2261
|
-
.catch(() =>
|
|
2305
|
+
.catch((error) => {
|
|
2306
|
+
captureSidecarError(error, "app-sidecar.sessions.list");
|
|
2307
|
+
json(res, 200, { sessions: [] });
|
|
2308
|
+
});
|
|
2262
2309
|
return;
|
|
2263
2310
|
}
|
|
2264
2311
|
if (method === "GET" && url.startsWith("/files")) {
|
|
@@ -2266,6 +2313,7 @@ async function createSession(deps, opts) {
|
|
|
2266
2313
|
void searchProjectFiles(cwd, q)
|
|
2267
2314
|
.then((files) => json(res, 200, { files }))
|
|
2268
2315
|
.catch((err) => {
|
|
2316
|
+
captureSidecarError(err, "app-sidecar.files.search");
|
|
2269
2317
|
log("ERROR", "app-sidecar", "searchProjectFiles failed", {
|
|
2270
2318
|
message: err instanceof Error ? err.message : String(err),
|
|
2271
2319
|
});
|
|
@@ -2833,6 +2881,7 @@ async function createSession(deps, opts) {
|
|
|
2833
2881
|
}
|
|
2834
2882
|
catch (err) {
|
|
2835
2883
|
const message = err instanceof Error ? err.message : String(err);
|
|
2884
|
+
captureSidecarError(err, "app-sidecar.prompt-enhancer");
|
|
2836
2885
|
log("ERROR", "app-sidecar", "enhance failed", { message });
|
|
2837
2886
|
json(res, 500, { error: message });
|
|
2838
2887
|
}
|
|
@@ -3158,6 +3207,7 @@ async function createSession(deps, opts) {
|
|
|
3158
3207
|
drained,
|
|
3159
3208
|
});
|
|
3160
3209
|
})().catch((error) => {
|
|
3210
|
+
captureSidecarError(error, "app-sidecar.run.cancel");
|
|
3161
3211
|
broadcast("cancel_failed", { error: "cancel_failed", runState: runLifecycle.state });
|
|
3162
3212
|
json(res, 500, {
|
|
3163
3213
|
error: "cancel_failed",
|
|
@@ -3185,6 +3235,7 @@ async function createSession(deps, opts) {
|
|
|
3185
3235
|
json(res, 200, { ok: true });
|
|
3186
3236
|
})
|
|
3187
3237
|
.catch((err) => {
|
|
3238
|
+
captureSidecarError(err, "app-sidecar.session.new");
|
|
3188
3239
|
json(res, 500, { error: err instanceof Error ? err.message : String(err) });
|
|
3189
3240
|
});
|
|
3190
3241
|
return;
|
|
@@ -3239,6 +3290,7 @@ async function createSession(deps, opts) {
|
|
|
3239
3290
|
json(res, 200, { ok: true, planTotal });
|
|
3240
3291
|
}
|
|
3241
3292
|
catch (err) {
|
|
3293
|
+
captureSidecarError(err, "app-sidecar.plan.accept");
|
|
3242
3294
|
json(res, 500, { error: err instanceof Error ? err.message : String(err) });
|
|
3243
3295
|
}
|
|
3244
3296
|
});
|
|
@@ -3335,6 +3387,7 @@ async function createSession(deps, opts) {
|
|
|
3335
3387
|
broadcast("auth_done", { provider });
|
|
3336
3388
|
}
|
|
3337
3389
|
catch (err) {
|
|
3390
|
+
captureSidecarError(err, "app-sidecar.auth.oauth", { provider });
|
|
3338
3391
|
broadcast("auth_error", {
|
|
3339
3392
|
provider,
|
|
3340
3393
|
message: err instanceof Error ? err.message : String(err),
|
|
@@ -3476,6 +3529,7 @@ async function createSession(deps, opts) {
|
|
|
3476
3529
|
}
|
|
3477
3530
|
catch (err) {
|
|
3478
3531
|
serveController = null;
|
|
3532
|
+
captureSidecarError(err, "app-sidecar.serve.start", { provider: st.provider });
|
|
3479
3533
|
json(res, 400, { error: err instanceof Error ? err.message : String(err) });
|
|
3480
3534
|
}
|
|
3481
3535
|
})();
|
|
@@ -3502,6 +3556,7 @@ async function createSession(deps, opts) {
|
|
|
3502
3556
|
void buildMcpRows(targetCwd)
|
|
3503
3557
|
.then((servers) => json(res, 200, { servers }))
|
|
3504
3558
|
.catch((err) => {
|
|
3559
|
+
captureSidecarError(err, "app-sidecar.mcp.list");
|
|
3505
3560
|
log("ERROR", "app-sidecar", "buildMcpRows failed", {
|
|
3506
3561
|
message: err instanceof Error ? err.message : String(err),
|
|
3507
3562
|
});
|
|
@@ -3558,6 +3613,7 @@ async function createSession(deps, opts) {
|
|
|
3558
3613
|
});
|
|
3559
3614
|
}
|
|
3560
3615
|
catch (err) {
|
|
3616
|
+
captureSidecarError(err, "app-sidecar.mcp.add", { server: config.name });
|
|
3561
3617
|
json(res, 500, {
|
|
3562
3618
|
error: err instanceof Error ? err.message : String(err),
|
|
3563
3619
|
});
|
|
@@ -3647,6 +3703,7 @@ async function createSession(deps, opts) {
|
|
|
3647
3703
|
}
|
|
3648
3704
|
}
|
|
3649
3705
|
catch (err) {
|
|
3706
|
+
captureSidecarError(err, "app-sidecar.mcp.login", { server: name });
|
|
3650
3707
|
broadcast("mcp_auth_error", {
|
|
3651
3708
|
name,
|
|
3652
3709
|
message: err instanceof Error ? err.message : String(err),
|
|
@@ -3693,7 +3750,9 @@ async function createSession(deps, opts) {
|
|
|
3693
3750
|
dispose,
|
|
3694
3751
|
};
|
|
3695
3752
|
}
|
|
3696
|
-
main().catch((err) => {
|
|
3753
|
+
main().catch(async (err) => {
|
|
3754
|
+
captureSidecarError(err, "app-sidecar.main", { severity: "fatal" });
|
|
3755
|
+
await flushSidecarErrors();
|
|
3697
3756
|
const message = err instanceof Error ? err.message : String(err);
|
|
3698
3757
|
process.stderr.write(`GG_APP_FATAL ${message}\n`);
|
|
3699
3758
|
process.exit(1);
|