@kenkaiiii/ggcoder 5.52.0 → 5.53.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/app-sidecar.js +24 -61
  2. package/dist/app-sidecar.js.map +1 -1
  3. package/dist/chat-agents/research.d.ts +1 -1
  4. package/dist/chat-agents/research.d.ts.map +1 -1
  5. package/dist/chat-agents/research.js +1 -1
  6. package/dist/chat-agents/research.js.map +1 -1
  7. package/dist/core/agent-session.d.ts +4 -4
  8. package/dist/core/agent-session.d.ts.map +1 -1
  9. package/dist/core/agent-session.js +3 -4
  10. package/dist/core/agent-session.js.map +1 -1
  11. package/dist/core/agents.d.ts +2 -3
  12. package/dist/core/agents.d.ts.map +1 -1
  13. package/dist/core/agents.js +2 -3
  14. package/dist/core/agents.js.map +1 -1
  15. package/dist/core/bundled-agents.d.ts.map +1 -1
  16. package/dist/core/bundled-agents.js +13 -4
  17. package/dist/core/bundled-agents.js.map +1 -1
  18. package/dist/core/ken-prompt.d.ts +1 -1
  19. package/dist/core/ken-prompt.js +6 -6
  20. package/dist/core/ken-prompt.js.map +1 -1
  21. package/dist/core/mcp/client.js +1 -1
  22. package/dist/core/mcp/client.js.map +1 -1
  23. package/dist/core/mcp/defaults.d.ts +4 -2
  24. package/dist/core/mcp/defaults.d.ts.map +1 -1
  25. package/dist/core/mcp/defaults.js +5 -10
  26. package/dist/core/mcp/defaults.js.map +1 -1
  27. package/dist/core/mcp/shared-pool.d.ts +2 -2
  28. package/dist/core/mcp/shared-pool.js +2 -2
  29. package/dist/core/platform-clis.d.ts +16 -0
  30. package/dist/core/platform-clis.d.ts.map +1 -0
  31. package/dist/core/platform-clis.js +299 -0
  32. package/dist/core/platform-clis.js.map +1 -0
  33. package/dist/core/prompt-commands.d.ts.map +1 -1
  34. package/dist/core/prompt-commands.js +50 -15
  35. package/dist/core/prompt-commands.js.map +1 -1
  36. package/dist/core/steroids.d.ts +59 -0
  37. package/dist/core/steroids.d.ts.map +1 -0
  38. package/dist/core/steroids.js +227 -0
  39. package/dist/core/steroids.js.map +1 -0
  40. package/dist/modes/json-mode.d.ts +2 -2
  41. package/dist/modes/json-mode.d.ts.map +1 -1
  42. package/dist/modes/json-mode.js +2 -8
  43. package/dist/modes/json-mode.js.map +1 -1
  44. package/dist/modes/subagent-worker-mode.d.ts.map +1 -1
  45. package/dist/modes/subagent-worker-mode.js +0 -10
  46. package/dist/modes/subagent-worker-mode.js.map +1 -1
  47. package/dist/system-prompt.d.ts.map +1 -1
  48. package/dist/system-prompt.js +16 -8
  49. package/dist/system-prompt.js.map +1 -1
  50. package/dist/tools/index.d.ts +6 -0
  51. package/dist/tools/index.d.ts.map +1 -1
  52. package/dist/tools/index.js +6 -0
  53. package/dist/tools/index.js.map +1 -1
  54. package/dist/tools/prompt-hints.d.ts.map +1 -1
  55. package/dist/tools/prompt-hints.js +3 -6
  56. package/dist/tools/prompt-hints.js.map +1 -1
  57. package/dist/tools/steroids.d.ts +46 -0
  58. package/dist/tools/steroids.d.ts.map +1 -0
  59. package/dist/tools/steroids.js +233 -0
  60. package/dist/tools/steroids.js.map +1 -0
  61. package/dist/tools/subagent-shared.d.ts +1 -1
  62. package/dist/tools/subagent-shared.d.ts.map +1 -1
  63. package/dist/tools/subagent-shared.js +1 -4
  64. package/dist/tools/subagent-shared.js.map +1 -1
  65. package/dist/tools/subagent.js +1 -1
  66. package/dist/tools/subagent.js.map +1 -1
  67. package/dist/tools/tool-tiers.d.ts.map +1 -1
  68. package/dist/tools/tool-tiers.js +1 -0
  69. package/dist/tools/tool-tiers.js.map +1 -1
  70. package/dist/ui/App.d.ts.map +1 -1
  71. package/dist/ui/App.js +3 -11
  72. package/dist/ui/App.js.map +1 -1
  73. package/dist/ui/components/ToolExecution.d.ts.map +1 -1
  74. package/dist/ui/components/ToolExecution.js +10 -3
  75. package/dist/ui/components/ToolExecution.js.map +1 -1
  76. package/dist/ui/terminal-history.js +4 -2
  77. package/dist/ui/terminal-history.js.map +1 -1
  78. package/dist/ui/tool-group-summary.d.ts +2 -0
  79. package/dist/ui/tool-group-summary.d.ts.map +1 -1
  80. package/dist/ui/tool-group-summary.js +11 -25
  81. package/dist/ui/tool-group-summary.js.map +1 -1
  82. package/dist/ui/tool-line-summary.d.ts.map +1 -1
  83. package/dist/ui/tool-line-summary.js +12 -9
  84. package/dist/ui/tool-line-summary.js.map +1 -1
  85. package/dist/ui/transcript/tool-presentation.d.ts.map +1 -1
  86. package/dist/ui/transcript/tool-presentation.js +2 -7
  87. package/dist/ui/transcript/tool-presentation.js.map +1 -1
  88. package/package.json +4 -5
  89. package/dist/core/sidecar-error-reporter.d.ts +0 -12
  90. package/dist/core/sidecar-error-reporter.d.ts.map +0 -1
  91. package/dist/core/sidecar-error-reporter.js +0 -57
  92. package/dist/core/sidecar-error-reporter.js.map +0 -1
@@ -69,6 +69,7 @@ import { RADIO_STATIONS, getCurrentStation, getRadioVolume, playRadio, setRadioV
69
69
  import { enrichProcessPath } from "./core/shell-path.js";
70
70
  import { downscaleForPreview, shrinkToFit, validateVisionImage } from "./utils/image.js";
71
71
  import { startServeMode } from "./modes/serve-mode.js";
72
+ import { installSteroids, probeSteroids } from "./core/steroids.js";
72
73
  import { loadTelegramConfig, saveTelegramConfig, verifyBotToken } from "./core/telegram-config.js";
73
74
  import { loadServers, addServer, removeServer, getServer, parseMcpAddCommand, MCPClientManager, McpOAuthStore, createElicitationBridge, } from "./core/mcp/index.js";
74
75
  import { createAskUserBridge } from "./core/ask-user.js";
@@ -78,7 +79,6 @@ import { loadProgress, peekProgress, updateProgress } from "./core/progress/stor
78
79
  import { awardPrompt, awardCommits } from "./core/progress/engine.js";
79
80
  import { detectNewCommits, repoKey } from "./core/progress/git-xp.js";
80
81
  import { rebuildFromSessions } from "./core/progress/rebuild.js";
81
- import { captureSidecarError, flushSidecarErrors, shouldCaptureToolFailure, shouldCaptureUsagePollingError, wrapSidecarHandler, } from "./core/sidecar-error-reporter.js";
82
82
  const AUTOMATION_PROVENANCE = {
83
83
  source: "runtime",
84
84
  kind: "automation",
@@ -199,7 +199,6 @@ async function persistModelSelection(settingsFile, provider, model) {
199
199
  await sm.set("defaultModel", model);
200
200
  }
201
201
  catch (err) {
202
- captureSidecarError(err, "app-sidecar.settings.persist-model");
203
202
  log("WARN", "app-sidecar", "failed to persist model selection", { err: String(err) });
204
203
  }
205
204
  }
@@ -216,7 +215,6 @@ async function persistThinkingLevel(settingsFile, level) {
216
215
  await sm.set("thinkingLevel", level);
217
216
  }
218
217
  catch (err) {
219
- captureSidecarError(err, "app-sidecar.settings.persist-thinking");
220
218
  log("WARN", "app-sidecar", "failed to persist thinking level", { err: String(err) });
221
219
  }
222
220
  }
@@ -522,10 +520,6 @@ async function runJsonModeIfRequested() {
522
520
  allowedMcpServers,
523
521
  promptCacheKey: values["prompt-cache-key"],
524
522
  }).catch(async (err) => {
525
- captureSidecarError(err, "app-sidecar.json-mode", {
526
- provider: String(values.provider ?? "anthropic"),
527
- });
528
- await flushSidecarErrors();
529
523
  process.stderr.write((err instanceof Error ? err.message : String(err)) + "\n");
530
524
  process.exit(1);
531
525
  });
@@ -730,9 +724,6 @@ async function main() {
730
724
  }
731
725
  catch (error) {
732
726
  const message = error instanceof Error ? error.message : String(error);
733
- if (shouldCaptureUsagePollingError(error)) {
734
- captureSidecarError(error, "app-sidecar.usage.fetch", { provider });
735
- }
736
727
  let backoffMs;
737
728
  if (error instanceof SubscriptionUsageError && error.status === 429) {
738
729
  backoffMs = Math.min(USAGE_RATE_LIMIT_MAX_BACKOFF_MS, Math.max(USAGE_RATE_LIMIT_MIN_BACKOFF_MS, error.retryAfterMs ?? USAGE_RATE_LIMIT_FALLBACK_BACKOFF_MS));
@@ -815,7 +806,7 @@ async function main() {
815
806
  return null;
816
807
  }
817
808
  }
818
- const server = http.createServer(wrapSidecarHandler((req, res) => {
809
+ const server = http.createServer((req, res) => {
819
810
  const url = req.url ?? "/";
820
811
  const method = req.method ?? "GET";
821
812
  // Answer preflights with a bare 204 but grant NO origins — the webview
@@ -879,7 +870,6 @@ async function main() {
879
870
  }
880
871
  catch (err) {
881
872
  const message = err instanceof Error ? err.message : String(err);
882
- captureSidecarError(err, "app-sidecar.session.create");
883
873
  log("ERROR", "app-sidecar", "session create failed", { message });
884
874
  daemonJson(res, 500, { error: message });
885
875
  }
@@ -916,7 +906,6 @@ async function main() {
916
906
  }
917
907
  daemonJson(res, 200, await subscriptionUsage(provider));
918
908
  })().catch((error) => {
919
- captureSidecarError(error, "app-sidecar.usage.request");
920
909
  log("ERROR", "app-sidecar", "subscription usage request failed", {
921
910
  message: error instanceof Error ? error.message : String(error),
922
911
  });
@@ -932,7 +921,7 @@ async function main() {
932
921
  return;
933
922
  }
934
923
  ctx.handle(req, res, url, method);
935
- }, "app-sidecar.http"));
924
+ });
936
925
  server.listen(port, host, () => {
937
926
  const addr = server.address();
938
927
  // The Rust shell reads this line to learn the daemon port (it already
@@ -997,11 +986,10 @@ const KEN_ALLOWED_TOOLS = [
997
986
  "web_fetch",
998
987
  "web_search",
999
988
  "screenshot",
989
+ // Local corpus of real repos: lets Ken verify against code that ships
990
+ // instead of assuming — core to how he's meant to work. Read-only.
991
+ "steroids",
1000
992
  ];
1001
- /** MCP servers Ken is allowed to use. kencode-search lets him look into real
1002
- * public repos / verify against actual code instead of assuming — core to how
1003
- * he's meant to work. Read-only research; no other MCP server is connected. */
1004
- const KEN_ALLOWED_MCP_SERVERS = ["kencode-search"];
1005
993
  /** Extract the plain text of the most recent assistant message (Ken's reply).
1006
994
  * Strips tool-call / image blocks, returning just the prose Ken streamed. */
1007
995
  function lastAssistantText(messages) {
@@ -1088,7 +1076,6 @@ async function createProgressManager(agentDir, broadcastAll) {
1088
1076
  broadcastAll(buildSnapshot(updated), originId);
1089
1077
  }
1090
1078
  catch (err) {
1091
- captureSidecarError(err, "app-sidecar.progress.award");
1092
1079
  log("DEBUG", "app-sidecar", "progress award failed", {
1093
1080
  message: err instanceof Error ? err.message : String(err),
1094
1081
  });
@@ -1122,7 +1109,6 @@ async function createProgressManager(agentDir, broadcastAll) {
1122
1109
  progressWatcher = watcher;
1123
1110
  }
1124
1111
  catch (err) {
1125
- captureSidecarError(err, "app-sidecar.progress.watch");
1126
1112
  log("DEBUG", "app-sidecar", "progress watch unavailable", {
1127
1113
  message: err instanceof Error ? err.message : String(err),
1128
1114
  });
@@ -1256,11 +1242,6 @@ async function createSession(deps, opts) {
1256
1242
  const f = formatError(err);
1257
1243
  const message = f.message ? desktopGuidance(f.message) : undefined;
1258
1244
  const guidance = localNetworkGuidance(f.source) ?? desktopGuidance(f.guidance);
1259
- captureSidecarError(err, `app-sidecar.${logLabel.replaceAll(" ", "-")}`, {
1260
- scope: type,
1261
- ...(f.provider ? { provider: f.provider } : {}),
1262
- ...(f.statusCode != null ? { status: String(f.statusCode) } : {}),
1263
- });
1264
1245
  log("ERROR", "app-sidecar", logLabel, {
1265
1246
  headline: f.headline,
1266
1247
  source: f.source,
@@ -1344,7 +1325,6 @@ async function createSession(deps, opts) {
1344
1325
  chatAgent = nextAgent;
1345
1326
  broadcast("chat_agent_change", { chatAgent: nextAgent });
1346
1327
  await session.persistAppMarker("agent_handoff", { chatAgent: nextAgent }).catch((error) => {
1347
- captureSidecarError(error, "app-sidecar.chat-agent.persist-handoff");
1348
1328
  log("WARN", "app-sidecar", "agent handoff marker persist failed", {
1349
1329
  message: error instanceof Error ? error.message : String(error),
1350
1330
  });
@@ -1793,7 +1773,6 @@ async function createSession(deps, opts) {
1793
1773
  .catch(() => false)
1794
1774
  .then(() => syncApprovedPlanProgress(generation))
1795
1775
  .catch((error) => {
1796
- captureSidecarError(error, "app-sidecar.plan.refresh-progress");
1797
1776
  log("WARN", "app-sidecar", "plan progress refresh failed", {
1798
1777
  message: error instanceof Error ? error.message : String(error),
1799
1778
  });
@@ -1852,11 +1831,6 @@ async function createSession(deps, opts) {
1852
1831
  session.eventBus.on("tool_call_end", (d) => {
1853
1832
  const name = toolCallNames.get(d.toolCallId) ?? "unknown";
1854
1833
  toolCallNames.delete(d.toolCallId);
1855
- if (d.isError && shouldCaptureToolFailure(name, d.result)) {
1856
- // Expected model-correctable validation failures stay in the local log and
1857
- // conversation. Unexpected failures are reported without private result data.
1858
- captureSidecarError(new Error(`Tool ${name} failed`), `tool.${name}`, { tool: name });
1859
- }
1860
1834
  log(d.isError ? "ERROR" : "INFO", "tool", `Tool call ended: ${name}`, {
1861
1835
  id: d.toolCallId,
1862
1836
  durationMs: String(d.durationMs),
@@ -2064,7 +2038,6 @@ async function createSession(deps, opts) {
2064
2038
  cwd,
2065
2039
  systemPrompt: await buildKenSystemPrompt(cwd),
2066
2040
  allowedTools: KEN_ALLOWED_TOOLS,
2067
- allowedMcpServers: KEN_ALLOWED_MCP_SERVERS,
2068
2041
  transient: true,
2069
2042
  signal: kenAbort.signal,
2070
2043
  // Ken belongs to THIS window, so its window is where an MCP prompt
@@ -2140,7 +2113,6 @@ async function createSession(deps, opts) {
2140
2113
  cwd,
2141
2114
  systemPrompt: await buildKenAutopilotSystemPrompt(cwd),
2142
2115
  allowedTools: KEN_ALLOWED_TOOLS,
2143
- allowedMcpServers: KEN_ALLOWED_MCP_SERVERS,
2144
2116
  transient: true,
2145
2117
  signal: kenAutoAbort.signal,
2146
2118
  // Same as Ken chat: this reviewer belongs to a window, so route prompts
@@ -2257,7 +2229,6 @@ async function createSession(deps, opts) {
2257
2229
  catch (error) {
2258
2230
  // Keep tracking when prompt cleanup fails; hiding the widget here
2259
2231
  // would claim completion while the approved-plan contract remained.
2260
- captureSidecarError(error, "app-sidecar.plan.cleanup");
2261
2232
  log("WARN", "app-sidecar", "completed plan cleanup failed", {
2262
2233
  message: error instanceof Error ? error.message : String(error),
2263
2234
  });
@@ -2797,7 +2768,6 @@ async function createSession(deps, opts) {
2797
2768
  .snapshot()
2798
2769
  .then((snapshot) => json(res, 200, snapshot))
2799
2770
  .catch((error) => {
2800
- captureSidecarError(error, "app-sidecar.memory.snapshot");
2801
2771
  json(res, 500, { error: error instanceof Error ? error.message : String(error) });
2802
2772
  });
2803
2773
  return;
@@ -2813,7 +2783,6 @@ async function createSession(deps, opts) {
2813
2783
  .then(() => memoryStore.snapshot())
2814
2784
  .then((snapshot) => json(res, 200, snapshot))
2815
2785
  .catch((error) => {
2816
- captureSidecarError(error, "app-sidecar.memory.forget");
2817
2786
  json(res, 500, { error: error instanceof Error ? error.message : String(error) });
2818
2787
  });
2819
2788
  return;
@@ -2823,7 +2792,6 @@ async function createSession(deps, opts) {
2823
2792
  .snapshot()
2824
2793
  .then((snapshot) => json(res, 200, snapshot))
2825
2794
  .catch((error) => {
2826
- captureSidecarError(error, "app-sidecar.jiwa.snapshot");
2827
2795
  json(res, 500, { error: error instanceof Error ? error.message : String(error) });
2828
2796
  });
2829
2797
  return;
@@ -2839,7 +2807,6 @@ async function createSession(deps, opts) {
2839
2807
  .then(() => jiwaStore.snapshot())
2840
2808
  .then((snapshot) => json(res, 200, snapshot))
2841
2809
  .catch((error) => {
2842
- captureSidecarError(error, "app-sidecar.jiwa.forget");
2843
2810
  json(res, 500, { error: error instanceof Error ? error.message : String(error) });
2844
2811
  });
2845
2812
  return;
@@ -2881,7 +2848,6 @@ async function createSession(deps, opts) {
2881
2848
  void listInstalledPlugins(paths.extensionsDir)
2882
2849
  .then((plugins) => json(res, 200, { plugins }))
2883
2850
  .catch((error) => {
2884
- captureSidecarError(error, "app-sidecar.plugins.list");
2885
2851
  json(res, 500, { error: error instanceof Error ? error.message : String(error) });
2886
2852
  });
2887
2853
  return;
@@ -2900,7 +2866,6 @@ async function createSession(deps, opts) {
2900
2866
  json(res, 200, { plugin, restartRequired: true });
2901
2867
  }
2902
2868
  catch (error) {
2903
- captureSidecarError(error, "app-sidecar.plugins.install");
2904
2869
  json(res, 400, { error: error instanceof Error ? error.message : String(error) });
2905
2870
  }
2906
2871
  });
@@ -2911,7 +2876,6 @@ async function createSession(deps, opts) {
2911
2876
  void removePlugin(pluginId, paths.extensionsDir)
2912
2877
  .then(() => json(res, 200, { removed: pluginId, restartRequired: true }))
2913
2878
  .catch((error) => {
2914
- captureSidecarError(error, "app-sidecar.plugins.remove");
2915
2879
  json(res, 400, { error: error instanceof Error ? error.message : String(error) });
2916
2880
  });
2917
2881
  return;
@@ -2996,7 +2960,6 @@ async function createSession(deps, opts) {
2996
2960
  json(res, 200, { path: dir });
2997
2961
  }
2998
2962
  catch (err) {
2999
- captureSidecarError(err, "app-sidecar.project.create");
3000
2963
  json(res, 500, { error: err instanceof Error ? err.message : String(err) });
3001
2964
  }
3002
2965
  });
@@ -3035,7 +2998,6 @@ async function createSession(deps, opts) {
3035
2998
  json(res, 200, { hidden: Array.from(current) });
3036
2999
  }
3037
3000
  catch (err) {
3038
- captureSidecarError(err, "app-sidecar.projects.hidden");
3039
3001
  json(res, 500, { error: err instanceof Error ? err.message : String(err) });
3040
3002
  }
3041
3003
  });
@@ -3053,7 +3015,6 @@ async function createSession(deps, opts) {
3053
3015
  }))
3054
3016
  .then((projects) => json(res, 200, { projects }))
3055
3017
  .catch((err) => {
3056
- captureSidecarError(err, "app-sidecar.projects.discover");
3057
3018
  log("ERROR", "app-sidecar", "discoverProjects failed", {
3058
3019
  message: err instanceof Error ? err.message : String(err),
3059
3020
  });
@@ -3072,10 +3033,7 @@ async function createSession(deps, opts) {
3072
3033
  // agent or request the combined, recency-sorted "all" listing.
3073
3034
  void listSidecarSessions(target, requestedAgent, paths.sessionsDir)
3074
3035
  .then((sessions) => json(res, 200, { sessions }))
3075
- .catch((error) => {
3076
- captureSidecarError(error, "app-sidecar.sessions.list");
3077
- json(res, 200, { sessions: [] });
3078
- });
3036
+ .catch(() => json(res, 200, { sessions: [] }));
3079
3037
  return;
3080
3038
  }
3081
3039
  if (method === "GET" && url.startsWith("/files")) {
@@ -3083,7 +3041,6 @@ async function createSession(deps, opts) {
3083
3041
  void searchProjectFiles(cwd, q)
3084
3042
  .then((files) => json(res, 200, { files }))
3085
3043
  .catch((err) => {
3086
- captureSidecarError(err, "app-sidecar.files.search");
3087
3044
  log("ERROR", "app-sidecar", "searchProjectFiles failed", {
3088
3045
  message: err instanceof Error ? err.message : String(err),
3089
3046
  });
@@ -3777,7 +3734,6 @@ async function createSession(deps, opts) {
3777
3734
  }
3778
3735
  catch (err) {
3779
3736
  const message = err instanceof Error ? err.message : String(err);
3780
- captureSidecarError(err, "app-sidecar.prompt-enhancer");
3781
3737
  log("ERROR", "app-sidecar", "enhance failed", { message });
3782
3738
  json(res, 500, { error: message });
3783
3739
  }
@@ -4217,7 +4173,6 @@ async function createSession(deps, opts) {
4217
4173
  drained,
4218
4174
  });
4219
4175
  })().catch((error) => {
4220
- captureSidecarError(error, "app-sidecar.run.cancel");
4221
4176
  broadcast("cancel_failed", { error: "cancel_failed", runState: runLifecycle.state });
4222
4177
  json(res, 500, {
4223
4178
  error: "cancel_failed",
@@ -4245,7 +4200,6 @@ async function createSession(deps, opts) {
4245
4200
  json(res, 200, { ok: true });
4246
4201
  })
4247
4202
  .catch((err) => {
4248
- captureSidecarError(err, "app-sidecar.session.new");
4249
4203
  json(res, 500, { error: err instanceof Error ? err.message : String(err) });
4250
4204
  });
4251
4205
  return;
@@ -4302,7 +4256,6 @@ async function createSession(deps, opts) {
4302
4256
  json(res, 200, { ok: true, planTotal });
4303
4257
  }
4304
4258
  catch (err) {
4305
- captureSidecarError(err, "app-sidecar.plan.accept");
4306
4259
  json(res, 500, { error: err instanceof Error ? err.message : String(err) });
4307
4260
  }
4308
4261
  });
@@ -4432,7 +4385,6 @@ async function createSession(deps, opts) {
4432
4385
  broadcastAll("models_change", {});
4433
4386
  }
4434
4387
  catch (err) {
4435
- captureSidecarError(err, "app-sidecar.auth.oauth", { provider });
4436
4388
  // Deliberately session-scoped: this is the outcome of ONE window's
4437
4389
  // attempt. Another window that never pressed Connect has nothing to
4438
4390
  // show an error about, and its modal correctly still offers login.
@@ -4825,7 +4777,6 @@ async function createSession(deps, opts) {
4825
4777
  }
4826
4778
  catch (err) {
4827
4779
  serveController = null;
4828
- captureSidecarError(err, "app-sidecar.serve.start", { provider: st.provider });
4829
4780
  json(res, 400, { error: err instanceof Error ? err.message : String(err) });
4830
4781
  }
4831
4782
  })();
@@ -4843,6 +4794,23 @@ async function createSession(deps, opts) {
4843
4794
  })();
4844
4795
  return;
4845
4796
  }
4797
+ // ── Agent Steroids (local code corpus) ───────────────────────────────
4798
+ if (method === "GET" && url === "/steroids") {
4799
+ void probeSteroids().then((status) => json(res, 200, status));
4800
+ return;
4801
+ }
4802
+ if (method === "POST" && url === "/steroids/install") {
4803
+ void installSteroids()
4804
+ .then((status) => {
4805
+ broadcast("steroids_change", status);
4806
+ log("INFO", "app-sidecar", "steroids installed", { version: status.version });
4807
+ json(res, 200, status);
4808
+ })
4809
+ .catch((err) => {
4810
+ json(res, 400, { error: err instanceof Error ? err.message : String(err) });
4811
+ });
4812
+ return;
4813
+ }
4846
4814
  // ── MCP server management (mirrors `ggcoder mcp`) ──────────────────
4847
4815
  // `targetCwd` (project scope) overrides the window cwd so a server can be
4848
4816
  // added/removed for ANY discovered project, not just this window's. Global
@@ -4852,7 +4820,6 @@ async function createSession(deps, opts) {
4852
4820
  void buildMcpRows(targetCwd, paths.settingsFile)
4853
4821
  .then((servers) => json(res, 200, { servers }))
4854
4822
  .catch((err) => {
4855
- captureSidecarError(err, "app-sidecar.mcp.list");
4856
4823
  log("ERROR", "app-sidecar", "buildMcpRows failed", {
4857
4824
  message: err instanceof Error ? err.message : String(err),
4858
4825
  });
@@ -4917,7 +4884,6 @@ async function createSession(deps, opts) {
4917
4884
  });
4918
4885
  }
4919
4886
  catch (err) {
4920
- captureSidecarError(err, "app-sidecar.mcp.add", { server: config.name });
4921
4887
  json(res, 500, {
4922
4888
  error: err instanceof Error ? err.message : String(err),
4923
4889
  });
@@ -5011,7 +4977,6 @@ async function createSession(deps, opts) {
5011
4977
  }
5012
4978
  }
5013
4979
  catch (err) {
5014
- captureSidecarError(err, "app-sidecar.mcp.login", { server: name });
5015
4980
  broadcast("mcp_auth_error", {
5016
4981
  name,
5017
4982
  message: err instanceof Error ? err.message : String(err),
@@ -5064,8 +5029,6 @@ async function createSession(deps, opts) {
5064
5029
  };
5065
5030
  }
5066
5031
  main().catch(async (err) => {
5067
- captureSidecarError(err, "app-sidecar.main", { severity: "fatal" });
5068
- await flushSidecarErrors();
5069
5032
  const message = err instanceof Error ? err.message : String(err);
5070
5033
  process.stderr.write(`GG_APP_FATAL ${message}\n`);
5071
5034
  process.exit(1);