premanmcp 1.1.8 → 1.1.10

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 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 three things that outlive it if nobody puts them back: the
889
- * alternate screen, a scrolling region, and the window title. Until now the
890
- * only thing that returned them was a `finally` around the read loop, which
891
- * covers a clean exit and nothing else -- not SIGTERM, not the tab being
892
- * closed, not an exception thrown from a callback rather than from the loop
893
- * body. And the damage is not self-correcting: the next `preman` sets its
894
- * region on top of the live one, so a shell keeps its clipped bottom rows
895
- * until something writes `ESC[r`.
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
- * So restoration is one idempotent routine with every exit wired to it. The
898
- * order inside it is the part that matters: the teardowns registered by the
899
- * session run first, while the screen they are writing to is still the one
900
- * they painted; then the region is released; then the alternate screen is left,
901
- * because releasing margins after switching buffers would leave them set on the
902
- * shell's screen -- `ESC[?1049h` does not save or reset them.
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 = {};