@menteeai/menteeswe 0.1.4 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +137 -94
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -96,6 +96,97 @@ var init_base = __esm({
|
|
|
96
96
|
}
|
|
97
97
|
});
|
|
98
98
|
|
|
99
|
+
// src/tools/exec.ts
|
|
100
|
+
import { spawn } from "child_process";
|
|
101
|
+
function killTree(child) {
|
|
102
|
+
if (child.pid === void 0) return;
|
|
103
|
+
if (process.platform === "win32") {
|
|
104
|
+
spawn(`taskkill /pid ${String(child.pid)} /T /F`, { stdio: "ignore", shell: true });
|
|
105
|
+
} else {
|
|
106
|
+
child.kill("SIGKILL");
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function killActiveChild() {
|
|
110
|
+
if (activeChild) killTree(activeChild);
|
|
111
|
+
}
|
|
112
|
+
async function runShellCommand(command, cwd, timeoutMs = 12e4, maxChars = 1e5) {
|
|
113
|
+
return new Promise((resolve) => {
|
|
114
|
+
const started = Date.now();
|
|
115
|
+
const child = spawn(command, {
|
|
116
|
+
shell: true,
|
|
117
|
+
cwd,
|
|
118
|
+
env: { ...process.env, MENTEE: "1" },
|
|
119
|
+
windowsHide: true
|
|
120
|
+
});
|
|
121
|
+
activeChild = child;
|
|
122
|
+
let stdout = "";
|
|
123
|
+
let stderr = "";
|
|
124
|
+
let killed = false;
|
|
125
|
+
const timer = setTimeout(() => {
|
|
126
|
+
killed = true;
|
|
127
|
+
killTree(child);
|
|
128
|
+
}, timeoutMs);
|
|
129
|
+
child.stdout?.on("data", (chunk) => {
|
|
130
|
+
if (stdout.length < maxChars * 2) stdout += chunk.toString("utf8");
|
|
131
|
+
});
|
|
132
|
+
child.stderr?.on("data", (chunk) => {
|
|
133
|
+
if (stderr.length < maxChars * 2) stderr += chunk.toString("utf8");
|
|
134
|
+
});
|
|
135
|
+
child.on("error", (error) => {
|
|
136
|
+
clearTimeout(timer);
|
|
137
|
+
if (activeChild === child) activeChild = null;
|
|
138
|
+
resolve({
|
|
139
|
+
exitCode: -1,
|
|
140
|
+
stdout,
|
|
141
|
+
stderr: `${stderr}
|
|
142
|
+
${error.message}`.trim(),
|
|
143
|
+
durationMs: Date.now() - started
|
|
144
|
+
});
|
|
145
|
+
});
|
|
146
|
+
child.on("close", (code) => {
|
|
147
|
+
clearTimeout(timer);
|
|
148
|
+
if (activeChild === child) activeChild = null;
|
|
149
|
+
resolve({
|
|
150
|
+
exitCode: killed ? "timeout" : code ?? -1,
|
|
151
|
+
stdout,
|
|
152
|
+
stderr,
|
|
153
|
+
durationMs: Date.now() - started
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function formatOutcome(outcome, maxChars = 1e5) {
|
|
159
|
+
const cut = (text, limit) => {
|
|
160
|
+
if (text.length <= limit) return { text, truncated: false };
|
|
161
|
+
const head = Math.floor(limit * 0.7);
|
|
162
|
+
return {
|
|
163
|
+
text: `${text.slice(0, head)}
|
|
164
|
+
...[truncated, ${text.length - head} chars removed]...`,
|
|
165
|
+
truncated: true
|
|
166
|
+
};
|
|
167
|
+
};
|
|
168
|
+
const out = cut(outcome.stdout.trim(), maxChars);
|
|
169
|
+
const err = cut(outcome.stderr.trim(), Math.floor(maxChars / 2));
|
|
170
|
+
const sections = [`exit_code: ${outcome.exitCode}`, `duration_ms: ${outcome.durationMs}`];
|
|
171
|
+
if (out.text) sections.push(`stdout:
|
|
172
|
+
${out.text}`);
|
|
173
|
+
if (err.text) sections.push(`stderr:
|
|
174
|
+
${err.text}`);
|
|
175
|
+
if (!out.text && !err.text) sections.push("(no output)");
|
|
176
|
+
return {
|
|
177
|
+
output: sections.join("\n"),
|
|
178
|
+
success: outcome.exitCode === 0,
|
|
179
|
+
truncated: out.truncated || err.truncated
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
var activeChild;
|
|
183
|
+
var init_exec = __esm({
|
|
184
|
+
"src/tools/exec.ts"() {
|
|
185
|
+
"use strict";
|
|
186
|
+
activeChild = null;
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
|
|
99
190
|
// src/events.ts
|
|
100
191
|
var EventBus;
|
|
101
192
|
var init_events = __esm({
|
|
@@ -159,7 +250,7 @@ function formatEvent(event) {
|
|
|
159
250
|
case "model_request":
|
|
160
251
|
return chalk.gray("\u25CF thinking...");
|
|
161
252
|
case "info":
|
|
162
|
-
return chalk.cyan(
|
|
253
|
+
return chalk.cyan.bold(`\u{1F4AD} ${event.message ?? ""}`);
|
|
163
254
|
case "tool_started": {
|
|
164
255
|
const tool = typeof event.data?.tool === "string" ? event.data.tool : "";
|
|
165
256
|
const color = CATEGORY_COLOR[TOOL_CATEGORY[tool] ?? "other"];
|
|
@@ -202,8 +293,10 @@ function formatEvent(event) {
|
|
|
202
293
|
const sep = chalk.dim("\u2500".repeat(48));
|
|
203
294
|
const statsLine = chalk.cyan(` ${stats.join(" \xB7 ")}`);
|
|
204
295
|
const statusLine = success ? chalk.green.bold("\u2714 Task completed") : chalk.red.bold("\u2716 Task failed");
|
|
205
|
-
const
|
|
206
|
-
|
|
296
|
+
const filesLine = modifiedFiles.length > 0 ? chalk.cyan.dim(` \u{1F4DD} ${modifiedFiles.length} file(s): ${modifiedFiles.join(", ")}`) : "";
|
|
297
|
+
const tipLine = success ? chalk.dim(" Next: type a new task, or /help for commands") : chalk.yellow.dim(" The task did not finish \u2014 check the steps above and retry");
|
|
298
|
+
const block = [sep, statusLine, statsLine, filesLine, tipLine, sep, ""];
|
|
299
|
+
return block.filter((line) => line !== "").join("\n");
|
|
207
300
|
}
|
|
208
301
|
default:
|
|
209
302
|
return null;
|
|
@@ -593,7 +686,8 @@ async function runAgent(options) {
|
|
|
593
686
|
bus,
|
|
594
687
|
approval,
|
|
595
688
|
maxIterations = 40,
|
|
596
|
-
systemExtra
|
|
689
|
+
systemExtra,
|
|
690
|
+
signal
|
|
597
691
|
} = options;
|
|
598
692
|
const state = createAgentState(task, maxIterations);
|
|
599
693
|
const prior = formatConversationContext(cwd);
|
|
@@ -618,6 +712,10 @@ ${systemExtra}` : "");
|
|
|
618
712
|
let finalText = "";
|
|
619
713
|
let sawFinish = false;
|
|
620
714
|
while (state.iteration < maxIterations) {
|
|
715
|
+
if (signal?.aborted) {
|
|
716
|
+
finalText = "Task cancelled.";
|
|
717
|
+
break;
|
|
718
|
+
}
|
|
621
719
|
state.iteration += 1;
|
|
622
720
|
state.usage.modelRequests += 1;
|
|
623
721
|
bus.emit("model_request", `iteration ${state.iteration}/${maxIterations}`);
|
|
@@ -774,6 +872,10 @@ ${systemExtra}` : "");
|
|
|
774
872
|
content: result.output
|
|
775
873
|
});
|
|
776
874
|
}
|
|
875
|
+
if (signal?.aborted) {
|
|
876
|
+
finalText = "Task cancelled.";
|
|
877
|
+
break;
|
|
878
|
+
}
|
|
777
879
|
if (estimateContextChars(messages, system) > MAX_CONTEXT_CHARS) {
|
|
778
880
|
bus.emit("warning", "Context is large; trimming oldest tool outputs.");
|
|
779
881
|
trimOldToolResults(messages);
|
|
@@ -784,7 +886,7 @@ ${systemExtra}` : "");
|
|
|
784
886
|
bus.emit("warning", finalText);
|
|
785
887
|
}
|
|
786
888
|
const success = sawFinish && state.errors.length === 0;
|
|
787
|
-
if (finalText) appendTurn(cwd, task, finalText);
|
|
889
|
+
if (finalText && !signal?.aborted) appendTurn(cwd, task, finalText);
|
|
788
890
|
bus.emit("task_completed", finalText.slice(0, 400), {
|
|
789
891
|
success,
|
|
790
892
|
finalText,
|
|
@@ -977,7 +1079,7 @@ var init_KeyDialog = __esm({
|
|
|
977
1079
|
var version;
|
|
978
1080
|
var init_package = __esm({
|
|
979
1081
|
"package.json"() {
|
|
980
|
-
version = "0.1.
|
|
1082
|
+
version = "0.1.7";
|
|
981
1083
|
}
|
|
982
1084
|
});
|
|
983
1085
|
|
|
@@ -1019,6 +1121,7 @@ function App(props) {
|
|
|
1019
1121
|
const counter = useRef(0);
|
|
1020
1122
|
const stateRef = useRef({ running, approval, dialog, factoryResult, providerName, model });
|
|
1021
1123
|
stateRef.current = { running, approval, dialog, factoryResult, providerName, model };
|
|
1124
|
+
const abortRef = useRef(null);
|
|
1022
1125
|
const appendLog = (text) => {
|
|
1023
1126
|
if (!text) return;
|
|
1024
1127
|
counter.current += 1;
|
|
@@ -1069,6 +1172,12 @@ function App(props) {
|
|
|
1069
1172
|
const timer = setInterval(() => setFrame((f) => (f + 1) % SPINNER_FRAMES.length), 80);
|
|
1070
1173
|
return () => clearInterval(timer);
|
|
1071
1174
|
}, [running]);
|
|
1175
|
+
useEffect2(() => {
|
|
1176
|
+
const turns = loadConversation(props.cwd);
|
|
1177
|
+
if (turns.length > 0) {
|
|
1178
|
+
appendLog(`Resumed previous session \u2014 ${turns.length} prior turn(s) loaded as context.`);
|
|
1179
|
+
}
|
|
1180
|
+
}, []);
|
|
1072
1181
|
useEffect2(() => {
|
|
1073
1182
|
if (!typing || finalPending == null) return;
|
|
1074
1183
|
if (typedText.length >= finalPending.length) {
|
|
@@ -1223,6 +1332,8 @@ function App(props) {
|
|
|
1223
1332
|
setInspectorIndex(null);
|
|
1224
1333
|
setDetailsOpen(false);
|
|
1225
1334
|
setRunning(true);
|
|
1335
|
+
const ac = new AbortController();
|
|
1336
|
+
abortRef.current = ac;
|
|
1226
1337
|
try {
|
|
1227
1338
|
await runAgent({
|
|
1228
1339
|
task,
|
|
@@ -1233,7 +1344,8 @@ function App(props) {
|
|
|
1233
1344
|
bus,
|
|
1234
1345
|
approval: props.yes ? async () => "allow" : bridge.handler,
|
|
1235
1346
|
maxIterations: props.maxIterations,
|
|
1236
|
-
systemExtra: props.systemExtra
|
|
1347
|
+
systemExtra: props.systemExtra,
|
|
1348
|
+
signal: ac.signal
|
|
1237
1349
|
});
|
|
1238
1350
|
} catch (error) {
|
|
1239
1351
|
bus.emit("error", error.message);
|
|
@@ -1270,16 +1382,22 @@ function App(props) {
|
|
|
1270
1382
|
}
|
|
1271
1383
|
};
|
|
1272
1384
|
useInput4((input, key) => {
|
|
1385
|
+
if (key.ctrl && input === "c") {
|
|
1386
|
+
if (stateRef.current.running) {
|
|
1387
|
+
killActiveChild();
|
|
1388
|
+
abortRef.current?.abort();
|
|
1389
|
+
return;
|
|
1390
|
+
}
|
|
1391
|
+
exit();
|
|
1392
|
+
setTimeout(() => process.exit(0), 50);
|
|
1393
|
+
return;
|
|
1394
|
+
}
|
|
1273
1395
|
if (stateRef.current.dialog || stateRef.current.approval || stateRef.current.running) return;
|
|
1274
1396
|
if (key.meta && (input === "m" || input === "M")) openModelDialog();
|
|
1275
1397
|
else if (key.ctrl && input === "p") setDialog({ kind: "provider" });
|
|
1276
1398
|
else if (key.ctrl && input === "k") setDialog({ kind: "key" });
|
|
1277
1399
|
else if (input === "d" || input === "D") cycleInspector();
|
|
1278
1400
|
else if (input === "t" || input === "T") setShowTools((v) => !v);
|
|
1279
|
-
else if (key.ctrl && input === "c") {
|
|
1280
|
-
exit();
|
|
1281
|
-
setTimeout(() => process.exit(0), 50);
|
|
1282
|
-
}
|
|
1283
1401
|
});
|
|
1284
1402
|
const modelLabel = model ?? factoryResult.provider?.defaultModel ?? (factoryResult.error ? "no key" : "");
|
|
1285
1403
|
const header = /* @__PURE__ */ jsxs4(Box4, { flexDirection: "column", marginBottom: 1, children: [
|
|
@@ -1410,6 +1528,8 @@ var init_App = __esm({
|
|
|
1410
1528
|
init_render();
|
|
1411
1529
|
init_approval();
|
|
1412
1530
|
init_loop();
|
|
1531
|
+
init_conversation();
|
|
1532
|
+
init_exec();
|
|
1413
1533
|
init_config();
|
|
1414
1534
|
init_Approval();
|
|
1415
1535
|
init_SelectDialog();
|
|
@@ -1424,11 +1544,10 @@ var init_App = __esm({
|
|
|
1424
1544
|
"zai-coding": "Z.ai GLM Coding Plan subscription \xB7 api.z.ai/api/coding",
|
|
1425
1545
|
mock: "offline testing \xB7 no network"
|
|
1426
1546
|
};
|
|
1427
|
-
BANNER =
|
|
1428
|
-
|
|
|
1429
|
-
|
|
|
1430
|
-
|
|
|
1431
|
-
\\__/
|
|
1547
|
+
BANNER = ` __ __ \u{1F380}
|
|
1548
|
+
| \\/ |
|
|
1549
|
+
| |
|
|
1550
|
+
| |
|
|
1432
1551
|
MenteE SWE \u2014 https://menteeai.org
|
|
1433
1552
|
Twitter: x.com/menteeaiorg`;
|
|
1434
1553
|
}
|
|
@@ -2375,85 +2494,8 @@ function classifyCommand(command) {
|
|
|
2375
2494
|
return overall;
|
|
2376
2495
|
}
|
|
2377
2496
|
|
|
2378
|
-
// src/tools/exec.ts
|
|
2379
|
-
import { spawn } from "child_process";
|
|
2380
|
-
function killTree(child) {
|
|
2381
|
-
if (child.pid === void 0) return;
|
|
2382
|
-
if (process.platform === "win32") {
|
|
2383
|
-
spawn(`taskkill /pid ${String(child.pid)} /T /F`, { stdio: "ignore", shell: true });
|
|
2384
|
-
} else {
|
|
2385
|
-
child.kill("SIGKILL");
|
|
2386
|
-
}
|
|
2387
|
-
}
|
|
2388
|
-
async function runShellCommand(command, cwd, timeoutMs = 12e4, maxChars = 1e5) {
|
|
2389
|
-
return new Promise((resolve) => {
|
|
2390
|
-
const started = Date.now();
|
|
2391
|
-
const child = spawn(command, {
|
|
2392
|
-
shell: true,
|
|
2393
|
-
cwd,
|
|
2394
|
-
env: { ...process.env, MENTEE: "1" },
|
|
2395
|
-
windowsHide: true
|
|
2396
|
-
});
|
|
2397
|
-
let stdout = "";
|
|
2398
|
-
let stderr = "";
|
|
2399
|
-
let killed = false;
|
|
2400
|
-
const timer = setTimeout(() => {
|
|
2401
|
-
killed = true;
|
|
2402
|
-
killTree(child);
|
|
2403
|
-
}, timeoutMs);
|
|
2404
|
-
child.stdout?.on("data", (chunk) => {
|
|
2405
|
-
if (stdout.length < maxChars * 2) stdout += chunk.toString("utf8");
|
|
2406
|
-
});
|
|
2407
|
-
child.stderr?.on("data", (chunk) => {
|
|
2408
|
-
if (stderr.length < maxChars * 2) stderr += chunk.toString("utf8");
|
|
2409
|
-
});
|
|
2410
|
-
child.on("error", (error) => {
|
|
2411
|
-
clearTimeout(timer);
|
|
2412
|
-
resolve({
|
|
2413
|
-
exitCode: -1,
|
|
2414
|
-
stdout,
|
|
2415
|
-
stderr: `${stderr}
|
|
2416
|
-
${error.message}`.trim(),
|
|
2417
|
-
durationMs: Date.now() - started
|
|
2418
|
-
});
|
|
2419
|
-
});
|
|
2420
|
-
child.on("close", (code) => {
|
|
2421
|
-
clearTimeout(timer);
|
|
2422
|
-
resolve({
|
|
2423
|
-
exitCode: killed ? "timeout" : code ?? -1,
|
|
2424
|
-
stdout,
|
|
2425
|
-
stderr,
|
|
2426
|
-
durationMs: Date.now() - started
|
|
2427
|
-
});
|
|
2428
|
-
});
|
|
2429
|
-
});
|
|
2430
|
-
}
|
|
2431
|
-
function formatOutcome(outcome, maxChars = 1e5) {
|
|
2432
|
-
const cut = (text, limit) => {
|
|
2433
|
-
if (text.length <= limit) return { text, truncated: false };
|
|
2434
|
-
const head = Math.floor(limit * 0.7);
|
|
2435
|
-
return {
|
|
2436
|
-
text: `${text.slice(0, head)}
|
|
2437
|
-
...[truncated, ${text.length - head} chars removed]...`,
|
|
2438
|
-
truncated: true
|
|
2439
|
-
};
|
|
2440
|
-
};
|
|
2441
|
-
const out = cut(outcome.stdout.trim(), maxChars);
|
|
2442
|
-
const err = cut(outcome.stderr.trim(), Math.floor(maxChars / 2));
|
|
2443
|
-
const sections = [`exit_code: ${outcome.exitCode}`, `duration_ms: ${outcome.durationMs}`];
|
|
2444
|
-
if (out.text) sections.push(`stdout:
|
|
2445
|
-
${out.text}`);
|
|
2446
|
-
if (err.text) sections.push(`stderr:
|
|
2447
|
-
${err.text}`);
|
|
2448
|
-
if (!out.text && !err.text) sections.push("(no output)");
|
|
2449
|
-
return {
|
|
2450
|
-
output: sections.join("\n"),
|
|
2451
|
-
success: outcome.exitCode === 0,
|
|
2452
|
-
truncated: out.truncated || err.truncated
|
|
2453
|
-
};
|
|
2454
|
-
}
|
|
2455
|
-
|
|
2456
2497
|
// src/tools/terminal.ts
|
|
2498
|
+
init_exec();
|
|
2457
2499
|
var DEFAULT_TIMEOUT_MS = 12e4;
|
|
2458
2500
|
var MAX_OUTPUT_CHARS = 1e5;
|
|
2459
2501
|
var executeCommand = {
|
|
@@ -2489,6 +2531,7 @@ var executeCommand = {
|
|
|
2489
2531
|
|
|
2490
2532
|
// src/tools/testing.ts
|
|
2491
2533
|
init_base();
|
|
2534
|
+
init_exec();
|
|
2492
2535
|
import fs4 from "fs";
|
|
2493
2536
|
import path4 from "path";
|
|
2494
2537
|
var DEFAULT_TIMEOUT_MS2 = 18e4;
|
package/package.json
CHANGED