premanmcp 1.1.8 → 1.1.9
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/bin/agent.js +20 -14
- package/bin/desktop.js +2 -2
- package/bin/detect.js +29 -0
- package/bin/eval.js +430 -22
- package/bin/eval_entry.js +762 -0
- package/bin/eval_harness.py +166 -5
- package/bin/eval_runtime.js +156 -0
- package/bin/eval_target.js +160 -113
- package/bin/eval_templates.js +684 -0
- package/bin/runner.js +42 -3
- package/bin/shared.js +2 -1
- package/bin/target.js +105 -3
- package/package.json +2 -2
package/bin/agent.js
CHANGED
|
@@ -885,21 +885,27 @@ export function logo(paint, columns) {
|
|
|
885
885
|
/**
|
|
886
886
|
* Hold the terminal, and give it back whatever happens to this process.
|
|
887
887
|
*
|
|
888
|
-
* A session takes
|
|
889
|
-
*
|
|
890
|
-
*
|
|
891
|
-
*
|
|
892
|
-
*
|
|
893
|
-
*
|
|
894
|
-
*
|
|
895
|
-
*
|
|
888
|
+
* A session takes two things that outlive it if nobody puts them back: a
|
|
889
|
+
* scrolling region and the window title. Until now the only thing that
|
|
890
|
+
* returned them was a `finally` around the read loop, which covers a clean
|
|
891
|
+
* exit and nothing else -- not SIGTERM, not the tab being closed, not an
|
|
892
|
+
* exception thrown from a callback rather than from the loop body. And the
|
|
893
|
+
* damage is not self-correcting: the next `preman` sets its region on top of
|
|
894
|
+
* the live one, so a shell keeps its clipped bottom rows until something
|
|
895
|
+
* writes `ESC[r`.
|
|
896
896
|
*
|
|
897
|
-
*
|
|
898
|
-
*
|
|
899
|
-
*
|
|
900
|
-
*
|
|
901
|
-
*
|
|
902
|
-
*
|
|
897
|
+
* It used to be three things, the alternate screen among them, and the order
|
|
898
|
+
* of the hand-back was mostly about that -- margins had to come off before the
|
|
899
|
+
* buffer was left, because `ESC[?1049h` neither saves nor resets them. The
|
|
900
|
+
* session shares the shell's screen now, so there is no buffer to leave and
|
|
901
|
+
* that constraint is gone with it.
|
|
902
|
+
*
|
|
903
|
+
* So restoration is one idempotent routine with every exit wired to it, and
|
|
904
|
+
* the order still matters for what remains: the teardowns registered by the
|
|
905
|
+
* session run first, while the rows they are writing to are still the rows
|
|
906
|
+
* they painted, and the region comes off after them -- released first, the
|
|
907
|
+
* furniture they are erasing would no longer be addressable, because inside a
|
|
908
|
+
* scrolling region the bottom rows cannot be cursored to.
|
|
903
909
|
*
|
|
904
910
|
* `exit` is registered too, as the last resort, which is why every write here
|
|
905
911
|
* is synchronous and every step is wrapped: an exit handler that throws turns a
|
package/bin/desktop.js
CHANGED
|
@@ -445,7 +445,7 @@ const BYTES_PER_MB = 1024 * 1024;
|
|
|
445
445
|
* through. Redirected output gets the summary line that already existed rather
|
|
446
446
|
* than a few hundred carriage returns, which is why this is TTY-only.
|
|
447
447
|
*/
|
|
448
|
-
function progressLine() {
|
|
448
|
+
export function progressLine() {
|
|
449
449
|
if (!process.stdout.isTTY) return { tick: () => {}, clear: () => {} };
|
|
450
450
|
let lastDrawn = 0;
|
|
451
451
|
let width = 0;
|
|
@@ -470,7 +470,7 @@ function progressLine() {
|
|
|
470
470
|
return { tick, clear };
|
|
471
471
|
}
|
|
472
472
|
|
|
473
|
-
async function download(url, destination, onProgress) {
|
|
473
|
+
export async function download(url, destination, onProgress) {
|
|
474
474
|
const controller = new AbortController();
|
|
475
475
|
const timer = setTimeout(() => controller.abort(), DOWNLOAD_TIMEOUT_MS);
|
|
476
476
|
try {
|
package/bin/detect.js
CHANGED
|
@@ -51,6 +51,35 @@ function readIfExists(filePath) {
|
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* The repository's own dotenv values, later files winning.
|
|
56
|
+
*
|
|
57
|
+
* An agent that reads its provider key with a bare `os.getenv` works in a
|
|
58
|
+
* terminal where somebody exported it and fails under a runner that did not --
|
|
59
|
+
* even though the key is sitting in the repository it was started from. Reading
|
|
60
|
+
* these files closes that gap without asking anybody to re-export anything.
|
|
61
|
+
*
|
|
62
|
+
* Callers must treat the result as secret: it belongs in the agent's own child
|
|
63
|
+
* process and nowhere else. It is never logged and never sent to the backend.
|
|
64
|
+
*/
|
|
65
|
+
export function repoEnv(projectPath) {
|
|
66
|
+
const out = {};
|
|
67
|
+
for (const name of ENV_FILES) {
|
|
68
|
+
for (const [key, value] of Object.entries(
|
|
69
|
+
parseEnvFile(readIfExists(path.join(projectPath, name)))
|
|
70
|
+
)) {
|
|
71
|
+
// An empty value is a placeholder, not a value. `OPENAI_API_KEY=` is the
|
|
72
|
+
// normal shape of a committed `.env.example`-style line, and carrying the
|
|
73
|
+
// empty string forward spread it over a real key saved in the dashboard
|
|
74
|
+
// and left the variable unset -- so a run failed for want of a key that
|
|
75
|
+
// was available. Skipping empties keeps the documented precedence
|
|
76
|
+
// (shell, then repository, then stored) true at every layer.
|
|
77
|
+
if (value) out[key] = value;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return out;
|
|
81
|
+
}
|
|
82
|
+
|
|
54
83
|
/** Minimal dotenv reader: KEY=value, ignoring comments, exports, and quotes. */
|
|
55
84
|
export function parseEnvFile(text) {
|
|
56
85
|
const out = {};
|