aether-code 0.33.2 → 0.33.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.
- package/bin/aether-code.js +1 -1
- package/package.json +1 -1
- package/src/box-input.js +14 -13
- package/src/repl.js +23 -26
package/bin/aether-code.js
CHANGED
|
@@ -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.33.
|
|
31
|
+
const VERSION = "0.33.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.33.
|
|
3
|
+
"version": "0.33.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/box-input.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// Minimal prompt input — raw-mode, cmd.exe-safe.
|
|
2
|
-
//
|
|
2
|
+
// Bare "> " prompt with bottom status bar, matching Claude Code's layout.
|
|
3
3
|
//
|
|
4
4
|
// Features:
|
|
5
5
|
// - Ctrl+V / Alt+V: paste image from clipboard
|
|
@@ -23,7 +23,6 @@ const HIDE = "\x1b[?25l";
|
|
|
23
23
|
const SHOW = "\x1b[?25h";
|
|
24
24
|
const INV = (s) => `\x1b[7m${s}\x1b[27m`;
|
|
25
25
|
|
|
26
|
-
// Save clipboard image to a temp file. Returns the file path or null.
|
|
27
26
|
function grabClipboardImage() {
|
|
28
27
|
const tmpFile = path.join(os.tmpdir(), `aether-paste-${Date.now()}.png`);
|
|
29
28
|
|
|
@@ -62,7 +61,7 @@ function grabClipboardImage() {
|
|
|
62
61
|
return null;
|
|
63
62
|
}
|
|
64
63
|
|
|
65
|
-
export function promptBox({ history = [], placeholder = "Message Aether
|
|
64
|
+
export function promptBox({ history = [], placeholder = "Message Aether...", mode = "review" } = {}) {
|
|
66
65
|
return new Promise((resolve) => {
|
|
67
66
|
if (!process.stdin.isTTY) {
|
|
68
67
|
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
@@ -79,16 +78,15 @@ export function promptBox({ history = [], placeholder = "Message Aether…" } =
|
|
|
79
78
|
let lastSigint = 0;
|
|
80
79
|
const clipImages = [];
|
|
81
80
|
|
|
82
|
-
const termW = () => Math.max(30, (process.stdout.columns || 80) -
|
|
81
|
+
const termW = () => Math.max(30, (process.stdout.columns || 80) - 2);
|
|
83
82
|
|
|
84
83
|
const draw = (first) => {
|
|
85
84
|
const W = termW();
|
|
86
85
|
if (!first) process.stdout.write(`\x1b[${drawn}A`);
|
|
87
86
|
process.stdout.write("\x1b[J");
|
|
88
87
|
|
|
89
|
-
|
|
90
|
-
const
|
|
91
|
-
const prefixLen = 2; // "> " visible chars
|
|
88
|
+
const prefixStr = "> ";
|
|
89
|
+
const prefixLen = 2;
|
|
92
90
|
const maxVisible = W - prefixLen;
|
|
93
91
|
const start = pos > maxVisible ? pos - maxVisible : 0;
|
|
94
92
|
const view = buf.slice(start, start + maxVisible);
|
|
@@ -112,12 +110,16 @@ export function promptBox({ history = [], placeholder = "Message Aether…" } =
|
|
|
112
110
|
content = s;
|
|
113
111
|
}
|
|
114
112
|
|
|
115
|
-
//
|
|
116
|
-
const promptLine =
|
|
113
|
+
// Bare prompt — just "> " like Claude Code
|
|
114
|
+
const promptLine = c.dim(prefixStr) + content;
|
|
117
115
|
|
|
118
|
-
//
|
|
119
|
-
const
|
|
120
|
-
const statusBar = c.dim(
|
|
116
|
+
// Bottom status bar — matches Claude's "manual mode on · ? for shortcuts · + for agents"
|
|
117
|
+
const imgNote = clipImages.length > 0 ? c.cyan(" images queued") + c.dim(" \xB7 ") : "";
|
|
118
|
+
const statusBar = c.dim(
|
|
119
|
+
mode + " mode" +
|
|
120
|
+
" \xB7 " + "? for shortcuts" +
|
|
121
|
+
" \xB7 " + "@file for images",
|
|
122
|
+
) + imgNote;
|
|
121
123
|
|
|
122
124
|
process.stdout.write(promptLine + "\n" + statusBar + "\n");
|
|
123
125
|
drawn = 2;
|
|
@@ -162,7 +164,6 @@ export function promptBox({ history = [], placeholder = "Message Aether…" } =
|
|
|
162
164
|
}
|
|
163
165
|
if (key.ctrl && k === "d") return finish(buf.length === 0 ? EXIT_SIGNAL : buf);
|
|
164
166
|
|
|
165
|
-
// Alt+V or Ctrl+V: paste image from clipboard
|
|
166
167
|
if ((key.meta && k === "v") || (key.ctrl && k === "v")) {
|
|
167
168
|
const imgPath = grabClipboardImage();
|
|
168
169
|
if (imgPath) {
|
package/src/repl.js
CHANGED
|
@@ -9,7 +9,7 @@ import { c, errorLine } 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.33.
|
|
12
|
+
const VERSION = "0.33.3";
|
|
13
13
|
const MODEL_NAME = "Aether Core";
|
|
14
14
|
|
|
15
15
|
const MODEL_ALIASES = {
|
|
@@ -49,7 +49,6 @@ export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafe
|
|
|
49
49
|
sessionOut: 0,
|
|
50
50
|
};
|
|
51
51
|
|
|
52
|
-
// Auto-update + balance fetch in parallel — zero startup latency added.
|
|
53
52
|
const updatePromise = autoUpdate().catch(() => null);
|
|
54
53
|
|
|
55
54
|
let needsSetup = false;
|
|
@@ -86,7 +85,7 @@ export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafe
|
|
|
86
85
|
const inputHistory = [];
|
|
87
86
|
|
|
88
87
|
while (true) {
|
|
89
|
-
const raw = await promptBox({ history: inputHistory });
|
|
88
|
+
const raw = await promptBox({ history: inputHistory, mode: state.autoYes ? "auto-yes" : "review" });
|
|
90
89
|
if (raw === EXIT_SIGNAL) { console.log(c.gray("bye.")); return; }
|
|
91
90
|
const line = (raw ?? "").trim();
|
|
92
91
|
if (!line) continue;
|
|
@@ -96,7 +95,6 @@ export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafe
|
|
|
96
95
|
if (line.startsWith("/") || line === "?") {
|
|
97
96
|
const handled = await handleSlash(line, state);
|
|
98
97
|
if (handled === "exit") return;
|
|
99
|
-
printStatusLine(state);
|
|
100
98
|
continue;
|
|
101
99
|
}
|
|
102
100
|
|
|
@@ -120,8 +118,6 @@ export async function runRepl({ cwd: initialCwd, autoYes: initialAutoYes, unsafe
|
|
|
120
118
|
if (!result.ok && result.error) {
|
|
121
119
|
console.log("\n" + errorLine(result.error.message || String(result.error)));
|
|
122
120
|
}
|
|
123
|
-
|
|
124
|
-
printStatusLine(state);
|
|
125
121
|
}
|
|
126
122
|
}
|
|
127
123
|
|
|
@@ -169,7 +165,7 @@ async function handleSlash(line, state) {
|
|
|
169
165
|
try {
|
|
170
166
|
process.chdir(next);
|
|
171
167
|
state.cwd = next;
|
|
172
|
-
console.log(c.gray(`cwd
|
|
168
|
+
console.log(c.gray(`cwd -> ${state.cwd}`));
|
|
173
169
|
} catch (err) {
|
|
174
170
|
console.log(errorLine(err.message));
|
|
175
171
|
}
|
|
@@ -201,7 +197,7 @@ async function handleSlash(line, state) {
|
|
|
201
197
|
state.modelName = MODEL_ALIASES[key].name;
|
|
202
198
|
const premium = state.model !== null;
|
|
203
199
|
console.log(
|
|
204
|
-
c.gray(`model
|
|
200
|
+
c.gray(`model -> ${c.cyan(state.modelName)}`) +
|
|
205
201
|
(premium ? c.gray(" (premium — needs purchased credits, else falls back to Core)") : ""),
|
|
206
202
|
);
|
|
207
203
|
} else {
|
|
@@ -215,35 +211,36 @@ async function handleSlash(line, state) {
|
|
|
215
211
|
return null;
|
|
216
212
|
}
|
|
217
213
|
|
|
218
|
-
/* ───────── banner
|
|
214
|
+
/* ───────── banner ───────── */
|
|
219
215
|
|
|
220
216
|
const shortenPath = (p, max) => (p.length <= max ? p : "..." + p.slice(p.length - max + 3));
|
|
221
217
|
|
|
222
218
|
function printBanner(state) {
|
|
223
219
|
const credits = state.balance != null ? `${state.balance.toLocaleString()} credits` : "";
|
|
224
|
-
const
|
|
220
|
+
const plan = state.plan && state.plan !== "FREE" ? state.plan : "";
|
|
221
|
+
|
|
222
|
+
// Block logo — CP437-safe colored squares, like Claude Code's logo
|
|
223
|
+
const b1 = c.cyan("\xDB\xDB"); // ██ full blocks
|
|
224
|
+
const b2 = c.blue("\xDB\xDB"); // ██ darker accent
|
|
225
|
+
const gap = " ";
|
|
225
226
|
|
|
226
|
-
//
|
|
227
|
+
// 3-line logo + text, no boxes — matches Claude Code layout
|
|
227
228
|
console.log("");
|
|
228
229
|
console.log(
|
|
229
|
-
" " +
|
|
230
|
+
" " + b1 + " " + b2 + gap +
|
|
230
231
|
c.bold("Aether Code") + " " + c.dim("v" + VERSION),
|
|
231
232
|
);
|
|
233
|
+
|
|
234
|
+
const modelParts = [state.modelName];
|
|
235
|
+
if (credits) modelParts.push(credits);
|
|
236
|
+
if (plan) modelParts.push(c.cyan(plan));
|
|
232
237
|
console.log(
|
|
233
|
-
"
|
|
234
|
-
(
|
|
235
|
-
(state.plan && state.plan !== "FREE" ? c.dim(" · ") + c.cyan(state.plan) : ""),
|
|
238
|
+
" " + b2 + " " + b1 + gap +
|
|
239
|
+
modelParts.join(c.dim(" \xB7 ")),
|
|
236
240
|
);
|
|
237
|
-
console.log(" " + c.dim(shortenPath(state.cwd, 60)));
|
|
238
|
-
}
|
|
239
241
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
if (state.messages.length > 0) {
|
|
245
|
-
parts.push(c.gray(`history: ${state.messages.length} msg${state.messages.length === 1 ? "" : "s"}`));
|
|
246
|
-
}
|
|
247
|
-
parts.push(c.cyan(state.autoYes ? "auto-yes" : "review"));
|
|
248
|
-
console.log(c.dim(parts.join(" · ")));
|
|
242
|
+
console.log(
|
|
243
|
+
" " + b1 + " " + b2 + gap +
|
|
244
|
+
c.dim(shortenPath(state.cwd, 60)),
|
|
245
|
+
);
|
|
249
246
|
}
|