codetyper-cli 0.2.2 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -3
- package/dist/index.js +3005 -364
- package/package.json +1 -1
- package/src/version.json +1 -1
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
|
|
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: "",
|
|
@@ -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,
|
|
@@ -66085,7 +66188,15 @@ var init_app = __esm(async () => {
|
|
|
66085
66188
|
exitPending: false,
|
|
66086
66189
|
isCompacting: false,
|
|
66087
66190
|
streamingLog: createInitialStreamingState(),
|
|
66088
|
-
suggestions: createInitialSuggestionState()
|
|
66191
|
+
suggestions: createInitialSuggestionState(),
|
|
66192
|
+
mcpServers: [],
|
|
66193
|
+
brain: {
|
|
66194
|
+
status: "disconnected",
|
|
66195
|
+
user: null,
|
|
66196
|
+
knowledgeCount: 0,
|
|
66197
|
+
memoryCount: 0,
|
|
66198
|
+
showBanner: true
|
|
66199
|
+
}
|
|
66089
66200
|
};
|
|
66090
66201
|
appStore = {
|
|
66091
66202
|
getState: () => {
|
|
@@ -66115,7 +66226,9 @@ var init_app = __esm(async () => {
|
|
|
66115
66226
|
exitPending: storeRef.exitPending(),
|
|
66116
66227
|
isCompacting: storeRef.isCompacting(),
|
|
66117
66228
|
streamingLog: storeRef.streamingLog(),
|
|
66118
|
-
suggestions: storeRef.suggestions()
|
|
66229
|
+
suggestions: storeRef.suggestions(),
|
|
66230
|
+
mcpServers: storeRef.mcpServers(),
|
|
66231
|
+
brain: storeRef.brain()
|
|
66119
66232
|
};
|
|
66120
66233
|
},
|
|
66121
66234
|
addLog: (entry) => {
|
|
@@ -66223,6 +66336,11 @@ var init_app = __esm(async () => {
|
|
|
66223
66336
|
return;
|
|
66224
66337
|
storeRef.resetSessionStats();
|
|
66225
66338
|
},
|
|
66339
|
+
setContextMaxTokens: (maxTokens) => {
|
|
66340
|
+
if (!storeRef)
|
|
66341
|
+
return;
|
|
66342
|
+
storeRef.setContextMaxTokens(maxTokens);
|
|
66343
|
+
},
|
|
66226
66344
|
toggleTodos: () => {
|
|
66227
66345
|
if (!storeRef)
|
|
66228
66346
|
return;
|
|
@@ -66292,6 +66410,46 @@ var init_app = __esm(async () => {
|
|
|
66292
66410
|
if (!storeRef)
|
|
66293
66411
|
return;
|
|
66294
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);
|
|
66295
66453
|
}
|
|
66296
66454
|
};
|
|
66297
66455
|
});
|
|
@@ -66380,76 +66538,74 @@ function DebugLogPanel() {
|
|
|
66380
66538
|
return msg.substring(0, maxLen - 3) + "...";
|
|
66381
66539
|
};
|
|
66382
66540
|
return (() => {
|
|
66383
|
-
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$
|
|
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");
|
|
66384
66542
|
insertNode(_el$, _el$2);
|
|
66543
|
+
insertNode(_el$, _el$6);
|
|
66385
66544
|
insertNode(_el$, _el$8);
|
|
66386
|
-
insertNode(_el$, _el$0);
|
|
66387
66545
|
setProp(_el$, "flexDirection", "column");
|
|
66388
66546
|
setProp(_el$, "width", "20%");
|
|
66389
66547
|
setProp(_el$, "border", ["top", "bottom", "left", "right"]);
|
|
66390
66548
|
insertNode(_el$2, _el$3);
|
|
66391
|
-
insertNode(_el$2, _el$5);
|
|
66392
66549
|
setProp(_el$2, "paddingLeft", 1);
|
|
66393
66550
|
setProp(_el$2, "paddingRight", 1);
|
|
66394
66551
|
setProp(_el$2, "border", ["bottom"]);
|
|
66395
|
-
|
|
66396
|
-
insertNode(_el$
|
|
66397
|
-
insertNode(_el$
|
|
66398
|
-
insert(_el$
|
|
66399
|
-
insertNode(_el$
|
|
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);
|
|
66400
66557
|
var _ref$ = scrollboxRef;
|
|
66401
|
-
typeof _ref$ === "function" ? use(_ref$, _el$
|
|
66402
|
-
setProp(_el$
|
|
66403
|
-
setProp(_el$
|
|
66404
|
-
setProp(_el$
|
|
66405
|
-
setProp(_el$
|
|
66406
|
-
setProp(_el$
|
|
66407
|
-
insert(_el$
|
|
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, {
|
|
66408
66565
|
get each() {
|
|
66409
66566
|
return entries2();
|
|
66410
66567
|
},
|
|
66411
66568
|
children: (entry) => (() => {
|
|
66412
|
-
var _el$
|
|
66413
|
-
insertNode(_el$
|
|
66414
|
-
insertNode(_el$
|
|
66415
|
-
insertNode(_el$
|
|
66416
|
-
setProp(_el$
|
|
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);
|
|
66417
66576
|
insertNode(_el$12, _el$13);
|
|
66418
|
-
|
|
66419
|
-
|
|
66420
|
-
|
|
66421
|
-
insert(_el$
|
|
66422
|
-
setProp(_el$18, "wrapMode", "word");
|
|
66423
|
-
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));
|
|
66424
66581
|
effect((_p$) => {
|
|
66425
|
-
var _v$
|
|
66426
|
-
_v$
|
|
66427
|
-
_v$
|
|
66428
|
-
_v$
|
|
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));
|
|
66429
66586
|
return _p$;
|
|
66430
66587
|
}, {
|
|
66431
66588
|
e: undefined,
|
|
66432
66589
|
t: undefined,
|
|
66433
66590
|
a: undefined
|
|
66434
66591
|
});
|
|
66435
|
-
return _el$
|
|
66592
|
+
return _el$1;
|
|
66436
66593
|
})()
|
|
66437
66594
|
}));
|
|
66438
|
-
insertNode(_el$
|
|
66439
|
-
setProp(_el$
|
|
66440
|
-
setProp(_el$
|
|
66441
|
-
insertNode(_el$
|
|
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`));
|
|
66442
66599
|
effect((_p$) => {
|
|
66443
|
-
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 =
|
|
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;
|
|
66444
66601
|
_v$ !== _p$.e && (_p$.e = setProp(_el$, "borderColor", _v$, _p$.e));
|
|
66445
66602
|
_v$2 !== _p$.t && (_p$.t = setProp(_el$, "backgroundColor", _v$2, _p$.t));
|
|
66446
66603
|
_v$3 !== _p$.a && (_p$.a = setProp(_el$2, "borderColor", _v$3, _p$.a));
|
|
66447
66604
|
_v$4 !== _p$.o && (_p$.o = setProp(_el$3, "fg", _v$4, _p$.o));
|
|
66448
66605
|
_v$5 !== _p$.i && (_p$.i = setProp(_el$3, "attributes", _v$5, _p$.i));
|
|
66449
|
-
_v$6 !== _p$.n && (_p$.n = setProp(_el$
|
|
66450
|
-
_v$7 !== _p$.s && (_p$.s = setProp(_el$8, "
|
|
66451
|
-
_v$8 !== _p$.h && (_p$.h = setProp(_el$
|
|
66452
|
-
_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));
|
|
66453
66609
|
return _p$;
|
|
66454
66610
|
}, {
|
|
66455
66611
|
e: undefined,
|
|
@@ -66459,8 +66615,7 @@ function DebugLogPanel() {
|
|
|
66459
66615
|
i: undefined,
|
|
66460
66616
|
n: undefined,
|
|
66461
66617
|
s: undefined,
|
|
66462
|
-
h: undefined
|
|
66463
|
-
r: undefined
|
|
66618
|
+
h: undefined
|
|
66464
66619
|
});
|
|
66465
66620
|
return _el$;
|
|
66466
66621
|
})();
|
|
@@ -66618,6 +66773,7 @@ var formatMessages = (messages) => messages.map((msg) => {
|
|
|
66618
66773
|
if (delta?.tool_calls) {
|
|
66619
66774
|
for (const tc of delta.tool_calls) {
|
|
66620
66775
|
addDebugLog("api", `Tool call chunk: ${JSON.stringify(tc)}`);
|
|
66776
|
+
console.log("Debug: Tool call chunk received:", JSON.stringify(tc));
|
|
66621
66777
|
onChunk({ type: "tool_call", toolCall: tc });
|
|
66622
66778
|
}
|
|
66623
66779
|
}
|
|
@@ -66935,10 +67091,22 @@ var init_models2 = __esm(() => {
|
|
|
66935
67091
|
});
|
|
66936
67092
|
|
|
66937
67093
|
// src/providers/ollama/chat.ts
|
|
66938
|
-
var formatMessages2 = (messages) => messages.map((msg) =>
|
|
66939
|
-
|
|
66940
|
-
|
|
66941
|
-
|
|
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) => {
|
|
66942
67110
|
if (!tools || tools.length === 0)
|
|
66943
67111
|
return;
|
|
66944
67112
|
return tools.map((tool) => ({
|
|
@@ -67235,7 +67403,7 @@ Available models:`,
|
|
|
67235
67403
|
});
|
|
67236
67404
|
|
|
67237
67405
|
// src/providers/credentials.ts
|
|
67238
|
-
import { readFile as readFile2, writeFile, mkdir } from "fs/promises";
|
|
67406
|
+
import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
67239
67407
|
import { existsSync as existsSync3 } from "fs";
|
|
67240
67408
|
var loadCredentials = async () => {
|
|
67241
67409
|
if (!existsSync3(FILES.credentials)) {
|
|
@@ -67248,8 +67416,8 @@ var loadCredentials = async () => {
|
|
|
67248
67416
|
return {};
|
|
67249
67417
|
}
|
|
67250
67418
|
}, saveCredentials = async (credentials) => {
|
|
67251
|
-
await
|
|
67252
|
-
await
|
|
67419
|
+
await mkdir2(DIRS.data, { recursive: true });
|
|
67420
|
+
await writeFile2(FILES.credentials, JSON.stringify(credentials, null, 2), {
|
|
67253
67421
|
mode: CREDENTIALS_FILE_MODE
|
|
67254
67422
|
});
|
|
67255
67423
|
};
|
|
@@ -73304,12 +73472,11 @@ class MCPClient {
|
|
|
73304
73472
|
var init_client = () => {};
|
|
73305
73473
|
|
|
73306
73474
|
// src/services/mcp/manager.ts
|
|
73307
|
-
import
|
|
73308
|
-
import
|
|
73309
|
-
import os6 from "os";
|
|
73475
|
+
import fs15 from "fs/promises";
|
|
73476
|
+
import path13 from "path";
|
|
73310
73477
|
var CONFIG_LOCATIONS, state3, loadConfigFile = async (filePath2) => {
|
|
73311
73478
|
try {
|
|
73312
|
-
const content = await
|
|
73479
|
+
const content = await fs15.readFile(filePath2, "utf-8");
|
|
73313
73480
|
return JSON.parse(content);
|
|
73314
73481
|
} catch {
|
|
73315
73482
|
return null;
|
|
@@ -73326,9 +73493,9 @@ var CONFIG_LOCATIONS, state3, loadConfigFile = async (filePath2) => {
|
|
|
73326
73493
|
return merged;
|
|
73327
73494
|
}, saveMCPConfig = async (config2, global3 = false) => {
|
|
73328
73495
|
const filePath2 = global3 ? CONFIG_LOCATIONS.global : CONFIG_LOCATIONS.local;
|
|
73329
|
-
const dir =
|
|
73330
|
-
await
|
|
73331
|
-
await
|
|
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");
|
|
73332
73499
|
}, initializeMCP = async () => {
|
|
73333
73500
|
if (state3.initialized)
|
|
73334
73501
|
return;
|
|
@@ -73440,9 +73607,10 @@ var CONFIG_LOCATIONS, state3, loadConfigFile = async (filePath2) => {
|
|
|
73440
73607
|
};
|
|
73441
73608
|
var init_manager = __esm(() => {
|
|
73442
73609
|
init_client();
|
|
73610
|
+
init_paths();
|
|
73443
73611
|
CONFIG_LOCATIONS = {
|
|
73444
|
-
global:
|
|
73445
|
-
local:
|
|
73612
|
+
global: path13.join(DIRS.config, "mcp.json"),
|
|
73613
|
+
local: path13.join(process.cwd(), LOCAL_CONFIG_DIR, "mcp.json")
|
|
73446
73614
|
};
|
|
73447
73615
|
state3 = {
|
|
73448
73616
|
clients: new Map,
|
|
@@ -73586,12 +73754,12 @@ var createEmptyIndex = (model) => ({
|
|
|
73586
73754
|
});
|
|
73587
73755
|
|
|
73588
73756
|
// src/services/learning/vector-store.ts
|
|
73589
|
-
import * as
|
|
73590
|
-
import * as
|
|
73591
|
-
var getIndexPath = (baseDir) =>
|
|
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) => {
|
|
73592
73760
|
const indexPath = getIndexPath(baseDir);
|
|
73593
73761
|
try {
|
|
73594
|
-
const data = await
|
|
73762
|
+
const data = await fs16.readFile(indexPath, "utf-8");
|
|
73595
73763
|
const index = JSON.parse(data);
|
|
73596
73764
|
if (index.version !== EMBEDDING_STORAGE.VERSION || index.model !== model) {
|
|
73597
73765
|
return createEmptyIndex(model);
|
|
@@ -73602,8 +73770,8 @@ var getIndexPath = (baseDir) => path13.join(baseDir, EMBEDDING_STORAGE.INDEX_FIL
|
|
|
73602
73770
|
}
|
|
73603
73771
|
}, saveIndex = async (baseDir, index) => {
|
|
73604
73772
|
const indexPath = getIndexPath(baseDir);
|
|
73605
|
-
await
|
|
73606
|
-
await
|
|
73773
|
+
await fs16.mkdir(baseDir, { recursive: true });
|
|
73774
|
+
await fs16.writeFile(indexPath, JSON.stringify(index, null, 2), "utf-8");
|
|
73607
73775
|
}, upsertEmbedding = (index, id, embedding) => {
|
|
73608
73776
|
const stored = {
|
|
73609
73777
|
id,
|
|
@@ -73625,8 +73793,8 @@ var init_vector_store = __esm(() => {
|
|
|
73625
73793
|
});
|
|
73626
73794
|
|
|
73627
73795
|
// src/services/learning/semantic-search.ts
|
|
73628
|
-
import * as
|
|
73629
|
-
var globalIndex = null, localIndex = null, getGlobalIndexDir = () =>
|
|
73796
|
+
import * as path15 from "path";
|
|
73797
|
+
var globalIndex = null, localIndex = null, getGlobalIndexDir = () => path15.join(getGlobalConfigDir(), "learnings"), getLocalIndexDir = () => path15.join(getLocalConfigDir(), "learnings"), getGlobalIndex = async () => {
|
|
73630
73798
|
if (!isEmbeddingAvailable()) {
|
|
73631
73799
|
return null;
|
|
73632
73800
|
}
|
|
@@ -73692,7 +73860,7 @@ var init_semantic_search = __esm(() => {
|
|
|
73692
73860
|
var version_default;
|
|
73693
73861
|
var init_version = __esm(() => {
|
|
73694
73862
|
version_default = {
|
|
73695
|
-
version: "0.2.
|
|
73863
|
+
version: "0.2.4"
|
|
73696
73864
|
};
|
|
73697
73865
|
});
|
|
73698
73866
|
|
|
@@ -74022,9 +74190,9 @@ var init_mcp_registry = __esm(() => {
|
|
|
74022
74190
|
|
|
74023
74191
|
// src/services/mcp/registry.ts
|
|
74024
74192
|
import { homedir as homedir4 } from "os";
|
|
74025
|
-
import { join as
|
|
74193
|
+
import { join as join14 } from "path";
|
|
74026
74194
|
var registryCache = null, getCacheFilePath = () => {
|
|
74027
|
-
return
|
|
74195
|
+
return join14(homedir4(), ".codetyper", MCP_REGISTRY_CACHE.FILE_NAME);
|
|
74028
74196
|
}, loadCache = async () => {
|
|
74029
74197
|
try {
|
|
74030
74198
|
const cachePath = getCacheFilePath();
|
|
@@ -74181,7 +74349,7 @@ var registryCache = null, getCacheFilePath = () => {
|
|
|
74181
74349
|
const instances = getServerInstances();
|
|
74182
74350
|
return instances.some((instance) => instance.config.name === serverId || instance.config.name.toLowerCase() === serverId.toLowerCase());
|
|
74183
74351
|
}, installServer = async (server, options2 = {}) => {
|
|
74184
|
-
const { global: global3 = false, connect = true, customArgs } = options2;
|
|
74352
|
+
const { global: global3 = false, connect: connect2 = true, customArgs } = options2;
|
|
74185
74353
|
if (isServerInstalled(server.id)) {
|
|
74186
74354
|
return {
|
|
74187
74355
|
success: false,
|
|
@@ -74199,7 +74367,7 @@ var registryCache = null, getCacheFilePath = () => {
|
|
|
74199
74367
|
enabled: true
|
|
74200
74368
|
}, global3);
|
|
74201
74369
|
let connected = false;
|
|
74202
|
-
if (
|
|
74370
|
+
if (connect2) {
|
|
74203
74371
|
try {
|
|
74204
74372
|
await connectServer(server.id);
|
|
74205
74373
|
connected = true;
|
|
@@ -74858,15 +75026,27 @@ var PROVIDER_ENV_VARS = {
|
|
|
74858
75026
|
ollama: "OLLAMA_HOST"
|
|
74859
75027
|
};
|
|
74860
75028
|
var configState = getDefaults();
|
|
75029
|
+
var configLoaded = false;
|
|
75030
|
+
var configLoadPromise = null;
|
|
74861
75031
|
var loadConfig = async () => {
|
|
74862
|
-
|
|
74863
|
-
|
|
74864
|
-
|
|
74865
|
-
|
|
74866
|
-
|
|
74867
|
-
} catch {
|
|
74868
|
-
configState = getDefaults();
|
|
75032
|
+
if (configLoaded) {
|
|
75033
|
+
return;
|
|
75034
|
+
}
|
|
75035
|
+
if (configLoadPromise) {
|
|
75036
|
+
return configLoadPromise;
|
|
74869
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;
|
|
74870
75050
|
};
|
|
74871
75051
|
var saveConfig = async () => {
|
|
74872
75052
|
try {
|
|
@@ -76462,7 +76642,7 @@ Read-only tools only:
|
|
|
76462
76642
|
|
|
76463
76643
|
- You are in READ-ONLY mode - you cannot modify files
|
|
76464
76644
|
- Always search before answering questions about the codebase
|
|
76465
|
-
- If asked to make changes, explain that you're in Ask mode and suggest switching to Agent mode (Ctrl+
|
|
76645
|
+
- If asked to make changes, explain that you're in Ask mode and suggest switching to Agent mode (Ctrl+M)
|
|
76466
76646
|
- For general programming questions, you can answer without searching`;
|
|
76467
76647
|
var buildAskPrompt = (context) => {
|
|
76468
76648
|
const envSection = `
|
|
@@ -79066,15 +79246,36 @@ var MODE_PROMPT_BUILDERS = {
|
|
|
79066
79246
|
prContext: ctx.prContext
|
|
79067
79247
|
})
|
|
79068
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
|
+
};
|
|
79069
79271
|
var getGitContext = async () => {
|
|
79070
79272
|
try {
|
|
79071
|
-
const
|
|
79072
|
-
|
|
79073
|
-
|
|
79074
|
-
|
|
79075
|
-
|
|
79076
|
-
|
|
79077
|
-
`).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
|
+
]);
|
|
79078
79279
|
return { isGitRepo: true, branch, status: status2, recentCommits: commits };
|
|
79079
79280
|
} catch {
|
|
79080
79281
|
return { isGitRepo: false };
|
|
@@ -79484,6 +79685,266 @@ var initSuggestionService = (cwd) => {
|
|
|
79484
79685
|
clearSuggestions();
|
|
79485
79686
|
};
|
|
79486
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
|
+
|
|
79487
79948
|
// src/services/chat-tui/files.ts
|
|
79488
79949
|
var import_fast_glob2 = __toESM(require_out4(), 1);
|
|
79489
79950
|
import { readFile as readFile5, stat as stat2 } from "fs/promises";
|
|
@@ -79543,7 +80004,7 @@ var AUTH_MESSAGES = {
|
|
|
79543
80004
|
2. Enter code: ${code}
|
|
79544
80005
|
|
|
79545
80006
|
Waiting for authentication...`,
|
|
79546
|
-
LOGGED_IN_AS: (
|
|
80007
|
+
LOGGED_IN_AS: (login2, name) => `Logged in as: ${login2}${name ? ` (${name})` : ""}`
|
|
79547
80008
|
};
|
|
79548
80009
|
var MODEL_MESSAGES = {
|
|
79549
80010
|
MODEL_AUTO: "Model set to auto - the provider will choose the best model.",
|
|
@@ -79772,6 +80233,30 @@ var initializeTheme = async () => {
|
|
|
79772
80233
|
themeActions.setTheme(savedTheme);
|
|
79773
80234
|
}
|
|
79774
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
|
+
};
|
|
79775
80260
|
var rebuildSystemPromptForMode = async (state2, newMode, appendPrompt) => {
|
|
79776
80261
|
if (state2.currentMode === newMode) {
|
|
79777
80262
|
return;
|
|
@@ -79787,16 +80272,21 @@ var rebuildSystemPromptForMode = async (state2, newMode, appendPrompt) => {
|
|
|
79787
80272
|
var initializeChatService = async (options2) => {
|
|
79788
80273
|
const initialMode = appStore.getState().interactionMode;
|
|
79789
80274
|
const state2 = await createInitialState4(options2, initialMode);
|
|
79790
|
-
await
|
|
79791
|
-
|
|
79792
|
-
|
|
80275
|
+
await Promise.all([
|
|
80276
|
+
validateProvider(state2),
|
|
80277
|
+
buildSystemPrompt(state2, options2),
|
|
80278
|
+
initializeTheme()
|
|
80279
|
+
]);
|
|
79793
80280
|
const session = await initializeSession(state2, options2);
|
|
79794
80281
|
if (state2.messages.length === 0) {
|
|
79795
80282
|
state2.messages.push({ role: "system", content: state2.systemPrompt });
|
|
79796
80283
|
}
|
|
79797
|
-
await
|
|
79798
|
-
|
|
80284
|
+
await Promise.all([
|
|
80285
|
+
addInitialContextFiles(state2, options2.files),
|
|
80286
|
+
initializePermissions()
|
|
80287
|
+
]);
|
|
79799
80288
|
initSuggestionService(process.cwd());
|
|
80289
|
+
initializeBrain().catch(() => {});
|
|
79800
80290
|
return { state: state2, session };
|
|
79801
80291
|
};
|
|
79802
80292
|
// node_modules/uuid/dist-node/stringify.js
|
|
@@ -93666,7 +94156,7 @@ var processLines = (lines, offset, limit) => {
|
|
|
93666
94156
|
};
|
|
93667
94157
|
};
|
|
93668
94158
|
// src/tools/read/execute.ts
|
|
93669
|
-
import
|
|
94159
|
+
import fs7 from "fs/promises";
|
|
93670
94160
|
import path7 from "path";
|
|
93671
94161
|
var createDeniedResult2 = (filePath2) => ({
|
|
93672
94162
|
success: false,
|
|
@@ -93711,8 +94201,8 @@ var checkPermission2 = async (fullPath, autoApprove) => {
|
|
|
93711
94201
|
const { allowed } = await promptFilePermission("Read", fullPath);
|
|
93712
94202
|
return allowed;
|
|
93713
94203
|
};
|
|
93714
|
-
var readDirectory = async (fullPath) =>
|
|
93715
|
-
var readFileContent = async (fullPath) =>
|
|
94204
|
+
var readDirectory = async (fullPath) => fs7.readdir(fullPath);
|
|
94205
|
+
var readFileContent = async (fullPath) => fs7.readFile(fullPath, "utf-8");
|
|
93716
94206
|
var executeRead = async (args, ctx) => {
|
|
93717
94207
|
const { filePath: filePath2, offset = 0, limit = READ_DEFAULTS.MAX_LINES } = args;
|
|
93718
94208
|
const fullPath = resolvePath(filePath2, ctx.workingDir);
|
|
@@ -93724,7 +94214,7 @@ var executeRead = async (args, ctx) => {
|
|
|
93724
94214
|
status: "running"
|
|
93725
94215
|
});
|
|
93726
94216
|
try {
|
|
93727
|
-
const stat3 = await
|
|
94217
|
+
const stat3 = await fs7.stat(fullPath);
|
|
93728
94218
|
if (stat3.isDirectory()) {
|
|
93729
94219
|
const files = await readDirectory(fullPath);
|
|
93730
94220
|
return createDirectoryResult(filePath2, files);
|
|
@@ -93751,7 +94241,7 @@ var writeParams = exports_external.object({
|
|
|
93751
94241
|
content: exports_external.string().describe("The content to write to the file")
|
|
93752
94242
|
});
|
|
93753
94243
|
// src/tools/write/execute.ts
|
|
93754
|
-
import
|
|
94244
|
+
import fs8 from "fs/promises";
|
|
93755
94245
|
import path8 from "path";
|
|
93756
94246
|
|
|
93757
94247
|
// src/constants/write.ts
|
|
@@ -94090,7 +94580,7 @@ var resolvePaths = (filePath2, workingDir3) => {
|
|
|
94090
94580
|
};
|
|
94091
94581
|
var readExistingContent = async (fullPath) => {
|
|
94092
94582
|
try {
|
|
94093
|
-
const content = await
|
|
94583
|
+
const content = await fs8.readFile(fullPath, "utf-8");
|
|
94094
94584
|
return { exists: true, content };
|
|
94095
94585
|
} catch {
|
|
94096
94586
|
return { exists: false, content: "" };
|
|
@@ -94106,10 +94596,10 @@ var checkPermission3 = async (fullPath, relativePath, exists, autoApprove) => {
|
|
|
94106
94596
|
return allowed;
|
|
94107
94597
|
};
|
|
94108
94598
|
var ensureDirectory = async (fullPath) => {
|
|
94109
|
-
await
|
|
94599
|
+
await fs8.mkdir(path8.dirname(fullPath), { recursive: true });
|
|
94110
94600
|
};
|
|
94111
94601
|
var writeContent = async (fullPath, content) => {
|
|
94112
|
-
await
|
|
94602
|
+
await fs8.writeFile(fullPath, content, "utf-8");
|
|
94113
94603
|
};
|
|
94114
94604
|
var executeWrite = async (args, ctx) => {
|
|
94115
94605
|
const { filePath: filePath2, content } = args;
|
|
@@ -94193,7 +94683,7 @@ var validateUniqueness = (content, oldString, replaceAll, relativePath) => {
|
|
|
94193
94683
|
};
|
|
94194
94684
|
var countOccurrences = (content, search) => content.split(search).length - 1;
|
|
94195
94685
|
// src/tools/edit/execute.ts
|
|
94196
|
-
import
|
|
94686
|
+
import fs9 from "fs/promises";
|
|
94197
94687
|
import path9 from "path";
|
|
94198
94688
|
var createDeniedResult4 = (relativePath) => ({
|
|
94199
94689
|
success: false,
|
|
@@ -94235,7 +94725,7 @@ var executeEdit = async (args, ctx) => {
|
|
|
94235
94725
|
const { filePath: filePath2, oldString, newString, replaceAll = false } = args;
|
|
94236
94726
|
const { fullPath, relativePath } = resolvePath2(filePath2, ctx.workingDir);
|
|
94237
94727
|
try {
|
|
94238
|
-
const content = await
|
|
94728
|
+
const content = await fs9.readFile(fullPath, "utf-8");
|
|
94239
94729
|
const existsError = validateTextExists(content, oldString, relativePath);
|
|
94240
94730
|
if (existsError)
|
|
94241
94731
|
return existsError;
|
|
@@ -94252,7 +94742,7 @@ var executeEdit = async (args, ctx) => {
|
|
|
94252
94742
|
const newContent = applyEdit(content, oldString, newString, replaceAll);
|
|
94253
94743
|
const diff = generateDiff(content, newContent);
|
|
94254
94744
|
const diffOutput = formatDiff(diff, relativePath);
|
|
94255
|
-
await
|
|
94745
|
+
await fs9.writeFile(fullPath, newContent, "utf-8");
|
|
94256
94746
|
const replacements2 = replaceAll ? countOccurrences(content, oldString) : 1;
|
|
94257
94747
|
return createSuccessResult2(relativePath, fullPath, diffOutput, replacements2, diff.additions, diff.deletions);
|
|
94258
94748
|
} catch (error49) {
|
|
@@ -94818,50 +95308,6 @@ ${formattedResults}`,
|
|
|
94818
95308
|
}
|
|
94819
95309
|
};
|
|
94820
95310
|
};
|
|
94821
|
-
var parseSearchResults = (html, maxResults) => {
|
|
94822
|
-
const results = [];
|
|
94823
|
-
const resultPattern = /<a[^>]+class="result-link"[^>]*href="([^"]+)"[^>]*>([^<]+)<\/a>[\s\S]*?<td[^>]*class="result-snippet"[^>]*>([^<]+)/gi;
|
|
94824
|
-
const altPattern = /<a[^>]+rel="nofollow"[^>]*href="([^"]+)"[^>]*>([^<]+)<\/a>[\s\S]*?<span[^>]*>([^<]{20,})/gi;
|
|
94825
|
-
let match;
|
|
94826
|
-
while ((match = resultPattern.exec(html)) !== null && results.length < maxResults) {
|
|
94827
|
-
const [, url2, title, snippet] = match;
|
|
94828
|
-
if (url2 && title && !url2.includes("duckduckgo.com")) {
|
|
94829
|
-
results.push({
|
|
94830
|
-
title: decodeHtmlEntities(title.trim()),
|
|
94831
|
-
url: decodeUrl(url2),
|
|
94832
|
-
snippet: decodeHtmlEntities(snippet.trim())
|
|
94833
|
-
});
|
|
94834
|
-
}
|
|
94835
|
-
}
|
|
94836
|
-
if (results.length === 0) {
|
|
94837
|
-
while ((match = altPattern.exec(html)) !== null && results.length < maxResults) {
|
|
94838
|
-
const [, url2, title, snippet] = match;
|
|
94839
|
-
if (url2 && title && !url2.includes("duckduckgo.com")) {
|
|
94840
|
-
results.push({
|
|
94841
|
-
title: decodeHtmlEntities(title.trim()),
|
|
94842
|
-
url: decodeUrl(url2),
|
|
94843
|
-
snippet: decodeHtmlEntities(snippet.trim())
|
|
94844
|
-
});
|
|
94845
|
-
}
|
|
94846
|
-
}
|
|
94847
|
-
}
|
|
94848
|
-
if (results.length === 0) {
|
|
94849
|
-
const linkPattern = /<a[^>]+href="(https?:\/\/(?!duckduckgo)[^"]+)"[^>]*>([^<]{10,100})<\/a>/gi;
|
|
94850
|
-
const seenUrls = new Set;
|
|
94851
|
-
while ((match = linkPattern.exec(html)) !== null && results.length < maxResults) {
|
|
94852
|
-
const [, url2, title] = match;
|
|
94853
|
-
if (!seenUrls.has(url2) && !url2.includes("duckduckgo")) {
|
|
94854
|
-
seenUrls.add(url2);
|
|
94855
|
-
results.push({
|
|
94856
|
-
title: decodeHtmlEntities(title.trim()),
|
|
94857
|
-
url: decodeUrl(url2),
|
|
94858
|
-
snippet: ""
|
|
94859
|
-
});
|
|
94860
|
-
}
|
|
94861
|
-
}
|
|
94862
|
-
}
|
|
94863
|
-
return results;
|
|
94864
|
-
};
|
|
94865
95311
|
var decodeHtmlEntities = (text) => {
|
|
94866
95312
|
const entities = {
|
|
94867
95313
|
"&": "&",
|
|
@@ -94880,22 +95326,32 @@ var decodeHtmlEntities = (text) => {
|
|
|
94880
95326
|
decoded = decoded.replace(/&#(\d+);/g, (_3, code) => String.fromCharCode(parseInt(code, 10)));
|
|
94881
95327
|
return decoded;
|
|
94882
95328
|
};
|
|
94883
|
-
var
|
|
94884
|
-
|
|
94885
|
-
|
|
94886
|
-
|
|
94887
|
-
|
|
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
|
+
});
|
|
94888
95344
|
}
|
|
94889
95345
|
}
|
|
94890
|
-
return
|
|
95346
|
+
return results;
|
|
94891
95347
|
};
|
|
94892
95348
|
var performSearch = async (query, maxResults, signal) => {
|
|
94893
95349
|
const encodedQuery = encodeURIComponent(query);
|
|
94894
|
-
const searchUrl = `https://
|
|
95350
|
+
const searchUrl = `https://www.bing.com/search?q=${encodedQuery}&format=rss`;
|
|
94895
95351
|
const response2 = await fetch(searchUrl, {
|
|
94896
95352
|
headers: {
|
|
94897
95353
|
"User-Agent": WEB_SEARCH_DEFAULTS.USER_AGENT,
|
|
94898
|
-
Accept: "text/
|
|
95354
|
+
Accept: "application/rss+xml, text/xml",
|
|
94899
95355
|
"Accept-Language": "en-US,en;q=0.9"
|
|
94900
95356
|
},
|
|
94901
95357
|
signal
|
|
@@ -94903,8 +95359,8 @@ var performSearch = async (query, maxResults, signal) => {
|
|
|
94903
95359
|
if (!response2.ok) {
|
|
94904
95360
|
throw new Error(`Search request failed: ${response2.status}`);
|
|
94905
95361
|
}
|
|
94906
|
-
const
|
|
94907
|
-
return
|
|
95362
|
+
const rss = await response2.text();
|
|
95363
|
+
return parseRssResults(rss, maxResults);
|
|
94908
95364
|
};
|
|
94909
95365
|
var executeWebSearch = async (args, ctx) => {
|
|
94910
95366
|
const { query, maxResults = 5 } = args;
|
|
@@ -94937,9 +95393,537 @@ var webSearchTool = {
|
|
|
94937
95393
|
parameters: webSearchParams,
|
|
94938
95394
|
execute: executeWebSearch
|
|
94939
95395
|
};
|
|
94940
|
-
// src/
|
|
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
|
+
"&": "&",
|
|
95493
|
+
"<": "<",
|
|
95494
|
+
">": ">",
|
|
95495
|
+
""": '"',
|
|
95496
|
+
"'": "'",
|
|
95497
|
+
" ": " ",
|
|
95498
|
+
"'": "'",
|
|
95499
|
+
"/": "/",
|
|
95500
|
+
"—": "—",
|
|
95501
|
+
"–": "–",
|
|
95502
|
+
"…": "…",
|
|
95503
|
+
"’": "'",
|
|
95504
|
+
"‘": "'",
|
|
95505
|
+
"”": '"',
|
|
95506
|
+
"“": '"',
|
|
95507
|
+
"©": "©",
|
|
95508
|
+
"®": "®",
|
|
95509
|
+
"™": "™"
|
|
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, "");
|
|
95545
|
+
content = content.replace(/<img[^>]*src="([^"]*)"[^>]*\/?>/gi, "");
|
|
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
|
|
94941
95672
|
import fs10 from "fs/promises";
|
|
94942
|
-
import
|
|
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";
|
|
94943
95927
|
import { EventEmitter as EventEmitter14 } from "events";
|
|
94944
95928
|
|
|
94945
95929
|
// src/services/lsp/client.ts
|
|
@@ -95339,11 +96323,11 @@ var createLSPClient = (process14, serverId, root) => {
|
|
|
95339
96323
|
|
|
95340
96324
|
// src/services/lsp/server.ts
|
|
95341
96325
|
import { spawn as spawn3, execSync } from "child_process";
|
|
95342
|
-
import
|
|
95343
|
-
import
|
|
96326
|
+
import path11 from "path";
|
|
96327
|
+
import fs11 from "fs/promises";
|
|
95344
96328
|
var fileExists = async (filePath2) => {
|
|
95345
96329
|
try {
|
|
95346
|
-
await
|
|
96330
|
+
await fs11.access(filePath2);
|
|
95347
96331
|
return true;
|
|
95348
96332
|
} catch {
|
|
95349
96333
|
return false;
|
|
@@ -95351,15 +96335,15 @@ var fileExists = async (filePath2) => {
|
|
|
95351
96335
|
};
|
|
95352
96336
|
var findProjectRoot = async (startDir, patterns) => {
|
|
95353
96337
|
let currentDir = startDir;
|
|
95354
|
-
const root =
|
|
96338
|
+
const root = path11.parse(currentDir).root;
|
|
95355
96339
|
while (currentDir !== root) {
|
|
95356
96340
|
for (const pattern of patterns) {
|
|
95357
|
-
const checkPath =
|
|
96341
|
+
const checkPath = path11.join(currentDir, pattern);
|
|
95358
96342
|
if (await fileExists(checkPath)) {
|
|
95359
96343
|
return currentDir;
|
|
95360
96344
|
}
|
|
95361
96345
|
}
|
|
95362
|
-
currentDir =
|
|
96346
|
+
currentDir = path11.dirname(currentDir);
|
|
95363
96347
|
}
|
|
95364
96348
|
return null;
|
|
95365
96349
|
};
|
|
@@ -95518,13 +96502,13 @@ var SERVERS = {
|
|
|
95518
96502
|
};
|
|
95519
96503
|
var getServersForFile = (filePath2) => {
|
|
95520
96504
|
const ext = "." + (filePath2.split(".").pop() ?? "");
|
|
95521
|
-
const fileName =
|
|
96505
|
+
const fileName = path11.basename(filePath2);
|
|
95522
96506
|
return Object.values(SERVERS).filter((server) => {
|
|
95523
96507
|
return server.extensions.includes(ext) || server.extensions.includes(fileName);
|
|
95524
96508
|
});
|
|
95525
96509
|
};
|
|
95526
96510
|
var findRootForServer = async (filePath2, server) => {
|
|
95527
|
-
const dir =
|
|
96511
|
+
const dir = path11.dirname(filePath2);
|
|
95528
96512
|
return findProjectRoot(dir, server.rootPatterns);
|
|
95529
96513
|
};
|
|
95530
96514
|
var spawnServer = async (server, root) => {
|
|
@@ -95616,11 +96600,11 @@ var spawnClient = async (server, root) => {
|
|
|
95616
96600
|
}
|
|
95617
96601
|
};
|
|
95618
96602
|
var openFile = async (filePath2) => {
|
|
95619
|
-
const absolutePath =
|
|
96603
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95620
96604
|
const clients = await getClientsForFile(absolutePath);
|
|
95621
96605
|
if (clients.length === 0)
|
|
95622
96606
|
return;
|
|
95623
|
-
const content = await
|
|
96607
|
+
const content = await fs12.readFile(absolutePath, "utf-8");
|
|
95624
96608
|
for (const client of clients) {
|
|
95625
96609
|
if (!client.isFileOpen(absolutePath)) {
|
|
95626
96610
|
await client.openFile(absolutePath, content);
|
|
@@ -95628,7 +96612,7 @@ var openFile = async (filePath2) => {
|
|
|
95628
96612
|
}
|
|
95629
96613
|
};
|
|
95630
96614
|
var updateFile = async (filePath2, content) => {
|
|
95631
|
-
const absolutePath =
|
|
96615
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95632
96616
|
const clients = await getClientsForFile(absolutePath);
|
|
95633
96617
|
for (const client of clients) {
|
|
95634
96618
|
if (client.isFileOpen(absolutePath)) {
|
|
@@ -95639,7 +96623,7 @@ var updateFile = async (filePath2, content) => {
|
|
|
95639
96623
|
}
|
|
95640
96624
|
};
|
|
95641
96625
|
var closeFile = async (filePath2) => {
|
|
95642
|
-
const absolutePath =
|
|
96626
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95643
96627
|
const clients = await getClientsForFile(absolutePath);
|
|
95644
96628
|
for (const client of clients) {
|
|
95645
96629
|
if (client.isFileOpen(absolutePath)) {
|
|
@@ -95648,7 +96632,7 @@ var closeFile = async (filePath2) => {
|
|
|
95648
96632
|
}
|
|
95649
96633
|
};
|
|
95650
96634
|
var getHover = async (filePath2, position) => {
|
|
95651
|
-
const absolutePath =
|
|
96635
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95652
96636
|
const clients = await getClientsForFile(absolutePath);
|
|
95653
96637
|
for (const client of clients) {
|
|
95654
96638
|
const hover = await client.getHover(absolutePath, position);
|
|
@@ -95658,7 +96642,7 @@ var getHover = async (filePath2, position) => {
|
|
|
95658
96642
|
return null;
|
|
95659
96643
|
};
|
|
95660
96644
|
var getDefinition = async (filePath2, position) => {
|
|
95661
|
-
const absolutePath =
|
|
96645
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95662
96646
|
const clients = await getClientsForFile(absolutePath);
|
|
95663
96647
|
for (const client of clients) {
|
|
95664
96648
|
const definition = await client.getDefinition(absolutePath, position);
|
|
@@ -95668,7 +96652,7 @@ var getDefinition = async (filePath2, position) => {
|
|
|
95668
96652
|
return null;
|
|
95669
96653
|
};
|
|
95670
96654
|
var getReferences = async (filePath2, position, includeDeclaration = true) => {
|
|
95671
|
-
const absolutePath =
|
|
96655
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95672
96656
|
const clients = await getClientsForFile(absolutePath);
|
|
95673
96657
|
const allRefs = [];
|
|
95674
96658
|
for (const client of clients) {
|
|
@@ -95685,7 +96669,7 @@ var getReferences = async (filePath2, position, includeDeclaration = true) => {
|
|
|
95685
96669
|
});
|
|
95686
96670
|
};
|
|
95687
96671
|
var getCompletions = async (filePath2, position) => {
|
|
95688
|
-
const absolutePath =
|
|
96672
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95689
96673
|
const clients = await getClientsForFile(absolutePath);
|
|
95690
96674
|
const allCompletions = [];
|
|
95691
96675
|
for (const client of clients) {
|
|
@@ -95695,7 +96679,7 @@ var getCompletions = async (filePath2, position) => {
|
|
|
95695
96679
|
return allCompletions;
|
|
95696
96680
|
};
|
|
95697
96681
|
var getDocumentSymbols = async (filePath2) => {
|
|
95698
|
-
const absolutePath =
|
|
96682
|
+
const absolutePath = path12.resolve(filePath2);
|
|
95699
96683
|
const clients = await getClientsForFile(absolutePath);
|
|
95700
96684
|
for (const client of clients) {
|
|
95701
96685
|
const symbols = await client.getDocumentSymbols(absolutePath);
|
|
@@ -95710,7 +96694,7 @@ var getDiagnostics = (filePath2) => {
|
|
|
95710
96694
|
const clientDiagnostics = client.getAllDiagnostics();
|
|
95711
96695
|
for (const [uri, diagnostics] of clientDiagnostics) {
|
|
95712
96696
|
if (filePath2) {
|
|
95713
|
-
const expectedUri = `file://${
|
|
96697
|
+
const expectedUri = `file://${path12.resolve(filePath2)}`;
|
|
95714
96698
|
if (uri !== expectedUri)
|
|
95715
96699
|
continue;
|
|
95716
96700
|
}
|
|
@@ -95772,7 +96756,7 @@ var lspService = {
|
|
|
95772
96756
|
};
|
|
95773
96757
|
|
|
95774
96758
|
// src/tools/lsp.ts
|
|
95775
|
-
import
|
|
96759
|
+
import fs13 from "fs/promises";
|
|
95776
96760
|
var PositionSchema = exports_external.object({
|
|
95777
96761
|
line: exports_external.number().describe("Zero-based line number"),
|
|
95778
96762
|
character: exports_external.number().describe("Zero-based character offset")
|
|
@@ -95889,7 +96873,7 @@ Examples:
|
|
|
95889
96873
|
execute: async (args) => {
|
|
95890
96874
|
const { operation, file: file2, position } = args;
|
|
95891
96875
|
try {
|
|
95892
|
-
await
|
|
96876
|
+
await fs13.access(file2);
|
|
95893
96877
|
} catch {
|
|
95894
96878
|
return {
|
|
95895
96879
|
success: false,
|
|
@@ -95967,6 +96951,754 @@ Examples:
|
|
|
95967
96951
|
};
|
|
95968
96952
|
}
|
|
95969
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
|
+
};
|
|
95970
97702
|
// src/services/mcp/tools.ts
|
|
95971
97703
|
init_manager();
|
|
95972
97704
|
var getMCPToolsForApi = async () => {
|
|
@@ -96056,12 +97788,15 @@ var tools = [
|
|
|
96056
97788
|
readTool,
|
|
96057
97789
|
writeTool,
|
|
96058
97790
|
editTool,
|
|
97791
|
+
multiEditTool,
|
|
96059
97792
|
globToolDefinition,
|
|
96060
97793
|
grepToolDefinition,
|
|
96061
97794
|
todoWriteTool,
|
|
96062
97795
|
todoReadTool,
|
|
96063
97796
|
webSearchTool,
|
|
96064
|
-
|
|
97797
|
+
webFetchTool,
|
|
97798
|
+
lspTool,
|
|
97799
|
+
applyPatchTool
|
|
96065
97800
|
];
|
|
96066
97801
|
var READ_ONLY_TOOLS = new Set([
|
|
96067
97802
|
"read",
|
|
@@ -96069,6 +97804,7 @@ var READ_ONLY_TOOLS = new Set([
|
|
|
96069
97804
|
"grep",
|
|
96070
97805
|
"todo_read",
|
|
96071
97806
|
"web_search",
|
|
97807
|
+
"web_fetch",
|
|
96072
97808
|
"lsp"
|
|
96073
97809
|
]);
|
|
96074
97810
|
var toolMap = new Map(tools.map((t2) => [t2.name, t2]));
|
|
@@ -98029,17 +99765,17 @@ var isCorrection = (message2) => {
|
|
|
98029
99765
|
return feedback.type === "negative" && feedback.confidence >= 0.6;
|
|
98030
99766
|
};
|
|
98031
99767
|
// src/services/provider-quality/persistence.ts
|
|
98032
|
-
import { join as
|
|
99768
|
+
import { join as join12 } from "path";
|
|
98033
99769
|
import { homedir as homedir3 } from "os";
|
|
98034
|
-
var QUALITY_DATA_DIR =
|
|
99770
|
+
var QUALITY_DATA_DIR = join12(homedir3(), ".config", "codetyper");
|
|
98035
99771
|
var QUALITY_DATA_FILE = "provider-quality.json";
|
|
98036
99772
|
var getQualityDataPath = () => {
|
|
98037
|
-
return
|
|
99773
|
+
return join12(QUALITY_DATA_DIR, QUALITY_DATA_FILE);
|
|
98038
99774
|
};
|
|
98039
99775
|
var ensureDataDir = async () => {
|
|
98040
|
-
const
|
|
99776
|
+
const fs17 = await import("fs/promises");
|
|
98041
99777
|
try {
|
|
98042
|
-
await
|
|
99778
|
+
await fs17.mkdir(QUALITY_DATA_DIR, { recursive: true });
|
|
98043
99779
|
} catch {}
|
|
98044
99780
|
};
|
|
98045
99781
|
var createDefaultScores = () => {
|
|
@@ -98066,20 +99802,20 @@ var createDefaultScores = () => {
|
|
|
98066
99802
|
return scores;
|
|
98067
99803
|
};
|
|
98068
99804
|
var loadQualityData = async () => {
|
|
98069
|
-
const
|
|
99805
|
+
const fs17 = await import("fs/promises");
|
|
98070
99806
|
const filePath2 = getQualityDataPath();
|
|
98071
99807
|
try {
|
|
98072
|
-
const content = await
|
|
99808
|
+
const content = await fs17.readFile(filePath2, "utf-8");
|
|
98073
99809
|
return JSON.parse(content);
|
|
98074
99810
|
} catch {
|
|
98075
99811
|
return {};
|
|
98076
99812
|
}
|
|
98077
99813
|
};
|
|
98078
99814
|
var saveQualityData = async (data) => {
|
|
98079
|
-
const
|
|
99815
|
+
const fs17 = await import("fs/promises");
|
|
98080
99816
|
await ensureDataDir();
|
|
98081
99817
|
const filePath2 = getQualityDataPath();
|
|
98082
|
-
await
|
|
99818
|
+
await fs17.writeFile(filePath2, JSON.stringify(data, null, 2));
|
|
98083
99819
|
};
|
|
98084
99820
|
var getProviderQuality = async (providerId) => {
|
|
98085
99821
|
const allData = await loadQualityData();
|
|
@@ -98637,7 +100373,7 @@ var handleMessage = async (state4, message2, callbacks) => {
|
|
|
98637
100373
|
}
|
|
98638
100374
|
if (isReadOnlyMode) {
|
|
98639
100375
|
const modeLabel = interactionMode === "ask" ? "Ask" : "Code Review";
|
|
98640
|
-
callbacks.onLog("system", `${modeLabel} mode: Read-only tools only (Ctrl+
|
|
100376
|
+
callbacks.onLog("system", `${modeLabel} mode: Read-only tools only (Ctrl+M to switch modes)`);
|
|
98641
100377
|
}
|
|
98642
100378
|
let processedMessage = await processFileReferences(state4, message2);
|
|
98643
100379
|
if (interactionMode === "code-review") {
|
|
@@ -99229,7 +100965,7 @@ await init_providers2();
|
|
|
99229
100965
|
// src/services/hooks-service.ts
|
|
99230
100966
|
import { spawn as spawn7 } from "child_process";
|
|
99231
100967
|
import { readFile as readFile7, access, constants as constants2 } from "fs/promises";
|
|
99232
|
-
import { join as
|
|
100968
|
+
import { join as join13, isAbsolute as isAbsolute3, resolve as resolve6 } from "path";
|
|
99233
100969
|
|
|
99234
100970
|
// src/constants/hooks.ts
|
|
99235
100971
|
var HOOKS_CONFIG_FILE = "hooks.json";
|
|
@@ -99264,8 +101000,8 @@ var loadHooksFromFile = async (filePath2) => {
|
|
|
99264
101000
|
}
|
|
99265
101001
|
};
|
|
99266
101002
|
var loadHooks = async (workingDir3) => {
|
|
99267
|
-
const globalPath =
|
|
99268
|
-
const localPath =
|
|
101003
|
+
const globalPath = join13(DIRS.config, HOOKS_CONFIG_FILE);
|
|
101004
|
+
const localPath = join13(workingDir3, LOCAL_CONFIG_DIR, HOOKS_CONFIG_FILE);
|
|
99269
101005
|
const [globalHooks, localHooks] = await Promise.all([
|
|
99270
101006
|
loadHooksFromFile(globalPath),
|
|
99271
101007
|
loadHooksFromFile(localPath)
|
|
@@ -99282,7 +101018,7 @@ var getHooksForEvent = (event) => {
|
|
|
99282
101018
|
return allHooks.filter((hook) => hook.event === event);
|
|
99283
101019
|
};
|
|
99284
101020
|
var resolveScriptPath = (script, workingDir3) => {
|
|
99285
|
-
if (
|
|
101021
|
+
if (isAbsolute3(script)) {
|
|
99286
101022
|
return script;
|
|
99287
101023
|
}
|
|
99288
101024
|
return resolve6(workingDir3, script);
|
|
@@ -99772,7 +101508,7 @@ var {
|
|
|
99772
101508
|
const clearContexts = () => {
|
|
99773
101509
|
setStore("contextStack", []);
|
|
99774
101510
|
};
|
|
99775
|
-
const
|
|
101511
|
+
const register2 = (binding) => {
|
|
99776
101512
|
const id = generateKeybindId();
|
|
99777
101513
|
const fullBinding = {
|
|
99778
101514
|
...binding,
|
|
@@ -99834,7 +101570,7 @@ var {
|
|
|
99834
101570
|
pushContext,
|
|
99835
101571
|
popContext,
|
|
99836
101572
|
clearContexts,
|
|
99837
|
-
register,
|
|
101573
|
+
register: register2,
|
|
99838
101574
|
unregister,
|
|
99839
101575
|
enable,
|
|
99840
101576
|
disable,
|
|
@@ -100224,7 +101960,7 @@ function InputArea(props) {
|
|
|
100224
101960
|
};
|
|
100225
101961
|
const isMenuOpen = createMemo(() => {
|
|
100226
101962
|
const mode = app.mode();
|
|
100227
|
-
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";
|
|
100228
101964
|
});
|
|
100229
101965
|
const placeholder = () => props.placeholder ?? "Ask anything... (@ for files, / for commands)";
|
|
100230
101966
|
const borderColor = createMemo(() => {
|
|
@@ -100235,7 +101971,7 @@ function InputArea(props) {
|
|
|
100235
101971
|
return theme.colors.border;
|
|
100236
101972
|
});
|
|
100237
101973
|
useKeyboard((evt) => {
|
|
100238
|
-
if (evt.ctrl && evt.name === "
|
|
101974
|
+
if (evt.ctrl && evt.name === "m") {
|
|
100239
101975
|
app.toggleInteractionMode();
|
|
100240
101976
|
evt.preventDefault();
|
|
100241
101977
|
evt.stopPropagation();
|
|
@@ -100404,7 +102140,9 @@ var MODE_DISPLAY_CONFIG = {
|
|
|
100404
102140
|
provider_select: { text: "Select Provider", color: "magenta" },
|
|
100405
102141
|
learning_prompt: { text: "Save Learning?", color: "cyan" },
|
|
100406
102142
|
help_menu: { text: "Help", color: "cyan" },
|
|
100407
|
-
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" }
|
|
100408
102146
|
};
|
|
100409
102147
|
var DEFAULT_MODE_DISPLAY = {
|
|
100410
102148
|
text: "Ready",
|
|
@@ -100481,6 +102219,11 @@ var SLASH_COMMANDS = [
|
|
|
100481
102219
|
name: "logout",
|
|
100482
102220
|
description: "Sign out from provider",
|
|
100483
102221
|
category: "account"
|
|
102222
|
+
},
|
|
102223
|
+
{
|
|
102224
|
+
name: "brain",
|
|
102225
|
+
description: "Configure CodeTyper Brain (memory & knowledge)",
|
|
102226
|
+
category: "account"
|
|
100484
102227
|
}
|
|
100485
102228
|
];
|
|
100486
102229
|
var COMMAND_CATEGORIES = [
|
|
@@ -100492,10 +102235,11 @@ var COMMAND_CATEGORIES = [
|
|
|
100492
102235
|
|
|
100493
102236
|
// src/tui-solid/components/command-menu.tsx
|
|
100494
102237
|
var filterCommands = (commands, filter2) => {
|
|
102238
|
+
let availableCommands = BRAIN_DISABLED ? commands.filter((cmd) => cmd.name !== "brain") : [...commands];
|
|
100495
102239
|
if (!filter2)
|
|
100496
|
-
return
|
|
102240
|
+
return availableCommands;
|
|
100497
102241
|
const query = filter2.toLowerCase();
|
|
100498
|
-
return
|
|
102242
|
+
return availableCommands.filter((cmd) => cmd.name.toLowerCase().includes(query) || cmd.description.toLowerCase().includes(query));
|
|
100499
102243
|
};
|
|
100500
102244
|
var groupCommandsByCategory = (commands) => {
|
|
100501
102245
|
return COMMAND_CATEGORIES.map((cat) => ({
|
|
@@ -101445,9 +103189,24 @@ function CenteredModal(props) {
|
|
|
101445
103189
|
|
|
101446
103190
|
// src/constants/home.ts
|
|
101447
103191
|
var HOME_VARS = {
|
|
101448
|
-
|
|
101449
|
-
|
|
101450
|
-
|
|
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
|
+
];
|
|
101451
103210
|
|
|
101452
103211
|
// src/tui-solid/routes/home.tsx
|
|
101453
103212
|
function Home(props) {
|
|
@@ -101466,9 +103225,9 @@ function Home(props) {
|
|
|
101466
103225
|
app.setMode("idle");
|
|
101467
103226
|
};
|
|
101468
103227
|
return (() => {
|
|
101469
|
-
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("box"), _el$4 = createElement("text"), _el$5 = createElement("
|
|
103228
|
+
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("box"), _el$4 = createElement("text"), _el$5 = createElement("box");
|
|
101470
103229
|
insertNode(_el$, _el$2);
|
|
101471
|
-
insertNode(_el$, _el$
|
|
103230
|
+
insertNode(_el$, _el$5);
|
|
101472
103231
|
setProp(_el$, "flexDirection", "column");
|
|
101473
103232
|
setProp(_el$, "flexGrow", 1);
|
|
101474
103233
|
insertNode(_el$2, _el$3);
|
|
@@ -101478,14 +103237,10 @@ function Home(props) {
|
|
|
101478
103237
|
setProp(_el$2, "flexDirection", "column");
|
|
101479
103238
|
insert(_el$2, createComponent2(Logo, {}), _el$3);
|
|
101480
103239
|
insertNode(_el$3, _el$4);
|
|
101481
|
-
insertNode(_el$3, _el$5);
|
|
101482
103240
|
setProp(_el$3, "marginTop", 2);
|
|
101483
|
-
|
|
101484
|
-
setProp(_el$
|
|
101485
|
-
insert(_el$
|
|
101486
|
-
insert(_el$5, () => HOME_VARS.subTitle);
|
|
101487
|
-
setProp(_el$6, "marginTop", 2);
|
|
101488
|
-
insert(_el$6, createComponent2(InputArea, {
|
|
103241
|
+
insert(_el$4, () => HOME_VARS.subTitle);
|
|
103242
|
+
setProp(_el$5, "marginTop", 2);
|
|
103243
|
+
insert(_el$5, createComponent2(InputArea, {
|
|
101489
103244
|
onSubmit: handleSubmit,
|
|
101490
103245
|
placeholder: "What would you like to build today?"
|
|
101491
103246
|
}));
|
|
@@ -101586,15 +103341,13 @@ function Home(props) {
|
|
|
101586
103341
|
}
|
|
101587
103342
|
}), null);
|
|
101588
103343
|
effect((_p$) => {
|
|
101589
|
-
var _v$ = theme.colors.background, _v$2 = theme.colors.textDim
|
|
103344
|
+
var _v$ = theme.colors.background, _v$2 = theme.colors.textDim;
|
|
101590
103345
|
_v$ !== _p$.e && (_p$.e = setProp(_el$, "backgroundColor", _v$, _p$.e));
|
|
101591
103346
|
_v$2 !== _p$.t && (_p$.t = setProp(_el$4, "fg", _v$2, _p$.t));
|
|
101592
|
-
_v$3 !== _p$.a && (_p$.a = setProp(_el$5, "fg", _v$3, _p$.a));
|
|
101593
103347
|
return _p$;
|
|
101594
103348
|
}, {
|
|
101595
103349
|
e: undefined,
|
|
101596
|
-
t: undefined
|
|
101597
|
-
a: undefined
|
|
103350
|
+
t: undefined
|
|
101598
103351
|
});
|
|
101599
103352
|
return _el$;
|
|
101600
103353
|
})();
|
|
@@ -101629,6 +103382,17 @@ await __promiseAll([
|
|
|
101629
103382
|
init_theme2(),
|
|
101630
103383
|
init_app()
|
|
101631
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
|
|
101632
103396
|
var MODE_LABELS = {
|
|
101633
103397
|
agent: "Agent",
|
|
101634
103398
|
ask: "Ask",
|
|
@@ -101644,6 +103408,24 @@ var MODE_COLORS = {
|
|
|
101644
103408
|
ask: "info",
|
|
101645
103409
|
"code-review": "success"
|
|
101646
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
|
+
};
|
|
101647
103429
|
function Header(props) {
|
|
101648
103430
|
const theme = useTheme();
|
|
101649
103431
|
const app = useAppStore();
|
|
@@ -101652,119 +103434,274 @@ function Header(props) {
|
|
|
101652
103434
|
const colorKey = MODE_COLORS[app.interactionMode()];
|
|
101653
103435
|
return theme.colors[colorKey];
|
|
101654
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
|
+
});
|
|
101655
103472
|
return (() => {
|
|
101656
|
-
var _el$ = createElement("box"), _el$
|
|
101657
|
-
insertNode(_el$, _el$
|
|
101658
|
-
|
|
101659
|
-
|
|
101660
|
-
|
|
101661
|
-
|
|
101662
|
-
|
|
101663
|
-
|
|
101664
|
-
|
|
101665
|
-
|
|
101666
|
-
|
|
101667
|
-
|
|
101668
|
-
|
|
101669
|
-
|
|
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, {
|
|
101670
103540
|
get when() {
|
|
101671
103541
|
return showBanner();
|
|
101672
103542
|
},
|
|
101673
103543
|
get children() {
|
|
101674
|
-
var _el$
|
|
101675
|
-
insertNode(_el$
|
|
103544
|
+
var _el$13 = createElement("text");
|
|
103545
|
+
insertNode(_el$13, createTextNode(`CodeTyper`));
|
|
101676
103546
|
effect((_p$) => {
|
|
101677
|
-
var _v$ = theme.colors.primary, _v$
|
|
101678
|
-
_v$ !== _p$.e && (_p$.e = setProp(_el$
|
|
101679
|
-
_v$
|
|
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));
|
|
101680
103550
|
return _p$;
|
|
101681
103551
|
}, {
|
|
101682
103552
|
e: undefined,
|
|
101683
103553
|
t: undefined
|
|
101684
103554
|
});
|
|
101685
|
-
return _el$
|
|
103555
|
+
return _el$13;
|
|
101686
103556
|
}
|
|
101687
|
-
}), _el$
|
|
101688
|
-
insertNode(_el$
|
|
101689
|
-
insert(_el$
|
|
101690
|
-
insertNode(_el$
|
|
101691
|
-
insertNode(_el$
|
|
101692
|
-
insertNode(_el$
|
|
101693
|
-
setProp(_el$
|
|
101694
|
-
insertNode(_el$
|
|
101695
|
-
insertNode(_el$
|
|
101696
|
-
insert(_el$
|
|
101697
|
-
insert(_el$
|
|
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, {
|
|
101698
103568
|
get when() {
|
|
101699
103569
|
return app.currentAgent() !== "default";
|
|
101700
103570
|
},
|
|
101701
103571
|
get children() {
|
|
101702
|
-
var _el$
|
|
101703
|
-
insertNode(_el$
|
|
101704
|
-
insert(_el$
|
|
103572
|
+
var _el$23 = createElement("text"), _el$24 = createTextNode(` @`);
|
|
103573
|
+
insertNode(_el$23, _el$24);
|
|
103574
|
+
insert(_el$23, () => app.currentAgent(), null);
|
|
101705
103575
|
effect((_p$) => {
|
|
101706
|
-
var _v$
|
|
101707
|
-
_v$
|
|
101708
|
-
_v$
|
|
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));
|
|
101709
103579
|
return _p$;
|
|
101710
103580
|
}, {
|
|
101711
103581
|
e: undefined,
|
|
101712
103582
|
t: undefined
|
|
101713
103583
|
});
|
|
101714
|
-
return _el$
|
|
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;
|
|
101715
103629
|
}
|
|
101716
|
-
}), _el$
|
|
101717
|
-
|
|
101718
|
-
|
|
101719
|
-
|
|
101720
|
-
|
|
101721
|
-
|
|
101722
|
-
|
|
101723
|
-
|
|
101724
|
-
|
|
101725
|
-
|
|
101726
|
-
|
|
101727
|
-
|
|
101728
|
-
|
|
101729
|
-
|
|
101730
|
-
|
|
101731
|
-
|
|
101732
|
-
|
|
101733
|
-
|
|
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, {
|
|
101734
103671
|
get when() {
|
|
101735
103672
|
return app.sessionId();
|
|
101736
103673
|
},
|
|
101737
103674
|
get children() {
|
|
101738
|
-
var _el$
|
|
101739
|
-
insertNode(_el$
|
|
101740
|
-
insertNode(_el$
|
|
101741
|
-
setProp(_el$
|
|
101742
|
-
insertNode(_el$
|
|
101743
|
-
insert(_el$
|
|
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));
|
|
101744
103681
|
effect((_p$) => {
|
|
101745
|
-
var _v$
|
|
101746
|
-
_v$
|
|
101747
|
-
_v$
|
|
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));
|
|
101748
103685
|
return _p$;
|
|
101749
103686
|
}, {
|
|
101750
103687
|
e: undefined,
|
|
101751
103688
|
t: undefined
|
|
101752
103689
|
});
|
|
101753
|
-
return _el$
|
|
103690
|
+
return _el$51;
|
|
101754
103691
|
}
|
|
101755
103692
|
}), null);
|
|
101756
103693
|
effect((_p$) => {
|
|
101757
|
-
var _v$
|
|
101758
|
-
_v$
|
|
101759
|
-
_v$
|
|
101760
|
-
_v$
|
|
101761
|
-
_v$
|
|
101762
|
-
_v$
|
|
101763
|
-
_v$
|
|
101764
|
-
_v$
|
|
101765
|
-
_v$
|
|
101766
|
-
_v$
|
|
101767
|
-
_v$
|
|
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));
|
|
101768
103705
|
return _p$;
|
|
101769
103706
|
}, {
|
|
101770
103707
|
e: undefined,
|
|
@@ -101793,7 +103730,6 @@ await __promiseAll([
|
|
|
101793
103730
|
init_solid(),
|
|
101794
103731
|
init_solid(),
|
|
101795
103732
|
init_solid(),
|
|
101796
|
-
init_solid(),
|
|
101797
103733
|
init_theme2(),
|
|
101798
103734
|
init_app()
|
|
101799
103735
|
]);
|
|
@@ -102636,13 +104572,25 @@ function LogPanel() {
|
|
|
102636
104572
|
},
|
|
102637
104573
|
get fallback() {
|
|
102638
104574
|
return (() => {
|
|
102639
|
-
var _el$4 = createElement("box"), _el$5 = createElement("text");
|
|
104575
|
+
var _el$4 = createElement("box"), _el$5 = createElement("box"), _el$6 = createElement("text");
|
|
102640
104576
|
insertNode(_el$4, _el$5);
|
|
102641
104577
|
setProp(_el$4, "flexGrow", 1);
|
|
102642
104578
|
setProp(_el$4, "alignItems", "center");
|
|
102643
104579
|
setProp(_el$4, "justifyContent", "center");
|
|
102644
|
-
|
|
102645
|
-
|
|
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));
|
|
102646
104594
|
return _el$4;
|
|
102647
104595
|
})();
|
|
102648
104596
|
},
|
|
@@ -102939,15 +104887,9 @@ function StatusBar() {
|
|
|
102939
104887
|
const totalTokens = createMemo(() => app.sessionStats().inputTokens + app.sessionStats().outputTokens);
|
|
102940
104888
|
const hints = createMemo(() => {
|
|
102941
104889
|
const result = [];
|
|
102942
|
-
if (!isProcessing()) {
|
|
102943
|
-
result.push("^Tab toggle mode");
|
|
102944
|
-
}
|
|
102945
104890
|
if (isProcessing()) {
|
|
102946
104891
|
result.push(app.interruptPending() ? STATUS_HINTS.INTERRUPT_CONFIRM : STATUS_HINTS.INTERRUPT);
|
|
102947
104892
|
}
|
|
102948
|
-
if (app.todosVisible()) {
|
|
102949
|
-
result.push(STATUS_HINTS.TOGGLE_TODOS);
|
|
102950
|
-
}
|
|
102951
104893
|
result.push(formatDuration2(elapsed()));
|
|
102952
104894
|
if (totalTokens() > 0) {
|
|
102953
104895
|
result.push(`↓ ${formatTokens(totalTokens())} tokens`);
|
|
@@ -103329,13 +105271,13 @@ var FIELD_ORDER = ["name", "command", "args", "scope"];
|
|
|
103329
105271
|
var FIELD_LABELS = {
|
|
103330
105272
|
name: "Server Name",
|
|
103331
105273
|
command: "Command",
|
|
103332
|
-
args: "Arguments (
|
|
105274
|
+
args: "Arguments (use quotes for paths with spaces)",
|
|
103333
105275
|
scope: "Scope"
|
|
103334
105276
|
};
|
|
103335
105277
|
var FIELD_PLACEHOLDERS = {
|
|
103336
|
-
name: "e.g.,
|
|
105278
|
+
name: "e.g., filesystem",
|
|
103337
105279
|
command: "e.g., npx",
|
|
103338
|
-
args:
|
|
105280
|
+
args: 'e.g., -y @modelcontextprotocol/server-filesystem "/path/to/dir"',
|
|
103339
105281
|
scope: ""
|
|
103340
105282
|
};
|
|
103341
105283
|
function MCPAddForm(props) {
|
|
@@ -103457,10 +105399,25 @@ function MCPAddForm(props) {
|
|
|
103457
105399
|
evt.preventDefault();
|
|
103458
105400
|
return;
|
|
103459
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
|
+
}
|
|
103460
105411
|
if (evt.name.length === 1 && !evt.ctrl && !evt.meta) {
|
|
103461
105412
|
setFieldValue(field, getFieldValue(field) + evt.name);
|
|
103462
105413
|
setError(null);
|
|
103463
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();
|
|
103464
105421
|
}
|
|
103465
105422
|
});
|
|
103466
105423
|
const renderField = (field) => {
|
|
@@ -104579,7 +106536,7 @@ var HELP_TOPICS = [
|
|
|
104579
106536
|
shortDescription: "Switch mode",
|
|
104580
106537
|
fullDescription: "Switch between Agent (full access), Ask (read-only), and Code Review modes.",
|
|
104581
106538
|
usage: "/mode",
|
|
104582
|
-
shortcuts: ["Ctrl+
|
|
106539
|
+
shortcuts: ["Ctrl+M"],
|
|
104583
106540
|
category: "commands"
|
|
104584
106541
|
},
|
|
104585
106542
|
{
|
|
@@ -104650,11 +106607,11 @@ var HELP_TOPICS = [
|
|
|
104650
106607
|
category: "shortcuts"
|
|
104651
106608
|
},
|
|
104652
106609
|
{
|
|
104653
|
-
id: "shortcut-
|
|
104654
|
-
name: "Ctrl+
|
|
106610
|
+
id: "shortcut-ctrlm",
|
|
106611
|
+
name: "Ctrl+M",
|
|
104655
106612
|
shortDescription: "Cycle modes",
|
|
104656
106613
|
fullDescription: "Cycle through interaction modes.",
|
|
104657
|
-
shortcuts: ["Ctrl+
|
|
106614
|
+
shortcuts: ["Ctrl+M"],
|
|
104658
106615
|
category: "shortcuts"
|
|
104659
106616
|
}
|
|
104660
106617
|
];
|
|
@@ -105139,9 +107096,567 @@ function TodoPanel(props) {
|
|
|
105139
107096
|
|
|
105140
107097
|
// src/tui-solid/routes/session.tsx
|
|
105141
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
|
|
107634
|
+
init_mcp();
|
|
105142
107635
|
function Session(props) {
|
|
105143
107636
|
const theme = useTheme();
|
|
105144
107637
|
const app = useAppStore();
|
|
107638
|
+
onMount(async () => {
|
|
107639
|
+
if (props.mcpServers && props.mcpServers.length > 0) {
|
|
107640
|
+
app.setMcpServers(props.mcpServers);
|
|
107641
|
+
}
|
|
107642
|
+
try {
|
|
107643
|
+
await initializeMCP();
|
|
107644
|
+
const instances = getServerInstances();
|
|
107645
|
+
const servers = [];
|
|
107646
|
+
for (const [id, instance] of instances) {
|
|
107647
|
+
servers.push({
|
|
107648
|
+
id,
|
|
107649
|
+
name: instance.config.name || id,
|
|
107650
|
+
status: instance.state === "connected" ? "connected" : instance.state === "error" ? "error" : "disconnected",
|
|
107651
|
+
description: instance.config.command
|
|
107652
|
+
});
|
|
107653
|
+
}
|
|
107654
|
+
if (servers.length > 0) {
|
|
107655
|
+
app.setMcpServers(servers);
|
|
107656
|
+
}
|
|
107657
|
+
} catch {}
|
|
107658
|
+
});
|
|
107659
|
+
const mcpServers = createMemo(() => app.mcpServers());
|
|
105145
107660
|
const [selectedHelpTopic, setSelectedHelpTopic] = createSignal(null);
|
|
105146
107661
|
const handleCommandSelect = (command) => {
|
|
105147
107662
|
const lowerCommand = command.toLowerCase();
|
|
@@ -105173,6 +107688,10 @@ function Session(props) {
|
|
|
105173
107688
|
app.transitionFromCommandMenu("help_menu");
|
|
105174
107689
|
return;
|
|
105175
107690
|
}
|
|
107691
|
+
if (lowerCommand === "brain" && !BRAIN_DISABLED) {
|
|
107692
|
+
app.transitionFromCommandMenu("brain_menu");
|
|
107693
|
+
return;
|
|
107694
|
+
}
|
|
105176
107695
|
app.closeCommandMenu();
|
|
105177
107696
|
props.onCommand(command);
|
|
105178
107697
|
};
|
|
@@ -105233,6 +107752,18 @@ function Session(props) {
|
|
|
105233
107752
|
setSelectedHelpTopic(null);
|
|
105234
107753
|
app.setMode("idle");
|
|
105235
107754
|
};
|
|
107755
|
+
const handleBrainMenuClose = () => {
|
|
107756
|
+
app.setMode("idle");
|
|
107757
|
+
};
|
|
107758
|
+
const handleBrainSetJwtToken = async (jwtToken) => {
|
|
107759
|
+
await props.onBrainSetJwtToken?.(jwtToken);
|
|
107760
|
+
};
|
|
107761
|
+
const handleBrainSetApiKey = async (apiKey) => {
|
|
107762
|
+
await props.onBrainSetApiKey?.(apiKey);
|
|
107763
|
+
};
|
|
107764
|
+
const handleBrainLogout = async () => {
|
|
107765
|
+
await props.onBrainLogout?.();
|
|
107766
|
+
};
|
|
105236
107767
|
return (() => {
|
|
105237
107768
|
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("box");
|
|
105238
107769
|
insertNode(_el$, _el$2);
|
|
@@ -105366,7 +107897,7 @@ function Session(props) {
|
|
|
105366
107897
|
get children() {
|
|
105367
107898
|
return createComponent2(MCPSelect, {
|
|
105368
107899
|
get servers() {
|
|
105369
|
-
return
|
|
107900
|
+
return mcpServers();
|
|
105370
107901
|
},
|
|
105371
107902
|
get onSelect() {
|
|
105372
107903
|
return props.onMCPSelect;
|
|
@@ -105544,6 +108075,25 @@ function Session(props) {
|
|
|
105544
108075
|
}
|
|
105545
108076
|
});
|
|
105546
108077
|
}
|
|
108078
|
+
}), createComponent2(Match, {
|
|
108079
|
+
get when() {
|
|
108080
|
+
return app.mode() === "brain_menu" && !BRAIN_DISABLED;
|
|
108081
|
+
},
|
|
108082
|
+
get children() {
|
|
108083
|
+
return createComponent2(CenteredModal, {
|
|
108084
|
+
get children() {
|
|
108085
|
+
return createComponent2(BrainMenu, {
|
|
108086
|
+
onSetJwtToken: handleBrainSetJwtToken,
|
|
108087
|
+
onSetApiKey: handleBrainSetApiKey,
|
|
108088
|
+
onLogout: handleBrainLogout,
|
|
108089
|
+
onClose: handleBrainMenuClose,
|
|
108090
|
+
get isActive() {
|
|
108091
|
+
return app.mode() === "brain_menu";
|
|
108092
|
+
}
|
|
108093
|
+
});
|
|
108094
|
+
}
|
|
108095
|
+
});
|
|
108096
|
+
}
|
|
105547
108097
|
})];
|
|
105548
108098
|
}
|
|
105549
108099
|
}), null);
|
|
@@ -105613,8 +108163,12 @@ function AppContent(props) {
|
|
|
105613
108163
|
if (props.cascadeEnabled !== undefined) {
|
|
105614
108164
|
app.setCascadeEnabled(props.cascadeEnabled);
|
|
105615
108165
|
}
|
|
105616
|
-
if (
|
|
105617
|
-
|
|
108166
|
+
if (!route.isSession()) {
|
|
108167
|
+
const sessionId = props.sessionId ?? `session-${Date.now()}`;
|
|
108168
|
+
batch(() => {
|
|
108169
|
+
app.setSessionInfo(sessionId, app.provider(), app.model());
|
|
108170
|
+
route.goToSession(sessionId);
|
|
108171
|
+
});
|
|
105618
108172
|
}
|
|
105619
108173
|
if (props.availableModels && props.availableModels.length > 0) {
|
|
105620
108174
|
app.setAvailableModels(props.availableModels);
|
|
@@ -105822,6 +108376,15 @@ function AppContent(props) {
|
|
|
105822
108376
|
onCascadeToggle: handleCascadeToggle,
|
|
105823
108377
|
onPermissionResponse: handlePermissionResponse,
|
|
105824
108378
|
onLearningResponse: handleLearningResponse,
|
|
108379
|
+
get onBrainSetJwtToken() {
|
|
108380
|
+
return props.onBrainSetJwtToken;
|
|
108381
|
+
},
|
|
108382
|
+
get onBrainSetApiKey() {
|
|
108383
|
+
return props.onBrainSetApiKey;
|
|
108384
|
+
},
|
|
108385
|
+
get onBrainLogout() {
|
|
108386
|
+
return props.onBrainLogout;
|
|
108387
|
+
},
|
|
105825
108388
|
get plan() {
|
|
105826
108389
|
return props.plan;
|
|
105827
108390
|
},
|
|
@@ -105916,8 +108479,8 @@ var showContextFiles = (contextFiles) => {
|
|
|
105916
108479
|
` + source_default.bold("Context Files:"));
|
|
105917
108480
|
if (contextFiles.size > 0) {
|
|
105918
108481
|
console.log(source_default.gray(" Pending (will be included in next message):"));
|
|
105919
|
-
for (const [
|
|
105920
|
-
console.log(` - ${filePath(basename6(
|
|
108482
|
+
for (const [path16] of contextFiles) {
|
|
108483
|
+
console.log(` - ${filePath(basename6(path16))}`);
|
|
105921
108484
|
}
|
|
105922
108485
|
}
|
|
105923
108486
|
if (files.length > 0) {
|
|
@@ -105937,10 +108500,10 @@ var removeFile = (filename, contextFiles) => {
|
|
|
105937
108500
|
warningMessage("Please specify a file to remove");
|
|
105938
108501
|
return;
|
|
105939
108502
|
}
|
|
105940
|
-
for (const [
|
|
105941
|
-
if (
|
|
105942
|
-
contextFiles.delete(
|
|
105943
|
-
successMessage(`Removed: ${basename7(
|
|
108503
|
+
for (const [path16] of contextFiles) {
|
|
108504
|
+
if (path16.includes(filename) || basename7(path16) === filename) {
|
|
108505
|
+
contextFiles.delete(path16);
|
|
108506
|
+
successMessage(`Removed: ${basename7(path16)}`);
|
|
105944
108507
|
return;
|
|
105945
108508
|
}
|
|
105946
108509
|
}
|
|
@@ -106254,8 +108817,8 @@ init_source();
|
|
|
106254
108817
|
|
|
106255
108818
|
// src/services/agent-loader.ts
|
|
106256
108819
|
var import_fast_glob5 = __toESM(require_out4(), 1);
|
|
106257
|
-
import
|
|
106258
|
-
import
|
|
108820
|
+
import fs17 from "fs/promises";
|
|
108821
|
+
import path16 from "path";
|
|
106259
108822
|
var AGENT_PATTERNS = [
|
|
106260
108823
|
".codetyper/agent/**/*.agent.md",
|
|
106261
108824
|
".codetyper/agents/**/*.agent.md",
|
|
@@ -106274,11 +108837,11 @@ var DEFAULT_AGENT = {
|
|
|
106274
108837
|
};
|
|
106275
108838
|
var cachedRegistry = null;
|
|
106276
108839
|
var extractNameFromFile = (filePath2) => {
|
|
106277
|
-
const basename8 =
|
|
108840
|
+
const basename8 = path16.basename(filePath2, ".agent.md");
|
|
106278
108841
|
return basename8.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
106279
108842
|
};
|
|
106280
108843
|
var extractIdFromFile = (filePath2) => {
|
|
106281
|
-
return
|
|
108844
|
+
return path16.basename(filePath2, ".agent.md").toLowerCase();
|
|
106282
108845
|
};
|
|
106283
108846
|
var parseFrontmatter = (content) => {
|
|
106284
108847
|
const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---\r?\n([\s\S]*)$/;
|
|
@@ -106328,7 +108891,7 @@ var parseFrontmatter = (content) => {
|
|
|
106328
108891
|
};
|
|
106329
108892
|
var parseAgentFile = async (filePath2) => {
|
|
106330
108893
|
try {
|
|
106331
|
-
const content = await
|
|
108894
|
+
const content = await fs17.readFile(filePath2, "utf-8");
|
|
106332
108895
|
const { data: frontmatter, body } = parseFrontmatter(content);
|
|
106333
108896
|
const id = extractIdFromFile(filePath2);
|
|
106334
108897
|
const name = frontmatter.name ?? extractNameFromFile(filePath2);
|
|
@@ -106877,9 +109440,9 @@ var sendMessage = async (content, state4) => {
|
|
|
106877
109440
|
let userMessage = content;
|
|
106878
109441
|
if (state4.contextFiles.size > 0) {
|
|
106879
109442
|
const contextParts = [];
|
|
106880
|
-
for (const [
|
|
106881
|
-
const ext = extname4(
|
|
106882
|
-
contextParts.push(`File: ${basename8(
|
|
109443
|
+
for (const [path17, fileContent] of state4.contextFiles) {
|
|
109444
|
+
const ext = extname4(path17).slice(1) || "txt";
|
|
109445
|
+
contextParts.push(`File: ${basename8(path17)}
|
|
106883
109446
|
\`\`\`${ext}
|
|
106884
109447
|
${fileContent}
|
|
106885
109448
|
\`\`\``);
|
|
@@ -107035,9 +109598,9 @@ var executePrintMode2 = async (prompt2, state4) => {
|
|
|
107035
109598
|
let userMessage = processedPrompt;
|
|
107036
109599
|
if (state4.contextFiles.size > 0) {
|
|
107037
109600
|
const contextParts = [];
|
|
107038
|
-
for (const [
|
|
107039
|
-
const ext = extname5(
|
|
107040
|
-
contextParts.push(`File: ${basename9(
|
|
109601
|
+
for (const [path17, fileContent] of state4.contextFiles) {
|
|
109602
|
+
const ext = extname5(path17).slice(1) || "txt";
|
|
109603
|
+
contextParts.push(`File: ${basename9(path17)}
|
|
107041
109604
|
\`\`\`${ext}
|
|
107042
109605
|
${fileContent}
|
|
107043
109606
|
\`\`\``);
|
|
@@ -107606,8 +110169,8 @@ var handlePlan = async (options2) => {
|
|
|
107606
110169
|
]
|
|
107607
110170
|
};
|
|
107608
110171
|
if (output) {
|
|
107609
|
-
const
|
|
107610
|
-
await
|
|
110172
|
+
const fs18 = await import("fs/promises");
|
|
110173
|
+
await fs18.writeFile(output, JSON.stringify(plan, null, 2));
|
|
107611
110174
|
successMessage(`Plan saved to ${filePath(output)}`);
|
|
107612
110175
|
} else {
|
|
107613
110176
|
hightLigthedJson(plan);
|
|
@@ -107632,8 +110195,8 @@ var handleValidate = async (options2) => {
|
|
|
107632
110195
|
console.log();
|
|
107633
110196
|
startSpinner("Validating plan...");
|
|
107634
110197
|
try {
|
|
107635
|
-
const
|
|
107636
|
-
const planData = await
|
|
110198
|
+
const fs18 = await import("fs/promises");
|
|
110199
|
+
const planData = await fs18.readFile(planFile, "utf-8");
|
|
107637
110200
|
const plan = JSON.parse(planData);
|
|
107638
110201
|
await new Promise((resolve4) => setTimeout(resolve4, 1000));
|
|
107639
110202
|
const config2 = await getConfig();
|
|
@@ -107914,14 +110477,89 @@ var onLearningDetected = async (candidate) => {
|
|
|
107914
110477
|
|
|
107915
110478
|
// src/commands/components/execute/execute.tsx
|
|
107916
110479
|
init_mcp();
|
|
110480
|
+
var parseArgs = (argsString) => {
|
|
110481
|
+
const trimmed = argsString.trim();
|
|
110482
|
+
if (!trimmed)
|
|
110483
|
+
return;
|
|
110484
|
+
const args = [];
|
|
110485
|
+
let current = "";
|
|
110486
|
+
let inQuote = null;
|
|
110487
|
+
for (let i2 = 0;i2 < trimmed.length; i2++) {
|
|
110488
|
+
const char = trimmed[i2];
|
|
110489
|
+
if (inQuote) {
|
|
110490
|
+
if (char === inQuote) {
|
|
110491
|
+
inQuote = null;
|
|
110492
|
+
} else {
|
|
110493
|
+
current += char;
|
|
110494
|
+
}
|
|
110495
|
+
} else if (char === '"' || char === "'") {
|
|
110496
|
+
inQuote = char;
|
|
110497
|
+
} else if (char === " " || char === "\t") {
|
|
110498
|
+
if (current) {
|
|
110499
|
+
args.push(current);
|
|
110500
|
+
current = "";
|
|
110501
|
+
}
|
|
110502
|
+
} else {
|
|
110503
|
+
current += char;
|
|
110504
|
+
}
|
|
110505
|
+
}
|
|
110506
|
+
if (current) {
|
|
110507
|
+
args.push(current);
|
|
110508
|
+
}
|
|
110509
|
+
return args.length > 0 ? args : undefined;
|
|
110510
|
+
};
|
|
107917
110511
|
var defaultHandleMCPAdd = async (data) => {
|
|
107918
|
-
const serverArgs =
|
|
110512
|
+
const serverArgs = parseArgs(data.args);
|
|
107919
110513
|
await addServer(data.name, {
|
|
107920
110514
|
command: data.command,
|
|
107921
110515
|
args: serverArgs,
|
|
107922
110516
|
enabled: true
|
|
107923
110517
|
}, data.isGlobal);
|
|
107924
|
-
|
|
110518
|
+
appStore.addMcpServer({
|
|
110519
|
+
id: data.name,
|
|
110520
|
+
name: data.name,
|
|
110521
|
+
status: "disconnected",
|
|
110522
|
+
description: data.command
|
|
110523
|
+
});
|
|
110524
|
+
try {
|
|
110525
|
+
await connectServer(data.name);
|
|
110526
|
+
appStore.updateMcpServerStatus(data.name, "connected");
|
|
110527
|
+
} catch {
|
|
110528
|
+
appStore.updateMcpServerStatus(data.name, "error");
|
|
110529
|
+
}
|
|
110530
|
+
};
|
|
110531
|
+
var defaultHandleBrainSetJwtToken = async (jwtToken) => {
|
|
110532
|
+
await setJwtToken(jwtToken);
|
|
110533
|
+
const connected = await connect();
|
|
110534
|
+
if (connected) {
|
|
110535
|
+
const state4 = getState2();
|
|
110536
|
+
appStore.setBrainStatus("connected");
|
|
110537
|
+
appStore.setBrainUser(state4.user);
|
|
110538
|
+
appStore.setBrainCounts(state4.knowledgeCount, state4.memoryCount);
|
|
110539
|
+
appStore.setBrainShowBanner(false);
|
|
110540
|
+
} else {
|
|
110541
|
+
throw new Error("Failed to connect with the provided JWT token.");
|
|
110542
|
+
}
|
|
110543
|
+
};
|
|
110544
|
+
var defaultHandleBrainSetApiKey = async (apiKey) => {
|
|
110545
|
+
await setApiKey(apiKey);
|
|
110546
|
+
const connected = await connect();
|
|
110547
|
+
if (connected) {
|
|
110548
|
+
const state4 = getState2();
|
|
110549
|
+
appStore.setBrainStatus("connected");
|
|
110550
|
+
appStore.setBrainUser(state4.user);
|
|
110551
|
+
appStore.setBrainCounts(state4.knowledgeCount, state4.memoryCount);
|
|
110552
|
+
appStore.setBrainShowBanner(false);
|
|
110553
|
+
} else {
|
|
110554
|
+
throw new Error("Failed to connect with the provided API key.");
|
|
110555
|
+
}
|
|
110556
|
+
};
|
|
110557
|
+
var defaultHandleBrainLogout = async () => {
|
|
110558
|
+
await logout3();
|
|
110559
|
+
appStore.setBrainStatus("disconnected");
|
|
110560
|
+
appStore.setBrainUser(null);
|
|
110561
|
+
appStore.setBrainCounts(0, 0);
|
|
110562
|
+
appStore.setBrainShowBanner(true);
|
|
107925
110563
|
};
|
|
107926
110564
|
var renderApp = async (props) => {
|
|
107927
110565
|
const {
|
|
@@ -107953,6 +110591,9 @@ var renderApp = async (props) => {
|
|
|
107953
110591
|
onMCPAdd: props.handleMCPAdd ?? defaultHandleMCPAdd,
|
|
107954
110592
|
onPermissionResponse: props.handlePermissionResponse ?? (() => {}),
|
|
107955
110593
|
onLearningResponse: props.handleLearningResponse ?? (() => {}),
|
|
110594
|
+
onBrainSetJwtToken: props.handleBrainSetJwtToken ?? defaultHandleBrainSetJwtToken,
|
|
110595
|
+
onBrainSetApiKey: props.handleBrainSetApiKey ?? defaultHandleBrainSetApiKey,
|
|
110596
|
+
onBrainLogout: props.handleBrainLogout ?? defaultHandleBrainLogout,
|
|
107956
110597
|
plan: props.plan
|
|
107957
110598
|
});
|
|
107958
110599
|
props.handleExit();
|
|
@@ -107962,34 +110603,34 @@ var renderApp = async (props) => {
|
|
|
107962
110603
|
init_terminal2();
|
|
107963
110604
|
|
|
107964
110605
|
// src/services/project-setup-service.ts
|
|
107965
|
-
import
|
|
107966
|
-
import
|
|
110606
|
+
import fs18 from "fs/promises";
|
|
110607
|
+
import path17 from "path";
|
|
107967
110608
|
var CODETYPER_DIR = ".codetyper";
|
|
107968
110609
|
var AGENTS_DIR = "agents";
|
|
107969
110610
|
var GITIGNORE_ENTRY = ".codetyper/";
|
|
107970
110611
|
var fileExists2 = async (filePath2) => {
|
|
107971
110612
|
try {
|
|
107972
|
-
await
|
|
110613
|
+
await fs18.access(filePath2);
|
|
107973
110614
|
return true;
|
|
107974
110615
|
} catch {
|
|
107975
110616
|
return false;
|
|
107976
110617
|
}
|
|
107977
110618
|
};
|
|
107978
110619
|
var isGitRepository = async (workingDir3) => {
|
|
107979
|
-
return fileExists2(
|
|
110620
|
+
return fileExists2(path17.join(workingDir3, ".git"));
|
|
107980
110621
|
};
|
|
107981
110622
|
var ensureDirectoryExists = async (dirPath) => {
|
|
107982
110623
|
try {
|
|
107983
|
-
await
|
|
110624
|
+
await fs18.mkdir(dirPath, { recursive: true });
|
|
107984
110625
|
} catch {}
|
|
107985
110626
|
};
|
|
107986
110627
|
var addToGitignore = async (workingDir3) => {
|
|
107987
|
-
const gitignorePath =
|
|
110628
|
+
const gitignorePath = path17.join(workingDir3, ".gitignore");
|
|
107988
110629
|
try {
|
|
107989
110630
|
let content = "";
|
|
107990
110631
|
const exists = await fileExists2(gitignorePath);
|
|
107991
110632
|
if (exists) {
|
|
107992
|
-
content = await
|
|
110633
|
+
content = await fs18.readFile(gitignorePath, "utf-8");
|
|
107993
110634
|
const lines = content.split(`
|
|
107994
110635
|
`).map((line2) => line2.trim());
|
|
107995
110636
|
if (lines.includes(GITIGNORE_ENTRY) || lines.includes(CODETYPER_DIR)) {
|
|
@@ -108001,7 +110642,7 @@ var addToGitignore = async (workingDir3) => {
|
|
|
108001
110642
|
` : `${content}
|
|
108002
110643
|
${GITIGNORE_ENTRY}
|
|
108003
110644
|
`;
|
|
108004
|
-
await
|
|
110645
|
+
await fs18.writeFile(gitignorePath, newContent, "utf-8");
|
|
108005
110646
|
return true;
|
|
108006
110647
|
} catch {
|
|
108007
110648
|
return false;
|
|
@@ -108242,17 +110883,17 @@ ${agent.prompt}
|
|
|
108242
110883
|
`;
|
|
108243
110884
|
};
|
|
108244
110885
|
var createDefaultAgents = async (workingDir3) => {
|
|
108245
|
-
const agentsDir =
|
|
110886
|
+
const agentsDir = path17.join(workingDir3, CODETYPER_DIR, AGENTS_DIR);
|
|
108246
110887
|
const created = [];
|
|
108247
110888
|
await ensureDirectoryExists(agentsDir);
|
|
108248
110889
|
for (const agent of DEFAULT_AGENTS) {
|
|
108249
|
-
const filePath2 =
|
|
110890
|
+
const filePath2 = path17.join(agentsDir, `${agent.id}.agent.md`);
|
|
108250
110891
|
if (await fileExists2(filePath2)) {
|
|
108251
110892
|
continue;
|
|
108252
110893
|
}
|
|
108253
110894
|
try {
|
|
108254
110895
|
const content = generateAgentFile(agent);
|
|
108255
|
-
await
|
|
110896
|
+
await fs18.writeFile(filePath2, content, "utf-8");
|
|
108256
110897
|
created.push(agent.id);
|
|
108257
110898
|
} catch {}
|
|
108258
110899
|
}
|
|
@@ -108277,12 +110918,12 @@ var setupProject = async (workingDir3) => {
|
|
|
108277
110918
|
};
|
|
108278
110919
|
var getSetupStatus = async (workingDir3) => {
|
|
108279
110920
|
const hasGit = await isGitRepository(workingDir3);
|
|
108280
|
-
const hasCodetyperDir = await fileExists2(
|
|
110921
|
+
const hasCodetyperDir = await fileExists2(path17.join(workingDir3, CODETYPER_DIR));
|
|
108281
110922
|
let agentCount = 0;
|
|
108282
110923
|
if (hasCodetyperDir) {
|
|
108283
|
-
const agentsDir =
|
|
110924
|
+
const agentsDir = path17.join(workingDir3, CODETYPER_DIR, AGENTS_DIR);
|
|
108284
110925
|
if (await fileExists2(agentsDir)) {
|
|
108285
|
-
const files = await
|
|
110926
|
+
const files = await fs18.readdir(agentsDir);
|
|
108286
110927
|
agentCount = files.filter((f) => f.endsWith(".agent.md")).length;
|
|
108287
110928
|
}
|
|
108288
110929
|
}
|
|
@@ -108598,13 +111239,13 @@ var approvePlan = () => {
|
|
|
108598
111239
|
|
|
108599
111240
|
// src/utils/ensure-directories.ts
|
|
108600
111241
|
init_paths();
|
|
108601
|
-
import { mkdir as
|
|
111242
|
+
import { mkdir as mkdir4 } from "fs/promises";
|
|
108602
111243
|
var ensureXdgDirectories = async () => {
|
|
108603
|
-
await
|
|
108604
|
-
await
|
|
108605
|
-
await
|
|
108606
|
-
await
|
|
108607
|
-
await
|
|
111244
|
+
await mkdir4(DIRS.config, { recursive: true });
|
|
111245
|
+
await mkdir4(DIRS.data, { recursive: true });
|
|
111246
|
+
await mkdir4(DIRS.cache, { recursive: true });
|
|
111247
|
+
await mkdir4(DIRS.state, { recursive: true });
|
|
111248
|
+
await mkdir4(DIRS.sessions, { recursive: true });
|
|
108608
111249
|
};
|
|
108609
111250
|
|
|
108610
111251
|
// src/index.ts
|
|
@@ -108970,4 +111611,4 @@ ${plan.steps.map((s) => `${s.id}. ${s.description}`).join(`
|
|
|
108970
111611
|
});
|
|
108971
111612
|
program2.parse(process.argv);
|
|
108972
111613
|
|
|
108973
|
-
//# debugId=
|
|
111614
|
+
//# debugId=6760CDEC64E149A464756E2164756E21
|