codetyper-cli 0.2.1 → 0.2.3

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/index.js CHANGED
@@ -27465,8 +27465,10 @@ var init_paths = __esm(() => {
27465
27465
  config: join(DIRS.config, "config.json"),
27466
27466
  keybindings: join(DIRS.config, "keybindings.json"),
27467
27467
  credentials: join(DIRS.data, "credentials.json"),
27468
+ vars: join(DIRS.config, "vars.json"),
27468
27469
  history: join(DIRS.data, "history.json"),
27469
27470
  modelsCache: join(DIRS.cache, "models.json"),
27471
+ copilotTokenCache: join(DIRS.cache, "copilot-token.json"),
27470
27472
  frecency: join(DIRS.cache, "frecency.json"),
27471
27473
  kvStore: join(DIRS.state, "kv.json"),
27472
27474
  settings: join(DIRS.config, "settings.json")
@@ -37144,11 +37146,25 @@ __export(exports_token, {
37144
37146
  getOAuthToken: () => getOAuthToken,
37145
37147
  buildHeaders: () => buildHeaders
37146
37148
  });
37147
- import { readFile } from "fs/promises";
37149
+ import { readFile, writeFile, mkdir } from "fs/promises";
37148
37150
  import { existsSync } from "fs";
37149
37151
  import { homedir as homedir2, platform } from "os";
37150
37152
  import { join as join2 } from "path";
37151
- var getConfigDir = () => {
37153
+ var loadCachedToken = async () => {
37154
+ try {
37155
+ const data = await readFile(FILES.copilotTokenCache, "utf-8");
37156
+ const token = JSON.parse(data);
37157
+ if (token.expires_at > Date.now() / 1000 + 60) {
37158
+ return token;
37159
+ }
37160
+ } catch {}
37161
+ return null;
37162
+ }, saveCachedToken = async (token) => {
37163
+ try {
37164
+ await mkdir(DIRS.cache, { recursive: true });
37165
+ await writeFile(FILES.copilotTokenCache, JSON.stringify(token), "utf-8");
37166
+ } catch {}
37167
+ }, getConfigDir = () => {
37152
37168
  const home = homedir2();
37153
37169
  const os4 = platform();
37154
37170
  if (process.env.XDG_CONFIG_HOME && existsSync(process.env.XDG_CONFIG_HOME)) {
@@ -37200,6 +37216,11 @@ var getConfigDir = () => {
37200
37216
  if (currentState.githubToken && currentState.githubToken.expires_at > Date.now() / 1000) {
37201
37217
  return currentState.githubToken;
37202
37218
  }
37219
+ const cachedToken = await loadCachedToken();
37220
+ if (cachedToken) {
37221
+ setGitHubToken(cachedToken);
37222
+ return cachedToken;
37223
+ }
37203
37224
  const response2 = await source_default2.get(COPILOT_AUTH_URL, {
37204
37225
  headers: {
37205
37226
  Authorization: `token ${currentState.oauthToken}`,
@@ -37210,6 +37231,7 @@ var getConfigDir = () => {
37210
37231
  throw new Error("Failed to refresh Copilot token");
37211
37232
  }
37212
37233
  setGitHubToken(response2);
37234
+ saveCachedToken(response2).catch(() => {});
37213
37235
  return response2;
37214
37236
  }, buildHeaders = (token) => ({
37215
37237
  Authorization: `Bearer ${token.token}`,
@@ -37223,6 +37245,7 @@ var getConfigDir = () => {
37223
37245
  var init_token = __esm(() => {
37224
37246
  init_source4();
37225
37247
  init_copilot();
37248
+ init_paths();
37226
37249
  init_state();
37227
37250
  });
37228
37251
 
@@ -65586,7 +65609,8 @@ var logIdCounter = 0, generateLogId = () => `log-${++logIdCounter}-${Date.now()}
65586
65609
  inputTokens: 0,
65587
65610
  outputTokens: 0,
65588
65611
  thinkingStartTime: null,
65589
- lastThinkingDuration: 0
65612
+ lastThinkingDuration: 0,
65613
+ contextMaxTokens: 128000
65590
65614
  }), createInitialStreamingState = () => ({
65591
65615
  logId: null,
65592
65616
  content: "",
@@ -65601,7 +65625,7 @@ var logIdCounter = 0, generateLogId = () => `log-${++logIdCounter}-${Date.now()}
65601
65625
  selectedIndex: 0
65602
65626
  }), AppStoreProvider, useAppStore, storeRef = null, setAppStoreRef = (store) => {
65603
65627
  storeRef = store;
65604
- }, appStore;
65628
+ }, defaultAppState, appStore;
65605
65629
  var init_app = __esm(async () => {
65606
65630
  init_server();
65607
65631
  init_server2();
@@ -65638,7 +65662,15 @@ var init_app = __esm(async () => {
65638
65662
  isCompacting: false,
65639
65663
  streamingLog: createInitialStreamingState(),
65640
65664
  suggestions: createInitialSuggestionState(),
65641
- cascadeEnabled: true
65665
+ cascadeEnabled: true,
65666
+ mcpServers: [],
65667
+ brain: {
65668
+ status: "disconnected",
65669
+ user: null,
65670
+ knowledgeCount: 0,
65671
+ memoryCount: 0,
65672
+ showBanner: true
65673
+ }
65642
65674
  });
65643
65675
  let inputInsertFn = null;
65644
65676
  const setInputInsertFn = (fn) => {
@@ -65678,6 +65710,8 @@ var init_app = __esm(async () => {
65678
65710
  const streamingLogIsActive = () => store.streamingLog.isStreaming;
65679
65711
  const suggestions = () => store.suggestions;
65680
65712
  const cascadeEnabled = () => store.cascadeEnabled;
65713
+ const mcpServers = () => store.mcpServers;
65714
+ const brain = () => store.brain;
65681
65715
  const setMode = (newMode) => {
65682
65716
  setStore("mode", newMode);
65683
65717
  };
@@ -65826,6 +65860,58 @@ var init_app = __esm(async () => {
65826
65860
  const toggleCascadeEnabled = () => {
65827
65861
  setStore("cascadeEnabled", !store.cascadeEnabled);
65828
65862
  };
65863
+ const setBrainStatus = (status) => {
65864
+ setStore("brain", {
65865
+ ...store.brain,
65866
+ status
65867
+ });
65868
+ };
65869
+ const setBrainUser = (user) => {
65870
+ setStore("brain", {
65871
+ ...store.brain,
65872
+ user
65873
+ });
65874
+ };
65875
+ const setBrainCounts = (knowledgeCount, memoryCount) => {
65876
+ setStore("brain", {
65877
+ ...store.brain,
65878
+ knowledgeCount,
65879
+ memoryCount
65880
+ });
65881
+ };
65882
+ const setBrainShowBanner = (showBanner) => {
65883
+ setStore("brain", {
65884
+ ...store.brain,
65885
+ showBanner
65886
+ });
65887
+ };
65888
+ const dismissBrainBanner = () => {
65889
+ setStore("brain", {
65890
+ ...store.brain,
65891
+ showBanner: false
65892
+ });
65893
+ };
65894
+ const setMcpServers = (servers) => {
65895
+ setStore("mcpServers", servers);
65896
+ };
65897
+ const addMcpServer = (server) => {
65898
+ setStore(produce((s) => {
65899
+ const existingIndex = s.mcpServers.findIndex((srv) => srv.id === server.id);
65900
+ if (existingIndex !== -1) {
65901
+ s.mcpServers[existingIndex] = server;
65902
+ } else {
65903
+ s.mcpServers.push(server);
65904
+ }
65905
+ }));
65906
+ };
65907
+ const updateMcpServerStatus = (id, status) => {
65908
+ setStore(produce((s) => {
65909
+ const server = s.mcpServers.find((srv) => srv.id === id);
65910
+ if (server) {
65911
+ server.status = status;
65912
+ }
65913
+ }));
65914
+ };
65829
65915
  const startThinking = () => {
65830
65916
  setStore("sessionStats", {
65831
65917
  ...store.sessionStats,
@@ -65850,6 +65936,12 @@ var init_app = __esm(async () => {
65850
65936
  const resetSessionStats = () => {
65851
65937
  setStore("sessionStats", createInitialSessionStats());
65852
65938
  };
65939
+ const setContextMaxTokens = (maxTokens) => {
65940
+ setStore("sessionStats", {
65941
+ ...store.sessionStats,
65942
+ contextMaxTokens: maxTokens
65943
+ });
65944
+ };
65853
65945
  const toggleTodos = () => {
65854
65946
  setStore("todosVisible", !store.todosVisible);
65855
65947
  };
@@ -66007,6 +66099,8 @@ var init_app = __esm(async () => {
66007
66099
  streamingLogIsActive,
66008
66100
  suggestions,
66009
66101
  cascadeEnabled,
66102
+ mcpServers,
66103
+ brain,
66010
66104
  setMode,
66011
66105
  setScreenMode,
66012
66106
  setInteractionMode,
@@ -66038,10 +66132,19 @@ var init_app = __esm(async () => {
66038
66132
  setProvider,
66039
66133
  setCascadeEnabled,
66040
66134
  toggleCascadeEnabled,
66135
+ setBrainStatus,
66136
+ setBrainUser,
66137
+ setBrainCounts,
66138
+ setBrainShowBanner,
66139
+ dismissBrainBanner,
66140
+ setMcpServers,
66141
+ addMcpServer,
66142
+ updateMcpServerStatus,
66041
66143
  startThinking,
66042
66144
  stopThinking,
66043
66145
  addTokens,
66044
66146
  resetSessionStats,
66147
+ setContextMaxTokens,
66045
66148
  toggleTodos,
66046
66149
  toggleDebugLog,
66047
66150
  setInterruptPending,
@@ -66062,10 +66165,44 @@ var init_app = __esm(async () => {
66062
66165
  };
66063
66166
  }
66064
66167
  }));
66168
+ defaultAppState = {
66169
+ mode: "idle",
66170
+ screenMode: "home",
66171
+ interactionMode: "agent",
66172
+ currentAgent: "default",
66173
+ inputBuffer: "",
66174
+ logs: [],
66175
+ currentToolCall: null,
66176
+ permissionRequest: null,
66177
+ learningPrompt: null,
66178
+ thinkingMessage: null,
66179
+ sessionId: null,
66180
+ provider: "copilot",
66181
+ model: "",
66182
+ version: "0.1.0",
66183
+ sessionStats: createInitialSessionStats(),
66184
+ cascadeEnabled: true,
66185
+ todosVisible: true,
66186
+ debugLogVisible: false,
66187
+ interruptPending: false,
66188
+ exitPending: false,
66189
+ isCompacting: false,
66190
+ streamingLog: createInitialStreamingState(),
66191
+ suggestions: createInitialSuggestionState(),
66192
+ mcpServers: [],
66193
+ brain: {
66194
+ status: "disconnected",
66195
+ user: null,
66196
+ knowledgeCount: 0,
66197
+ memoryCount: 0,
66198
+ showBanner: true
66199
+ }
66200
+ };
66065
66201
  appStore = {
66066
66202
  getState: () => {
66067
- if (!storeRef)
66068
- throw new Error("AppStore not initialized");
66203
+ if (!storeRef) {
66204
+ return defaultAppState;
66205
+ }
66069
66206
  return {
66070
66207
  mode: storeRef.mode(),
66071
66208
  screenMode: storeRef.screenMode(),
@@ -66089,183 +66226,230 @@ var init_app = __esm(async () => {
66089
66226
  exitPending: storeRef.exitPending(),
66090
66227
  isCompacting: storeRef.isCompacting(),
66091
66228
  streamingLog: storeRef.streamingLog(),
66092
- suggestions: storeRef.suggestions()
66229
+ suggestions: storeRef.suggestions(),
66230
+ mcpServers: storeRef.mcpServers(),
66231
+ brain: storeRef.brain()
66093
66232
  };
66094
66233
  },
66095
66234
  addLog: (entry) => {
66096
66235
  if (!storeRef)
66097
- throw new Error("AppStore not initialized");
66236
+ return "";
66098
66237
  return storeRef.addLog(entry);
66099
66238
  },
66100
66239
  updateLog: (id, updates) => {
66101
66240
  if (!storeRef)
66102
- throw new Error("AppStore not initialized");
66241
+ return;
66103
66242
  storeRef.updateLog(id, updates);
66104
66243
  },
66105
66244
  setMode: (mode) => {
66106
66245
  if (!storeRef)
66107
- throw new Error("AppStore not initialized");
66246
+ return;
66108
66247
  storeRef.setMode(mode);
66109
66248
  },
66110
66249
  toggleInteractionMode: () => {
66111
66250
  if (!storeRef)
66112
- throw new Error("AppStore not initialized");
66251
+ return;
66113
66252
  storeRef.toggleInteractionMode();
66114
66253
  },
66115
66254
  setCurrentAgent: (agent) => {
66116
66255
  if (!storeRef)
66117
- throw new Error("AppStore not initialized");
66256
+ return;
66118
66257
  storeRef.setCurrentAgent(agent);
66119
66258
  },
66120
66259
  setCurrentToolCall: (toolCall) => {
66121
66260
  if (!storeRef)
66122
- throw new Error("AppStore not initialized");
66261
+ return;
66123
66262
  storeRef.setCurrentToolCall(toolCall);
66124
66263
  },
66125
66264
  updateToolCall: (updates) => {
66126
66265
  if (!storeRef)
66127
- throw new Error("AppStore not initialized");
66266
+ return;
66128
66267
  storeRef.updateToolCall(updates);
66129
66268
  },
66130
66269
  setThinkingMessage: (message) => {
66131
66270
  if (!storeRef)
66132
- throw new Error("AppStore not initialized");
66271
+ return;
66133
66272
  storeRef.setThinkingMessage(message);
66134
66273
  },
66135
66274
  setPermissionRequest: (request) => {
66136
66275
  if (!storeRef)
66137
- throw new Error("AppStore not initialized");
66276
+ return;
66138
66277
  storeRef.setPermissionRequest(request);
66139
66278
  },
66140
66279
  setLearningPrompt: (prompt2) => {
66141
66280
  if (!storeRef)
66142
- throw new Error("AppStore not initialized");
66281
+ return;
66143
66282
  storeRef.setLearningPrompt(prompt2);
66144
66283
  },
66145
66284
  clearInput: () => {
66146
66285
  if (!storeRef)
66147
- throw new Error("AppStore not initialized");
66286
+ return;
66148
66287
  storeRef.clearInput();
66149
66288
  },
66150
66289
  clearLogs: () => {
66151
66290
  if (!storeRef)
66152
- throw new Error("AppStore not initialized");
66291
+ return;
66153
66292
  storeRef.clearLogs();
66154
66293
  },
66155
66294
  openCommandMenu: () => {
66156
66295
  if (!storeRef)
66157
- throw new Error("AppStore not initialized");
66296
+ return;
66158
66297
  storeRef.openCommandMenu();
66159
66298
  },
66160
66299
  closeCommandMenu: () => {
66161
66300
  if (!storeRef)
66162
- throw new Error("AppStore not initialized");
66301
+ return;
66163
66302
  storeRef.closeCommandMenu();
66164
66303
  },
66165
66304
  transitionFromCommandMenu: (newMode) => {
66166
66305
  if (!storeRef)
66167
- throw new Error("AppStore not initialized");
66306
+ return;
66168
66307
  storeRef.transitionFromCommandMenu(newMode);
66169
66308
  },
66170
66309
  setAvailableModels: (models) => {
66171
66310
  if (!storeRef)
66172
- throw new Error("AppStore not initialized");
66311
+ return;
66173
66312
  storeRef.setAvailableModels(models);
66174
66313
  },
66175
66314
  setModel: (model) => {
66176
66315
  if (!storeRef)
66177
- throw new Error("AppStore not initialized");
66316
+ return;
66178
66317
  storeRef.setModel(model);
66179
66318
  },
66180
66319
  startThinking: () => {
66181
66320
  if (!storeRef)
66182
- throw new Error("AppStore not initialized");
66321
+ return;
66183
66322
  storeRef.startThinking();
66184
66323
  },
66185
66324
  stopThinking: () => {
66186
66325
  if (!storeRef)
66187
- throw new Error("AppStore not initialized");
66326
+ return;
66188
66327
  storeRef.stopThinking();
66189
66328
  },
66190
66329
  addTokens: (input, output) => {
66191
66330
  if (!storeRef)
66192
- throw new Error("AppStore not initialized");
66331
+ return;
66193
66332
  storeRef.addTokens(input, output);
66194
66333
  },
66195
66334
  resetSessionStats: () => {
66196
66335
  if (!storeRef)
66197
- throw new Error("AppStore not initialized");
66336
+ return;
66198
66337
  storeRef.resetSessionStats();
66199
66338
  },
66339
+ setContextMaxTokens: (maxTokens) => {
66340
+ if (!storeRef)
66341
+ return;
66342
+ storeRef.setContextMaxTokens(maxTokens);
66343
+ },
66200
66344
  toggleTodos: () => {
66201
66345
  if (!storeRef)
66202
- throw new Error("AppStore not initialized");
66346
+ return;
66203
66347
  storeRef.toggleTodos();
66204
66348
  },
66205
66349
  toggleDebugLog: () => {
66206
66350
  if (!storeRef)
66207
- throw new Error("AppStore not initialized");
66351
+ return;
66208
66352
  storeRef.toggleDebugLog();
66209
66353
  },
66210
66354
  setInterruptPending: (pending) => {
66211
66355
  if (!storeRef)
66212
- throw new Error("AppStore not initialized");
66356
+ return;
66213
66357
  storeRef.setInterruptPending(pending);
66214
66358
  },
66215
66359
  setIsCompacting: (compacting) => {
66216
66360
  if (!storeRef)
66217
- throw new Error("AppStore not initialized");
66361
+ return;
66218
66362
  storeRef.setIsCompacting(compacting);
66219
66363
  },
66220
66364
  startStreaming: () => {
66221
66365
  if (!storeRef)
66222
- throw new Error("AppStore not initialized");
66366
+ return "";
66223
66367
  return storeRef.startStreaming();
66224
66368
  },
66225
66369
  appendStreamContent: (content) => {
66226
66370
  if (!storeRef)
66227
- throw new Error("AppStore not initialized");
66371
+ return;
66228
66372
  storeRef.appendStreamContent(content);
66229
66373
  },
66230
66374
  completeStreaming: () => {
66231
66375
  if (!storeRef)
66232
- throw new Error("AppStore not initialized");
66376
+ return;
66233
66377
  storeRef.completeStreaming();
66234
66378
  },
66235
66379
  cancelStreaming: () => {
66236
66380
  if (!storeRef)
66237
- throw new Error("AppStore not initialized");
66381
+ return;
66238
66382
  storeRef.cancelStreaming();
66239
66383
  },
66240
66384
  setSuggestions: (suggestions) => {
66241
66385
  if (!storeRef)
66242
- throw new Error("AppStore not initialized");
66386
+ return;
66243
66387
  storeRef.setSuggestions(suggestions);
66244
66388
  },
66245
66389
  clearSuggestions: () => {
66246
66390
  if (!storeRef)
66247
- throw new Error("AppStore not initialized");
66391
+ return;
66248
66392
  storeRef.clearSuggestions();
66249
66393
  },
66250
66394
  hideSuggestions: () => {
66251
66395
  if (!storeRef)
66252
- throw new Error("AppStore not initialized");
66396
+ return;
66253
66397
  storeRef.hideSuggestions();
66254
66398
  },
66255
66399
  setProvider: (provider) => {
66256
66400
  if (!storeRef)
66257
- throw new Error("AppStore not initialized");
66401
+ return;
66258
66402
  storeRef.setProvider(provider);
66259
66403
  },
66260
66404
  setCascadeEnabled: (enabled) => {
66261
66405
  if (!storeRef)
66262
- throw new Error("AppStore not initialized");
66406
+ return;
66263
66407
  storeRef.setCascadeEnabled(enabled);
66264
66408
  },
66265
66409
  toggleCascadeEnabled: () => {
66266
66410
  if (!storeRef)
66267
- throw new Error("AppStore not initialized");
66411
+ return;
66268
66412
  storeRef.toggleCascadeEnabled();
66413
+ },
66414
+ setBrainStatus: (status) => {
66415
+ if (!storeRef)
66416
+ return;
66417
+ storeRef.setBrainStatus(status);
66418
+ },
66419
+ setBrainUser: (user) => {
66420
+ if (!storeRef)
66421
+ return;
66422
+ storeRef.setBrainUser(user);
66423
+ },
66424
+ setBrainCounts: (knowledge, memory) => {
66425
+ if (!storeRef)
66426
+ return;
66427
+ storeRef.setBrainCounts(knowledge, memory);
66428
+ },
66429
+ setBrainShowBanner: (show) => {
66430
+ if (!storeRef)
66431
+ return;
66432
+ storeRef.setBrainShowBanner(show);
66433
+ },
66434
+ dismissBrainBanner: () => {
66435
+ if (!storeRef)
66436
+ return;
66437
+ storeRef.dismissBrainBanner();
66438
+ },
66439
+ setMcpServers: (servers) => {
66440
+ if (!storeRef)
66441
+ return;
66442
+ storeRef.setMcpServers(servers);
66443
+ },
66444
+ addMcpServer: (server) => {
66445
+ if (!storeRef)
66446
+ return;
66447
+ storeRef.addMcpServer(server);
66448
+ },
66449
+ updateMcpServerStatus: (id, status) => {
66450
+ if (!storeRef)
66451
+ return;
66452
+ storeRef.updateMcpServerStatus(id, status);
66269
66453
  }
66270
66454
  };
66271
66455
  });
@@ -66354,76 +66538,74 @@ function DebugLogPanel() {
66354
66538
  return msg.substring(0, maxLen - 3) + "...";
66355
66539
  };
66356
66540
  return (() => {
66357
- var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$5 = createElement("text"), _el$6 = createTextNode(` (`), _el$7 = createTextNode(`)`), _el$8 = createElement("scrollbox"), _el$9 = createElement("box"), _el$0 = createElement("box"), _el$1 = createElement("text");
66541
+ var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$4 = createTextNode(`Debug Logs (`), _el$5 = createTextNode(`)`), _el$6 = createElement("scrollbox"), _el$7 = createElement("box"), _el$8 = createElement("box"), _el$9 = createElement("text");
66358
66542
  insertNode(_el$, _el$2);
66543
+ insertNode(_el$, _el$6);
66359
66544
  insertNode(_el$, _el$8);
66360
- insertNode(_el$, _el$0);
66361
66545
  setProp(_el$, "flexDirection", "column");
66362
66546
  setProp(_el$, "width", "20%");
66363
66547
  setProp(_el$, "border", ["top", "bottom", "left", "right"]);
66364
66548
  insertNode(_el$2, _el$3);
66365
- insertNode(_el$2, _el$5);
66366
66549
  setProp(_el$2, "paddingLeft", 1);
66367
66550
  setProp(_el$2, "paddingRight", 1);
66368
66551
  setProp(_el$2, "border", ["bottom"]);
66369
- insertNode(_el$3, createTextNode(`Debug Logs`));
66370
- insertNode(_el$5, _el$6);
66371
- insertNode(_el$5, _el$7);
66372
- insert(_el$5, () => entries2().length, _el$7);
66373
- insertNode(_el$8, _el$9);
66552
+ setProp(_el$2, "flexDirection", "row");
66553
+ insertNode(_el$3, _el$4);
66554
+ insertNode(_el$3, _el$5);
66555
+ insert(_el$3, () => entries2().length, _el$5);
66556
+ insertNode(_el$6, _el$7);
66374
66557
  var _ref$ = scrollboxRef;
66375
- typeof _ref$ === "function" ? use(_ref$, _el$8) : scrollboxRef = _el$8;
66376
- setProp(_el$8, "stickyStart", "bottom");
66377
- setProp(_el$8, "flexGrow", 1);
66378
- setProp(_el$8, "paddingLeft", 1);
66379
- setProp(_el$8, "paddingRight", 1);
66380
- setProp(_el$9, "flexDirection", "column");
66381
- insert(_el$9, createComponent2(For, {
66558
+ typeof _ref$ === "function" ? use(_ref$, _el$6) : scrollboxRef = _el$6;
66559
+ setProp(_el$6, "stickyStart", "bottom");
66560
+ setProp(_el$6, "flexGrow", 1);
66561
+ setProp(_el$6, "paddingLeft", 1);
66562
+ setProp(_el$6, "paddingRight", 1);
66563
+ setProp(_el$7, "flexDirection", "column");
66564
+ insert(_el$7, createComponent2(For, {
66382
66565
  get each() {
66383
66566
  return entries2();
66384
66567
  },
66385
66568
  children: (entry) => (() => {
66386
- var _el$11 = createElement("box"), _el$12 = createElement("text"), _el$13 = createTextNode(` `), _el$14 = createElement("text"), _el$15 = createTextNode(`[`), _el$16 = createTextNode(`] `), _el$18 = createElement("text");
66387
- insertNode(_el$11, _el$12);
66388
- insertNode(_el$11, _el$14);
66389
- insertNode(_el$11, _el$18);
66390
- setProp(_el$11, "flexDirection", "row");
66569
+ var _el$1 = createElement("box"), _el$10 = createElement("text"), _el$11 = createTextNode(` `), _el$12 = createElement("text"), _el$13 = createTextNode(`[`), _el$14 = createTextNode(`] `), _el$16 = createElement("text");
66570
+ insertNode(_el$1, _el$10);
66571
+ insertNode(_el$1, _el$12);
66572
+ insertNode(_el$1, _el$16);
66573
+ setProp(_el$1, "flexDirection", "row");
66574
+ insertNode(_el$10, _el$11);
66575
+ insert(_el$10, () => formatTime(entry.timestamp), _el$11);
66391
66576
  insertNode(_el$12, _el$13);
66392
- insert(_el$12, () => formatTime(entry.timestamp), _el$13);
66393
- insertNode(_el$14, _el$15);
66394
- insertNode(_el$14, _el$16);
66395
- insert(_el$14, () => getTypeLabel(entry.type), _el$16);
66396
- setProp(_el$18, "wrapMode", "word");
66397
- insert(_el$18, () => truncateMessage(entry.message, 50));
66577
+ insertNode(_el$12, _el$14);
66578
+ insert(_el$12, () => getTypeLabel(entry.type), _el$14);
66579
+ setProp(_el$16, "wrapMode", "word");
66580
+ insert(_el$16, () => truncateMessage(entry.message, 50));
66398
66581
  effect((_p$) => {
66399
- var _v$0 = theme.colors.textDim, _v$1 = getTypeColor(entry.type), _v$10 = theme.colors.text;
66400
- _v$0 !== _p$.e && (_p$.e = setProp(_el$12, "fg", _v$0, _p$.e));
66401
- _v$1 !== _p$.t && (_p$.t = setProp(_el$14, "fg", _v$1, _p$.t));
66402
- _v$10 !== _p$.a && (_p$.a = setProp(_el$18, "fg", _v$10, _p$.a));
66582
+ var _v$9 = theme.colors.textDim, _v$0 = getTypeColor(entry.type), _v$1 = theme.colors.text;
66583
+ _v$9 !== _p$.e && (_p$.e = setProp(_el$10, "fg", _v$9, _p$.e));
66584
+ _v$0 !== _p$.t && (_p$.t = setProp(_el$12, "fg", _v$0, _p$.t));
66585
+ _v$1 !== _p$.a && (_p$.a = setProp(_el$16, "fg", _v$1, _p$.a));
66403
66586
  return _p$;
66404
66587
  }, {
66405
66588
  e: undefined,
66406
66589
  t: undefined,
66407
66590
  a: undefined
66408
66591
  });
66409
- return _el$11;
66592
+ return _el$1;
66410
66593
  })()
66411
66594
  }));
66412
- insertNode(_el$0, _el$1);
66413
- setProp(_el$0, "paddingLeft", 1);
66414
- setProp(_el$0, "border", ["top"]);
66415
- insertNode(_el$1, createTextNode(`Shift+PgUp/PgDn scroll`));
66595
+ insertNode(_el$8, _el$9);
66596
+ setProp(_el$8, "paddingLeft", 1);
66597
+ setProp(_el$8, "border", ["top"]);
66598
+ insertNode(_el$9, createTextNode(`Shift+PgUp/PgDn scroll`));
66416
66599
  effect((_p$) => {
66417
- var _v$ = theme.colors.border, _v$2 = theme.colors.background, _v$3 = theme.colors.border, _v$4 = theme.colors.accent, _v$5 = TextAttributes.BOLD, _v$6 = theme.colors.textDim, _v$7 = stickyEnabled(), _v$8 = theme.colors.border, _v$9 = theme.colors.textDim;
66600
+ var _v$ = theme.colors.border, _v$2 = theme.colors.background, _v$3 = theme.colors.border, _v$4 = theme.colors.accent, _v$5 = TextAttributes.BOLD, _v$6 = stickyEnabled(), _v$7 = theme.colors.border, _v$8 = theme.colors.textDim;
66418
66601
  _v$ !== _p$.e && (_p$.e = setProp(_el$, "borderColor", _v$, _p$.e));
66419
66602
  _v$2 !== _p$.t && (_p$.t = setProp(_el$, "backgroundColor", _v$2, _p$.t));
66420
66603
  _v$3 !== _p$.a && (_p$.a = setProp(_el$2, "borderColor", _v$3, _p$.a));
66421
66604
  _v$4 !== _p$.o && (_p$.o = setProp(_el$3, "fg", _v$4, _p$.o));
66422
66605
  _v$5 !== _p$.i && (_p$.i = setProp(_el$3, "attributes", _v$5, _p$.i));
66423
- _v$6 !== _p$.n && (_p$.n = setProp(_el$5, "fg", _v$6, _p$.n));
66424
- _v$7 !== _p$.s && (_p$.s = setProp(_el$8, "stickyScroll", _v$7, _p$.s));
66425
- _v$8 !== _p$.h && (_p$.h = setProp(_el$0, "borderColor", _v$8, _p$.h));
66426
- _v$9 !== _p$.r && (_p$.r = setProp(_el$1, "fg", _v$9, _p$.r));
66606
+ _v$6 !== _p$.n && (_p$.n = setProp(_el$6, "stickyScroll", _v$6, _p$.n));
66607
+ _v$7 !== _p$.s && (_p$.s = setProp(_el$8, "borderColor", _v$7, _p$.s));
66608
+ _v$8 !== _p$.h && (_p$.h = setProp(_el$9, "fg", _v$8, _p$.h));
66427
66609
  return _p$;
66428
66610
  }, {
66429
66611
  e: undefined,
@@ -66433,8 +66615,7 @@ function DebugLogPanel() {
66433
66615
  i: undefined,
66434
66616
  n: undefined,
66435
66617
  s: undefined,
66436
- h: undefined,
66437
- r: undefined
66618
+ h: undefined
66438
66619
  });
66439
66620
  return _el$;
66440
66621
  })();
@@ -66592,6 +66773,7 @@ var formatMessages = (messages) => messages.map((msg) => {
66592
66773
  if (delta?.tool_calls) {
66593
66774
  for (const tc of delta.tool_calls) {
66594
66775
  addDebugLog("api", `Tool call chunk: ${JSON.stringify(tc)}`);
66776
+ console.log("Debug: Tool call chunk received:", JSON.stringify(tc));
66595
66777
  onChunk({ type: "tool_call", toolCall: tc });
66596
66778
  }
66597
66779
  }
@@ -66909,10 +67091,22 @@ var init_models2 = __esm(() => {
66909
67091
  });
66910
67092
 
66911
67093
  // src/providers/ollama/chat.ts
66912
- var formatMessages2 = (messages) => messages.map((msg) => ({
66913
- role: msg.role,
66914
- content: msg.content
66915
- })), formatTools = (tools) => {
67094
+ var formatMessages2 = (messages) => messages.map((msg) => {
67095
+ const formatted = {
67096
+ role: msg.role,
67097
+ content: msg.content
67098
+ };
67099
+ if (msg.tool_calls && msg.tool_calls.length > 0) {
67100
+ formatted.tool_calls = msg.tool_calls.map((tc) => ({
67101
+ id: tc.id,
67102
+ function: {
67103
+ name: tc.function.name,
67104
+ arguments: typeof tc.function.arguments === "string" ? JSON.parse(tc.function.arguments) : tc.function.arguments
67105
+ }
67106
+ }));
67107
+ }
67108
+ return formatted;
67109
+ }), formatTools = (tools) => {
66916
67110
  if (!tools || tools.length === 0)
66917
67111
  return;
66918
67112
  return tools.map((tool) => ({
@@ -67209,7 +67403,7 @@ Available models:`,
67209
67403
  });
67210
67404
 
67211
67405
  // src/providers/credentials.ts
67212
- import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
67406
+ import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
67213
67407
  import { existsSync as existsSync3 } from "fs";
67214
67408
  var loadCredentials = async () => {
67215
67409
  if (!existsSync3(FILES.credentials)) {
@@ -67222,8 +67416,8 @@ var loadCredentials = async () => {
67222
67416
  return {};
67223
67417
  }
67224
67418
  }, saveCredentials = async (credentials) => {
67225
- await mkdir(DIRS.data, { recursive: true });
67226
- await writeFile(FILES.credentials, JSON.stringify(credentials, null, 2), {
67419
+ await mkdir2(DIRS.data, { recursive: true });
67420
+ await writeFile2(FILES.credentials, JSON.stringify(credentials, null, 2), {
67227
67421
  mode: CREDENTIALS_FILE_MODE
67228
67422
  });
67229
67423
  };
@@ -73278,12 +73472,11 @@ class MCPClient {
73278
73472
  var init_client = () => {};
73279
73473
 
73280
73474
  // src/services/mcp/manager.ts
73281
- import fs12 from "fs/promises";
73282
- import path12 from "path";
73283
- import os6 from "os";
73475
+ import fs15 from "fs/promises";
73476
+ import path13 from "path";
73284
73477
  var CONFIG_LOCATIONS, state3, loadConfigFile = async (filePath2) => {
73285
73478
  try {
73286
- const content = await fs12.readFile(filePath2, "utf-8");
73479
+ const content = await fs15.readFile(filePath2, "utf-8");
73287
73480
  return JSON.parse(content);
73288
73481
  } catch {
73289
73482
  return null;
@@ -73300,9 +73493,9 @@ var CONFIG_LOCATIONS, state3, loadConfigFile = async (filePath2) => {
73300
73493
  return merged;
73301
73494
  }, saveMCPConfig = async (config2, global3 = false) => {
73302
73495
  const filePath2 = global3 ? CONFIG_LOCATIONS.global : CONFIG_LOCATIONS.local;
73303
- const dir = path12.dirname(filePath2);
73304
- await fs12.mkdir(dir, { recursive: true });
73305
- await fs12.writeFile(filePath2, JSON.stringify(config2, null, 2), "utf-8");
73496
+ const dir = path13.dirname(filePath2);
73497
+ await fs15.mkdir(dir, { recursive: true });
73498
+ await fs15.writeFile(filePath2, JSON.stringify(config2, null, 2), "utf-8");
73306
73499
  }, initializeMCP = async () => {
73307
73500
  if (state3.initialized)
73308
73501
  return;
@@ -73414,9 +73607,10 @@ var CONFIG_LOCATIONS, state3, loadConfigFile = async (filePath2) => {
73414
73607
  };
73415
73608
  var init_manager = __esm(() => {
73416
73609
  init_client();
73610
+ init_paths();
73417
73611
  CONFIG_LOCATIONS = {
73418
- global: path12.join(os6.homedir(), ".codetyper", "mcp.json"),
73419
- local: path12.join(process.cwd(), ".codetyper", "mcp.json")
73612
+ global: path13.join(DIRS.config, "mcp.json"),
73613
+ local: path13.join(process.cwd(), LOCAL_CONFIG_DIR, "mcp.json")
73420
73614
  };
73421
73615
  state3 = {
73422
73616
  clients: new Map,
@@ -73560,12 +73754,12 @@ var createEmptyIndex = (model) => ({
73560
73754
  });
73561
73755
 
73562
73756
  // src/services/learning/vector-store.ts
73563
- import * as fs13 from "fs/promises";
73564
- import * as path13 from "path";
73565
- var getIndexPath = (baseDir) => path13.join(baseDir, EMBEDDING_STORAGE.INDEX_FILE), loadIndex = async (baseDir, model) => {
73757
+ import * as fs16 from "fs/promises";
73758
+ import * as path14 from "path";
73759
+ var getIndexPath = (baseDir) => path14.join(baseDir, EMBEDDING_STORAGE.INDEX_FILE), loadIndex = async (baseDir, model) => {
73566
73760
  const indexPath = getIndexPath(baseDir);
73567
73761
  try {
73568
- const data = await fs13.readFile(indexPath, "utf-8");
73762
+ const data = await fs16.readFile(indexPath, "utf-8");
73569
73763
  const index = JSON.parse(data);
73570
73764
  if (index.version !== EMBEDDING_STORAGE.VERSION || index.model !== model) {
73571
73765
  return createEmptyIndex(model);
@@ -73576,8 +73770,8 @@ var getIndexPath = (baseDir) => path13.join(baseDir, EMBEDDING_STORAGE.INDEX_FIL
73576
73770
  }
73577
73771
  }, saveIndex = async (baseDir, index) => {
73578
73772
  const indexPath = getIndexPath(baseDir);
73579
- await fs13.mkdir(baseDir, { recursive: true });
73580
- await fs13.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
73773
+ await fs16.mkdir(baseDir, { recursive: true });
73774
+ await fs16.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
73581
73775
  }, upsertEmbedding = (index, id, embedding) => {
73582
73776
  const stored = {
73583
73777
  id,
@@ -73599,8 +73793,8 @@ var init_vector_store = __esm(() => {
73599
73793
  });
73600
73794
 
73601
73795
  // src/services/learning/semantic-search.ts
73602
- import * as path14 from "path";
73603
- var globalIndex = null, localIndex = null, getGlobalIndexDir = () => path14.join(getGlobalConfigDir(), "learnings"), getLocalIndexDir = () => path14.join(getLocalConfigDir(), "learnings"), getGlobalIndex = async () => {
73796
+ import * as path15 from "path";
73797
+ var globalIndex = null, localIndex = null, getGlobalIndexDir = () => path15.join(getGlobalConfigDir(), "learnings"), getLocalIndexDir = () => path15.join(getLocalConfigDir(), "learnings"), getGlobalIndex = async () => {
73604
73798
  if (!isEmbeddingAvailable()) {
73605
73799
  return null;
73606
73800
  }
@@ -73666,7 +73860,7 @@ var init_semantic_search = __esm(() => {
73666
73860
  var version_default;
73667
73861
  var init_version = __esm(() => {
73668
73862
  version_default = {
73669
- version: "0.2.1"
73863
+ version: "0.2.3"
73670
73864
  };
73671
73865
  });
73672
73866
 
@@ -73996,9 +74190,9 @@ var init_mcp_registry = __esm(() => {
73996
74190
 
73997
74191
  // src/services/mcp/registry.ts
73998
74192
  import { homedir as homedir4 } from "os";
73999
- import { join as join13 } from "path";
74193
+ import { join as join14 } from "path";
74000
74194
  var registryCache = null, getCacheFilePath = () => {
74001
- return join13(homedir4(), ".codetyper", MCP_REGISTRY_CACHE.FILE_NAME);
74195
+ return join14(homedir4(), ".codetyper", MCP_REGISTRY_CACHE.FILE_NAME);
74002
74196
  }, loadCache = async () => {
74003
74197
  try {
74004
74198
  const cachePath = getCacheFilePath();
@@ -74155,7 +74349,7 @@ var registryCache = null, getCacheFilePath = () => {
74155
74349
  const instances = getServerInstances();
74156
74350
  return instances.some((instance) => instance.config.name === serverId || instance.config.name.toLowerCase() === serverId.toLowerCase());
74157
74351
  }, installServer = async (server, options2 = {}) => {
74158
- const { global: global3 = false, connect = true, customArgs } = options2;
74352
+ const { global: global3 = false, connect: connect2 = true, customArgs } = options2;
74159
74353
  if (isServerInstalled(server.id)) {
74160
74354
  return {
74161
74355
  success: false,
@@ -74173,7 +74367,7 @@ var registryCache = null, getCacheFilePath = () => {
74173
74367
  enabled: true
74174
74368
  }, global3);
74175
74369
  let connected = false;
74176
- if (connect) {
74370
+ if (connect2) {
74177
74371
  try {
74178
74372
  await connectServer(server.id);
74179
74373
  connected = true;
@@ -74832,15 +75026,27 @@ var PROVIDER_ENV_VARS = {
74832
75026
  ollama: "OLLAMA_HOST"
74833
75027
  };
74834
75028
  var configState = getDefaults();
75029
+ var configLoaded = false;
75030
+ var configLoadPromise = null;
74835
75031
  var loadConfig = async () => {
74836
- try {
74837
- const data = await fs2.readFile(FILES.config, "utf-8");
74838
- const loaded = JSON.parse(data);
74839
- delete loaded.models;
74840
- configState = { ...getDefaults(), ...loaded };
74841
- } catch {
74842
- configState = getDefaults();
75032
+ if (configLoaded) {
75033
+ return;
74843
75034
  }
75035
+ if (configLoadPromise) {
75036
+ return configLoadPromise;
75037
+ }
75038
+ configLoadPromise = (async () => {
75039
+ try {
75040
+ const data = await fs2.readFile(FILES.config, "utf-8");
75041
+ const loaded = JSON.parse(data);
75042
+ delete loaded.models;
75043
+ configState = { ...getDefaults(), ...loaded };
75044
+ } catch {
75045
+ configState = getDefaults();
75046
+ }
75047
+ configLoaded = true;
75048
+ })();
75049
+ return configLoadPromise;
74844
75050
  };
74845
75051
  var saveConfig = async () => {
74846
75052
  try {
@@ -76436,7 +76642,7 @@ Read-only tools only:
76436
76642
 
76437
76643
  - You are in READ-ONLY mode - you cannot modify files
76438
76644
  - Always search before answering questions about the codebase
76439
- - If asked to make changes, explain that you're in Ask mode and suggest switching to Agent mode (Ctrl+Tab)
76645
+ - If asked to make changes, explain that you're in Ask mode and suggest switching to Agent mode (Ctrl+M)
76440
76646
  - For general programming questions, you can answer without searching`;
76441
76647
  var buildAskPrompt = (context) => {
76442
76648
  const envSection = `
@@ -79040,15 +79246,36 @@ var MODE_PROMPT_BUILDERS = {
79040
79246
  prContext: ctx.prContext
79041
79247
  })
79042
79248
  };
79249
+ var execGitCommand = (args) => {
79250
+ return new Promise((resolve4, reject) => {
79251
+ const { spawn: spawn2 } = __require("child_process");
79252
+ const proc = spawn2("git", args, { cwd: process.cwd() });
79253
+ let stdout = "";
79254
+ let stderr = "";
79255
+ proc.stdout.on("data", (data) => {
79256
+ stdout += data.toString();
79257
+ });
79258
+ proc.stderr.on("data", (data) => {
79259
+ stderr += data.toString();
79260
+ });
79261
+ proc.on("close", (code) => {
79262
+ if (code === 0) {
79263
+ resolve4(stdout.trim());
79264
+ } else {
79265
+ reject(new Error(stderr || `git exited with code ${code}`));
79266
+ }
79267
+ });
79268
+ proc.on("error", reject);
79269
+ });
79270
+ };
79043
79271
  var getGitContext = async () => {
79044
79272
  try {
79045
- const { execSync } = await import("child_process");
79046
- const branch = execSync("git branch --show-current", {
79047
- encoding: "utf-8"
79048
- }).trim();
79049
- const status2 = execSync("git status --short", { encoding: "utf-8" }).trim() || "(clean)";
79050
- const commits = execSync("git log --oneline -5", { encoding: "utf-8" }).trim().split(`
79051
- `).filter(Boolean);
79273
+ const [branch, status2, commits] = await Promise.all([
79274
+ execGitCommand(["branch", "--show-current"]),
79275
+ execGitCommand(["status", "--short"]).then((s) => s || "(clean)"),
79276
+ execGitCommand(["log", "--oneline", "-5"]).then((s) => s.split(`
79277
+ `).filter(Boolean))
79278
+ ]);
79052
79279
  return { isGitRepo: true, branch, status: status2, recentCommits: commits };
79053
79280
  } catch {
79054
79281
  return { isGitRepo: false };
@@ -79458,6 +79685,266 @@ var initSuggestionService = (cwd) => {
79458
79685
  clearSuggestions();
79459
79686
  };
79460
79687
 
79688
+ // src/services/brain.ts
79689
+ init_paths();
79690
+ import fs6 from "fs/promises";
79691
+
79692
+ // src/constants/brain.ts
79693
+ var BRAIN_DISABLED = true;
79694
+ var BRAIN_DEFAULTS = {
79695
+ BASE_URL: "http://localhost:5001",
79696
+ PROJECT_ID: 1
79697
+ };
79698
+ var BRAIN_ENDPOINTS = {
79699
+ HEALTH: "/",
79700
+ AUTH_REGISTER: "/auth/register",
79701
+ AUTH_LOGIN: "/auth/login",
79702
+ AUTH_LOGOUT: "/auth/logout",
79703
+ AUTH_REFRESH: "/auth/refresh",
79704
+ AUTH_ME: "/auth/me",
79705
+ KNOWLEDGE_LEARN: "/api/knowledge/learn",
79706
+ KNOWLEDGE_RECALL: "/api/knowledge/recall",
79707
+ KNOWLEDGE_RELATE: "/api/knowledge/relate",
79708
+ KNOWLEDGE_EXTRACT: "/api/knowledge/extract",
79709
+ KNOWLEDGE_CONTEXT: "/api/knowledge/context",
79710
+ KNOWLEDGE_CONCEPTS: "/api/knowledge/concepts",
79711
+ KNOWLEDGE_STATS: "/api/knowledge/stats",
79712
+ MEMORY_STATUS: "/api/memory/status",
79713
+ MEMORY_STATS: "/api/memory/stats",
79714
+ MEMORY_SEARCH: "/api/memory/search",
79715
+ MEMORY_STORE: "/api/memory/store",
79716
+ MEMORY_TOP: "/api/memory/top",
79717
+ MEMORY_FEEDBACK: "/api/memory/feedback",
79718
+ GRAPHQL: "/graphql"
79719
+ };
79720
+ var BRAIN_TIMEOUTS = {
79721
+ HEALTH: 3000,
79722
+ AUTH: 1e4,
79723
+ KNOWLEDGE: 15000,
79724
+ MEMORY: 1e4,
79725
+ EXTRACT: 30000
79726
+ };
79727
+ var BRAIN_ERRORS = {
79728
+ NOT_RUNNING: "Brain service not available. Start the API server at localhost:5001",
79729
+ NOT_AUTHENTICATED: "Not authenticated. Please login or set an API key.",
79730
+ INVALID_API_KEY: "Invalid API key. Please check your credentials.",
79731
+ CONNECTION_FAILED: "Failed to connect to Brain service.",
79732
+ RECALL_FAILED: "Failed to recall knowledge from Brain.",
79733
+ LEARN_FAILED: "Failed to store knowledge in Brain.",
79734
+ EXTRACT_FAILED: "Failed to extract concepts from content."
79735
+ };
79736
+ var BRAIN_BANNER = {
79737
+ TITLE: "CodeTyper has a Brain!",
79738
+ CTA: "Login and get an API key to enable long-term memory",
79739
+ URL: "http://localhost:5001",
79740
+ LOGIN_URL: "http://localhost:5173/docs/login",
79741
+ EMOJI_CONNECTED: "\uD83E\uDDE0",
79742
+ EMOJI_DISCONNECTED: "\uD83D\uDCA4"
79743
+ };
79744
+ var BRAIN_HEADERS = {
79745
+ API_KEY: "api-key",
79746
+ AUTHORIZATION: "Authorization",
79747
+ CONTENT_TYPE: "Content-Type"
79748
+ };
79749
+
79750
+ // src/api/brain/index.ts
79751
+ init_source4();
79752
+ var buildHeaders2 = (apiKey, accessToken) => ({
79753
+ [BRAIN_HEADERS.CONTENT_TYPE]: "application/json",
79754
+ ...apiKey ? { [BRAIN_HEADERS.API_KEY]: apiKey } : {},
79755
+ ...accessToken ? { [BRAIN_HEADERS.AUTHORIZATION]: `Bearer ${accessToken}` } : {}
79756
+ });
79757
+ var getBaseUrl = (customUrl) => {
79758
+ return customUrl ?? BRAIN_DEFAULTS.BASE_URL;
79759
+ };
79760
+ var checkHealth = async (baseUrl) => {
79761
+ const url = `${getBaseUrl(baseUrl)}${BRAIN_ENDPOINTS.HEALTH}`;
79762
+ const response2 = await source_default2.get(url, {
79763
+ timeout: { request: BRAIN_TIMEOUTS.HEALTH }
79764
+ }).json();
79765
+ return response2;
79766
+ };
79767
+ var logout2 = async (refreshToken2, baseUrl) => {
79768
+ const url = `${getBaseUrl(baseUrl)}${BRAIN_ENDPOINTS.AUTH_LOGOUT}`;
79769
+ await source_default2.post(url, {
79770
+ json: { refresh_token: refreshToken2 },
79771
+ timeout: { request: BRAIN_TIMEOUTS.AUTH }
79772
+ });
79773
+ };
79774
+ var getKnowledgeStats = async (projectId, apiKey, baseUrl) => {
79775
+ const url = `${getBaseUrl(baseUrl)}${BRAIN_ENDPOINTS.KNOWLEDGE_STATS}?project_id=${projectId}`;
79776
+ const response2 = await source_default2.get(url, {
79777
+ ...{ headers: buildHeaders2(apiKey) },
79778
+ timeout: { request: BRAIN_TIMEOUTS.KNOWLEDGE }
79779
+ }).json();
79780
+ return response2;
79781
+ };
79782
+ var getMemoryStats = async (apiKey, baseUrl) => {
79783
+ const url = `${getBaseUrl(baseUrl)}${BRAIN_ENDPOINTS.MEMORY_STATS}`;
79784
+ const response2 = await source_default2.get(url, {
79785
+ ...{ headers: buildHeaders2(apiKey) },
79786
+ timeout: { request: BRAIN_TIMEOUTS.MEMORY }
79787
+ }).json();
79788
+ return response2;
79789
+ };
79790
+
79791
+ // src/services/brain.ts
79792
+ var brainState = {
79793
+ status: "disconnected",
79794
+ user: null,
79795
+ projectId: BRAIN_DEFAULTS.PROJECT_ID,
79796
+ knowledgeCount: 0,
79797
+ memoryCount: 0,
79798
+ lastError: null
79799
+ };
79800
+ var cachedCredentials = null;
79801
+ var cachedVars = null;
79802
+ var loadVarsFile = async () => {
79803
+ if (cachedVars) {
79804
+ return cachedVars;
79805
+ }
79806
+ try {
79807
+ const data = await fs6.readFile(FILES.vars, "utf-8");
79808
+ cachedVars = JSON.parse(data);
79809
+ return cachedVars;
79810
+ } catch {
79811
+ return {};
79812
+ }
79813
+ };
79814
+ var saveVarsFile = async (vars) => {
79815
+ try {
79816
+ await fs6.mkdir(DIRS.config, { recursive: true });
79817
+ await fs6.writeFile(FILES.vars, JSON.stringify(vars, null, 2), "utf-8");
79818
+ cachedVars = vars;
79819
+ } catch (error2) {
79820
+ throw new Error(`Failed to save vars file: ${error2}`);
79821
+ }
79822
+ };
79823
+ var getCredentialsPath = () => {
79824
+ return `${DIRS.data}/brain-credentials.json`;
79825
+ };
79826
+ var loadCredentials2 = async () => {
79827
+ if (cachedCredentials) {
79828
+ return cachedCredentials;
79829
+ }
79830
+ try {
79831
+ const data = await fs6.readFile(getCredentialsPath(), "utf-8");
79832
+ cachedCredentials = JSON.parse(data);
79833
+ return cachedCredentials;
79834
+ } catch {
79835
+ return null;
79836
+ }
79837
+ };
79838
+ var clearCredentials2 = async () => {
79839
+ try {
79840
+ await fs6.unlink(getCredentialsPath());
79841
+ cachedCredentials = null;
79842
+ } catch {}
79843
+ try {
79844
+ const vars = await loadVarsFile();
79845
+ await saveVarsFile({
79846
+ ...vars,
79847
+ brainApiKey: undefined,
79848
+ brainJwtToken: undefined
79849
+ });
79850
+ } catch {}
79851
+ };
79852
+ var getApiKey2 = async () => {
79853
+ const envKey = process.env.CODETYPER_BRAIN_API_KEY;
79854
+ if (envKey) {
79855
+ return envKey;
79856
+ }
79857
+ const vars = await loadVarsFile();
79858
+ return vars.brainApiKey;
79859
+ };
79860
+ var getJwtToken = async () => {
79861
+ const vars = await loadVarsFile();
79862
+ return vars.brainJwtToken;
79863
+ };
79864
+ var setApiKey = async (apiKey) => {
79865
+ const vars = await loadVarsFile();
79866
+ await saveVarsFile({ ...vars, brainApiKey: apiKey });
79867
+ };
79868
+ var setJwtToken = async (jwtToken) => {
79869
+ const vars = await loadVarsFile();
79870
+ await saveVarsFile({ ...vars, brainJwtToken: jwtToken });
79871
+ };
79872
+ var logout3 = async () => {
79873
+ try {
79874
+ const credentials = await loadCredentials2();
79875
+ if (credentials?.refreshToken) {
79876
+ await logout2(credentials.refreshToken);
79877
+ }
79878
+ } catch {} finally {
79879
+ await clearCredentials2();
79880
+ updateState({
79881
+ status: "disconnected",
79882
+ user: null,
79883
+ knowledgeCount: 0,
79884
+ memoryCount: 0
79885
+ });
79886
+ }
79887
+ };
79888
+ var getAuthToken = async () => {
79889
+ const apiKey = await getApiKey2();
79890
+ if (apiKey) {
79891
+ return apiKey;
79892
+ }
79893
+ return getJwtToken();
79894
+ };
79895
+ var connect = async () => {
79896
+ if (BRAIN_DISABLED) {
79897
+ return false;
79898
+ }
79899
+ try {
79900
+ updateState({ status: "connecting" });
79901
+ await checkHealth();
79902
+ const authToken = await getAuthToken();
79903
+ if (!authToken) {
79904
+ updateState({ status: "disconnected", lastError: null });
79905
+ return false;
79906
+ }
79907
+ const projectId = brainState.projectId ?? BRAIN_DEFAULTS.PROJECT_ID;
79908
+ const statsResponse = await getKnowledgeStats(projectId, authToken);
79909
+ if (statsResponse.success && statsResponse.data) {
79910
+ updateState({
79911
+ status: "connected",
79912
+ knowledgeCount: statsResponse.data.total_concepts,
79913
+ lastError: null
79914
+ });
79915
+ try {
79916
+ const memoryStats = await getMemoryStats(authToken);
79917
+ updateState({ memoryCount: memoryStats.totalNodes });
79918
+ } catch {}
79919
+ return true;
79920
+ }
79921
+ updateState({ status: "error", lastError: BRAIN_ERRORS.INVALID_API_KEY });
79922
+ return false;
79923
+ } catch (error2) {
79924
+ const errorMessage2 = error2 instanceof Error ? error2.message : BRAIN_ERRORS.CONNECTION_FAILED;
79925
+ updateState({ status: "error", lastError: errorMessage2 });
79926
+ return false;
79927
+ }
79928
+ };
79929
+ var getState2 = () => {
79930
+ return { ...brainState };
79931
+ };
79932
+ var updateState = (updates) => {
79933
+ brainState = { ...brainState, ...updates };
79934
+ };
79935
+ var isAuthenticated = async () => {
79936
+ const apiKey = await getApiKey2();
79937
+ const jwtToken = await getJwtToken();
79938
+ return apiKey !== undefined || jwtToken !== undefined;
79939
+ };
79940
+ var initialize = async () => {
79941
+ const hasAuth = await isAuthenticated();
79942
+ if (hasAuth) {
79943
+ return connect();
79944
+ }
79945
+ return false;
79946
+ };
79947
+
79461
79948
  // src/services/chat-tui/files.ts
79462
79949
  var import_fast_glob2 = __toESM(require_out4(), 1);
79463
79950
  import { readFile as readFile5, stat as stat2 } from "fs/promises";
@@ -79517,7 +80004,7 @@ var AUTH_MESSAGES = {
79517
80004
  2. Enter code: ${code}
79518
80005
 
79519
80006
  Waiting for authentication...`,
79520
- LOGGED_IN_AS: (login, name) => `Logged in as: ${login}${name ? ` (${name})` : ""}`
80007
+ LOGGED_IN_AS: (login2, name) => `Logged in as: ${login2}${name ? ` (${name})` : ""}`
79521
80008
  };
79522
80009
  var MODEL_MESSAGES = {
79523
80010
  MODEL_AUTO: "Model set to auto - the provider will choose the best model.",
@@ -79746,6 +80233,30 @@ var initializeTheme = async () => {
79746
80233
  themeActions.setTheme(savedTheme);
79747
80234
  }
79748
80235
  };
80236
+ var initializeBrain = async () => {
80237
+ if (BRAIN_DISABLED) {
80238
+ appStore.setBrainStatus("disconnected");
80239
+ appStore.setBrainShowBanner(false);
80240
+ return;
80241
+ }
80242
+ try {
80243
+ appStore.setBrainStatus("connecting");
80244
+ const connected = await initialize();
80245
+ if (connected) {
80246
+ const state2 = getState2();
80247
+ appStore.setBrainStatus("connected");
80248
+ appStore.setBrainUser(state2.user);
80249
+ appStore.setBrainCounts(state2.knowledgeCount, state2.memoryCount);
80250
+ appStore.setBrainShowBanner(false);
80251
+ } else {
80252
+ appStore.setBrainStatus("disconnected");
80253
+ appStore.setBrainShowBanner(true);
80254
+ }
80255
+ } catch {
80256
+ appStore.setBrainStatus("disconnected");
80257
+ appStore.setBrainShowBanner(true);
80258
+ }
80259
+ };
79749
80260
  var rebuildSystemPromptForMode = async (state2, newMode, appendPrompt) => {
79750
80261
  if (state2.currentMode === newMode) {
79751
80262
  return;
@@ -79761,16 +80272,21 @@ var rebuildSystemPromptForMode = async (state2, newMode, appendPrompt) => {
79761
80272
  var initializeChatService = async (options2) => {
79762
80273
  const initialMode = appStore.getState().interactionMode;
79763
80274
  const state2 = await createInitialState4(options2, initialMode);
79764
- await validateProvider(state2);
79765
- await buildSystemPrompt(state2, options2);
79766
- await initializeTheme();
80275
+ await Promise.all([
80276
+ validateProvider(state2),
80277
+ buildSystemPrompt(state2, options2),
80278
+ initializeTheme()
80279
+ ]);
79767
80280
  const session = await initializeSession(state2, options2);
79768
80281
  if (state2.messages.length === 0) {
79769
80282
  state2.messages.push({ role: "system", content: state2.systemPrompt });
79770
80283
  }
79771
- await addInitialContextFiles(state2, options2.files);
79772
- await initializePermissions();
80284
+ await Promise.all([
80285
+ addInitialContextFiles(state2, options2.files),
80286
+ initializePermissions()
80287
+ ]);
79773
80288
  initSuggestionService(process.cwd());
80289
+ initializeBrain().catch(() => {});
79774
80290
  return { state: state2, session };
79775
80291
  };
79776
80292
  // node_modules/uuid/dist-node/stringify.js
@@ -93640,7 +94156,7 @@ var processLines = (lines, offset, limit) => {
93640
94156
  };
93641
94157
  };
93642
94158
  // src/tools/read/execute.ts
93643
- import fs6 from "fs/promises";
94159
+ import fs7 from "fs/promises";
93644
94160
  import path7 from "path";
93645
94161
  var createDeniedResult2 = (filePath2) => ({
93646
94162
  success: false,
@@ -93685,8 +94201,8 @@ var checkPermission2 = async (fullPath, autoApprove) => {
93685
94201
  const { allowed } = await promptFilePermission("Read", fullPath);
93686
94202
  return allowed;
93687
94203
  };
93688
- var readDirectory = async (fullPath) => fs6.readdir(fullPath);
93689
- var readFileContent = async (fullPath) => fs6.readFile(fullPath, "utf-8");
94204
+ var readDirectory = async (fullPath) => fs7.readdir(fullPath);
94205
+ var readFileContent = async (fullPath) => fs7.readFile(fullPath, "utf-8");
93690
94206
  var executeRead = async (args, ctx) => {
93691
94207
  const { filePath: filePath2, offset = 0, limit = READ_DEFAULTS.MAX_LINES } = args;
93692
94208
  const fullPath = resolvePath(filePath2, ctx.workingDir);
@@ -93698,7 +94214,7 @@ var executeRead = async (args, ctx) => {
93698
94214
  status: "running"
93699
94215
  });
93700
94216
  try {
93701
- const stat3 = await fs6.stat(fullPath);
94217
+ const stat3 = await fs7.stat(fullPath);
93702
94218
  if (stat3.isDirectory()) {
93703
94219
  const files = await readDirectory(fullPath);
93704
94220
  return createDirectoryResult(filePath2, files);
@@ -93725,7 +94241,7 @@ var writeParams = exports_external.object({
93725
94241
  content: exports_external.string().describe("The content to write to the file")
93726
94242
  });
93727
94243
  // src/tools/write/execute.ts
93728
- import fs7 from "fs/promises";
94244
+ import fs8 from "fs/promises";
93729
94245
  import path8 from "path";
93730
94246
 
93731
94247
  // src/constants/write.ts
@@ -94064,7 +94580,7 @@ var resolvePaths = (filePath2, workingDir3) => {
94064
94580
  };
94065
94581
  var readExistingContent = async (fullPath) => {
94066
94582
  try {
94067
- const content = await fs7.readFile(fullPath, "utf-8");
94583
+ const content = await fs8.readFile(fullPath, "utf-8");
94068
94584
  return { exists: true, content };
94069
94585
  } catch {
94070
94586
  return { exists: false, content: "" };
@@ -94080,10 +94596,10 @@ var checkPermission3 = async (fullPath, relativePath, exists, autoApprove) => {
94080
94596
  return allowed;
94081
94597
  };
94082
94598
  var ensureDirectory = async (fullPath) => {
94083
- await fs7.mkdir(path8.dirname(fullPath), { recursive: true });
94599
+ await fs8.mkdir(path8.dirname(fullPath), { recursive: true });
94084
94600
  };
94085
94601
  var writeContent = async (fullPath, content) => {
94086
- await fs7.writeFile(fullPath, content, "utf-8");
94602
+ await fs8.writeFile(fullPath, content, "utf-8");
94087
94603
  };
94088
94604
  var executeWrite = async (args, ctx) => {
94089
94605
  const { filePath: filePath2, content } = args;
@@ -94167,7 +94683,7 @@ var validateUniqueness = (content, oldString, replaceAll, relativePath) => {
94167
94683
  };
94168
94684
  var countOccurrences = (content, search) => content.split(search).length - 1;
94169
94685
  // src/tools/edit/execute.ts
94170
- import fs8 from "fs/promises";
94686
+ import fs9 from "fs/promises";
94171
94687
  import path9 from "path";
94172
94688
  var createDeniedResult4 = (relativePath) => ({
94173
94689
  success: false,
@@ -94209,7 +94725,7 @@ var executeEdit = async (args, ctx) => {
94209
94725
  const { filePath: filePath2, oldString, newString, replaceAll = false } = args;
94210
94726
  const { fullPath, relativePath } = resolvePath2(filePath2, ctx.workingDir);
94211
94727
  try {
94212
- const content = await fs8.readFile(fullPath, "utf-8");
94728
+ const content = await fs9.readFile(fullPath, "utf-8");
94213
94729
  const existsError = validateTextExists(content, oldString, relativePath);
94214
94730
  if (existsError)
94215
94731
  return existsError;
@@ -94226,7 +94742,7 @@ var executeEdit = async (args, ctx) => {
94226
94742
  const newContent = applyEdit(content, oldString, newString, replaceAll);
94227
94743
  const diff = generateDiff(content, newContent);
94228
94744
  const diffOutput = formatDiff(diff, relativePath);
94229
- await fs8.writeFile(fullPath, newContent, "utf-8");
94745
+ await fs9.writeFile(fullPath, newContent, "utf-8");
94230
94746
  const replacements2 = replaceAll ? countOccurrences(content, oldString) : 1;
94231
94747
  return createSuccessResult2(relativePath, fullPath, diffOutput, replacements2, diff.additions, diff.deletions);
94232
94748
  } catch (error49) {
@@ -94792,50 +95308,6 @@ ${formattedResults}`,
94792
95308
  }
94793
95309
  };
94794
95310
  };
94795
- var parseSearchResults = (html, maxResults) => {
94796
- const results = [];
94797
- const resultPattern = /<a[^>]+class="result-link"[^>]*href="([^"]+)"[^>]*>([^<]+)<\/a>[\s\S]*?<td[^>]*class="result-snippet"[^>]*>([^<]+)/gi;
94798
- const altPattern = /<a[^>]+rel="nofollow"[^>]*href="([^"]+)"[^>]*>([^<]+)<\/a>[\s\S]*?<span[^>]*>([^<]{20,})/gi;
94799
- let match;
94800
- while ((match = resultPattern.exec(html)) !== null && results.length < maxResults) {
94801
- const [, url2, title, snippet] = match;
94802
- if (url2 && title && !url2.includes("duckduckgo.com")) {
94803
- results.push({
94804
- title: decodeHtmlEntities(title.trim()),
94805
- url: decodeUrl(url2),
94806
- snippet: decodeHtmlEntities(snippet.trim())
94807
- });
94808
- }
94809
- }
94810
- if (results.length === 0) {
94811
- while ((match = altPattern.exec(html)) !== null && results.length < maxResults) {
94812
- const [, url2, title, snippet] = match;
94813
- if (url2 && title && !url2.includes("duckduckgo.com")) {
94814
- results.push({
94815
- title: decodeHtmlEntities(title.trim()),
94816
- url: decodeUrl(url2),
94817
- snippet: decodeHtmlEntities(snippet.trim())
94818
- });
94819
- }
94820
- }
94821
- }
94822
- if (results.length === 0) {
94823
- const linkPattern = /<a[^>]+href="(https?:\/\/(?!duckduckgo)[^"]+)"[^>]*>([^<]{10,100})<\/a>/gi;
94824
- const seenUrls = new Set;
94825
- while ((match = linkPattern.exec(html)) !== null && results.length < maxResults) {
94826
- const [, url2, title] = match;
94827
- if (!seenUrls.has(url2) && !url2.includes("duckduckgo")) {
94828
- seenUrls.add(url2);
94829
- results.push({
94830
- title: decodeHtmlEntities(title.trim()),
94831
- url: decodeUrl(url2),
94832
- snippet: ""
94833
- });
94834
- }
94835
- }
94836
- }
94837
- return results;
94838
- };
94839
95311
  var decodeHtmlEntities = (text) => {
94840
95312
  const entities = {
94841
95313
  "&amp;": "&",
@@ -94854,22 +95326,32 @@ var decodeHtmlEntities = (text) => {
94854
95326
  decoded = decoded.replace(/&#(\d+);/g, (_3, code) => String.fromCharCode(parseInt(code, 10)));
94855
95327
  return decoded;
94856
95328
  };
94857
- var decodeUrl = (url2) => {
94858
- if (url2.includes("uddg=")) {
94859
- const match = url2.match(/uddg=([^&]+)/);
94860
- if (match) {
94861
- return decodeURIComponent(match[1]);
95329
+ var parseRssResults = (rss, maxResults) => {
95330
+ const results = [];
95331
+ const itemPattern = /<item>([\s\S]*?)<\/item>/gi;
95332
+ let match;
95333
+ while ((match = itemPattern.exec(rss)) !== null && results.length < maxResults) {
95334
+ const itemContent = match[1];
95335
+ const titleMatch = itemContent.match(/<title>([^<]+)<\/title>/);
95336
+ const linkMatch = itemContent.match(/<link>([^<]+)<\/link>/);
95337
+ const descMatch = itemContent.match(/<description>([^<]*)<\/description>/);
95338
+ if (titleMatch && linkMatch) {
95339
+ results.push({
95340
+ title: decodeHtmlEntities(titleMatch[1].trim()),
95341
+ url: linkMatch[1].trim(),
95342
+ snippet: descMatch ? decodeHtmlEntities(descMatch[1].trim()) : ""
95343
+ });
94862
95344
  }
94863
95345
  }
94864
- return url2;
95346
+ return results;
94865
95347
  };
94866
95348
  var performSearch = async (query, maxResults, signal) => {
94867
95349
  const encodedQuery = encodeURIComponent(query);
94868
- const searchUrl = `https://lite.duckduckgo.com/lite/?q=${encodedQuery}`;
95350
+ const searchUrl = `https://www.bing.com/search?q=${encodedQuery}&format=rss`;
94869
95351
  const response2 = await fetch(searchUrl, {
94870
95352
  headers: {
94871
95353
  "User-Agent": WEB_SEARCH_DEFAULTS.USER_AGENT,
94872
- Accept: "text/html",
95354
+ Accept: "application/rss+xml, text/xml",
94873
95355
  "Accept-Language": "en-US,en;q=0.9"
94874
95356
  },
94875
95357
  signal
@@ -94877,8 +95359,8 @@ var performSearch = async (query, maxResults, signal) => {
94877
95359
  if (!response2.ok) {
94878
95360
  throw new Error(`Search request failed: ${response2.status}`);
94879
95361
  }
94880
- const html = await response2.text();
94881
- return parseSearchResults(html, maxResults);
95362
+ const rss = await response2.text();
95363
+ return parseRssResults(rss, maxResults);
94882
95364
  };
94883
95365
  var executeWebSearch = async (args, ctx) => {
94884
95366
  const { query, maxResults = 5 } = args;
@@ -94911,9 +95393,537 @@ var webSearchTool = {
94911
95393
  parameters: webSearchParams,
94912
95394
  execute: executeWebSearch
94913
95395
  };
94914
- // src/services/lsp/index.ts
95396
+ // src/constants/web-fetch.ts
95397
+ var WEB_FETCH_DEFAULTS = {
95398
+ TIMEOUT_MS: 30000,
95399
+ MAX_CONTENT_LENGTH: 500000,
95400
+ USER_AGENT: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
95401
+ };
95402
+ var WEB_FETCH_TITLES = {
95403
+ FETCHING: (url2) => `Fetching: ${url2}`,
95404
+ SUCCESS: "Content fetched",
95405
+ FAILED: "Fetch failed",
95406
+ TIMEOUT: "Fetch timed out"
95407
+ };
95408
+ var WEB_FETCH_MESSAGES = {
95409
+ URL_REQUIRED: "URL is required",
95410
+ INVALID_URL: (url2) => `Invalid URL: ${url2}`,
95411
+ TIMEOUT: "Request timed out",
95412
+ FETCH_ERROR: (error49) => `Fetch failed: ${error49}`,
95413
+ CONTENT_TOO_LARGE: "Content exceeds maximum size limit",
95414
+ REDIRECT_DETECTED: (from2, to) => `Redirected from ${from2} to ${to}`
95415
+ };
95416
+ var WEB_FETCH_DESCRIPTION = `Fetch content from a URL and convert HTML to markdown.
95417
+
95418
+ Use this tool when you need to:
95419
+ - Read documentation from a URL
95420
+ - Fetch API responses
95421
+ - Get content from web pages
95422
+
95423
+ The content will be converted to markdown for readability.
95424
+ HTML will be cleaned and converted. JSON responses are formatted.
95425
+
95426
+ Note: This tool cannot access authenticated or private URLs.
95427
+ For GitHub URLs, prefer using the \`bash\` tool with \`gh\` CLI instead.`;
95428
+ var HTML_REMOVE_ELEMENTS = [
95429
+ "script",
95430
+ "style",
95431
+ "noscript",
95432
+ "iframe",
95433
+ "svg",
95434
+ "canvas",
95435
+ "video",
95436
+ "audio",
95437
+ "nav",
95438
+ "footer",
95439
+ "aside"
95440
+ ];
95441
+
95442
+ // src/tools/web-fetch/params.ts
95443
+ var webFetchParams = exports_external.object({
95444
+ url: exports_external.string().describe("The URL to fetch content from"),
95445
+ prompt: exports_external.string().optional().describe("Optional prompt to extract specific information from the content"),
95446
+ timeout: exports_external.number().optional().describe("Timeout in milliseconds (default: 30000)")
95447
+ });
95448
+
95449
+ // src/tools/web-fetch/execute.ts
95450
+ var createErrorResult7 = (error49) => ({
95451
+ success: false,
95452
+ title: WEB_FETCH_TITLES.FAILED,
95453
+ output: "",
95454
+ error: error49
95455
+ });
95456
+ var createSuccessResult5 = (url2, content, contentType) => ({
95457
+ success: true,
95458
+ title: WEB_FETCH_TITLES.SUCCESS,
95459
+ output: content,
95460
+ metadata: {
95461
+ url: url2,
95462
+ contentType,
95463
+ contentLength: content.length
95464
+ }
95465
+ });
95466
+ var validateUrl = (url2) => {
95467
+ try {
95468
+ const parsed = new URL(url2);
95469
+ if (parsed.protocol === "http:") {
95470
+ parsed.protocol = "https:";
95471
+ }
95472
+ if (!["https:", "http:"].includes(parsed.protocol)) {
95473
+ return null;
95474
+ }
95475
+ return parsed;
95476
+ } catch {
95477
+ return null;
95478
+ }
95479
+ };
95480
+ var removeElements = (html, tags) => {
95481
+ let result = html;
95482
+ for (const tag of tags) {
95483
+ const selfClosingPattern = new RegExp(`<${tag}[^>]*/>`, "gi");
95484
+ const openClosePattern = new RegExp(`<${tag}[^>]*>[\\s\\S]*?</${tag}>`, "gi");
95485
+ result = result.replace(selfClosingPattern, "");
95486
+ result = result.replace(openClosePattern, "");
95487
+ }
95488
+ return result;
95489
+ };
95490
+ var decodeHtmlEntities2 = (text) => {
95491
+ const entities = {
95492
+ "&amp;": "&",
95493
+ "&lt;": "<",
95494
+ "&gt;": ">",
95495
+ "&quot;": '"',
95496
+ "&#39;": "'",
95497
+ "&nbsp;": " ",
95498
+ "&#x27;": "'",
95499
+ "&#x2F;": "/",
95500
+ "&mdash;": "—",
95501
+ "&ndash;": "–",
95502
+ "&hellip;": "…",
95503
+ "&rsquo;": "'",
95504
+ "&lsquo;": "'",
95505
+ "&rdquo;": '"',
95506
+ "&ldquo;": '"',
95507
+ "&copy;": "©",
95508
+ "&reg;": "®",
95509
+ "&trade;": "™"
95510
+ };
95511
+ let decoded = text;
95512
+ for (const [entity, char] of Object.entries(entities)) {
95513
+ decoded = decoded.replace(new RegExp(entity, "g"), char);
95514
+ }
95515
+ decoded = decoded.replace(/&#(\d+);/g, (_3, code) => String.fromCharCode(parseInt(code, 10)));
95516
+ decoded = decoded.replace(/&#x([0-9a-fA-F]+);/g, (_3, code) => String.fromCharCode(parseInt(code, 16)));
95517
+ return decoded;
95518
+ };
95519
+ var htmlToMarkdown = (html) => {
95520
+ let content = removeElements(html, HTML_REMOVE_ELEMENTS);
95521
+ const bodyMatch = content.match(/<body[^>]*>([\s\S]*)<\/body>/i);
95522
+ if (bodyMatch) {
95523
+ content = bodyMatch[1];
95524
+ }
95525
+ content = content.replace(/<h1[^>]*>([\s\S]*?)<\/h1>/gi, `
95526
+ # $1
95527
+ `);
95528
+ content = content.replace(/<h2[^>]*>([\s\S]*?)<\/h2>/gi, `
95529
+ ## $1
95530
+ `);
95531
+ content = content.replace(/<h3[^>]*>([\s\S]*?)<\/h3>/gi, `
95532
+ ### $1
95533
+ `);
95534
+ content = content.replace(/<h4[^>]*>([\s\S]*?)<\/h4>/gi, `
95535
+ #### $1
95536
+ `);
95537
+ content = content.replace(/<h5[^>]*>([\s\S]*?)<\/h5>/gi, `
95538
+ ##### $1
95539
+ `);
95540
+ content = content.replace(/<h6[^>]*>([\s\S]*?)<\/h6>/gi, `
95541
+ ###### $1
95542
+ `);
95543
+ content = content.replace(/<a[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi, "[$2]($1)");
95544
+ content = content.replace(/<img[^>]*src="([^"]*)"[^>]*alt="([^"]*)"[^>]*\/?>/gi, "![$2]($1)");
95545
+ content = content.replace(/<img[^>]*src="([^"]*)"[^>]*\/?>/gi, "![]($1)");
95546
+ content = content.replace(/<strong[^>]*>([\s\S]*?)<\/strong>/gi, "**$1**");
95547
+ content = content.replace(/<b[^>]*>([\s\S]*?)<\/b>/gi, "**$1**");
95548
+ content = content.replace(/<em[^>]*>([\s\S]*?)<\/em>/gi, "*$1*");
95549
+ content = content.replace(/<i[^>]*>([\s\S]*?)<\/i>/gi, "*$1*");
95550
+ content = content.replace(/<code[^>]*>([\s\S]*?)<\/code>/gi, "`$1`");
95551
+ content = content.replace(/<pre[^>]*>([\s\S]*?)<\/pre>/gi, "\n```\n$1\n```\n");
95552
+ content = content.replace(/<li[^>]*>([\s\S]*?)<\/li>/gi, `- $1
95553
+ `);
95554
+ content = content.replace(/<\/?[ou]l[^>]*>/gi, `
95555
+ `);
95556
+ content = content.replace(/<p[^>]*>([\s\S]*?)<\/p>/gi, `
95557
+ $1
95558
+ `);
95559
+ content = content.replace(/<br\s*\/?>/gi, `
95560
+ `);
95561
+ content = content.replace(/<hr\s*\/?>/gi, `
95562
+ ---
95563
+ `);
95564
+ content = content.replace(/<blockquote[^>]*>([\s\S]*?)<\/blockquote>/gi, (_3, text) => {
95565
+ return text.split(`
95566
+ `).map((line2) => `> ${line2}`).join(`
95567
+ `);
95568
+ });
95569
+ content = content.replace(/<[^>]+>/g, "");
95570
+ content = decodeHtmlEntities2(content);
95571
+ content = content.replace(/\n{3,}/g, `
95572
+
95573
+ `);
95574
+ content = content.replace(/[ \t]+/g, " ");
95575
+ content = content.trim();
95576
+ return content;
95577
+ };
95578
+ var formatJson = (json2) => {
95579
+ try {
95580
+ const parsed = JSON.parse(json2);
95581
+ return "```json\n" + JSON.stringify(parsed, null, 2) + "\n```";
95582
+ } catch {
95583
+ return json2;
95584
+ }
95585
+ };
95586
+ var processContent = (content, contentType) => {
95587
+ const type = contentType.toLowerCase();
95588
+ if (type.includes("json")) {
95589
+ return formatJson(content);
95590
+ }
95591
+ if (type.includes("html") || type.includes("xhtml")) {
95592
+ return htmlToMarkdown(content);
95593
+ }
95594
+ return content;
95595
+ };
95596
+ var truncateContent = (content, maxLength) => {
95597
+ if (content.length <= maxLength) {
95598
+ return content;
95599
+ }
95600
+ const truncated = content.slice(0, maxLength);
95601
+ const lastNewline = truncated.lastIndexOf(`
95602
+ `);
95603
+ const cutPoint = lastNewline > maxLength * 0.8 ? lastNewline : maxLength;
95604
+ return truncated.slice(0, cutPoint) + `
95605
+
95606
+ ... (content truncated, showing first ` + Math.round(maxLength / 1000) + "KB)";
95607
+ };
95608
+ var executeWebFetch = async (args, ctx) => {
95609
+ const { url: url2, timeout = WEB_FETCH_DEFAULTS.TIMEOUT_MS } = args;
95610
+ if (!url2 || url2.trim().length === 0) {
95611
+ return createErrorResult7(WEB_FETCH_MESSAGES.URL_REQUIRED);
95612
+ }
95613
+ const parsedUrl = validateUrl(url2);
95614
+ if (!parsedUrl) {
95615
+ return createErrorResult7(WEB_FETCH_MESSAGES.INVALID_URL(url2));
95616
+ }
95617
+ ctx.onMetadata?.({
95618
+ title: WEB_FETCH_TITLES.FETCHING(parsedUrl.hostname),
95619
+ status: "running"
95620
+ });
95621
+ try {
95622
+ const controller = new AbortController;
95623
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
95624
+ ctx.abort.signal.addEventListener("abort", () => controller.abort());
95625
+ const response2 = await fetch(parsedUrl.toString(), {
95626
+ headers: {
95627
+ "User-Agent": WEB_FETCH_DEFAULTS.USER_AGENT,
95628
+ Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,application/json,text/plain;q=0.8",
95629
+ "Accept-Language": "en-US,en;q=0.9"
95630
+ },
95631
+ signal: controller.signal,
95632
+ redirect: "follow"
95633
+ });
95634
+ clearTimeout(timeoutId);
95635
+ if (!response2.ok) {
95636
+ return createErrorResult7(WEB_FETCH_MESSAGES.FETCH_ERROR(`HTTP ${response2.status}`));
95637
+ }
95638
+ const finalUrl = new URL(response2.url);
95639
+ if (finalUrl.host !== parsedUrl.host) {
95640
+ return {
95641
+ success: true,
95642
+ title: WEB_FETCH_TITLES.SUCCESS,
95643
+ output: WEB_FETCH_MESSAGES.REDIRECT_DETECTED(parsedUrl.host, finalUrl.host),
95644
+ metadata: {
95645
+ redirectUrl: response2.url,
95646
+ originalUrl: url2
95647
+ }
95648
+ };
95649
+ }
95650
+ const contentType = response2.headers.get("content-type") || "text/plain";
95651
+ let content = await response2.text();
95652
+ if (content.length > WEB_FETCH_DEFAULTS.MAX_CONTENT_LENGTH) {
95653
+ content = truncateContent(content, WEB_FETCH_DEFAULTS.MAX_CONTENT_LENGTH);
95654
+ }
95655
+ const processed = processContent(content, contentType);
95656
+ return createSuccessResult5(response2.url, processed, contentType);
95657
+ } catch (error49) {
95658
+ if (ctx.abort.signal.aborted) {
95659
+ return createErrorResult7(WEB_FETCH_MESSAGES.TIMEOUT);
95660
+ }
95661
+ const message2 = error49 instanceof Error ? error49.message : String(error49);
95662
+ return createErrorResult7(WEB_FETCH_MESSAGES.FETCH_ERROR(message2));
95663
+ }
95664
+ };
95665
+ var webFetchTool = {
95666
+ name: "web_fetch",
95667
+ description: WEB_FETCH_DESCRIPTION,
95668
+ parameters: webFetchParams,
95669
+ execute: executeWebFetch
95670
+ };
95671
+ // src/tools/multi-edit/execute.ts
94915
95672
  import fs10 from "fs/promises";
94916
- import path11 from "path";
95673
+ import path10 from "path";
95674
+
95675
+ // src/constants/multi-edit.ts
95676
+ var MULTI_EDIT_DEFAULTS = {
95677
+ MAX_EDITS: 50,
95678
+ MAX_FILE_SIZE: 1024 * 1024
95679
+ };
95680
+ var MULTI_EDIT_TITLES = {
95681
+ VALIDATING: (count) => `Validating ${count} edits...`,
95682
+ APPLYING: (current, total) => `Applying edit ${current}/${total}`,
95683
+ SUCCESS: (count) => `Applied ${count} edits`,
95684
+ PARTIAL: (success3, failed) => `Applied ${success3} edits, ${failed} failed`,
95685
+ FAILED: "Multi-edit failed",
95686
+ ROLLBACK: "Rolling back changes..."
95687
+ };
95688
+ var MULTI_EDIT_MESSAGES = {
95689
+ NO_EDITS: "No edits provided",
95690
+ TOO_MANY_EDITS: (max) => `Too many edits (max: ${max})`,
95691
+ VALIDATION_FAILED: "Validation failed for one or more edits",
95692
+ ATOMIC_FAILURE: "Atomic edit failed - all changes rolled back",
95693
+ DUPLICATE_FILE: (path10) => `Multiple edits to same file must be ordered: ${path10}`,
95694
+ OLD_STRING_NOT_FOUND: (path10, preview) => `Old string not found in ${path10}: "${preview}..."`,
95695
+ OLD_STRING_NOT_UNIQUE: (path10, count) => `Old string found ${count} times in ${path10} (must be unique)`,
95696
+ FILE_NOT_FOUND: (path10) => `File not found: ${path10}`,
95697
+ FILE_TOO_LARGE: (path10) => `File too large: ${path10}`
95698
+ };
95699
+ var MULTI_EDIT_DESCRIPTION = `Edit multiple files in a single atomic operation.
95700
+
95701
+ Use this tool when you need to:
95702
+ - Make related changes across multiple files
95703
+ - Refactor code that spans several files
95704
+ - Apply consistent changes to many files
95705
+
95706
+ All edits are validated before any changes are applied.
95707
+ If any edit fails validation, no changes are made.
95708
+
95709
+ Each edit requires:
95710
+ - file_path: Absolute path to the file
95711
+ - old_string: The exact text to find and replace
95712
+ - new_string: The replacement text
95713
+
95714
+ The old_string must be unique in the file. If it appears multiple times,
95715
+ provide more context to make it unique.`;
95716
+
95717
+ // src/tools/multi-edit/params.ts
95718
+ var editItemSchema = exports_external.object({
95719
+ file_path: exports_external.string().describe("Absolute path to the file to edit"),
95720
+ old_string: exports_external.string().describe("The exact text to find and replace"),
95721
+ new_string: exports_external.string().describe("The replacement text")
95722
+ });
95723
+ var multiEditParams = exports_external.object({
95724
+ edits: exports_external.array(editItemSchema).min(1).describe("Array of edits to apply atomically")
95725
+ });
95726
+
95727
+ // src/tools/multi-edit/execute.ts
95728
+ var createErrorResult8 = (error49) => ({
95729
+ success: false,
95730
+ title: MULTI_EDIT_TITLES.FAILED,
95731
+ output: "",
95732
+ error: error49
95733
+ });
95734
+ var createSuccessResult6 = (results, totalEdits) => {
95735
+ const successful = results.filter((r) => r.success);
95736
+ const failed = results.filter((r) => !r.success);
95737
+ const diffOutput = successful.map((r) => `## ${path10.basename(r.path)}
95738
+
95739
+ ${r.diff}`).join(`
95740
+
95741
+ ---
95742
+
95743
+ `);
95744
+ const totalAdditions = successful.reduce((sum, r) => sum + (r.additions ?? 0), 0);
95745
+ const totalDeletions = successful.reduce((sum, r) => sum + (r.deletions ?? 0), 0);
95746
+ const title = failed.length > 0 ? MULTI_EDIT_TITLES.PARTIAL(successful.length, failed.length) : MULTI_EDIT_TITLES.SUCCESS(successful.length);
95747
+ let output = diffOutput;
95748
+ if (failed.length > 0) {
95749
+ output += `
95750
+
95751
+ ## Failed Edits
95752
+
95753
+ ` + failed.map((r) => `- ${r.path}: ${r.error}`).join(`
95754
+ `);
95755
+ }
95756
+ return {
95757
+ success: failed.length === 0,
95758
+ title,
95759
+ output,
95760
+ metadata: {
95761
+ totalEdits,
95762
+ successful: successful.length,
95763
+ failed: failed.length,
95764
+ totalAdditions,
95765
+ totalDeletions
95766
+ }
95767
+ };
95768
+ };
95769
+ var validateEdit = async (edit, workingDir3) => {
95770
+ const fullPath = path10.isAbsolute(edit.file_path) ? edit.file_path : path10.join(workingDir3, edit.file_path);
95771
+ try {
95772
+ const stat3 = await fs10.stat(fullPath);
95773
+ if (!stat3.isFile()) {
95774
+ return { valid: false, error: `Not a file: ${edit.file_path}` };
95775
+ }
95776
+ if (stat3.size > MULTI_EDIT_DEFAULTS.MAX_FILE_SIZE) {
95777
+ return { valid: false, error: MULTI_EDIT_MESSAGES.FILE_TOO_LARGE(edit.file_path) };
95778
+ }
95779
+ const content = await fs10.readFile(fullPath, "utf-8");
95780
+ if (!content.includes(edit.old_string)) {
95781
+ const preview = edit.old_string.slice(0, 50);
95782
+ return {
95783
+ valid: false,
95784
+ error: MULTI_EDIT_MESSAGES.OLD_STRING_NOT_FOUND(edit.file_path, preview)
95785
+ };
95786
+ }
95787
+ const occurrences = content.split(edit.old_string).length - 1;
95788
+ if (occurrences > 1) {
95789
+ return {
95790
+ valid: false,
95791
+ error: MULTI_EDIT_MESSAGES.OLD_STRING_NOT_UNIQUE(edit.file_path, occurrences)
95792
+ };
95793
+ }
95794
+ return { valid: true, fileContent: content };
95795
+ } catch (error49) {
95796
+ if (error49.code === "ENOENT") {
95797
+ return { valid: false, error: MULTI_EDIT_MESSAGES.FILE_NOT_FOUND(edit.file_path) };
95798
+ }
95799
+ const message2 = error49 instanceof Error ? error49.message : String(error49);
95800
+ return { valid: false, error: message2 };
95801
+ }
95802
+ };
95803
+ var checkPermissions = async (edits, workingDir3, autoApprove) => {
95804
+ const denied = [];
95805
+ for (const edit of edits) {
95806
+ const fullPath = path10.isAbsolute(edit.file_path) ? edit.file_path : path10.join(workingDir3, edit.file_path);
95807
+ if (!autoApprove && !isFileOpAllowed("Edit", fullPath)) {
95808
+ const { allowed } = await promptFilePermission("Edit", fullPath, `Edit file: ${edit.file_path}`);
95809
+ if (!allowed) {
95810
+ denied.push(edit.file_path);
95811
+ }
95812
+ }
95813
+ }
95814
+ return { allowed: denied.length === 0, denied };
95815
+ };
95816
+ var applyEdit2 = async (edit, workingDir3, fileContent) => {
95817
+ const fullPath = path10.isAbsolute(edit.file_path) ? edit.file_path : path10.join(workingDir3, edit.file_path);
95818
+ try {
95819
+ const newContent = fileContent.replace(edit.old_string, edit.new_string);
95820
+ const diff = generateDiff(fileContent, newContent);
95821
+ const relativePath = path10.relative(workingDir3, fullPath);
95822
+ const diffOutput = formatDiff(diff, relativePath);
95823
+ await fs10.writeFile(fullPath, newContent, "utf-8");
95824
+ return {
95825
+ path: edit.file_path,
95826
+ success: true,
95827
+ diff: diffOutput,
95828
+ additions: diff.additions,
95829
+ deletions: diff.deletions
95830
+ };
95831
+ } catch (error49) {
95832
+ const message2 = error49 instanceof Error ? error49.message : String(error49);
95833
+ return {
95834
+ path: edit.file_path,
95835
+ success: false,
95836
+ error: message2
95837
+ };
95838
+ }
95839
+ };
95840
+ var rollback = async (backups) => {
95841
+ for (const backup of backups) {
95842
+ try {
95843
+ await fs10.writeFile(backup.path, backup.content, "utf-8");
95844
+ } catch {}
95845
+ }
95846
+ };
95847
+ var executeMultiEdit = async (args, ctx) => {
95848
+ const { edits } = args;
95849
+ if (edits.length === 0) {
95850
+ return createErrorResult8(MULTI_EDIT_MESSAGES.NO_EDITS);
95851
+ }
95852
+ if (edits.length > MULTI_EDIT_DEFAULTS.MAX_EDITS) {
95853
+ return createErrorResult8(MULTI_EDIT_MESSAGES.TOO_MANY_EDITS(MULTI_EDIT_DEFAULTS.MAX_EDITS));
95854
+ }
95855
+ ctx.onMetadata?.({
95856
+ title: MULTI_EDIT_TITLES.VALIDATING(edits.length),
95857
+ status: "running"
95858
+ });
95859
+ const validations = new Map;
95860
+ const errors5 = [];
95861
+ for (const edit of edits) {
95862
+ const validation = await validateEdit(edit, ctx.workingDir);
95863
+ validations.set(edit.file_path, { validation, edit });
95864
+ if (!validation.valid) {
95865
+ errors5.push(validation.error ?? "Unknown error");
95866
+ }
95867
+ }
95868
+ if (errors5.length > 0) {
95869
+ return createErrorResult8(MULTI_EDIT_MESSAGES.VALIDATION_FAILED + `:
95870
+ ` + errors5.join(`
95871
+ `));
95872
+ }
95873
+ const permCheck = await checkPermissions(edits, ctx.workingDir, ctx.autoApprove ?? false);
95874
+ if (!permCheck.allowed) {
95875
+ return createErrorResult8(`Permission denied for: ${permCheck.denied.join(", ")}`);
95876
+ }
95877
+ const backups = [];
95878
+ const results = [];
95879
+ let failed = false;
95880
+ for (let i2 = 0;i2 < edits.length; i2++) {
95881
+ const edit = edits[i2];
95882
+ const data = validations.get(edit.file_path);
95883
+ if (!data?.validation.fileContent)
95884
+ continue;
95885
+ ctx.onMetadata?.({
95886
+ title: MULTI_EDIT_TITLES.APPLYING(i2 + 1, edits.length),
95887
+ status: "running"
95888
+ });
95889
+ const fullPath = path10.isAbsolute(edit.file_path) ? edit.file_path : path10.join(ctx.workingDir, edit.file_path);
95890
+ backups.push({
95891
+ path: fullPath,
95892
+ content: data.validation.fileContent
95893
+ });
95894
+ const result = await applyEdit2(edit, ctx.workingDir, data.validation.fileContent);
95895
+ results.push(result);
95896
+ if (!result.success) {
95897
+ failed = true;
95898
+ break;
95899
+ }
95900
+ if (result.success) {
95901
+ const newContent = data.validation.fileContent.replace(edit.old_string, edit.new_string);
95902
+ validations.set(edit.file_path, {
95903
+ ...data,
95904
+ validation: { ...data.validation, fileContent: newContent }
95905
+ });
95906
+ }
95907
+ }
95908
+ if (failed) {
95909
+ ctx.onMetadata?.({
95910
+ title: MULTI_EDIT_TITLES.ROLLBACK,
95911
+ status: "running"
95912
+ });
95913
+ await rollback(backups);
95914
+ return createErrorResult8(MULTI_EDIT_MESSAGES.ATOMIC_FAILURE);
95915
+ }
95916
+ return createSuccessResult6(results, edits.length);
95917
+ };
95918
+ var multiEditTool = {
95919
+ name: "multi_edit",
95920
+ description: MULTI_EDIT_DESCRIPTION,
95921
+ parameters: multiEditParams,
95922
+ execute: executeMultiEdit
95923
+ };
95924
+ // src/services/lsp/index.ts
95925
+ import fs12 from "fs/promises";
95926
+ import path12 from "path";
94917
95927
  import { EventEmitter as EventEmitter14 } from "events";
94918
95928
 
94919
95929
  // src/services/lsp/client.ts
@@ -95313,11 +96323,11 @@ var createLSPClient = (process14, serverId, root) => {
95313
96323
 
95314
96324
  // src/services/lsp/server.ts
95315
96325
  import { spawn as spawn3, execSync } from "child_process";
95316
- import path10 from "path";
95317
- import fs9 from "fs/promises";
96326
+ import path11 from "path";
96327
+ import fs11 from "fs/promises";
95318
96328
  var fileExists = async (filePath2) => {
95319
96329
  try {
95320
- await fs9.access(filePath2);
96330
+ await fs11.access(filePath2);
95321
96331
  return true;
95322
96332
  } catch {
95323
96333
  return false;
@@ -95325,15 +96335,15 @@ var fileExists = async (filePath2) => {
95325
96335
  };
95326
96336
  var findProjectRoot = async (startDir, patterns) => {
95327
96337
  let currentDir = startDir;
95328
- const root = path10.parse(currentDir).root;
96338
+ const root = path11.parse(currentDir).root;
95329
96339
  while (currentDir !== root) {
95330
96340
  for (const pattern of patterns) {
95331
- const checkPath = path10.join(currentDir, pattern);
96341
+ const checkPath = path11.join(currentDir, pattern);
95332
96342
  if (await fileExists(checkPath)) {
95333
96343
  return currentDir;
95334
96344
  }
95335
96345
  }
95336
- currentDir = path10.dirname(currentDir);
96346
+ currentDir = path11.dirname(currentDir);
95337
96347
  }
95338
96348
  return null;
95339
96349
  };
@@ -95492,13 +96502,13 @@ var SERVERS = {
95492
96502
  };
95493
96503
  var getServersForFile = (filePath2) => {
95494
96504
  const ext = "." + (filePath2.split(".").pop() ?? "");
95495
- const fileName = path10.basename(filePath2);
96505
+ const fileName = path11.basename(filePath2);
95496
96506
  return Object.values(SERVERS).filter((server) => {
95497
96507
  return server.extensions.includes(ext) || server.extensions.includes(fileName);
95498
96508
  });
95499
96509
  };
95500
96510
  var findRootForServer = async (filePath2, server) => {
95501
- const dir = path10.dirname(filePath2);
96511
+ const dir = path11.dirname(filePath2);
95502
96512
  return findProjectRoot(dir, server.rootPatterns);
95503
96513
  };
95504
96514
  var spawnServer = async (server, root) => {
@@ -95590,11 +96600,11 @@ var spawnClient = async (server, root) => {
95590
96600
  }
95591
96601
  };
95592
96602
  var openFile = async (filePath2) => {
95593
- const absolutePath = path11.resolve(filePath2);
96603
+ const absolutePath = path12.resolve(filePath2);
95594
96604
  const clients = await getClientsForFile(absolutePath);
95595
96605
  if (clients.length === 0)
95596
96606
  return;
95597
- const content = await fs10.readFile(absolutePath, "utf-8");
96607
+ const content = await fs12.readFile(absolutePath, "utf-8");
95598
96608
  for (const client of clients) {
95599
96609
  if (!client.isFileOpen(absolutePath)) {
95600
96610
  await client.openFile(absolutePath, content);
@@ -95602,7 +96612,7 @@ var openFile = async (filePath2) => {
95602
96612
  }
95603
96613
  };
95604
96614
  var updateFile = async (filePath2, content) => {
95605
- const absolutePath = path11.resolve(filePath2);
96615
+ const absolutePath = path12.resolve(filePath2);
95606
96616
  const clients = await getClientsForFile(absolutePath);
95607
96617
  for (const client of clients) {
95608
96618
  if (client.isFileOpen(absolutePath)) {
@@ -95613,7 +96623,7 @@ var updateFile = async (filePath2, content) => {
95613
96623
  }
95614
96624
  };
95615
96625
  var closeFile = async (filePath2) => {
95616
- const absolutePath = path11.resolve(filePath2);
96626
+ const absolutePath = path12.resolve(filePath2);
95617
96627
  const clients = await getClientsForFile(absolutePath);
95618
96628
  for (const client of clients) {
95619
96629
  if (client.isFileOpen(absolutePath)) {
@@ -95622,7 +96632,7 @@ var closeFile = async (filePath2) => {
95622
96632
  }
95623
96633
  };
95624
96634
  var getHover = async (filePath2, position) => {
95625
- const absolutePath = path11.resolve(filePath2);
96635
+ const absolutePath = path12.resolve(filePath2);
95626
96636
  const clients = await getClientsForFile(absolutePath);
95627
96637
  for (const client of clients) {
95628
96638
  const hover = await client.getHover(absolutePath, position);
@@ -95632,7 +96642,7 @@ var getHover = async (filePath2, position) => {
95632
96642
  return null;
95633
96643
  };
95634
96644
  var getDefinition = async (filePath2, position) => {
95635
- const absolutePath = path11.resolve(filePath2);
96645
+ const absolutePath = path12.resolve(filePath2);
95636
96646
  const clients = await getClientsForFile(absolutePath);
95637
96647
  for (const client of clients) {
95638
96648
  const definition = await client.getDefinition(absolutePath, position);
@@ -95642,7 +96652,7 @@ var getDefinition = async (filePath2, position) => {
95642
96652
  return null;
95643
96653
  };
95644
96654
  var getReferences = async (filePath2, position, includeDeclaration = true) => {
95645
- const absolutePath = path11.resolve(filePath2);
96655
+ const absolutePath = path12.resolve(filePath2);
95646
96656
  const clients = await getClientsForFile(absolutePath);
95647
96657
  const allRefs = [];
95648
96658
  for (const client of clients) {
@@ -95659,7 +96669,7 @@ var getReferences = async (filePath2, position, includeDeclaration = true) => {
95659
96669
  });
95660
96670
  };
95661
96671
  var getCompletions = async (filePath2, position) => {
95662
- const absolutePath = path11.resolve(filePath2);
96672
+ const absolutePath = path12.resolve(filePath2);
95663
96673
  const clients = await getClientsForFile(absolutePath);
95664
96674
  const allCompletions = [];
95665
96675
  for (const client of clients) {
@@ -95669,7 +96679,7 @@ var getCompletions = async (filePath2, position) => {
95669
96679
  return allCompletions;
95670
96680
  };
95671
96681
  var getDocumentSymbols = async (filePath2) => {
95672
- const absolutePath = path11.resolve(filePath2);
96682
+ const absolutePath = path12.resolve(filePath2);
95673
96683
  const clients = await getClientsForFile(absolutePath);
95674
96684
  for (const client of clients) {
95675
96685
  const symbols = await client.getDocumentSymbols(absolutePath);
@@ -95684,7 +96694,7 @@ var getDiagnostics = (filePath2) => {
95684
96694
  const clientDiagnostics = client.getAllDiagnostics();
95685
96695
  for (const [uri, diagnostics] of clientDiagnostics) {
95686
96696
  if (filePath2) {
95687
- const expectedUri = `file://${path11.resolve(filePath2)}`;
96697
+ const expectedUri = `file://${path12.resolve(filePath2)}`;
95688
96698
  if (uri !== expectedUri)
95689
96699
  continue;
95690
96700
  }
@@ -95746,7 +96756,7 @@ var lspService = {
95746
96756
  };
95747
96757
 
95748
96758
  // src/tools/lsp.ts
95749
- import fs11 from "fs/promises";
96759
+ import fs13 from "fs/promises";
95750
96760
  var PositionSchema = exports_external.object({
95751
96761
  line: exports_external.number().describe("Zero-based line number"),
95752
96762
  character: exports_external.number().describe("Zero-based character offset")
@@ -95863,7 +96873,7 @@ Examples:
95863
96873
  execute: async (args) => {
95864
96874
  const { operation, file: file2, position } = args;
95865
96875
  try {
95866
- await fs11.access(file2);
96876
+ await fs13.access(file2);
95867
96877
  } catch {
95868
96878
  return {
95869
96879
  success: false,
@@ -95941,6 +96951,754 @@ Examples:
95941
96951
  };
95942
96952
  }
95943
96953
  };
96954
+ // src/constants/apply-patch.ts
96955
+ var PATCH_DEFAULTS = {
96956
+ FUZZ: 2,
96957
+ MAX_FUZZ: 3,
96958
+ IGNORE_WHITESPACE: false,
96959
+ IGNORE_CASE: false,
96960
+ CONTEXT_LINES: 3
96961
+ };
96962
+ var PATCH_PATTERNS = {
96963
+ HUNK_HEADER: /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)$/,
96964
+ FILE_HEADER_OLD: /^--- (.+?)(?:\t.*)?$/,
96965
+ FILE_HEADER_NEW: /^\+\+\+ (.+?)(?:\t.*)?$/,
96966
+ GIT_DIFF: /^diff --git a\/(.+) b\/(.+)$/,
96967
+ INDEX_LINE: /^index [a-f0-9]+\.\.[a-f0-9]+(?: \d+)?$/,
96968
+ BINARY_FILE: /^Binary files .+ differ$/,
96969
+ NEW_FILE: /^new file mode \d+$/,
96970
+ DELETED_FILE: /^deleted file mode \d+$/,
96971
+ RENAME_FROM: /^rename from (.+)$/,
96972
+ RENAME_TO: /^rename to (.+)$/,
96973
+ NO_NEWLINE: /^\$/
96974
+ };
96975
+ var LINE_PREFIXES2 = {
96976
+ CONTEXT: " ",
96977
+ ADDITION: "+",
96978
+ DELETION: "-"
96979
+ };
96980
+ var PATCH_ERRORS = {
96981
+ INVALID_PATCH: "Invalid patch format",
96982
+ PARSE_FAILED: (detail) => `Failed to parse patch: ${detail}`,
96983
+ HUNK_FAILED: (index, reason) => `Hunk #${index + 1} failed: ${reason}`,
96984
+ FILE_NOT_FOUND: (path13) => `Target file not found: ${path13}`,
96985
+ CONTEXT_MISMATCH: (line2) => `Context mismatch at line ${line2}`,
96986
+ FUZZY_MATCH_FAILED: (hunk) => `Could not find match for hunk #${hunk + 1} even with fuzzy matching`,
96987
+ ALREADY_APPLIED: "Patch appears to be already applied",
96988
+ REVERSED_PATCH: "Patch appears to be reversed",
96989
+ BINARY_NOT_SUPPORTED: "Binary patches are not supported",
96990
+ WRITE_FAILED: (path13, error49) => `Failed to write patched file ${path13}: ${error49}`
96991
+ };
96992
+ var PATCH_MESSAGES = {
96993
+ PARSING: "Parsing patch...",
96994
+ APPLYING: (file2) => `Applying patch to ${file2}`,
96995
+ APPLIED: (files, hunks) => `Successfully applied ${hunks} hunk(s) to ${files} file(s)`,
96996
+ DRY_RUN: (files, hunks) => `Dry run: ${hunks} hunk(s) would be applied to ${files} file(s)`,
96997
+ FUZZY_APPLIED: (hunk, offset) => `Hunk #${hunk + 1} applied with fuzzy offset of ${offset}`,
96998
+ ROLLBACK_AVAILABLE: "Rollback is available if needed",
96999
+ SKIPPED_BINARY: (file2) => `Skipped binary file: ${file2}`
97000
+ };
97001
+ var PATCH_TITLES = {
97002
+ APPLYING: (file2) => `Patching: ${file2}`,
97003
+ SUCCESS: (files) => `Patched ${files} file(s)`,
97004
+ PARTIAL: (success3, failed) => `Partial success: ${success3} patched, ${failed} failed`,
97005
+ FAILED: "Patch failed",
97006
+ DRY_RUN: "Patch dry run",
97007
+ VALIDATING: "Validating patch"
97008
+ };
97009
+ var SPECIAL_PATHS = {
97010
+ DEV_NULL: "/dev/null",
97011
+ A_PREFIX: "a/",
97012
+ B_PREFIX: "b/"
97013
+ };
97014
+
97015
+ // src/tools/apply-patch/params.ts
97016
+ var applyPatchParams = exports_external.object({
97017
+ patch: exports_external.string().describe("The unified diff patch content to apply"),
97018
+ targetFile: exports_external.string().optional().describe("Override the target file path from the patch header"),
97019
+ dryRun: exports_external.boolean().optional().default(false).describe("Validate and preview changes without actually applying them"),
97020
+ fuzz: exports_external.number().int().min(0).max(PATCH_DEFAULTS.MAX_FUZZ).optional().default(PATCH_DEFAULTS.FUZZ).describe(`Context line tolerance for fuzzy matching (0-${PATCH_DEFAULTS.MAX_FUZZ})`),
97021
+ reverse: exports_external.boolean().optional().default(false).describe("Apply the patch in reverse (undo the changes)")
97022
+ });
97023
+
97024
+ // src/tools/apply-patch/execute.ts
97025
+ import fs14 from "fs/promises";
97026
+ import { dirname as dirname2, join as join9, isAbsolute as isAbsolute2 } from "path";
97027
+
97028
+ // src/tools/apply-patch/parser.ts
97029
+ var parsePatch2 = (patchContent) => {
97030
+ const lines = patchContent.split(`
97031
+ `);
97032
+ const files = [];
97033
+ let currentFile = null;
97034
+ let currentHunk = null;
97035
+ let lineIndex = 0;
97036
+ while (lineIndex < lines.length) {
97037
+ const line2 = lines[lineIndex];
97038
+ const gitDiffMatch = line2.match(PATCH_PATTERNS.GIT_DIFF);
97039
+ if (gitDiffMatch) {
97040
+ if (currentFile && (currentFile.hunks.length > 0 || currentFile.isBinary)) {
97041
+ files.push(currentFile);
97042
+ }
97043
+ currentFile = createEmptyFilePatch(gitDiffMatch[1], gitDiffMatch[2]);
97044
+ currentHunk = null;
97045
+ lineIndex++;
97046
+ continue;
97047
+ }
97048
+ const oldHeaderMatch = line2.match(PATCH_PATTERNS.FILE_HEADER_OLD);
97049
+ if (oldHeaderMatch) {
97050
+ if (!currentFile) {
97051
+ currentFile = createEmptyFilePatch("", "");
97052
+ }
97053
+ currentFile.oldPath = cleanPath(oldHeaderMatch[1]);
97054
+ if (currentFile.oldPath === SPECIAL_PATHS.DEV_NULL) {
97055
+ currentFile.isNew = true;
97056
+ }
97057
+ lineIndex++;
97058
+ continue;
97059
+ }
97060
+ const newHeaderMatch = line2.match(PATCH_PATTERNS.FILE_HEADER_NEW);
97061
+ if (newHeaderMatch) {
97062
+ if (!currentFile) {
97063
+ currentFile = createEmptyFilePatch("", "");
97064
+ }
97065
+ currentFile.newPath = cleanPath(newHeaderMatch[1]);
97066
+ if (currentFile.newPath === SPECIAL_PATHS.DEV_NULL) {
97067
+ currentFile.isDeleted = true;
97068
+ }
97069
+ lineIndex++;
97070
+ continue;
97071
+ }
97072
+ if (PATCH_PATTERNS.INDEX_LINE.test(line2)) {
97073
+ lineIndex++;
97074
+ continue;
97075
+ }
97076
+ if (PATCH_PATTERNS.BINARY_FILE.test(line2)) {
97077
+ if (currentFile) {
97078
+ currentFile.isBinary = true;
97079
+ }
97080
+ lineIndex++;
97081
+ continue;
97082
+ }
97083
+ if (PATCH_PATTERNS.NEW_FILE.test(line2)) {
97084
+ if (currentFile) {
97085
+ currentFile.isNew = true;
97086
+ }
97087
+ lineIndex++;
97088
+ continue;
97089
+ }
97090
+ if (PATCH_PATTERNS.DELETED_FILE.test(line2)) {
97091
+ if (currentFile) {
97092
+ currentFile.isDeleted = true;
97093
+ }
97094
+ lineIndex++;
97095
+ continue;
97096
+ }
97097
+ const renameFromMatch = line2.match(PATCH_PATTERNS.RENAME_FROM);
97098
+ if (renameFromMatch) {
97099
+ if (currentFile) {
97100
+ currentFile.isRenamed = true;
97101
+ currentFile.oldPath = cleanPath(renameFromMatch[1]);
97102
+ }
97103
+ lineIndex++;
97104
+ continue;
97105
+ }
97106
+ const renameToMatch = line2.match(PATCH_PATTERNS.RENAME_TO);
97107
+ if (renameToMatch) {
97108
+ if (currentFile) {
97109
+ currentFile.newPath = cleanPath(renameToMatch[1]);
97110
+ }
97111
+ lineIndex++;
97112
+ continue;
97113
+ }
97114
+ const hunkMatch = line2.match(PATCH_PATTERNS.HUNK_HEADER);
97115
+ if (hunkMatch) {
97116
+ if (currentHunk && currentFile) {
97117
+ currentFile.hunks.push(currentHunk);
97118
+ }
97119
+ currentHunk = {
97120
+ oldStart: parseInt(hunkMatch[1], 10),
97121
+ oldLines: hunkMatch[2] ? parseInt(hunkMatch[2], 10) : 1,
97122
+ newStart: parseInt(hunkMatch[3], 10),
97123
+ newLines: hunkMatch[4] ? parseInt(hunkMatch[4], 10) : 1,
97124
+ lines: [],
97125
+ header: line2
97126
+ };
97127
+ lineIndex++;
97128
+ continue;
97129
+ }
97130
+ if (currentHunk) {
97131
+ const patchLine = parsePatchLine(line2, currentHunk);
97132
+ if (patchLine) {
97133
+ currentHunk.lines.push(patchLine);
97134
+ }
97135
+ }
97136
+ lineIndex++;
97137
+ }
97138
+ if (currentHunk && currentFile) {
97139
+ currentFile.hunks.push(currentHunk);
97140
+ }
97141
+ if (currentFile && (currentFile.hunks.length > 0 || currentFile.isBinary)) {
97142
+ files.push(currentFile);
97143
+ }
97144
+ return {
97145
+ files,
97146
+ rawPatch: patchContent
97147
+ };
97148
+ };
97149
+ var createEmptyFilePatch = (oldPath, newPath) => ({
97150
+ oldPath: cleanPath(oldPath),
97151
+ newPath: cleanPath(newPath),
97152
+ hunks: [],
97153
+ isBinary: false,
97154
+ isNew: false,
97155
+ isDeleted: false,
97156
+ isRenamed: false
97157
+ });
97158
+ var cleanPath = (path13) => {
97159
+ if (path13.startsWith(SPECIAL_PATHS.A_PREFIX)) {
97160
+ return path13.slice(2);
97161
+ }
97162
+ if (path13.startsWith(SPECIAL_PATHS.B_PREFIX)) {
97163
+ return path13.slice(2);
97164
+ }
97165
+ return path13;
97166
+ };
97167
+ var parsePatchLine = (line2, _hunk) => {
97168
+ if (PATCH_PATTERNS.NO_NEWLINE.test(line2)) {
97169
+ return null;
97170
+ }
97171
+ if (line2 === "") {
97172
+ return null;
97173
+ }
97174
+ const prefix = line2[0];
97175
+ const content = line2.slice(1);
97176
+ const typeMap = {
97177
+ [LINE_PREFIXES2.CONTEXT]: "context",
97178
+ [LINE_PREFIXES2.ADDITION]: "addition",
97179
+ [LINE_PREFIXES2.DELETION]: "deletion"
97180
+ };
97181
+ const type = typeMap[prefix];
97182
+ if (!type) {
97183
+ return {
97184
+ type: "context",
97185
+ content: line2
97186
+ };
97187
+ }
97188
+ return {
97189
+ type,
97190
+ content
97191
+ };
97192
+ };
97193
+ var validatePatch = (patch) => {
97194
+ const errors5 = [];
97195
+ const warnings = [];
97196
+ let hunkCount = 0;
97197
+ if (patch.files.length === 0) {
97198
+ errors5.push(PATCH_ERRORS.INVALID_PATCH);
97199
+ return {
97200
+ valid: false,
97201
+ errors: errors5,
97202
+ warnings,
97203
+ fileCount: 0,
97204
+ hunkCount: 0
97205
+ };
97206
+ }
97207
+ for (const file2 of patch.files) {
97208
+ if (file2.isBinary) {
97209
+ warnings.push(PATCH_ERRORS.BINARY_NOT_SUPPORTED);
97210
+ continue;
97211
+ }
97212
+ if (!file2.newPath && !file2.isDeleted) {
97213
+ errors5.push(`Missing target path for file`);
97214
+ }
97215
+ for (const hunk of file2.hunks) {
97216
+ hunkCount++;
97217
+ let contextCount = 0;
97218
+ let additionCount = 0;
97219
+ let deletionCount = 0;
97220
+ for (const line2 of hunk.lines) {
97221
+ if (line2.type === "context")
97222
+ contextCount++;
97223
+ if (line2.type === "addition")
97224
+ additionCount++;
97225
+ if (line2.type === "deletion")
97226
+ deletionCount++;
97227
+ }
97228
+ const expectedOld = contextCount + deletionCount;
97229
+ const expectedNew = contextCount + additionCount;
97230
+ if (expectedOld !== hunk.oldLines) {
97231
+ warnings.push(`Hunk line count mismatch: expected ${hunk.oldLines} old lines, found ${expectedOld}`);
97232
+ }
97233
+ if (expectedNew !== hunk.newLines) {
97234
+ warnings.push(`Hunk line count mismatch: expected ${hunk.newLines} new lines, found ${expectedNew}`);
97235
+ }
97236
+ }
97237
+ }
97238
+ return {
97239
+ valid: errors5.length === 0,
97240
+ errors: errors5,
97241
+ warnings,
97242
+ fileCount: patch.files.length,
97243
+ hunkCount
97244
+ };
97245
+ };
97246
+ var getTargetPath = (filePatch) => {
97247
+ if (filePatch.isNew) {
97248
+ return filePatch.newPath;
97249
+ }
97250
+ if (filePatch.isDeleted) {
97251
+ return filePatch.oldPath;
97252
+ }
97253
+ return filePatch.newPath || filePatch.oldPath;
97254
+ };
97255
+ var reversePatch = (patch) => {
97256
+ return {
97257
+ ...patch,
97258
+ oldPath: patch.newPath,
97259
+ newPath: patch.oldPath,
97260
+ isNew: patch.isDeleted,
97261
+ isDeleted: patch.isNew,
97262
+ hunks: patch.hunks.map((hunk) => ({
97263
+ ...hunk,
97264
+ oldStart: hunk.newStart,
97265
+ oldLines: hunk.newLines,
97266
+ newStart: hunk.oldStart,
97267
+ newLines: hunk.oldLines,
97268
+ lines: hunk.lines.map((line2) => ({
97269
+ ...line2,
97270
+ type: line2.type === "addition" ? "deletion" : line2.type === "deletion" ? "addition" : line2.type
97271
+ }))
97272
+ }))
97273
+ };
97274
+ };
97275
+
97276
+ // src/tools/apply-patch/matcher.ts
97277
+ var DEFAULT_MATCH_OPTIONS = {
97278
+ fuzz: PATCH_DEFAULTS.FUZZ,
97279
+ ignoreWhitespace: PATCH_DEFAULTS.IGNORE_WHITESPACE,
97280
+ ignoreCase: PATCH_DEFAULTS.IGNORE_CASE
97281
+ };
97282
+ var normalizeLine = (line2, options2) => {
97283
+ let normalized = line2;
97284
+ if (options2.ignoreWhitespace) {
97285
+ normalized = normalized.replace(/\s+/g, " ").trim();
97286
+ }
97287
+ if (options2.ignoreCase) {
97288
+ normalized = normalized.toLowerCase();
97289
+ }
97290
+ return normalized;
97291
+ };
97292
+ var extractOriginalLines = (hunk) => {
97293
+ return hunk.lines.filter((line2) => line2.type === "context" || line2.type === "deletion").map((line2) => line2.content);
97294
+ };
97295
+ var checkMatchAtPosition = (fileLines, originalLines, startLine, options2) => {
97296
+ let matchCount = 0;
97297
+ let totalLines = originalLines.length;
97298
+ if (startLine + originalLines.length > fileLines.length) {
97299
+ return { matches: false, confidence: 0 };
97300
+ }
97301
+ for (let i2 = 0;i2 < originalLines.length; i2++) {
97302
+ const fileLine = normalizeLine(fileLines[startLine + i2], options2);
97303
+ const patchLine = normalizeLine(originalLines[i2], options2);
97304
+ if (fileLine === patchLine) {
97305
+ matchCount++;
97306
+ }
97307
+ }
97308
+ const confidence = totalLines > 0 ? matchCount / totalLines : 0;
97309
+ const requiredMatches = Math.max(1, totalLines - options2.fuzz);
97310
+ const matches = matchCount >= requiredMatches;
97311
+ return { matches, confidence };
97312
+ };
97313
+ var findHunkPosition = (fileContent, hunk, options2 = {}) => {
97314
+ const fullOptions = {
97315
+ ...DEFAULT_MATCH_OPTIONS,
97316
+ ...options2
97317
+ };
97318
+ const fileLines = fileContent.split(`
97319
+ `);
97320
+ const originalLines = extractOriginalLines(hunk);
97321
+ if (originalLines.length === 0) {
97322
+ const targetLine = Math.min(hunk.oldStart - 1, fileLines.length);
97323
+ return {
97324
+ found: true,
97325
+ lineNumber: targetLine,
97326
+ offset: 0,
97327
+ confidence: 1
97328
+ };
97329
+ }
97330
+ const expectedLine = hunk.oldStart - 1;
97331
+ const exactMatch = checkMatchAtPosition(fileLines, originalLines, expectedLine, fullOptions);
97332
+ if (exactMatch.matches && exactMatch.confidence === 1) {
97333
+ return {
97334
+ found: true,
97335
+ lineNumber: expectedLine,
97336
+ offset: 0,
97337
+ confidence: exactMatch.confidence
97338
+ };
97339
+ }
97340
+ const maxOffset = fullOptions.fuzz * PATCH_DEFAULTS.CONTEXT_LINES;
97341
+ let bestMatch = null;
97342
+ for (let offset = 1;offset <= maxOffset; offset++) {
97343
+ const beforePos = expectedLine - offset;
97344
+ if (beforePos >= 0) {
97345
+ const beforeMatch = checkMatchAtPosition(fileLines, originalLines, beforePos, fullOptions);
97346
+ if (beforeMatch.matches) {
97347
+ if (!bestMatch || beforeMatch.confidence > bestMatch.confidence) {
97348
+ bestMatch = {
97349
+ found: true,
97350
+ lineNumber: beforePos,
97351
+ offset: -offset,
97352
+ confidence: beforeMatch.confidence
97353
+ };
97354
+ }
97355
+ }
97356
+ }
97357
+ const afterPos = expectedLine + offset;
97358
+ if (afterPos < fileLines.length) {
97359
+ const afterMatch = checkMatchAtPosition(fileLines, originalLines, afterPos, fullOptions);
97360
+ if (afterMatch.matches) {
97361
+ if (!bestMatch || afterMatch.confidence > bestMatch.confidence) {
97362
+ bestMatch = {
97363
+ found: true,
97364
+ lineNumber: afterPos,
97365
+ offset,
97366
+ confidence: afterMatch.confidence
97367
+ };
97368
+ }
97369
+ }
97370
+ }
97371
+ if (bestMatch && bestMatch.confidence === 1) {
97372
+ break;
97373
+ }
97374
+ }
97375
+ if (bestMatch) {
97376
+ return bestMatch;
97377
+ }
97378
+ if (exactMatch.confidence > 0.5) {
97379
+ return {
97380
+ found: true,
97381
+ lineNumber: expectedLine,
97382
+ offset: 0,
97383
+ confidence: exactMatch.confidence
97384
+ };
97385
+ }
97386
+ return {
97387
+ found: false,
97388
+ lineNumber: -1,
97389
+ offset: 0,
97390
+ confidence: 0
97391
+ };
97392
+ };
97393
+ var isHunkApplied = (fileContent, hunk, options2 = {}) => {
97394
+ const fullOptions = {
97395
+ ...DEFAULT_MATCH_OPTIONS,
97396
+ ...options2
97397
+ };
97398
+ const fileLines = fileContent.split(`
97399
+ `);
97400
+ let additionsPresent = 0;
97401
+ let deletionsAbsent = 0;
97402
+ for (const line2 of hunk.lines) {
97403
+ const normalizedContent = normalizeLine(line2.content, fullOptions);
97404
+ if (line2.type === "addition") {
97405
+ const found = fileLines.some((fl) => normalizeLine(fl, fullOptions) === normalizedContent);
97406
+ if (found)
97407
+ additionsPresent++;
97408
+ }
97409
+ if (line2.type === "deletion") {
97410
+ const found = fileLines.some((fl) => normalizeLine(fl, fullOptions) === normalizedContent);
97411
+ if (!found)
97412
+ deletionsAbsent++;
97413
+ }
97414
+ }
97415
+ const totalAdditions = hunk.lines.filter((l) => l.type === "addition").length;
97416
+ const totalDeletions = hunk.lines.filter((l) => l.type === "deletion").length;
97417
+ const additionsMatch = totalAdditions === 0 || additionsPresent >= totalAdditions * 0.8;
97418
+ const deletionsMatch = totalDeletions === 0 || deletionsAbsent >= totalDeletions * 0.8;
97419
+ return additionsMatch && deletionsMatch;
97420
+ };
97421
+ var previewHunkApplication = (fileContent, hunk, position) => {
97422
+ const fileLines = fileContent.split(`
97423
+ `);
97424
+ const resultLines = [];
97425
+ for (let i2 = 0;i2 < position; i2++) {
97426
+ resultLines.push(fileLines[i2]);
97427
+ }
97428
+ let originalLinesConsumed = 0;
97429
+ for (const line2 of hunk.lines) {
97430
+ if (line2.type === "context" || line2.type === "deletion") {
97431
+ originalLinesConsumed++;
97432
+ }
97433
+ }
97434
+ for (const line2 of hunk.lines) {
97435
+ if (line2.type === "context") {
97436
+ resultLines.push(line2.content);
97437
+ } else if (line2.type === "addition") {
97438
+ resultLines.push(line2.content);
97439
+ }
97440
+ }
97441
+ for (let i2 = position + originalLinesConsumed;i2 < fileLines.length; i2++) {
97442
+ resultLines.push(fileLines[i2]);
97443
+ }
97444
+ return {
97445
+ success: true,
97446
+ preview: resultLines
97447
+ };
97448
+ };
97449
+
97450
+ // src/tools/apply-patch/execute.ts
97451
+ var rollbackStore = new Map;
97452
+ var executeApplyPatch = async (params, ctx) => {
97453
+ try {
97454
+ const parsedPatch = parsePatch2(params.patch);
97455
+ const validation = validatePatch(parsedPatch);
97456
+ if (!validation.valid) {
97457
+ return {
97458
+ success: false,
97459
+ title: PATCH_TITLES.FAILED,
97460
+ output: "",
97461
+ error: validation.errors.join(`
97462
+ `)
97463
+ };
97464
+ }
97465
+ const results = [];
97466
+ let totalPatched = 0;
97467
+ let totalFailed = 0;
97468
+ for (let filePatch of parsedPatch.files) {
97469
+ if (filePatch.isBinary) {
97470
+ results.push({
97471
+ success: true,
97472
+ filePath: getTargetPath(filePatch),
97473
+ hunksApplied: 0,
97474
+ hunksFailed: 0,
97475
+ hunkResults: [],
97476
+ error: PATCH_MESSAGES.SKIPPED_BINARY(getTargetPath(filePatch))
97477
+ });
97478
+ continue;
97479
+ }
97480
+ if (params.reverse) {
97481
+ filePatch = reversePatch(filePatch);
97482
+ }
97483
+ const targetPath = params.targetFile ?? getTargetPath(filePatch);
97484
+ const absolutePath = isAbsolute2(targetPath) ? targetPath : join9(ctx.workingDir, targetPath);
97485
+ const result = await applyFilePatch(filePatch, absolutePath, {
97486
+ fuzz: params.fuzz ?? PATCH_DEFAULTS.FUZZ,
97487
+ dryRun: params.dryRun ?? false
97488
+ });
97489
+ results.push(result);
97490
+ if (result.success) {
97491
+ totalPatched++;
97492
+ } else {
97493
+ totalFailed++;
97494
+ }
97495
+ }
97496
+ const output = formatPatchResults(results, params.dryRun ?? false);
97497
+ const success3 = totalFailed === 0;
97498
+ const title = params.dryRun ? PATCH_TITLES.DRY_RUN : totalFailed === 0 ? PATCH_TITLES.SUCCESS(totalPatched) : totalPatched > 0 ? PATCH_TITLES.PARTIAL(totalPatched, totalFailed) : PATCH_TITLES.FAILED;
97499
+ return {
97500
+ success: success3,
97501
+ title,
97502
+ output,
97503
+ error: success3 ? undefined : `${totalFailed} file(s) failed to patch`
97504
+ };
97505
+ } catch (error49) {
97506
+ const message2 = error49 instanceof Error ? error49.message : String(error49);
97507
+ return {
97508
+ success: false,
97509
+ title: PATCH_TITLES.FAILED,
97510
+ output: "",
97511
+ error: PATCH_ERRORS.PARSE_FAILED(message2)
97512
+ };
97513
+ }
97514
+ };
97515
+ var applyFilePatch = async (filePatch, targetPath, options2) => {
97516
+ const hunkResults = [];
97517
+ let currentContent;
97518
+ let originalContent;
97519
+ try {
97520
+ if (filePatch.isNew) {
97521
+ currentContent = "";
97522
+ originalContent = "";
97523
+ } else {
97524
+ try {
97525
+ currentContent = await fs14.readFile(targetPath, "utf-8");
97526
+ originalContent = currentContent;
97527
+ } catch {
97528
+ return {
97529
+ success: false,
97530
+ filePath: targetPath,
97531
+ hunksApplied: 0,
97532
+ hunksFailed: filePatch.hunks.length,
97533
+ hunkResults: [],
97534
+ error: PATCH_ERRORS.FILE_NOT_FOUND(targetPath)
97535
+ };
97536
+ }
97537
+ }
97538
+ if (filePatch.isDeleted) {
97539
+ if (!options2.dryRun) {
97540
+ rollbackStore.set(targetPath, {
97541
+ filePath: targetPath,
97542
+ originalContent,
97543
+ patchedContent: "",
97544
+ timestamp: Date.now()
97545
+ });
97546
+ await fs14.unlink(targetPath);
97547
+ }
97548
+ return {
97549
+ success: true,
97550
+ filePath: targetPath,
97551
+ hunksApplied: 1,
97552
+ hunksFailed: 0,
97553
+ hunkResults: [
97554
+ {
97555
+ success: true,
97556
+ hunkIndex: 0,
97557
+ appliedAt: 0
97558
+ }
97559
+ ],
97560
+ newContent: ""
97561
+ };
97562
+ }
97563
+ let hunksApplied = 0;
97564
+ let hunksFailed = 0;
97565
+ for (let i2 = 0;i2 < filePatch.hunks.length; i2++) {
97566
+ const hunk = filePatch.hunks[i2];
97567
+ if (isHunkApplied(currentContent, hunk, { fuzz: options2.fuzz })) {
97568
+ hunkResults.push({
97569
+ success: true,
97570
+ hunkIndex: i2,
97571
+ appliedAt: hunk.oldStart - 1
97572
+ });
97573
+ hunksApplied++;
97574
+ continue;
97575
+ }
97576
+ const position = findHunkPosition(currentContent, hunk, { fuzz: options2.fuzz });
97577
+ if (!position.found) {
97578
+ hunkResults.push({
97579
+ success: false,
97580
+ hunkIndex: i2,
97581
+ error: PATCH_ERRORS.FUZZY_MATCH_FAILED(i2)
97582
+ });
97583
+ hunksFailed++;
97584
+ continue;
97585
+ }
97586
+ const preview = previewHunkApplication(currentContent, hunk, position.lineNumber);
97587
+ if (!preview.success) {
97588
+ hunkResults.push({
97589
+ success: false,
97590
+ hunkIndex: i2,
97591
+ error: preview.error ?? PATCH_ERRORS.HUNK_FAILED(i2, "unknown")
97592
+ });
97593
+ hunksFailed++;
97594
+ continue;
97595
+ }
97596
+ currentContent = preview.preview.join(`
97597
+ `);
97598
+ hunksApplied++;
97599
+ hunkResults.push({
97600
+ success: true,
97601
+ hunkIndex: i2,
97602
+ appliedAt: position.lineNumber,
97603
+ fuzzyOffset: position.offset !== 0 ? position.offset : undefined
97604
+ });
97605
+ }
97606
+ if (!options2.dryRun && hunksApplied > 0) {
97607
+ rollbackStore.set(targetPath, {
97608
+ filePath: targetPath,
97609
+ originalContent,
97610
+ patchedContent: currentContent,
97611
+ timestamp: Date.now()
97612
+ });
97613
+ await fs14.mkdir(dirname2(targetPath), { recursive: true });
97614
+ await fs14.writeFile(targetPath, currentContent, "utf-8");
97615
+ }
97616
+ return {
97617
+ success: hunksFailed === 0,
97618
+ filePath: targetPath,
97619
+ hunksApplied,
97620
+ hunksFailed,
97621
+ hunkResults,
97622
+ newContent: currentContent
97623
+ };
97624
+ } catch (error49) {
97625
+ const message2 = error49 instanceof Error ? error49.message : String(error49);
97626
+ return {
97627
+ success: false,
97628
+ filePath: targetPath,
97629
+ hunksApplied: 0,
97630
+ hunksFailed: filePatch.hunks.length,
97631
+ hunkResults,
97632
+ error: PATCH_ERRORS.WRITE_FAILED(targetPath, message2)
97633
+ };
97634
+ }
97635
+ };
97636
+ var formatPatchResults = (results, dryRun) => {
97637
+ const lines = [];
97638
+ for (const result of results) {
97639
+ lines.push(`${result.success ? "✓" : "✗"} ${result.filePath}`);
97640
+ if (result.hunksApplied > 0 || result.hunksFailed > 0) {
97641
+ lines.push(` ${result.hunksApplied} hunk(s) applied, ${result.hunksFailed} failed`);
97642
+ }
97643
+ for (const hunk of result.hunkResults) {
97644
+ if (hunk.fuzzyOffset) {
97645
+ lines.push(` ${PATCH_MESSAGES.FUZZY_APPLIED(hunk.hunkIndex, hunk.fuzzyOffset)}`);
97646
+ }
97647
+ }
97648
+ if (result.error) {
97649
+ lines.push(` Error: ${result.error}`);
97650
+ }
97651
+ }
97652
+ if (dryRun) {
97653
+ lines.push("");
97654
+ lines.push("(dry run - no changes were made)");
97655
+ } else if (results.some((r) => r.success)) {
97656
+ lines.push("");
97657
+ lines.push(PATCH_MESSAGES.ROLLBACK_AVAILABLE);
97658
+ }
97659
+ return lines.join(`
97660
+ `);
97661
+ };
97662
+
97663
+ // src/tools/apply-patch/index.ts
97664
+ var APPLY_PATCH_DESCRIPTION = `Apply a unified diff patch to one or more files.
97665
+
97666
+ Use this tool to:
97667
+ - Apply changes from a diff/patch
97668
+ - Update files based on patch content
97669
+ - Preview changes before applying (dry run)
97670
+
97671
+ Parameters:
97672
+ - patch: The unified diff content (required)
97673
+ - targetFile: Override the target file path (optional)
97674
+ - dryRun: Preview without applying changes (default: false)
97675
+ - fuzz: Context line tolerance 0-3 (default: 2)
97676
+ - reverse: Apply patch in reverse to undo changes (default: false)
97677
+
97678
+ The tool supports:
97679
+ - Standard unified diff format (git diff, diff -u)
97680
+ - Fuzzy context matching when lines have shifted
97681
+ - Creating new files
97682
+ - Deleting files
97683
+ - Rollback on failure
97684
+
97685
+ Example patch format:
97686
+ \`\`\`
97687
+ --- a/src/example.ts
97688
+ +++ b/src/example.ts
97689
+ @@ -10,6 +10,7 @@ function example() {
97690
+ const a = 1;
97691
+ const b = 2;
97692
+ + const c = 3;
97693
+ return a + b;
97694
+ }
97695
+ \`\`\``;
97696
+ var applyPatchTool = {
97697
+ name: "apply_patch",
97698
+ description: APPLY_PATCH_DESCRIPTION,
97699
+ parameters: applyPatchParams,
97700
+ execute: executeApplyPatch
97701
+ };
95944
97702
  // src/services/mcp/tools.ts
95945
97703
  init_manager();
95946
97704
  var getMCPToolsForApi = async () => {
@@ -96030,12 +97788,15 @@ var tools = [
96030
97788
  readTool,
96031
97789
  writeTool,
96032
97790
  editTool,
97791
+ multiEditTool,
96033
97792
  globToolDefinition,
96034
97793
  grepToolDefinition,
96035
97794
  todoWriteTool,
96036
97795
  todoReadTool,
96037
97796
  webSearchTool,
96038
- lspTool
97797
+ webFetchTool,
97798
+ lspTool,
97799
+ applyPatchTool
96039
97800
  ];
96040
97801
  var READ_ONLY_TOOLS = new Set([
96041
97802
  "read",
@@ -96043,6 +97804,7 @@ var READ_ONLY_TOOLS = new Set([
96043
97804
  "grep",
96044
97805
  "todo_read",
96045
97806
  "web_search",
97807
+ "web_fetch",
96046
97808
  "lsp"
96047
97809
  ]);
96048
97810
  var toolMap = new Map(tools.map((t2) => [t2.name, t2]));
@@ -98003,17 +99765,17 @@ var isCorrection = (message2) => {
98003
99765
  return feedback.type === "negative" && feedback.confidence >= 0.6;
98004
99766
  };
98005
99767
  // src/services/provider-quality/persistence.ts
98006
- import { join as join11 } from "path";
99768
+ import { join as join12 } from "path";
98007
99769
  import { homedir as homedir3 } from "os";
98008
- var QUALITY_DATA_DIR = join11(homedir3(), ".config", "codetyper");
99770
+ var QUALITY_DATA_DIR = join12(homedir3(), ".config", "codetyper");
98009
99771
  var QUALITY_DATA_FILE = "provider-quality.json";
98010
99772
  var getQualityDataPath = () => {
98011
- return join11(QUALITY_DATA_DIR, QUALITY_DATA_FILE);
99773
+ return join12(QUALITY_DATA_DIR, QUALITY_DATA_FILE);
98012
99774
  };
98013
99775
  var ensureDataDir = async () => {
98014
- const fs14 = await import("fs/promises");
99776
+ const fs17 = await import("fs/promises");
98015
99777
  try {
98016
- await fs14.mkdir(QUALITY_DATA_DIR, { recursive: true });
99778
+ await fs17.mkdir(QUALITY_DATA_DIR, { recursive: true });
98017
99779
  } catch {}
98018
99780
  };
98019
99781
  var createDefaultScores = () => {
@@ -98040,20 +99802,20 @@ var createDefaultScores = () => {
98040
99802
  return scores;
98041
99803
  };
98042
99804
  var loadQualityData = async () => {
98043
- const fs14 = await import("fs/promises");
99805
+ const fs17 = await import("fs/promises");
98044
99806
  const filePath2 = getQualityDataPath();
98045
99807
  try {
98046
- const content = await fs14.readFile(filePath2, "utf-8");
99808
+ const content = await fs17.readFile(filePath2, "utf-8");
98047
99809
  return JSON.parse(content);
98048
99810
  } catch {
98049
99811
  return {};
98050
99812
  }
98051
99813
  };
98052
99814
  var saveQualityData = async (data) => {
98053
- const fs14 = await import("fs/promises");
99815
+ const fs17 = await import("fs/promises");
98054
99816
  await ensureDataDir();
98055
99817
  const filePath2 = getQualityDataPath();
98056
- await fs14.writeFile(filePath2, JSON.stringify(data, null, 2));
99818
+ await fs17.writeFile(filePath2, JSON.stringify(data, null, 2));
98057
99819
  };
98058
99820
  var getProviderQuality = async (providerId) => {
98059
99821
  const allData = await loadQualityData();
@@ -98611,7 +100373,7 @@ var handleMessage = async (state4, message2, callbacks) => {
98611
100373
  }
98612
100374
  if (isReadOnlyMode) {
98613
100375
  const modeLabel = interactionMode === "ask" ? "Ask" : "Code Review";
98614
- callbacks.onLog("system", `${modeLabel} mode: Read-only tools only (Ctrl+Tab to switch modes)`);
100376
+ callbacks.onLog("system", `${modeLabel} mode: Read-only tools only (Ctrl+M to switch modes)`);
98615
100377
  }
98616
100378
  let processedMessage = await processFileReferences(state4, message2);
98617
100379
  if (interactionMode === "code-review") {
@@ -99203,7 +100965,7 @@ await init_providers2();
99203
100965
  // src/services/hooks-service.ts
99204
100966
  import { spawn as spawn7 } from "child_process";
99205
100967
  import { readFile as readFile7, access, constants as constants2 } from "fs/promises";
99206
- import { join as join12, isAbsolute as isAbsolute2, resolve as resolve6 } from "path";
100968
+ import { join as join13, isAbsolute as isAbsolute3, resolve as resolve6 } from "path";
99207
100969
 
99208
100970
  // src/constants/hooks.ts
99209
100971
  var HOOKS_CONFIG_FILE = "hooks.json";
@@ -99238,8 +101000,8 @@ var loadHooksFromFile = async (filePath2) => {
99238
101000
  }
99239
101001
  };
99240
101002
  var loadHooks = async (workingDir3) => {
99241
- const globalPath = join12(DIRS.config, HOOKS_CONFIG_FILE);
99242
- const localPath = join12(workingDir3, LOCAL_CONFIG_DIR, HOOKS_CONFIG_FILE);
101003
+ const globalPath = join13(DIRS.config, HOOKS_CONFIG_FILE);
101004
+ const localPath = join13(workingDir3, LOCAL_CONFIG_DIR, HOOKS_CONFIG_FILE);
99243
101005
  const [globalHooks, localHooks] = await Promise.all([
99244
101006
  loadHooksFromFile(globalPath),
99245
101007
  loadHooksFromFile(localPath)
@@ -99256,7 +101018,7 @@ var getHooksForEvent = (event) => {
99256
101018
  return allHooks.filter((hook) => hook.event === event);
99257
101019
  };
99258
101020
  var resolveScriptPath = (script, workingDir3) => {
99259
- if (isAbsolute2(script)) {
101021
+ if (isAbsolute3(script)) {
99260
101022
  return script;
99261
101023
  }
99262
101024
  return resolve6(workingDir3, script);
@@ -99746,7 +101508,7 @@ var {
99746
101508
  const clearContexts = () => {
99747
101509
  setStore("contextStack", []);
99748
101510
  };
99749
- const register = (binding) => {
101511
+ const register2 = (binding) => {
99750
101512
  const id = generateKeybindId();
99751
101513
  const fullBinding = {
99752
101514
  ...binding,
@@ -99808,7 +101570,7 @@ var {
99808
101570
  pushContext,
99809
101571
  popContext,
99810
101572
  clearContexts,
99811
- register,
101573
+ register: register2,
99812
101574
  unregister,
99813
101575
  enable,
99814
101576
  disable,
@@ -100198,7 +101960,7 @@ function InputArea(props) {
100198
101960
  };
100199
101961
  const isMenuOpen = createMemo(() => {
100200
101962
  const mode = app.mode();
100201
- return app.commandMenu().isOpen || mode === "command_menu" || mode === "model_select" || mode === "theme_select" || mode === "agent_select" || mode === "mode_select" || mode === "mcp_select" || mode === "mcp_add" || mode === "file_picker" || mode === "permission_prompt" || mode === "learning_prompt" || mode === "help_menu" || mode === "help_detail";
101963
+ return app.commandMenu().isOpen || mode === "command_menu" || mode === "model_select" || mode === "theme_select" || mode === "agent_select" || mode === "mode_select" || mode === "mcp_select" || mode === "mcp_add" || mode === "file_picker" || mode === "permission_prompt" || mode === "learning_prompt" || mode === "help_menu" || mode === "help_detail" || mode === "brain_menu" || mode === "brain_login" || mode === "provider_select" || mode === "mcp_browse";
100202
101964
  });
100203
101965
  const placeholder = () => props.placeholder ?? "Ask anything... (@ for files, / for commands)";
100204
101966
  const borderColor = createMemo(() => {
@@ -100209,7 +101971,7 @@ function InputArea(props) {
100209
101971
  return theme.colors.border;
100210
101972
  });
100211
101973
  useKeyboard((evt) => {
100212
- if (evt.ctrl && evt.name === "tab") {
101974
+ if (evt.ctrl && evt.name === "m") {
100213
101975
  app.toggleInteractionMode();
100214
101976
  evt.preventDefault();
100215
101977
  evt.stopPropagation();
@@ -100378,7 +102140,9 @@ var MODE_DISPLAY_CONFIG = {
100378
102140
  provider_select: { text: "Select Provider", color: "magenta" },
100379
102141
  learning_prompt: { text: "Save Learning?", color: "cyan" },
100380
102142
  help_menu: { text: "Help", color: "cyan" },
100381
- help_detail: { text: "Help Detail", color: "cyan" }
102143
+ help_detail: { text: "Help Detail", color: "cyan" },
102144
+ brain_menu: { text: "Brain Settings", color: "magenta" },
102145
+ brain_login: { text: "Brain Login", color: "magenta" }
100382
102146
  };
100383
102147
  var DEFAULT_MODE_DISPLAY = {
100384
102148
  text: "Ready",
@@ -100455,6 +102219,11 @@ var SLASH_COMMANDS = [
100455
102219
  name: "logout",
100456
102220
  description: "Sign out from provider",
100457
102221
  category: "account"
102222
+ },
102223
+ {
102224
+ name: "brain",
102225
+ description: "Configure CodeTyper Brain (memory & knowledge)",
102226
+ category: "account"
100458
102227
  }
100459
102228
  ];
100460
102229
  var COMMAND_CATEGORIES = [
@@ -100466,10 +102235,11 @@ var COMMAND_CATEGORIES = [
100466
102235
 
100467
102236
  // src/tui-solid/components/command-menu.tsx
100468
102237
  var filterCommands = (commands, filter2) => {
102238
+ let availableCommands = BRAIN_DISABLED ? commands.filter((cmd) => cmd.name !== "brain") : [...commands];
100469
102239
  if (!filter2)
100470
- return [...commands];
102240
+ return availableCommands;
100471
102241
  const query = filter2.toLowerCase();
100472
- return commands.filter((cmd) => cmd.name.toLowerCase().includes(query) || cmd.description.toLowerCase().includes(query));
102242
+ return availableCommands.filter((cmd) => cmd.name.toLowerCase().includes(query) || cmd.description.toLowerCase().includes(query));
100473
102243
  };
100474
102244
  var groupCommandsByCategory = (commands) => {
100475
102245
  return COMMAND_CATEGORIES.map((cat) => ({
@@ -101419,9 +103189,24 @@ function CenteredModal(props) {
101419
103189
 
101420
103190
  // src/constants/home.ts
101421
103191
  var HOME_VARS = {
101422
- title: "Welcome to CodeTyper - Your AI Coding Assistant",
101423
- subTitle: "Type a prompt below to start a new session"
101424
- };
103192
+ subTitle: "Type a prompt below to start"
103193
+ };
103194
+ var ASCII_LOGO = [
103195
+ " ██████╗ ██████╗ ██████╗ ███████╗ ████████╗ ██╗ ██╗ ██████╗ ███████╗ ██████╗ ",
103196
+ "██╔════╝ ██╔═══██╗ ██╔══██╗ ██╔════╝ ╚══██╔══╝ ╚██╗ ██╔╝ ██╔══██╗ ██╔════╝ ██╔══██╗",
103197
+ "██║ ██║ ██║ ██║ ██║ █████╗ ██║ ╚████╔╝ ██████╔╝ █████╗ ██████╔╝",
103198
+ "██║ ██║ ██║ ██║ ██║ ██╔══╝ ██║ ╚██╔╝ ██╔═══╝ ██╔══╝ ██╔══██╗",
103199
+ "╚██████╗ ╚██████╔╝ ██████╔╝ ███████╗ ██║ ██║ ██║ ███████╗ ██║ ██║",
103200
+ " ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚══════╝ ╚═╝ ╚═╝"
103201
+ ];
103202
+ var ASCII_LOGO_GRADIENT = [
103203
+ "#00FFFF",
103204
+ "#00D4FF",
103205
+ "#00AAFF",
103206
+ "#0080FF",
103207
+ "#0055FF",
103208
+ "#AA00FF"
103209
+ ];
101425
103210
 
101426
103211
  // src/tui-solid/routes/home.tsx
101427
103212
  function Home(props) {
@@ -101440,9 +103225,9 @@ function Home(props) {
101440
103225
  app.setMode("idle");
101441
103226
  };
101442
103227
  return (() => {
101443
- var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("box"), _el$4 = createElement("text"), _el$5 = createElement("text"), _el$6 = createElement("box");
103228
+ var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("box"), _el$4 = createElement("text"), _el$5 = createElement("box");
101444
103229
  insertNode(_el$, _el$2);
101445
- insertNode(_el$, _el$6);
103230
+ insertNode(_el$, _el$5);
101446
103231
  setProp(_el$, "flexDirection", "column");
101447
103232
  setProp(_el$, "flexGrow", 1);
101448
103233
  insertNode(_el$2, _el$3);
@@ -101452,14 +103237,10 @@ function Home(props) {
101452
103237
  setProp(_el$2, "flexDirection", "column");
101453
103238
  insert(_el$2, createComponent2(Logo, {}), _el$3);
101454
103239
  insertNode(_el$3, _el$4);
101455
- insertNode(_el$3, _el$5);
101456
103240
  setProp(_el$3, "marginTop", 2);
101457
- setProp(_el$3, "flexDirection", "column");
101458
- setProp(_el$3, "alignItems", "center");
101459
- insert(_el$4, () => HOME_VARS.title);
101460
- insert(_el$5, () => HOME_VARS.subTitle);
101461
- setProp(_el$6, "marginTop", 2);
101462
- insert(_el$6, createComponent2(InputArea, {
103241
+ insert(_el$4, () => HOME_VARS.subTitle);
103242
+ setProp(_el$5, "marginTop", 2);
103243
+ insert(_el$5, createComponent2(InputArea, {
101463
103244
  onSubmit: handleSubmit,
101464
103245
  placeholder: "What would you like to build today?"
101465
103246
  }));
@@ -101560,15 +103341,13 @@ function Home(props) {
101560
103341
  }
101561
103342
  }), null);
101562
103343
  effect((_p$) => {
101563
- var _v$ = theme.colors.background, _v$2 = theme.colors.textDim, _v$3 = theme.colors.textDim;
103344
+ var _v$ = theme.colors.background, _v$2 = theme.colors.textDim;
101564
103345
  _v$ !== _p$.e && (_p$.e = setProp(_el$, "backgroundColor", _v$, _p$.e));
101565
103346
  _v$2 !== _p$.t && (_p$.t = setProp(_el$4, "fg", _v$2, _p$.t));
101566
- _v$3 !== _p$.a && (_p$.a = setProp(_el$5, "fg", _v$3, _p$.a));
101567
103347
  return _p$;
101568
103348
  }, {
101569
103349
  e: undefined,
101570
- t: undefined,
101571
- a: undefined
103350
+ t: undefined
101572
103351
  });
101573
103352
  return _el$;
101574
103353
  })();
@@ -101603,6 +103382,17 @@ await __promiseAll([
101603
103382
  init_theme2(),
101604
103383
  init_app()
101605
103384
  ]);
103385
+
103386
+ // src/constants/token.ts
103387
+ var TOKEN_WARNING_THRESHOLD = 0.75;
103388
+ var TOKEN_CRITICAL_THRESHOLD = 0.9;
103389
+ var PRUNE_PROTECTED_TOOLS = new Set([
103390
+ "skill",
103391
+ "todo_read",
103392
+ "todo_write"
103393
+ ]);
103394
+
103395
+ // src/tui-solid/components/header.tsx
101606
103396
  var MODE_LABELS = {
101607
103397
  agent: "Agent",
101608
103398
  ask: "Ask",
@@ -101618,6 +103408,24 @@ var MODE_COLORS = {
101618
103408
  ask: "info",
101619
103409
  "code-review": "success"
101620
103410
  };
103411
+ var BRAIN_STATUS_COLORS = {
103412
+ connected: "success",
103413
+ connecting: "warning",
103414
+ disconnected: "textDim",
103415
+ error: "error"
103416
+ };
103417
+ var TOKEN_STATUS_COLORS = {
103418
+ normal: "textDim",
103419
+ warning: "warning",
103420
+ critical: "error",
103421
+ compacting: "info"
103422
+ };
103423
+ var formatTokenCount = (tokens) => {
103424
+ if (tokens >= 1000) {
103425
+ return `${(tokens / 1000).toFixed(1)}K`;
103426
+ }
103427
+ return tokens.toString();
103428
+ };
101621
103429
  function Header(props) {
101622
103430
  const theme = useTheme();
101623
103431
  const app = useAppStore();
@@ -101626,119 +103434,274 @@ function Header(props) {
101626
103434
  const colorKey = MODE_COLORS[app.interactionMode()];
101627
103435
  return theme.colors[colorKey];
101628
103436
  });
103437
+ const brainColor = createMemo(() => {
103438
+ const brain = app.brain();
103439
+ const colorKey = BRAIN_STATUS_COLORS[brain.status];
103440
+ return theme.colors[colorKey];
103441
+ });
103442
+ const shouldShowBrainBanner = createMemo(() => {
103443
+ if (BRAIN_DISABLED)
103444
+ return false;
103445
+ const brain = app.brain();
103446
+ return brain.showBanner && brain.status === "disconnected";
103447
+ });
103448
+ const contextUsage = createMemo(() => {
103449
+ const stats = app.sessionStats();
103450
+ const totalTokens = stats.inputTokens + stats.outputTokens;
103451
+ const maxTokens = stats.contextMaxTokens;
103452
+ const usagePercent = maxTokens > 0 ? totalTokens / maxTokens * 100 : 0;
103453
+ let status2 = "normal";
103454
+ if (app.isCompacting()) {
103455
+ status2 = "compacting";
103456
+ } else if (usagePercent >= TOKEN_CRITICAL_THRESHOLD * 100) {
103457
+ status2 = "critical";
103458
+ } else if (usagePercent >= TOKEN_WARNING_THRESHOLD * 100) {
103459
+ status2 = "warning";
103460
+ }
103461
+ return {
103462
+ current: totalTokens,
103463
+ max: maxTokens,
103464
+ percent: usagePercent,
103465
+ status: status2
103466
+ };
103467
+ });
103468
+ const tokenColor = createMemo(() => {
103469
+ const colorKey = TOKEN_STATUS_COLORS[contextUsage().status];
103470
+ return theme.colors[colorKey];
103471
+ });
101629
103472
  return (() => {
101630
- var _el$ = createElement("box"), _el$2 = createElement("box"), _el$5 = createElement("text"), _el$6 = createTextNode(`v`), _el$7 = createElement("text"), _el$9 = createElement("box"), _el$0 = createElement("text"), _el$1 = createTextNode(`[`), _el$10 = createTextNode(`]`), _el$14 = createElement("text"), _el$15 = createTextNode(` - `), _el$17 = createElement("box"), _el$18 = createElement("box"), _el$19 = createElement("text"), _el$21 = createElement("text"), _el$22 = createElement("box"), _el$23 = createElement("text"), _el$25 = createElement("text");
101631
- insertNode(_el$, _el$2);
101632
- insertNode(_el$, _el$17);
101633
- setProp(_el$, "flexDirection", "row");
101634
- setProp(_el$, "justifyContent", "space-between");
101635
- setProp(_el$, "paddingLeft", 1);
101636
- setProp(_el$, "paddingRight", 1);
101637
- setProp(_el$, "border", ["bottom"]);
101638
- insertNode(_el$2, _el$5);
101639
- insertNode(_el$2, _el$7);
101640
- insertNode(_el$2, _el$9);
101641
- setProp(_el$2, "flexDirection", "row");
101642
- setProp(_el$2, "gap", 1);
101643
- insert(_el$2, createComponent2(Show, {
103473
+ var _el$ = createElement("box"), _el$11 = createElement("box"), _el$12 = createElement("box"), _el$15 = createElement("text"), _el$16 = createTextNode(`v`), _el$17 = createElement("text"), _el$19 = createElement("box"), _el$20 = createElement("text"), _el$21 = createTextNode(`[`), _el$22 = createTextNode(`]`), _el$26 = createElement("text"), _el$27 = createTextNode(` - `), _el$29 = createElement("box"), _el$43 = createElement("box"), _el$44 = createElement("text"), _el$46 = createElement("text"), _el$47 = createElement("box"), _el$48 = createElement("text"), _el$50 = createElement("text");
103474
+ insertNode(_el$, _el$11);
103475
+ setProp(_el$, "flexDirection", "column");
103476
+ insert(_el$, createComponent2(Show, {
103477
+ get when() {
103478
+ return shouldShowBrainBanner();
103479
+ },
103480
+ get children() {
103481
+ var _el$2 = createElement("box"), _el$3 = createElement("box"), _el$4 = createElement("text"), _el$5 = createElement("text"), _el$6 = createElement("text"), _el$8 = createElement("text"), _el$9 = createTextNode(`:`), _el$0 = createElement("text"), _el$1 = createElement("text");
103482
+ insertNode(_el$2, _el$3);
103483
+ insertNode(_el$2, _el$1);
103484
+ setProp(_el$2, "flexDirection", "row");
103485
+ setProp(_el$2, "justifyContent", "space-between");
103486
+ setProp(_el$2, "paddingLeft", 1);
103487
+ setProp(_el$2, "paddingRight", 1);
103488
+ setProp(_el$2, "backgroundColor", "#1a1a2e");
103489
+ insertNode(_el$3, _el$4);
103490
+ insertNode(_el$3, _el$5);
103491
+ insertNode(_el$3, _el$6);
103492
+ insertNode(_el$3, _el$8);
103493
+ insertNode(_el$3, _el$0);
103494
+ setProp(_el$3, "flexDirection", "row");
103495
+ setProp(_el$3, "gap", 1);
103496
+ setProp(_el$4, "fg", "#ff69b4");
103497
+ insert(_el$4, () => BRAIN_BANNER.EMOJI_CONNECTED);
103498
+ setProp(_el$5, "fg", "#ffffff");
103499
+ insert(_el$5, () => BRAIN_BANNER.TITLE);
103500
+ insertNode(_el$6, createTextNode(`-`));
103501
+ insertNode(_el$8, _el$9);
103502
+ insert(_el$8, () => BRAIN_BANNER.CTA, _el$9);
103503
+ insert(_el$0, () => BRAIN_BANNER.URL);
103504
+ insertNode(_el$1, createTextNode(`[Ctrl+B dismiss]`));
103505
+ effect((_p$) => {
103506
+ var _v$ = TextAttributes.BOLD, _v$2 = TextAttributes.BOLD, _v$3 = theme.colors.textDim, _v$4 = theme.colors.textDim, _v$5 = theme.colors.info, _v$6 = TextAttributes.UNDERLINE, _v$7 = theme.colors.textDim;
103507
+ _v$ !== _p$.e && (_p$.e = setProp(_el$4, "attributes", _v$, _p$.e));
103508
+ _v$2 !== _p$.t && (_p$.t = setProp(_el$5, "attributes", _v$2, _p$.t));
103509
+ _v$3 !== _p$.a && (_p$.a = setProp(_el$6, "fg", _v$3, _p$.a));
103510
+ _v$4 !== _p$.o && (_p$.o = setProp(_el$8, "fg", _v$4, _p$.o));
103511
+ _v$5 !== _p$.i && (_p$.i = setProp(_el$0, "fg", _v$5, _p$.i));
103512
+ _v$6 !== _p$.n && (_p$.n = setProp(_el$0, "attributes", _v$6, _p$.n));
103513
+ _v$7 !== _p$.s && (_p$.s = setProp(_el$1, "fg", _v$7, _p$.s));
103514
+ return _p$;
103515
+ }, {
103516
+ e: undefined,
103517
+ t: undefined,
103518
+ a: undefined,
103519
+ o: undefined,
103520
+ i: undefined,
103521
+ n: undefined,
103522
+ s: undefined
103523
+ });
103524
+ return _el$2;
103525
+ }
103526
+ }), _el$11);
103527
+ insertNode(_el$11, _el$12);
103528
+ insertNode(_el$11, _el$29);
103529
+ setProp(_el$11, "flexDirection", "row");
103530
+ setProp(_el$11, "justifyContent", "space-between");
103531
+ setProp(_el$11, "paddingLeft", 1);
103532
+ setProp(_el$11, "paddingRight", 1);
103533
+ setProp(_el$11, "border", ["bottom"]);
103534
+ insertNode(_el$12, _el$15);
103535
+ insertNode(_el$12, _el$17);
103536
+ insertNode(_el$12, _el$19);
103537
+ setProp(_el$12, "flexDirection", "row");
103538
+ setProp(_el$12, "gap", 1);
103539
+ insert(_el$12, createComponent2(Show, {
101644
103540
  get when() {
101645
103541
  return showBanner();
101646
103542
  },
101647
103543
  get children() {
101648
- var _el$3 = createElement("text");
101649
- insertNode(_el$3, createTextNode(`CodeTyper`));
103544
+ var _el$13 = createElement("text");
103545
+ insertNode(_el$13, createTextNode(`CodeTyper`));
101650
103546
  effect((_p$) => {
101651
- var _v$ = theme.colors.primary, _v$2 = TextAttributes.BOLD;
101652
- _v$ !== _p$.e && (_p$.e = setProp(_el$3, "fg", _v$, _p$.e));
101653
- _v$2 !== _p$.t && (_p$.t = setProp(_el$3, "attributes", _v$2, _p$.t));
103547
+ var _v$8 = theme.colors.primary, _v$9 = TextAttributes.BOLD;
103548
+ _v$8 !== _p$.e && (_p$.e = setProp(_el$13, "fg", _v$8, _p$.e));
103549
+ _v$9 !== _p$.t && (_p$.t = setProp(_el$13, "attributes", _v$9, _p$.t));
101654
103550
  return _p$;
101655
103551
  }, {
101656
103552
  e: undefined,
101657
103553
  t: undefined
101658
103554
  });
101659
- return _el$3;
103555
+ return _el$13;
101660
103556
  }
101661
- }), _el$5);
101662
- insertNode(_el$5, _el$6);
101663
- insert(_el$5, () => app.version(), null);
101664
- insertNode(_el$7, createTextNode(`|`));
101665
- insertNode(_el$9, _el$0);
101666
- insertNode(_el$9, _el$14);
101667
- setProp(_el$9, "flexDirection", "row");
101668
- insertNode(_el$0, _el$1);
101669
- insertNode(_el$0, _el$10);
101670
- insert(_el$0, () => MODE_LABELS[app.interactionMode()], _el$10);
101671
- insert(_el$9, createComponent2(Show, {
103557
+ }), _el$15);
103558
+ insertNode(_el$15, _el$16);
103559
+ insert(_el$15, () => app.version(), null);
103560
+ insertNode(_el$17, createTextNode(`|`));
103561
+ insertNode(_el$19, _el$20);
103562
+ insertNode(_el$19, _el$26);
103563
+ setProp(_el$19, "flexDirection", "row");
103564
+ insertNode(_el$20, _el$21);
103565
+ insertNode(_el$20, _el$22);
103566
+ insert(_el$20, () => MODE_LABELS[app.interactionMode()], _el$22);
103567
+ insert(_el$19, createComponent2(Show, {
101672
103568
  get when() {
101673
103569
  return app.currentAgent() !== "default";
101674
103570
  },
101675
103571
  get children() {
101676
- var _el$11 = createElement("text"), _el$12 = createTextNode(` @`);
101677
- insertNode(_el$11, _el$12);
101678
- insert(_el$11, () => app.currentAgent(), null);
103572
+ var _el$23 = createElement("text"), _el$24 = createTextNode(` @`);
103573
+ insertNode(_el$23, _el$24);
103574
+ insert(_el$23, () => app.currentAgent(), null);
101679
103575
  effect((_p$) => {
101680
- var _v$3 = theme.colors.secondary, _v$4 = TextAttributes.BOLD;
101681
- _v$3 !== _p$.e && (_p$.e = setProp(_el$11, "fg", _v$3, _p$.e));
101682
- _v$4 !== _p$.t && (_p$.t = setProp(_el$11, "attributes", _v$4, _p$.t));
103576
+ var _v$0 = theme.colors.secondary, _v$1 = TextAttributes.BOLD;
103577
+ _v$0 !== _p$.e && (_p$.e = setProp(_el$23, "fg", _v$0, _p$.e));
103578
+ _v$1 !== _p$.t && (_p$.t = setProp(_el$23, "attributes", _v$1, _p$.t));
101683
103579
  return _p$;
101684
103580
  }, {
101685
103581
  e: undefined,
101686
103582
  t: undefined
101687
103583
  });
101688
- return _el$11;
103584
+ return _el$23;
103585
+ }
103586
+ }), _el$26);
103587
+ insertNode(_el$26, _el$27);
103588
+ insert(_el$26, () => MODE_DESCRIPTIONS[app.interactionMode()], null);
103589
+ insertNode(_el$29, _el$43);
103590
+ insertNode(_el$29, _el$47);
103591
+ setProp(_el$29, "flexDirection", "row");
103592
+ setProp(_el$29, "gap", 2);
103593
+ insert(_el$29, createComponent2(Show, {
103594
+ get when() {
103595
+ return contextUsage().max > 0;
103596
+ },
103597
+ get children() {
103598
+ var _el$30 = createElement("box"), _el$31 = createElement("text"), _el$32 = createElement("text"), _el$34 = createElement("text");
103599
+ insertNode(_el$30, _el$31);
103600
+ insertNode(_el$30, _el$32);
103601
+ insertNode(_el$30, _el$34);
103602
+ setProp(_el$30, "flexDirection", "row");
103603
+ insert(_el$31, () => formatTokenCount(contextUsage().current));
103604
+ insertNode(_el$32, createTextNode(`/`));
103605
+ insert(_el$34, () => formatTokenCount(contextUsage().max));
103606
+ insert(_el$30, createComponent2(Show, {
103607
+ get when() {
103608
+ return contextUsage().status === "compacting";
103609
+ },
103610
+ get children() {
103611
+ var _el$35 = createElement("text");
103612
+ insertNode(_el$35, createTextNode(` [compacting]`));
103613
+ effect((_$p) => setProp(_el$35, "fg", theme.colors.info, _$p));
103614
+ return _el$35;
103615
+ }
103616
+ }), null);
103617
+ effect((_p$) => {
103618
+ var _v$10 = tokenColor(), _v$11 = theme.colors.textDim, _v$12 = theme.colors.textDim;
103619
+ _v$10 !== _p$.e && (_p$.e = setProp(_el$31, "fg", _v$10, _p$.e));
103620
+ _v$11 !== _p$.t && (_p$.t = setProp(_el$32, "fg", _v$11, _p$.t));
103621
+ _v$12 !== _p$.a && (_p$.a = setProp(_el$34, "fg", _v$12, _p$.a));
103622
+ return _p$;
103623
+ }, {
103624
+ e: undefined,
103625
+ t: undefined,
103626
+ a: undefined
103627
+ });
103628
+ return _el$30;
101689
103629
  }
101690
- }), _el$14);
101691
- insertNode(_el$14, _el$15);
101692
- insert(_el$14, () => MODE_DESCRIPTIONS[app.interactionMode()], null);
101693
- insertNode(_el$17, _el$18);
101694
- insertNode(_el$17, _el$22);
101695
- setProp(_el$17, "flexDirection", "row");
101696
- setProp(_el$17, "gap", 2);
101697
- insertNode(_el$18, _el$19);
101698
- insertNode(_el$18, _el$21);
101699
- setProp(_el$18, "flexDirection", "row");
101700
- insertNode(_el$19, createTextNode(`Provider: `));
101701
- insert(_el$21, () => app.provider());
101702
- insertNode(_el$22, _el$23);
101703
- insertNode(_el$22, _el$25);
101704
- setProp(_el$22, "flexDirection", "row");
101705
- insertNode(_el$23, createTextNode(`Model: `));
101706
- insert(_el$25, () => app.model() || "auto");
101707
- insert(_el$17, createComponent2(Show, {
103630
+ }), _el$43);
103631
+ insert(_el$29, createComponent2(Show, {
103632
+ when: !BRAIN_DISABLED,
103633
+ get children() {
103634
+ var _el$37 = createElement("box"), _el$38 = createElement("text");
103635
+ insertNode(_el$37, _el$38);
103636
+ setProp(_el$37, "flexDirection", "row");
103637
+ insert(_el$38, (() => {
103638
+ var _c$ = memo2(() => app.brain().status === "connected");
103639
+ return () => _c$() ? BRAIN_BANNER.EMOJI_CONNECTED : memo2(() => app.brain().status === "connecting")() ? "..." : BRAIN_BANNER.EMOJI_DISCONNECTED;
103640
+ })());
103641
+ insert(_el$37, createComponent2(Show, {
103642
+ get when() {
103643
+ return app.brain().status === "connected";
103644
+ },
103645
+ get children() {
103646
+ var _el$39 = createElement("text"), _el$40 = createTextNode(` `), _el$41 = createTextNode(`K/`), _el$42 = createTextNode(`M`);
103647
+ insertNode(_el$39, _el$40);
103648
+ insertNode(_el$39, _el$41);
103649
+ insertNode(_el$39, _el$42);
103650
+ insert(_el$39, () => app.brain().knowledgeCount, _el$41);
103651
+ insert(_el$39, () => app.brain().memoryCount, _el$42);
103652
+ effect((_$p) => setProp(_el$39, "fg", theme.colors.textDim, _$p));
103653
+ return _el$39;
103654
+ }
103655
+ }), null);
103656
+ effect((_$p) => setProp(_el$38, "fg", brainColor(), _$p));
103657
+ return _el$37;
103658
+ }
103659
+ }), _el$43);
103660
+ insertNode(_el$43, _el$44);
103661
+ insertNode(_el$43, _el$46);
103662
+ setProp(_el$43, "flexDirection", "row");
103663
+ insertNode(_el$44, createTextNode(`Provider: `));
103664
+ insert(_el$46, () => app.provider());
103665
+ insertNode(_el$47, _el$48);
103666
+ insertNode(_el$47, _el$50);
103667
+ setProp(_el$47, "flexDirection", "row");
103668
+ insertNode(_el$48, createTextNode(`Model: `));
103669
+ insert(_el$50, () => app.model() || "auto");
103670
+ insert(_el$29, createComponent2(Show, {
101708
103671
  get when() {
101709
103672
  return app.sessionId();
101710
103673
  },
101711
103674
  get children() {
101712
- var _el$26 = createElement("box"), _el$27 = createElement("text"), _el$29 = createElement("text");
101713
- insertNode(_el$26, _el$27);
101714
- insertNode(_el$26, _el$29);
101715
- setProp(_el$26, "flexDirection", "row");
101716
- insertNode(_el$27, createTextNode(`Session: `));
101717
- insert(_el$29, () => app.sessionId()?.replace("session-", "").slice(-5));
103675
+ var _el$51 = createElement("box"), _el$52 = createElement("text"), _el$54 = createElement("text");
103676
+ insertNode(_el$51, _el$52);
103677
+ insertNode(_el$51, _el$54);
103678
+ setProp(_el$51, "flexDirection", "row");
103679
+ insertNode(_el$52, createTextNode(`Session: `));
103680
+ insert(_el$54, () => app.sessionId()?.replace("session-", "").slice(-5));
101718
103681
  effect((_p$) => {
101719
- var _v$5 = theme.colors.textDim, _v$6 = theme.colors.info;
101720
- _v$5 !== _p$.e && (_p$.e = setProp(_el$27, "fg", _v$5, _p$.e));
101721
- _v$6 !== _p$.t && (_p$.t = setProp(_el$29, "fg", _v$6, _p$.t));
103682
+ var _v$13 = theme.colors.textDim, _v$14 = theme.colors.info;
103683
+ _v$13 !== _p$.e && (_p$.e = setProp(_el$52, "fg", _v$13, _p$.e));
103684
+ _v$14 !== _p$.t && (_p$.t = setProp(_el$54, "fg", _v$14, _p$.t));
101722
103685
  return _p$;
101723
103686
  }, {
101724
103687
  e: undefined,
101725
103688
  t: undefined
101726
103689
  });
101727
- return _el$26;
103690
+ return _el$51;
101728
103691
  }
101729
103692
  }), null);
101730
103693
  effect((_p$) => {
101731
- var _v$7 = theme.colors.border, _v$8 = theme.colors.textDim, _v$9 = theme.colors.textDim, _v$0 = modeColor(), _v$1 = TextAttributes.BOLD, _v$10 = theme.colors.textDim, _v$11 = theme.colors.textDim, _v$12 = theme.colors.secondary, _v$13 = theme.colors.textDim, _v$14 = theme.colors.accent;
101732
- _v$7 !== _p$.e && (_p$.e = setProp(_el$, "borderColor", _v$7, _p$.e));
101733
- _v$8 !== _p$.t && (_p$.t = setProp(_el$5, "fg", _v$8, _p$.t));
101734
- _v$9 !== _p$.a && (_p$.a = setProp(_el$7, "fg", _v$9, _p$.a));
101735
- _v$0 !== _p$.o && (_p$.o = setProp(_el$0, "fg", _v$0, _p$.o));
101736
- _v$1 !== _p$.i && (_p$.i = setProp(_el$0, "attributes", _v$1, _p$.i));
101737
- _v$10 !== _p$.n && (_p$.n = setProp(_el$14, "fg", _v$10, _p$.n));
101738
- _v$11 !== _p$.s && (_p$.s = setProp(_el$19, "fg", _v$11, _p$.s));
101739
- _v$12 !== _p$.h && (_p$.h = setProp(_el$21, "fg", _v$12, _p$.h));
101740
- _v$13 !== _p$.r && (_p$.r = setProp(_el$23, "fg", _v$13, _p$.r));
101741
- _v$14 !== _p$.d && (_p$.d = setProp(_el$25, "fg", _v$14, _p$.d));
103694
+ var _v$15 = theme.colors.border, _v$16 = theme.colors.textDim, _v$17 = theme.colors.textDim, _v$18 = modeColor(), _v$19 = TextAttributes.BOLD, _v$20 = theme.colors.textDim, _v$21 = theme.colors.textDim, _v$22 = theme.colors.secondary, _v$23 = theme.colors.textDim, _v$24 = theme.colors.accent;
103695
+ _v$15 !== _p$.e && (_p$.e = setProp(_el$11, "borderColor", _v$15, _p$.e));
103696
+ _v$16 !== _p$.t && (_p$.t = setProp(_el$15, "fg", _v$16, _p$.t));
103697
+ _v$17 !== _p$.a && (_p$.a = setProp(_el$17, "fg", _v$17, _p$.a));
103698
+ _v$18 !== _p$.o && (_p$.o = setProp(_el$20, "fg", _v$18, _p$.o));
103699
+ _v$19 !== _p$.i && (_p$.i = setProp(_el$20, "attributes", _v$19, _p$.i));
103700
+ _v$20 !== _p$.n && (_p$.n = setProp(_el$26, "fg", _v$20, _p$.n));
103701
+ _v$21 !== _p$.s && (_p$.s = setProp(_el$44, "fg", _v$21, _p$.s));
103702
+ _v$22 !== _p$.h && (_p$.h = setProp(_el$46, "fg", _v$22, _p$.h));
103703
+ _v$23 !== _p$.r && (_p$.r = setProp(_el$48, "fg", _v$23, _p$.r));
103704
+ _v$24 !== _p$.d && (_p$.d = setProp(_el$50, "fg", _v$24, _p$.d));
101742
103705
  return _p$;
101743
103706
  }, {
101744
103707
  e: undefined,
@@ -101767,7 +103730,6 @@ await __promiseAll([
101767
103730
  init_solid(),
101768
103731
  init_solid(),
101769
103732
  init_solid(),
101770
- init_solid(),
101771
103733
  init_theme2(),
101772
103734
  init_app()
101773
103735
  ]);
@@ -102610,13 +104572,25 @@ function LogPanel() {
102610
104572
  },
102611
104573
  get fallback() {
102612
104574
  return (() => {
102613
- var _el$4 = createElement("box"), _el$5 = createElement("text");
104575
+ var _el$4 = createElement("box"), _el$5 = createElement("box"), _el$6 = createElement("text");
102614
104576
  insertNode(_el$4, _el$5);
102615
104577
  setProp(_el$4, "flexGrow", 1);
102616
104578
  setProp(_el$4, "alignItems", "center");
102617
104579
  setProp(_el$4, "justifyContent", "center");
102618
- insertNode(_el$5, createTextNode(`No messages yet. Type your prompt below.`));
102619
- effect((_$p) => setProp(_el$5, "fg", theme.colors.textDim, _$p));
104580
+ setProp(_el$4, "flexDirection", "column");
104581
+ insert(_el$4, createComponent2(For, {
104582
+ each: ASCII_LOGO,
104583
+ children: (line2, index) => (() => {
104584
+ var _el$7 = createElement("text");
104585
+ insert(_el$7, line2);
104586
+ effect((_$p) => setProp(_el$7, "fg", ASCII_LOGO_GRADIENT[index()] ?? theme.colors.primary, _$p));
104587
+ return _el$7;
104588
+ })()
104589
+ }), _el$5);
104590
+ insertNode(_el$5, _el$6);
104591
+ setProp(_el$5, "marginTop", 2);
104592
+ insert(_el$6, () => HOME_VARS.subTitle);
104593
+ effect((_$p) => setProp(_el$6, "fg", theme.colors.textDim, _$p));
102620
104594
  return _el$4;
102621
104595
  })();
102622
104596
  },
@@ -102913,15 +104887,9 @@ function StatusBar() {
102913
104887
  const totalTokens = createMemo(() => app.sessionStats().inputTokens + app.sessionStats().outputTokens);
102914
104888
  const hints = createMemo(() => {
102915
104889
  const result = [];
102916
- if (!isProcessing()) {
102917
- result.push("^Tab toggle mode");
102918
- }
102919
104890
  if (isProcessing()) {
102920
104891
  result.push(app.interruptPending() ? STATUS_HINTS.INTERRUPT_CONFIRM : STATUS_HINTS.INTERRUPT);
102921
104892
  }
102922
- if (app.todosVisible()) {
102923
- result.push(STATUS_HINTS.TOGGLE_TODOS);
102924
- }
102925
104893
  result.push(formatDuration2(elapsed()));
102926
104894
  if (totalTokens() > 0) {
102927
104895
  result.push(`↓ ${formatTokens(totalTokens())} tokens`);
@@ -103303,13 +105271,13 @@ var FIELD_ORDER = ["name", "command", "args", "scope"];
103303
105271
  var FIELD_LABELS = {
103304
105272
  name: "Server Name",
103305
105273
  command: "Command",
103306
- args: "Arguments (space-separated)",
105274
+ args: "Arguments (use quotes for paths with spaces)",
103307
105275
  scope: "Scope"
103308
105276
  };
103309
105277
  var FIELD_PLACEHOLDERS = {
103310
- name: "e.g., sqlite",
105278
+ name: "e.g., filesystem",
103311
105279
  command: "e.g., npx",
103312
- args: "e.g., @modelcontextprotocol/server-sqlite",
105280
+ args: 'e.g., -y @modelcontextprotocol/server-filesystem "/path/to/dir"',
103313
105281
  scope: ""
103314
105282
  };
103315
105283
  function MCPAddForm(props) {
@@ -103431,10 +105399,25 @@ function MCPAddForm(props) {
103431
105399
  evt.preventDefault();
103432
105400
  return;
103433
105401
  }
105402
+ if (evt.name === "space") {
105403
+ setFieldValue(field, getFieldValue(field) + " ");
105404
+ setError(null);
105405
+ evt.preventDefault();
105406
+ return;
105407
+ }
105408
+ if (evt.ctrl && evt.name === "v") {
105409
+ return;
105410
+ }
103434
105411
  if (evt.name.length === 1 && !evt.ctrl && !evt.meta) {
103435
105412
  setFieldValue(field, getFieldValue(field) + evt.name);
103436
105413
  setError(null);
103437
105414
  evt.preventDefault();
105415
+ return;
105416
+ }
105417
+ if (evt.sequence && evt.sequence.length > 1 && !evt.ctrl && !evt.meta) {
105418
+ setFieldValue(field, getFieldValue(field) + evt.sequence);
105419
+ setError(null);
105420
+ evt.preventDefault();
103438
105421
  }
103439
105422
  });
103440
105423
  const renderField = (field) => {
@@ -104553,7 +106536,7 @@ var HELP_TOPICS = [
104553
106536
  shortDescription: "Switch mode",
104554
106537
  fullDescription: "Switch between Agent (full access), Ask (read-only), and Code Review modes.",
104555
106538
  usage: "/mode",
104556
- shortcuts: ["Ctrl+Tab"],
106539
+ shortcuts: ["Ctrl+M"],
104557
106540
  category: "commands"
104558
106541
  },
104559
106542
  {
@@ -104624,11 +106607,11 @@ var HELP_TOPICS = [
104624
106607
  category: "shortcuts"
104625
106608
  },
104626
106609
  {
104627
- id: "shortcut-ctrltab",
104628
- name: "Ctrl+Tab",
106610
+ id: "shortcut-ctrlm",
106611
+ name: "Ctrl+M",
104629
106612
  shortDescription: "Cycle modes",
104630
106613
  fullDescription: "Cycle through interaction modes.",
104631
- shortcuts: ["Ctrl+Tab"],
106614
+ shortcuts: ["Ctrl+M"],
104632
106615
  category: "shortcuts"
104633
106616
  }
104634
106617
  ];
@@ -105113,9 +107096,550 @@ function TodoPanel(props) {
105113
107096
 
105114
107097
  // src/tui-solid/routes/session.tsx
105115
107098
  await init_debug_log_panel();
107099
+
107100
+ // src/tui-solid/components/brain-menu.tsx
107101
+ init_server();
107102
+ await __promiseAll([
107103
+ init_solid(),
107104
+ init_solid(),
107105
+ init_solid(),
107106
+ init_solid(),
107107
+ init_solid(),
107108
+ init_solid(),
107109
+ init_solid(),
107110
+ init_solid(),
107111
+ init_solid(),
107112
+ init_core2(),
107113
+ init_theme2(),
107114
+ init_app()
107115
+ ]);
107116
+ function BrainMenu(props) {
107117
+ const theme = useTheme();
107118
+ const app = useAppStore();
107119
+ const isActive = () => props.isActive ?? true;
107120
+ const [view, setView] = createSignal("main");
107121
+ const [selectedIndex, setSelectedIndex] = createSignal(0);
107122
+ const [jwtToken, setJwtToken2] = createSignal("");
107123
+ const [apiKey, setApiKey2] = createSignal("");
107124
+ const [error49, setError] = createSignal(null);
107125
+ const [loading, setLoading] = createSignal(false);
107126
+ const isConnected = () => app.brain().status === "connected";
107127
+ const menuItems = () => {
107128
+ const items = [];
107129
+ if (!isConnected()) {
107130
+ items.push({
107131
+ id: "login",
107132
+ label: "Login with Email",
107133
+ description: "Get JWT token from the web portal",
107134
+ action: () => {
107135
+ setView("login_url");
107136
+ setSelectedIndex(0);
107137
+ }
107138
+ });
107139
+ items.push({
107140
+ id: "apikey",
107141
+ label: "Use API Key",
107142
+ description: "Enter your API key directly",
107143
+ action: () => {
107144
+ setView("apikey");
107145
+ setSelectedIndex(0);
107146
+ }
107147
+ });
107148
+ } else {
107149
+ items.push({
107150
+ id: "logout",
107151
+ label: "Logout",
107152
+ description: "Disconnect from CodeTyper Brain",
107153
+ action: async () => {
107154
+ setLoading(true);
107155
+ try {
107156
+ await props.onLogout();
107157
+ } catch (err) {
107158
+ setError(err instanceof Error ? err.message : "Logout failed");
107159
+ } finally {
107160
+ setLoading(false);
107161
+ }
107162
+ }
107163
+ });
107164
+ }
107165
+ items.push({
107166
+ id: "close",
107167
+ label: "Close",
107168
+ description: "Return to session",
107169
+ action: () => props.onClose()
107170
+ });
107171
+ return items;
107172
+ };
107173
+ const handleJwtSubmit = async () => {
107174
+ if (!jwtToken()) {
107175
+ setError("JWT token is required");
107176
+ return;
107177
+ }
107178
+ setLoading(true);
107179
+ setError(null);
107180
+ try {
107181
+ await props.onSetJwtToken(jwtToken());
107182
+ setView("main");
107183
+ setJwtToken2("");
107184
+ } catch (err) {
107185
+ setError(err instanceof Error ? err.message : "Failed to set JWT token");
107186
+ } finally {
107187
+ setLoading(false);
107188
+ }
107189
+ };
107190
+ const handleApiKey = async () => {
107191
+ if (!apiKey()) {
107192
+ setError("API key is required");
107193
+ return;
107194
+ }
107195
+ setLoading(true);
107196
+ setError(null);
107197
+ try {
107198
+ await props.onSetApiKey(apiKey());
107199
+ setView("main");
107200
+ setApiKey2("");
107201
+ } catch (err) {
107202
+ setError(err instanceof Error ? err.message : "Failed to set API key");
107203
+ } finally {
107204
+ setLoading(false);
107205
+ }
107206
+ };
107207
+ useKeyboard((evt) => {
107208
+ if (!isActive())
107209
+ return;
107210
+ if (evt.name === "escape") {
107211
+ if (view() !== "main") {
107212
+ setView("main");
107213
+ setError(null);
107214
+ setSelectedIndex(0);
107215
+ } else {
107216
+ props.onClose();
107217
+ }
107218
+ evt.preventDefault();
107219
+ evt.stopPropagation();
107220
+ return;
107221
+ }
107222
+ if (view() === "main") {
107223
+ if (evt.name === "up") {
107224
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : menuItems().length - 1);
107225
+ evt.preventDefault();
107226
+ return;
107227
+ }
107228
+ if (evt.name === "down") {
107229
+ setSelectedIndex((prev) => prev < menuItems().length - 1 ? prev + 1 : 0);
107230
+ evt.preventDefault();
107231
+ return;
107232
+ }
107233
+ if (evt.name === "return") {
107234
+ const item = menuItems()[selectedIndex()];
107235
+ if (item && !item.disabled) {
107236
+ item.action();
107237
+ }
107238
+ evt.preventDefault();
107239
+ return;
107240
+ }
107241
+ }
107242
+ if (view() === "login_url") {
107243
+ if (evt.name === "return") {
107244
+ setView("jwt_input");
107245
+ evt.preventDefault();
107246
+ return;
107247
+ }
107248
+ }
107249
+ if (view() === "jwt_input") {
107250
+ if (evt.name === "return") {
107251
+ handleJwtSubmit();
107252
+ evt.preventDefault();
107253
+ return;
107254
+ }
107255
+ if (evt.name === "backspace") {
107256
+ setJwtToken2((prev) => prev.slice(0, -1));
107257
+ evt.preventDefault();
107258
+ return;
107259
+ }
107260
+ if (evt.name.length === 1 && !evt.ctrl && !evt.meta) {
107261
+ setJwtToken2((prev) => prev + evt.name);
107262
+ evt.preventDefault();
107263
+ return;
107264
+ }
107265
+ }
107266
+ if (view() === "apikey") {
107267
+ if (evt.name === "return") {
107268
+ handleApiKey();
107269
+ evt.preventDefault();
107270
+ return;
107271
+ }
107272
+ if (evt.name === "backspace") {
107273
+ setApiKey2((prev) => prev.slice(0, -1));
107274
+ evt.preventDefault();
107275
+ return;
107276
+ }
107277
+ if (evt.name.length === 1 && !evt.ctrl && !evt.meta) {
107278
+ setApiKey2((prev) => prev + evt.name);
107279
+ evt.preventDefault();
107280
+ return;
107281
+ }
107282
+ }
107283
+ });
107284
+ const getStatusColor = () => {
107285
+ const status2 = app.brain().status;
107286
+ const colorMap = {
107287
+ connected: theme.colors.success,
107288
+ connecting: theme.colors.warning,
107289
+ disconnected: theme.colors.textDim,
107290
+ error: theme.colors.error
107291
+ };
107292
+ return colorMap[status2] ?? theme.colors.textDim;
107293
+ };
107294
+ const getStatusText2 = () => {
107295
+ const status2 = app.brain().status;
107296
+ const textMap = {
107297
+ connected: "Connected",
107298
+ connecting: "Connecting...",
107299
+ disconnected: "Not connected",
107300
+ error: "Connection error"
107301
+ };
107302
+ return textMap[status2] ?? "Unknown";
107303
+ };
107304
+ return (() => {
107305
+ var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$4 = createElement("text"), _el$6 = createElement("box"), _el$7 = createElement("text"), _el$9 = createElement("text");
107306
+ insertNode(_el$, _el$2);
107307
+ insertNode(_el$, _el$6);
107308
+ setProp(_el$, "flexDirection", "column");
107309
+ setProp(_el$, "border", ["top", "bottom", "left", "right"]);
107310
+ setProp(_el$, "paddingLeft", 1);
107311
+ setProp(_el$, "paddingRight", 1);
107312
+ setProp(_el$, "width", 60);
107313
+ insertNode(_el$2, _el$3);
107314
+ insertNode(_el$2, _el$4);
107315
+ setProp(_el$2, "marginBottom", 1);
107316
+ setProp(_el$2, "flexDirection", "row");
107317
+ setProp(_el$2, "gap", 1);
107318
+ setProp(_el$3, "fg", "#ff69b4");
107319
+ insert(_el$3, () => BRAIN_BANNER.EMOJI_CONNECTED);
107320
+ insertNode(_el$4, createTextNode(`CodeTyper Brain`));
107321
+ insertNode(_el$6, _el$7);
107322
+ insertNode(_el$6, _el$9);
107323
+ setProp(_el$6, "marginBottom", 1);
107324
+ setProp(_el$6, "flexDirection", "row");
107325
+ insertNode(_el$7, createTextNode(`Status: `));
107326
+ insert(_el$9, getStatusText2);
107327
+ insert(_el$6, createComponent2(Show, {
107328
+ get when() {
107329
+ return isConnected();
107330
+ },
107331
+ get children() {
107332
+ var _el$0 = createElement("text"), _el$1 = createTextNode(` (`), _el$11 = createTextNode(`K / `), _el$12 = createTextNode(`M)`);
107333
+ insertNode(_el$0, _el$1);
107334
+ insertNode(_el$0, _el$11);
107335
+ insertNode(_el$0, _el$12);
107336
+ insert(_el$0, () => app.brain().knowledgeCount, _el$11);
107337
+ insert(_el$0, () => app.brain().memoryCount, _el$12);
107338
+ effect((_$p) => setProp(_el$0, "fg", theme.colors.textDim, _$p));
107339
+ return _el$0;
107340
+ }
107341
+ }), null);
107342
+ insert(_el$, createComponent2(Show, {
107343
+ get when() {
107344
+ return memo2(() => !!isConnected())() && app.brain().user;
107345
+ },
107346
+ get children() {
107347
+ var _el$13 = createElement("box"), _el$14 = createElement("text"), _el$16 = createElement("text");
107348
+ insertNode(_el$13, _el$14);
107349
+ insertNode(_el$13, _el$16);
107350
+ setProp(_el$13, "marginBottom", 1);
107351
+ setProp(_el$13, "flexDirection", "row");
107352
+ insertNode(_el$14, createTextNode(`User: `));
107353
+ insert(_el$16, () => app.brain().user?.display_name ?? app.brain().user?.email);
107354
+ effect((_p$) => {
107355
+ var _v$ = theme.colors.textDim, _v$2 = theme.colors.info;
107356
+ _v$ !== _p$.e && (_p$.e = setProp(_el$14, "fg", _v$, _p$.e));
107357
+ _v$2 !== _p$.t && (_p$.t = setProp(_el$16, "fg", _v$2, _p$.t));
107358
+ return _p$;
107359
+ }, {
107360
+ e: undefined,
107361
+ t: undefined
107362
+ });
107363
+ return _el$13;
107364
+ }
107365
+ }), null);
107366
+ insert(_el$, createComponent2(Show, {
107367
+ get when() {
107368
+ return error49();
107369
+ },
107370
+ get children() {
107371
+ var _el$17 = createElement("box"), _el$18 = createElement("text");
107372
+ insertNode(_el$17, _el$18);
107373
+ setProp(_el$17, "marginBottom", 1);
107374
+ insert(_el$18, error49);
107375
+ effect((_$p) => setProp(_el$18, "fg", theme.colors.error, _$p));
107376
+ return _el$17;
107377
+ }
107378
+ }), null);
107379
+ insert(_el$, createComponent2(Show, {
107380
+ get when() {
107381
+ return view() === "main";
107382
+ },
107383
+ get children() {
107384
+ return [(() => {
107385
+ var _el$19 = createElement("box");
107386
+ setProp(_el$19, "flexDirection", "column");
107387
+ insert(_el$19, createComponent2(For, {
107388
+ get each() {
107389
+ return menuItems();
107390
+ },
107391
+ children: (item, index) => {
107392
+ const isSelected = () => index() === selectedIndex();
107393
+ return (() => {
107394
+ var _el$62 = createElement("box"), _el$63 = createElement("box"), _el$64 = createElement("text"), _el$65 = createElement("text"), _el$66 = createElement("box"), _el$67 = createElement("text");
107395
+ insertNode(_el$62, _el$63);
107396
+ insertNode(_el$62, _el$66);
107397
+ setProp(_el$62, "flexDirection", "column");
107398
+ setProp(_el$62, "marginBottom", 1);
107399
+ insertNode(_el$63, _el$64);
107400
+ insertNode(_el$63, _el$65);
107401
+ setProp(_el$63, "flexDirection", "row");
107402
+ insert(_el$64, () => isSelected() ? "> " : " ");
107403
+ insert(_el$65, () => item.label);
107404
+ insertNode(_el$66, _el$67);
107405
+ setProp(_el$66, "marginLeft", 4);
107406
+ insert(_el$67, () => item.description);
107407
+ effect((_p$) => {
107408
+ var _v$21 = isSelected() ? theme.colors.accent : undefined, _v$22 = isSelected() ? TextAttributes.BOLD : TextAttributes.NONE, _v$23 = isSelected() ? theme.colors.accent : undefined, _v$24 = isSelected() ? TextAttributes.BOLD : TextAttributes.NONE, _v$25 = theme.colors.textDim;
107409
+ _v$21 !== _p$.e && (_p$.e = setProp(_el$64, "fg", _v$21, _p$.e));
107410
+ _v$22 !== _p$.t && (_p$.t = setProp(_el$64, "attributes", _v$22, _p$.t));
107411
+ _v$23 !== _p$.a && (_p$.a = setProp(_el$65, "fg", _v$23, _p$.a));
107412
+ _v$24 !== _p$.o && (_p$.o = setProp(_el$65, "attributes", _v$24, _p$.o));
107413
+ _v$25 !== _p$.i && (_p$.i = setProp(_el$67, "fg", _v$25, _p$.i));
107414
+ return _p$;
107415
+ }, {
107416
+ e: undefined,
107417
+ t: undefined,
107418
+ a: undefined,
107419
+ o: undefined,
107420
+ i: undefined
107421
+ });
107422
+ return _el$62;
107423
+ })();
107424
+ }
107425
+ }));
107426
+ return _el$19;
107427
+ })(), (() => {
107428
+ var _el$20 = createElement("box"), _el$21 = createElement("text"), _el$22 = createTextNode(`: `), _el$23 = createElement("text");
107429
+ insertNode(_el$20, _el$21);
107430
+ insertNode(_el$20, _el$23);
107431
+ setProp(_el$20, "marginTop", 1);
107432
+ setProp(_el$20, "flexDirection", "column");
107433
+ insertNode(_el$21, _el$22);
107434
+ insert(_el$21, () => BRAIN_BANNER.CTA, _el$22);
107435
+ insert(_el$21, () => BRAIN_BANNER.URL, null);
107436
+ insertNode(_el$23, createTextNode(`Arrow keys navigate | Enter select | Esc close`));
107437
+ effect((_p$) => {
107438
+ var _v$3 = theme.colors.info, _v$4 = theme.colors.textDim;
107439
+ _v$3 !== _p$.e && (_p$.e = setProp(_el$21, "fg", _v$3, _p$.e));
107440
+ _v$4 !== _p$.t && (_p$.t = setProp(_el$23, "fg", _v$4, _p$.t));
107441
+ return _p$;
107442
+ }, {
107443
+ e: undefined,
107444
+ t: undefined
107445
+ });
107446
+ return _el$20;
107447
+ })()];
107448
+ }
107449
+ }), null);
107450
+ insert(_el$, createComponent2(Show, {
107451
+ get when() {
107452
+ return view() === "login_url";
107453
+ },
107454
+ get children() {
107455
+ return [(() => {
107456
+ var _el$25 = createElement("box"), _el$26 = createElement("box"), _el$27 = createElement("text"), _el$29 = createElement("box"), _el$30 = createElement("text"), _el$31 = createElement("box"), _el$32 = createElement("text"), _el$34 = createElement("box"), _el$35 = createElement("text");
107457
+ insertNode(_el$25, _el$26);
107458
+ insertNode(_el$25, _el$29);
107459
+ insertNode(_el$25, _el$31);
107460
+ insertNode(_el$25, _el$34);
107461
+ setProp(_el$25, "flexDirection", "column");
107462
+ insertNode(_el$26, _el$27);
107463
+ setProp(_el$26, "marginBottom", 1);
107464
+ insertNode(_el$27, createTextNode(`1. Go to this page to login:`));
107465
+ insertNode(_el$29, _el$30);
107466
+ setProp(_el$29, "marginBottom", 1);
107467
+ insert(_el$30, () => BRAIN_BANNER.LOGIN_URL);
107468
+ insertNode(_el$31, _el$32);
107469
+ setProp(_el$31, "marginBottom", 1);
107470
+ insertNode(_el$32, createTextNode(`2. After logging in, copy your JWT token`));
107471
+ insertNode(_el$34, _el$35);
107472
+ setProp(_el$34, "marginBottom", 1);
107473
+ insertNode(_el$35, createTextNode(`3. Press Enter to input your token`));
107474
+ effect((_p$) => {
107475
+ var _v$5 = theme.colors.text, _v$6 = theme.colors.accent, _v$7 = TextAttributes.BOLD, _v$8 = theme.colors.text, _v$9 = theme.colors.text;
107476
+ _v$5 !== _p$.e && (_p$.e = setProp(_el$27, "fg", _v$5, _p$.e));
107477
+ _v$6 !== _p$.t && (_p$.t = setProp(_el$30, "fg", _v$6, _p$.t));
107478
+ _v$7 !== _p$.a && (_p$.a = setProp(_el$30, "attributes", _v$7, _p$.a));
107479
+ _v$8 !== _p$.o && (_p$.o = setProp(_el$32, "fg", _v$8, _p$.o));
107480
+ _v$9 !== _p$.i && (_p$.i = setProp(_el$35, "fg", _v$9, _p$.i));
107481
+ return _p$;
107482
+ }, {
107483
+ e: undefined,
107484
+ t: undefined,
107485
+ a: undefined,
107486
+ o: undefined,
107487
+ i: undefined
107488
+ });
107489
+ return _el$25;
107490
+ })(), (() => {
107491
+ var _el$37 = createElement("box"), _el$38 = createElement("text");
107492
+ insertNode(_el$37, _el$38);
107493
+ setProp(_el$37, "marginTop", 1);
107494
+ insertNode(_el$38, createTextNode(`Enter continue | Esc back`));
107495
+ effect((_$p) => setProp(_el$38, "fg", theme.colors.textDim, _$p));
107496
+ return _el$37;
107497
+ })()];
107498
+ }
107499
+ }), null);
107500
+ insert(_el$, createComponent2(Show, {
107501
+ get when() {
107502
+ return view() === "jwt_input";
107503
+ },
107504
+ get children() {
107505
+ return [(() => {
107506
+ var _el$40 = createElement("box"), _el$41 = createElement("box"), _el$42 = createElement("text"), _el$44 = createElement("box"), _el$45 = createElement("text");
107507
+ insertNode(_el$40, _el$41);
107508
+ setProp(_el$40, "flexDirection", "column");
107509
+ insertNode(_el$41, _el$42);
107510
+ insertNode(_el$41, _el$44);
107511
+ setProp(_el$41, "marginBottom", 1);
107512
+ setProp(_el$41, "flexDirection", "column");
107513
+ insertNode(_el$42, createTextNode(`JWT Token:`));
107514
+ insertNode(_el$44, _el$45);
107515
+ setProp(_el$44, "border", ["top", "bottom", "left", "right"]);
107516
+ setProp(_el$44, "paddingLeft", 1);
107517
+ setProp(_el$44, "paddingRight", 1);
107518
+ insert(_el$45, (() => {
107519
+ var _c$ = memo2(() => !!jwtToken());
107520
+ return () => _c$() ? "*".repeat(Math.min(jwtToken().length, 40)) : " ";
107521
+ })());
107522
+ insert(_el$40, createComponent2(Show, {
107523
+ get when() {
107524
+ return loading();
107525
+ },
107526
+ get children() {
107527
+ var _el$46 = createElement("text");
107528
+ insertNode(_el$46, createTextNode(`Saving token...`));
107529
+ effect((_$p) => setProp(_el$46, "fg", theme.colors.warning, _$p));
107530
+ return _el$46;
107531
+ }
107532
+ }), null);
107533
+ effect((_p$) => {
107534
+ var _v$0 = theme.colors.accent, _v$1 = theme.colors.accent, _v$10 = theme.colors.text;
107535
+ _v$0 !== _p$.e && (_p$.e = setProp(_el$42, "fg", _v$0, _p$.e));
107536
+ _v$1 !== _p$.t && (_p$.t = setProp(_el$44, "borderColor", _v$1, _p$.t));
107537
+ _v$10 !== _p$.a && (_p$.a = setProp(_el$45, "fg", _v$10, _p$.a));
107538
+ return _p$;
107539
+ }, {
107540
+ e: undefined,
107541
+ t: undefined,
107542
+ a: undefined
107543
+ });
107544
+ return _el$40;
107545
+ })(), (() => {
107546
+ var _el$48 = createElement("box"), _el$49 = createElement("text");
107547
+ insertNode(_el$48, _el$49);
107548
+ setProp(_el$48, "marginTop", 1);
107549
+ insertNode(_el$49, createTextNode(`Enter save | Esc back`));
107550
+ effect((_$p) => setProp(_el$49, "fg", theme.colors.textDim, _$p));
107551
+ return _el$48;
107552
+ })()];
107553
+ }
107554
+ }), null);
107555
+ insert(_el$, createComponent2(Show, {
107556
+ get when() {
107557
+ return view() === "apikey";
107558
+ },
107559
+ get children() {
107560
+ return [(() => {
107561
+ var _el$51 = createElement("box"), _el$52 = createElement("box"), _el$53 = createElement("text"), _el$55 = createElement("box"), _el$56 = createElement("text");
107562
+ insertNode(_el$51, _el$52);
107563
+ setProp(_el$51, "flexDirection", "column");
107564
+ insertNode(_el$52, _el$53);
107565
+ insertNode(_el$52, _el$55);
107566
+ setProp(_el$52, "marginBottom", 1);
107567
+ setProp(_el$52, "flexDirection", "column");
107568
+ insertNode(_el$53, createTextNode(`API Key:`));
107569
+ insertNode(_el$55, _el$56);
107570
+ setProp(_el$55, "border", ["top", "bottom", "left", "right"]);
107571
+ setProp(_el$55, "paddingLeft", 1);
107572
+ setProp(_el$55, "paddingRight", 1);
107573
+ insert(_el$56, (() => {
107574
+ var _c$2 = memo2(() => !!apiKey());
107575
+ return () => _c$2() ? "*".repeat(Math.min(apiKey().length, 40)) : " ";
107576
+ })());
107577
+ insert(_el$51, createComponent2(Show, {
107578
+ get when() {
107579
+ return loading();
107580
+ },
107581
+ get children() {
107582
+ var _el$57 = createElement("text");
107583
+ insertNode(_el$57, createTextNode(`Setting API key...`));
107584
+ effect((_$p) => setProp(_el$57, "fg", theme.colors.warning, _$p));
107585
+ return _el$57;
107586
+ }
107587
+ }), null);
107588
+ effect((_p$) => {
107589
+ var _v$11 = theme.colors.accent, _v$12 = theme.colors.accent, _v$13 = theme.colors.text;
107590
+ _v$11 !== _p$.e && (_p$.e = setProp(_el$53, "fg", _v$11, _p$.e));
107591
+ _v$12 !== _p$.t && (_p$.t = setProp(_el$55, "borderColor", _v$12, _p$.t));
107592
+ _v$13 !== _p$.a && (_p$.a = setProp(_el$56, "fg", _v$13, _p$.a));
107593
+ return _p$;
107594
+ }, {
107595
+ e: undefined,
107596
+ t: undefined,
107597
+ a: undefined
107598
+ });
107599
+ return _el$51;
107600
+ })(), (() => {
107601
+ var _el$59 = createElement("box"), _el$60 = createElement("text");
107602
+ insertNode(_el$59, _el$60);
107603
+ setProp(_el$59, "marginTop", 1);
107604
+ insertNode(_el$60, createTextNode(`Enter save | Esc back`));
107605
+ effect((_$p) => setProp(_el$60, "fg", theme.colors.textDim, _$p));
107606
+ return _el$59;
107607
+ })()];
107608
+ }
107609
+ }), null);
107610
+ effect((_p$) => {
107611
+ var _v$14 = theme.colors.accent, _v$15 = theme.colors.background, _v$16 = TextAttributes.BOLD, _v$17 = theme.colors.accent, _v$18 = TextAttributes.BOLD, _v$19 = theme.colors.textDim, _v$20 = getStatusColor();
107612
+ _v$14 !== _p$.e && (_p$.e = setProp(_el$, "borderColor", _v$14, _p$.e));
107613
+ _v$15 !== _p$.t && (_p$.t = setProp(_el$, "backgroundColor", _v$15, _p$.t));
107614
+ _v$16 !== _p$.a && (_p$.a = setProp(_el$3, "attributes", _v$16, _p$.a));
107615
+ _v$17 !== _p$.o && (_p$.o = setProp(_el$4, "fg", _v$17, _p$.o));
107616
+ _v$18 !== _p$.i && (_p$.i = setProp(_el$4, "attributes", _v$18, _p$.i));
107617
+ _v$19 !== _p$.n && (_p$.n = setProp(_el$7, "fg", _v$19, _p$.n));
107618
+ _v$20 !== _p$.s && (_p$.s = setProp(_el$9, "fg", _v$20, _p$.s));
107619
+ return _p$;
107620
+ }, {
107621
+ e: undefined,
107622
+ t: undefined,
107623
+ a: undefined,
107624
+ o: undefined,
107625
+ i: undefined,
107626
+ n: undefined,
107627
+ s: undefined
107628
+ });
107629
+ return _el$;
107630
+ })();
107631
+ }
107632
+
107633
+ // src/tui-solid/routes/session.tsx
105116
107634
  function Session(props) {
105117
107635
  const theme = useTheme();
105118
107636
  const app = useAppStore();
107637
+ onMount(() => {
107638
+ if (props.mcpServers && props.mcpServers.length > 0) {
107639
+ app.setMcpServers(props.mcpServers);
107640
+ }
107641
+ });
107642
+ const mcpServers = createMemo(() => app.mcpServers());
105119
107643
  const [selectedHelpTopic, setSelectedHelpTopic] = createSignal(null);
105120
107644
  const handleCommandSelect = (command) => {
105121
107645
  const lowerCommand = command.toLowerCase();
@@ -105147,6 +107671,10 @@ function Session(props) {
105147
107671
  app.transitionFromCommandMenu("help_menu");
105148
107672
  return;
105149
107673
  }
107674
+ if (lowerCommand === "brain" && !BRAIN_DISABLED) {
107675
+ app.transitionFromCommandMenu("brain_menu");
107676
+ return;
107677
+ }
105150
107678
  app.closeCommandMenu();
105151
107679
  props.onCommand(command);
105152
107680
  };
@@ -105207,6 +107735,18 @@ function Session(props) {
105207
107735
  setSelectedHelpTopic(null);
105208
107736
  app.setMode("idle");
105209
107737
  };
107738
+ const handleBrainMenuClose = () => {
107739
+ app.setMode("idle");
107740
+ };
107741
+ const handleBrainSetJwtToken = async (jwtToken) => {
107742
+ await props.onBrainSetJwtToken?.(jwtToken);
107743
+ };
107744
+ const handleBrainSetApiKey = async (apiKey) => {
107745
+ await props.onBrainSetApiKey?.(apiKey);
107746
+ };
107747
+ const handleBrainLogout = async () => {
107748
+ await props.onBrainLogout?.();
107749
+ };
105210
107750
  return (() => {
105211
107751
  var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("box");
105212
107752
  insertNode(_el$, _el$2);
@@ -105340,7 +107880,7 @@ function Session(props) {
105340
107880
  get children() {
105341
107881
  return createComponent2(MCPSelect, {
105342
107882
  get servers() {
105343
- return props.mcpServers ?? [];
107883
+ return mcpServers();
105344
107884
  },
105345
107885
  get onSelect() {
105346
107886
  return props.onMCPSelect;
@@ -105518,6 +108058,25 @@ function Session(props) {
105518
108058
  }
105519
108059
  });
105520
108060
  }
108061
+ }), createComponent2(Match, {
108062
+ get when() {
108063
+ return app.mode() === "brain_menu" && !BRAIN_DISABLED;
108064
+ },
108065
+ get children() {
108066
+ return createComponent2(CenteredModal, {
108067
+ get children() {
108068
+ return createComponent2(BrainMenu, {
108069
+ onSetJwtToken: handleBrainSetJwtToken,
108070
+ onSetApiKey: handleBrainSetApiKey,
108071
+ onLogout: handleBrainLogout,
108072
+ onClose: handleBrainMenuClose,
108073
+ get isActive() {
108074
+ return app.mode() === "brain_menu";
108075
+ }
108076
+ });
108077
+ }
108078
+ });
108079
+ }
105521
108080
  })];
105522
108081
  }
105523
108082
  }), null);
@@ -105587,8 +108146,12 @@ function AppContent(props) {
105587
108146
  if (props.cascadeEnabled !== undefined) {
105588
108147
  app.setCascadeEnabled(props.cascadeEnabled);
105589
108148
  }
105590
- if (props.sessionId) {
105591
- route.goToSession(props.sessionId);
108149
+ if (!route.isSession()) {
108150
+ const sessionId = props.sessionId ?? `session-${Date.now()}`;
108151
+ batch(() => {
108152
+ app.setSessionInfo(sessionId, app.provider(), app.model());
108153
+ route.goToSession(sessionId);
108154
+ });
105592
108155
  }
105593
108156
  if (props.availableModels && props.availableModels.length > 0) {
105594
108157
  app.setAvailableModels(props.availableModels);
@@ -105796,6 +108359,15 @@ function AppContent(props) {
105796
108359
  onCascadeToggle: handleCascadeToggle,
105797
108360
  onPermissionResponse: handlePermissionResponse,
105798
108361
  onLearningResponse: handleLearningResponse,
108362
+ get onBrainSetJwtToken() {
108363
+ return props.onBrainSetJwtToken;
108364
+ },
108365
+ get onBrainSetApiKey() {
108366
+ return props.onBrainSetApiKey;
108367
+ },
108368
+ get onBrainLogout() {
108369
+ return props.onBrainLogout;
108370
+ },
105799
108371
  get plan() {
105800
108372
  return props.plan;
105801
108373
  },
@@ -105890,8 +108462,8 @@ var showContextFiles = (contextFiles) => {
105890
108462
  ` + source_default.bold("Context Files:"));
105891
108463
  if (contextFiles.size > 0) {
105892
108464
  console.log(source_default.gray(" Pending (will be included in next message):"));
105893
- for (const [path15] of contextFiles) {
105894
- console.log(` - ${filePath(basename6(path15))}`);
108465
+ for (const [path16] of contextFiles) {
108466
+ console.log(` - ${filePath(basename6(path16))}`);
105895
108467
  }
105896
108468
  }
105897
108469
  if (files.length > 0) {
@@ -105911,10 +108483,10 @@ var removeFile = (filename, contextFiles) => {
105911
108483
  warningMessage("Please specify a file to remove");
105912
108484
  return;
105913
108485
  }
105914
- for (const [path15] of contextFiles) {
105915
- if (path15.includes(filename) || basename7(path15) === filename) {
105916
- contextFiles.delete(path15);
105917
- successMessage(`Removed: ${basename7(path15)}`);
108486
+ for (const [path16] of contextFiles) {
108487
+ if (path16.includes(filename) || basename7(path16) === filename) {
108488
+ contextFiles.delete(path16);
108489
+ successMessage(`Removed: ${basename7(path16)}`);
105918
108490
  return;
105919
108491
  }
105920
108492
  }
@@ -106228,8 +108800,8 @@ init_source();
106228
108800
 
106229
108801
  // src/services/agent-loader.ts
106230
108802
  var import_fast_glob5 = __toESM(require_out4(), 1);
106231
- import fs14 from "fs/promises";
106232
- import path15 from "path";
108803
+ import fs17 from "fs/promises";
108804
+ import path16 from "path";
106233
108805
  var AGENT_PATTERNS = [
106234
108806
  ".codetyper/agent/**/*.agent.md",
106235
108807
  ".codetyper/agents/**/*.agent.md",
@@ -106248,11 +108820,11 @@ var DEFAULT_AGENT = {
106248
108820
  };
106249
108821
  var cachedRegistry = null;
106250
108822
  var extractNameFromFile = (filePath2) => {
106251
- const basename8 = path15.basename(filePath2, ".agent.md");
108823
+ const basename8 = path16.basename(filePath2, ".agent.md");
106252
108824
  return basename8.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
106253
108825
  };
106254
108826
  var extractIdFromFile = (filePath2) => {
106255
- return path15.basename(filePath2, ".agent.md").toLowerCase();
108827
+ return path16.basename(filePath2, ".agent.md").toLowerCase();
106256
108828
  };
106257
108829
  var parseFrontmatter = (content) => {
106258
108830
  const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;
@@ -106302,7 +108874,7 @@ var parseFrontmatter = (content) => {
106302
108874
  };
106303
108875
  var parseAgentFile = async (filePath2) => {
106304
108876
  try {
106305
- const content = await fs14.readFile(filePath2, "utf-8");
108877
+ const content = await fs17.readFile(filePath2, "utf-8");
106306
108878
  const { data: frontmatter, body } = parseFrontmatter(content);
106307
108879
  const id = extractIdFromFile(filePath2);
106308
108880
  const name = frontmatter.name ?? extractNameFromFile(filePath2);
@@ -106497,7 +109069,6 @@ MCP Status
106497
109069
  };
106498
109070
 
106499
109071
  // src/commands/components/chat/mcp/handle-mcp.ts
106500
- await init_app();
106501
109072
  var handleMCP = async (args) => {
106502
109073
  const subcommand = args[0] || "status";
106503
109074
  const handlers = {
@@ -106852,9 +109423,9 @@ var sendMessage = async (content, state4) => {
106852
109423
  let userMessage = content;
106853
109424
  if (state4.contextFiles.size > 0) {
106854
109425
  const contextParts = [];
106855
- for (const [path16, fileContent] of state4.contextFiles) {
106856
- const ext = extname4(path16).slice(1) || "txt";
106857
- contextParts.push(`File: ${basename8(path16)}
109426
+ for (const [path17, fileContent] of state4.contextFiles) {
109427
+ const ext = extname4(path17).slice(1) || "txt";
109428
+ contextParts.push(`File: ${basename8(path17)}
106858
109429
  \`\`\`${ext}
106859
109430
  ${fileContent}
106860
109431
  \`\`\``);
@@ -107010,9 +109581,9 @@ var executePrintMode2 = async (prompt2, state4) => {
107010
109581
  let userMessage = processedPrompt;
107011
109582
  if (state4.contextFiles.size > 0) {
107012
109583
  const contextParts = [];
107013
- for (const [path16, fileContent] of state4.contextFiles) {
107014
- const ext = extname5(path16).slice(1) || "txt";
107015
- contextParts.push(`File: ${basename9(path16)}
109584
+ for (const [path17, fileContent] of state4.contextFiles) {
109585
+ const ext = extname5(path17).slice(1) || "txt";
109586
+ contextParts.push(`File: ${basename9(path17)}
107016
109587
  \`\`\`${ext}
107017
109588
  ${fileContent}
107018
109589
  \`\`\``);
@@ -107581,8 +110152,8 @@ var handlePlan = async (options2) => {
107581
110152
  ]
107582
110153
  };
107583
110154
  if (output) {
107584
- const fs15 = await import("fs/promises");
107585
- await fs15.writeFile(output, JSON.stringify(plan, null, 2));
110155
+ const fs18 = await import("fs/promises");
110156
+ await fs18.writeFile(output, JSON.stringify(plan, null, 2));
107586
110157
  successMessage(`Plan saved to ${filePath(output)}`);
107587
110158
  } else {
107588
110159
  hightLigthedJson(plan);
@@ -107607,8 +110178,8 @@ var handleValidate = async (options2) => {
107607
110178
  console.log();
107608
110179
  startSpinner("Validating plan...");
107609
110180
  try {
107610
- const fs15 = await import("fs/promises");
107611
- const planData = await fs15.readFile(planFile, "utf-8");
110181
+ const fs18 = await import("fs/promises");
110182
+ const planData = await fs18.readFile(planFile, "utf-8");
107612
110183
  const plan = JSON.parse(planData);
107613
110184
  await new Promise((resolve4) => setTimeout(resolve4, 1000));
107614
110185
  const config2 = await getConfig();
@@ -107889,14 +110460,89 @@ var onLearningDetected = async (candidate) => {
107889
110460
 
107890
110461
  // src/commands/components/execute/execute.tsx
107891
110462
  init_mcp();
110463
+ var parseArgs = (argsString) => {
110464
+ const trimmed = argsString.trim();
110465
+ if (!trimmed)
110466
+ return;
110467
+ const args = [];
110468
+ let current = "";
110469
+ let inQuote = null;
110470
+ for (let i2 = 0;i2 < trimmed.length; i2++) {
110471
+ const char = trimmed[i2];
110472
+ if (inQuote) {
110473
+ if (char === inQuote) {
110474
+ inQuote = null;
110475
+ } else {
110476
+ current += char;
110477
+ }
110478
+ } else if (char === '"' || char === "'") {
110479
+ inQuote = char;
110480
+ } else if (char === " " || char === "\t") {
110481
+ if (current) {
110482
+ args.push(current);
110483
+ current = "";
110484
+ }
110485
+ } else {
110486
+ current += char;
110487
+ }
110488
+ }
110489
+ if (current) {
110490
+ args.push(current);
110491
+ }
110492
+ return args.length > 0 ? args : undefined;
110493
+ };
107892
110494
  var defaultHandleMCPAdd = async (data) => {
107893
- const serverArgs = data.args.trim() ? data.args.trim().split(/\s+/) : undefined;
110495
+ const serverArgs = parseArgs(data.args);
107894
110496
  await addServer(data.name, {
107895
110497
  command: data.command,
107896
110498
  args: serverArgs,
107897
110499
  enabled: true
107898
110500
  }, data.isGlobal);
107899
- await connectServer(data.name);
110501
+ appStore.addMcpServer({
110502
+ id: data.name,
110503
+ name: data.name,
110504
+ status: "disconnected",
110505
+ description: data.command
110506
+ });
110507
+ try {
110508
+ await connectServer(data.name);
110509
+ appStore.updateMcpServerStatus(data.name, "connected");
110510
+ } catch {
110511
+ appStore.updateMcpServerStatus(data.name, "error");
110512
+ }
110513
+ };
110514
+ var defaultHandleBrainSetJwtToken = async (jwtToken) => {
110515
+ await setJwtToken(jwtToken);
110516
+ const connected = await connect();
110517
+ if (connected) {
110518
+ const state4 = getState2();
110519
+ appStore.setBrainStatus("connected");
110520
+ appStore.setBrainUser(state4.user);
110521
+ appStore.setBrainCounts(state4.knowledgeCount, state4.memoryCount);
110522
+ appStore.setBrainShowBanner(false);
110523
+ } else {
110524
+ throw new Error("Failed to connect with the provided JWT token.");
110525
+ }
110526
+ };
110527
+ var defaultHandleBrainSetApiKey = async (apiKey) => {
110528
+ await setApiKey(apiKey);
110529
+ const connected = await connect();
110530
+ if (connected) {
110531
+ const state4 = getState2();
110532
+ appStore.setBrainStatus("connected");
110533
+ appStore.setBrainUser(state4.user);
110534
+ appStore.setBrainCounts(state4.knowledgeCount, state4.memoryCount);
110535
+ appStore.setBrainShowBanner(false);
110536
+ } else {
110537
+ throw new Error("Failed to connect with the provided API key.");
110538
+ }
110539
+ };
110540
+ var defaultHandleBrainLogout = async () => {
110541
+ await logout3();
110542
+ appStore.setBrainStatus("disconnected");
110543
+ appStore.setBrainUser(null);
110544
+ appStore.setBrainCounts(0, 0);
110545
+ appStore.setBrainShowBanner(true);
107900
110546
  };
107901
110547
  var renderApp = async (props) => {
107902
110548
  const {
@@ -107928,6 +110574,9 @@ var renderApp = async (props) => {
107928
110574
  onMCPAdd: props.handleMCPAdd ?? defaultHandleMCPAdd,
107929
110575
  onPermissionResponse: props.handlePermissionResponse ?? (() => {}),
107930
110576
  onLearningResponse: props.handleLearningResponse ?? (() => {}),
110577
+ onBrainSetJwtToken: props.handleBrainSetJwtToken ?? defaultHandleBrainSetJwtToken,
110578
+ onBrainSetApiKey: props.handleBrainSetApiKey ?? defaultHandleBrainSetApiKey,
110579
+ onBrainLogout: props.handleBrainLogout ?? defaultHandleBrainLogout,
107931
110580
  plan: props.plan
107932
110581
  });
107933
110582
  props.handleExit();
@@ -107937,34 +110586,34 @@ var renderApp = async (props) => {
107937
110586
  init_terminal2();
107938
110587
 
107939
110588
  // src/services/project-setup-service.ts
107940
- import fs15 from "fs/promises";
107941
- import path16 from "path";
110589
+ import fs18 from "fs/promises";
110590
+ import path17 from "path";
107942
110591
  var CODETYPER_DIR = ".codetyper";
107943
110592
  var AGENTS_DIR = "agents";
107944
110593
  var GITIGNORE_ENTRY = ".codetyper/";
107945
110594
  var fileExists2 = async (filePath2) => {
107946
110595
  try {
107947
- await fs15.access(filePath2);
110596
+ await fs18.access(filePath2);
107948
110597
  return true;
107949
110598
  } catch {
107950
110599
  return false;
107951
110600
  }
107952
110601
  };
107953
110602
  var isGitRepository = async (workingDir3) => {
107954
- return fileExists2(path16.join(workingDir3, ".git"));
110603
+ return fileExists2(path17.join(workingDir3, ".git"));
107955
110604
  };
107956
110605
  var ensureDirectoryExists = async (dirPath) => {
107957
110606
  try {
107958
- await fs15.mkdir(dirPath, { recursive: true });
110607
+ await fs18.mkdir(dirPath, { recursive: true });
107959
110608
  } catch {}
107960
110609
  };
107961
110610
  var addToGitignore = async (workingDir3) => {
107962
- const gitignorePath = path16.join(workingDir3, ".gitignore");
110611
+ const gitignorePath = path17.join(workingDir3, ".gitignore");
107963
110612
  try {
107964
110613
  let content = "";
107965
110614
  const exists = await fileExists2(gitignorePath);
107966
110615
  if (exists) {
107967
- content = await fs15.readFile(gitignorePath, "utf-8");
110616
+ content = await fs18.readFile(gitignorePath, "utf-8");
107968
110617
  const lines = content.split(`
107969
110618
  `).map((line2) => line2.trim());
107970
110619
  if (lines.includes(GITIGNORE_ENTRY) || lines.includes(CODETYPER_DIR)) {
@@ -107976,7 +110625,7 @@ var addToGitignore = async (workingDir3) => {
107976
110625
  ` : `${content}
107977
110626
  ${GITIGNORE_ENTRY}
107978
110627
  `;
107979
- await fs15.writeFile(gitignorePath, newContent, "utf-8");
110628
+ await fs18.writeFile(gitignorePath, newContent, "utf-8");
107980
110629
  return true;
107981
110630
  } catch {
107982
110631
  return false;
@@ -108217,17 +110866,17 @@ ${agent.prompt}
108217
110866
  `;
108218
110867
  };
108219
110868
  var createDefaultAgents = async (workingDir3) => {
108220
- const agentsDir = path16.join(workingDir3, CODETYPER_DIR, AGENTS_DIR);
110869
+ const agentsDir = path17.join(workingDir3, CODETYPER_DIR, AGENTS_DIR);
108221
110870
  const created = [];
108222
110871
  await ensureDirectoryExists(agentsDir);
108223
110872
  for (const agent of DEFAULT_AGENTS) {
108224
- const filePath2 = path16.join(agentsDir, `${agent.id}.agent.md`);
110873
+ const filePath2 = path17.join(agentsDir, `${agent.id}.agent.md`);
108225
110874
  if (await fileExists2(filePath2)) {
108226
110875
  continue;
108227
110876
  }
108228
110877
  try {
108229
110878
  const content = generateAgentFile(agent);
108230
- await fs15.writeFile(filePath2, content, "utf-8");
110879
+ await fs18.writeFile(filePath2, content, "utf-8");
108231
110880
  created.push(agent.id);
108232
110881
  } catch {}
108233
110882
  }
@@ -108252,12 +110901,12 @@ var setupProject = async (workingDir3) => {
108252
110901
  };
108253
110902
  var getSetupStatus = async (workingDir3) => {
108254
110903
  const hasGit = await isGitRepository(workingDir3);
108255
- const hasCodetyperDir = await fileExists2(path16.join(workingDir3, CODETYPER_DIR));
110904
+ const hasCodetyperDir = await fileExists2(path17.join(workingDir3, CODETYPER_DIR));
108256
110905
  let agentCount = 0;
108257
110906
  if (hasCodetyperDir) {
108258
- const agentsDir = path16.join(workingDir3, CODETYPER_DIR, AGENTS_DIR);
110907
+ const agentsDir = path17.join(workingDir3, CODETYPER_DIR, AGENTS_DIR);
108259
110908
  if (await fileExists2(agentsDir)) {
108260
- const files = await fs15.readdir(agentsDir);
110909
+ const files = await fs18.readdir(agentsDir);
108261
110910
  agentCount = files.filter((f) => f.endsWith(".agent.md")).length;
108262
110911
  }
108263
110912
  }
@@ -108573,13 +111222,13 @@ var approvePlan = () => {
108573
111222
 
108574
111223
  // src/utils/ensure-directories.ts
108575
111224
  init_paths();
108576
- import { mkdir as mkdir3 } from "fs/promises";
111225
+ import { mkdir as mkdir4 } from "fs/promises";
108577
111226
  var ensureXdgDirectories = async () => {
108578
- await mkdir3(DIRS.config, { recursive: true });
108579
- await mkdir3(DIRS.data, { recursive: true });
108580
- await mkdir3(DIRS.cache, { recursive: true });
108581
- await mkdir3(DIRS.state, { recursive: true });
108582
- await mkdir3(DIRS.sessions, { recursive: true });
111227
+ await mkdir4(DIRS.config, { recursive: true });
111228
+ await mkdir4(DIRS.data, { recursive: true });
111229
+ await mkdir4(DIRS.cache, { recursive: true });
111230
+ await mkdir4(DIRS.state, { recursive: true });
111231
+ await mkdir4(DIRS.sessions, { recursive: true });
108583
111232
  };
108584
111233
 
108585
111234
  // src/index.ts
@@ -108945,4 +111594,4 @@ ${plan.steps.map((s) => `${s.id}. ${s.description}`).join(`
108945
111594
  });
108946
111595
  program2.parse(process.argv);
108947
111596
 
108948
- //# debugId=A668908B12C6E01864756E2164756E21
111597
+ //# debugId=C7789F3EA83B0C0864756E2164756E21