aether-code 0.36.2 → 0.36.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -28,7 +28,7 @@ import {
28
28
  import readline from "node:readline";
29
29
  import { c, errorLine, divider, setTerminalTitle } from "../src/render.js";
30
30
 
31
- const VERSION = "0.36.2";
31
+ const VERSION = "0.36.3";
32
32
 
33
33
  /**
34
34
  * Try to start MCP servers from ~/.aether/mcp.json. Returns a started
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aether-code",
3
- "version": "0.36.2",
3
+ "version": "0.36.3",
4
4
  "description": "Uncensored AI coding agent for your terminal — Claude Code alternative with MCP support. Reads code, writes files, runs commands. Drives IDA Pro, Roblox Studio, Wireshark, Blender, and any MCP server. No refusal layer.",
5
5
  "homepage": "https://trynoguard.com",
6
6
  "repository": {
package/src/repl.js CHANGED
@@ -9,7 +9,7 @@ import { c, errorLine, turnStats } from "./render.js";
9
9
  import { autoUpdate } from "./update-check.js";
10
10
  import { promptBox, EXIT_SIGNAL } from "./box-input.js";
11
11
 
12
- const VERSION = "0.36.2";
12
+ const VERSION = "0.36.3";
13
13
  const MODEL_NAME = "Aether Core";
14
14
 
15
15
  const MODEL_ALIASES = {
@@ -35,6 +35,21 @@ ${c.gray("Conversation history is kept across messages until you /clear.")}
35
35
 
36
36
  const stripAnsi = (s) => s.replace(/\x1b\[[0-9;]*m/g, "");
37
37
 
38
+ function getVisibleRows() {
39
+ let rows = process.stdout.rows || 24;
40
+ if (process.platform === "win32" && !process.env.WT_SESSION && rows > 60) {
41
+ rows = 24;
42
+ }
43
+ return rows;
44
+ }
45
+
46
+ function pushPromptToBottom(contentLines) {
47
+ const visibleRows = getVisibleRows();
48
+ const promptHeight = 4;
49
+ const gap = Math.max(0, visibleRows - contentLines - promptHeight);
50
+ if (gap > 0) process.stdout.write("\n".repeat(gap));
51
+ }
52
+
38
53
  export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafePaths: initialUnsafePaths, maxTurns: initialMaxTurns, model: initialModel = null, mcpManager = null }) {
39
54
  const initialAlias = Object.values(MODEL_ALIASES).find((a) => a.id === initialModel);
40
55
  const state = {
@@ -88,18 +103,7 @@ export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafe
88
103
  let extraLines = 0;
89
104
  if (updateMsg) { console.log(updateMsg); extraLines++; }
90
105
 
91
- // Push prompt to bottom of visible viewport using newline padding.
92
- // process.stdout.rows is accurate on Windows Terminal (WT_SESSION set),
93
- // macOS, and Linux. On raw cmd.exe/conhost it returns the scroll-buffer
94
- // height (~300) instead of the visible viewport — detect and fall back.
95
- let visibleRows = process.stdout.rows || 24;
96
- if (process.platform === "win32" && !process.env.WT_SESSION && visibleRows > 60) {
97
- visibleRows = 24;
98
- }
99
- const promptHeight = 4;
100
- const contentEnd = bannerLineCount + extraLines;
101
- const gap = Math.max(0, visibleRows - contentEnd - promptHeight);
102
- if (gap > 0) process.stdout.write("\n".repeat(gap));
106
+ pushPromptToBottom(bannerLineCount + extraLines);
103
107
 
104
108
  const inputHistory = [];
105
109
 
@@ -126,6 +130,22 @@ export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafe
126
130
  const echoBar = `\x1b[48;5;236m ${echoDisplay}${" ".repeat(echoPad)}\x1b[0m`;
127
131
  process.stdout.write("\x1b[2J\x1b[H" + bLines.join("\n") + "\n" + echoBar + "\n");
128
132
 
133
+ const contentAbove = bLines.length + 1;
134
+
135
+ // Count newlines in all output during agent run + stats so we know
136
+ // how far down the cursor moved and can pad to the bottom.
137
+ let outputNewlines = 0;
138
+ const _origWrite = process.stdout.write;
139
+ const _boundWrite = _origWrite.bind(process.stdout);
140
+ process.stdout.write = function countingWrite(chunk, ...args) {
141
+ if (typeof chunk === "string") {
142
+ for (let i = 0; i < chunk.length; i++) { if (chunk[i] === "\n") outputNewlines++; }
143
+ } else if (Buffer.isBuffer(chunk)) {
144
+ for (let i = 0; i < chunk.length; i++) { if (chunk[i] === 0x0A) outputNewlines++; }
145
+ }
146
+ return _boundWrite(chunk, ...args);
147
+ };
148
+
129
149
  const t0 = Date.now();
130
150
  const result = await runAgent({
131
151
  initialPrompt: line,
@@ -158,6 +178,10 @@ export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafe
158
178
  });
159
179
  if (stats) console.log(stats);
160
180
  console.log("");
181
+
182
+ // Restore stdout and push prompt to bottom
183
+ process.stdout.write = _origWrite;
184
+ pushPromptToBottom(contentAbove + outputNewlines);
161
185
  }
162
186
  }
163
187