@krishivpb60/aether-ai-cli 1.3.11 → 1.4.0
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/HIGHLIGHTS.md +9 -0
- package/package.json +1 -1
- package/src/chat.js +3 -2
- package/src/config.js +1 -1
- package/src/ui/banner.js +6 -6
- package/src/ui/dashboard.html +1 -1
- package/src/ui/theme.js +26 -0
- package/test/config.test.js +1 -0
- package/test/ux.test.js +17 -1
package/HIGHLIGHTS.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# Aether CLI v1.4.0 Highlights
|
|
2
|
+
- **Microphone Audio Input & Dynamic Nerd Font Glyphs (`/mic`)**:
|
|
3
|
+
- Adds `/mic` voice command to record audio directly from your microphone inside the terminal session.
|
|
4
|
+
- Implements native zero-dependency audio recording on Windows using the WinMM Multimedia Control Interface (MCI) via PowerShell.
|
|
5
|
+
- Automatically transcribes speech using Google Gemini (base64 inlineData), Groq Whisper, or OpenAI Whisper.
|
|
6
|
+
- Fixes readline interface raw mode pausing blockages to ensure Enter keypress resolves transcription correctly.
|
|
7
|
+
- Introduces dynamic `getIcon` helper supporting high-definition vector icons in the terminal.
|
|
8
|
+
- Adds optional `"NERD_FONTS"` configuration parameter (`aether config set NERD_FONTS true`) to automatically switch between standard emojis and Nerd Font glyphs (like FontAwesome microphones, folders, gears, and branch trees) based on your preferences.
|
|
9
|
+
|
|
1
10
|
# Aether CLI v1.3.11 Highlights
|
|
2
11
|
- **Microphone Audio Input Non-TTY Safety & Transcription (`/mic`)**:
|
|
3
12
|
- Adds `/mic` voice command to record audio directly from your microphone inside the terminal session.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@krishivpb60/aether-ai-cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Aether Core AI — A cyberpunk command-line AI assistant with multi-mode reasoning, 12-node failover mesh, file context injection, and offline fallbacks.",
|
|
5
5
|
"main": "src/cli.js",
|
|
6
6
|
"bin": {
|
package/src/chat.js
CHANGED
|
@@ -25,7 +25,8 @@ import {
|
|
|
25
25
|
getActiveTheme,
|
|
26
26
|
setTheme,
|
|
27
27
|
getThemesList,
|
|
28
|
-
interactiveMenu
|
|
28
|
+
interactiveMenu,
|
|
29
|
+
getIcon
|
|
29
30
|
} from "./ui/theme.js";
|
|
30
31
|
import { createSpinner } from "./ui/spinner.js";
|
|
31
32
|
import { showBanner } from "./ui/banner.js";
|
|
@@ -2256,7 +2257,7 @@ export async function handleMicInput(ctx) {
|
|
|
2256
2257
|
return;
|
|
2257
2258
|
}
|
|
2258
2259
|
|
|
2259
|
-
console.log("\n" + label.system + " " + colors.brand("
|
|
2260
|
+
console.log("\n" + label.system + " " + colors.brand(getIcon("mic", ctx.aiConfig) + "AUDIO VOICE INPUT"));
|
|
2260
2261
|
console.log(separator("─"));
|
|
2261
2262
|
console.log(colors.accent(" Recording started..."));
|
|
2262
2263
|
console.log(" " + colors.muted("Speak into your microphone."));
|
package/src/config.js
CHANGED
|
@@ -176,7 +176,7 @@ export function isValidConfigKey(key) {
|
|
|
176
176
|
const allowedSpecialKeys = [
|
|
177
177
|
"THEME", "CUSTOM_COMMANDS", "AUTOPILOT",
|
|
178
178
|
"AUTO_UPDATE", "SHOW_HIGHLIGHTS", "LAST_UPDATE_CHECK", "LAST_NOTIFIED_VERSION",
|
|
179
|
-
"SHOW_TOKENS", "DIAGNOSE_CMD"
|
|
179
|
+
"SHOW_TOKENS", "DIAGNOSE_CMD", "NERD_FONTS"
|
|
180
180
|
];
|
|
181
181
|
if (upper.endsWith("_API_KEY") || upper.endsWith("_API_KEYS") || upper.endsWith("_MODEL") || allowedSpecialKeys.includes(upper)) {
|
|
182
182
|
return true;
|
package/src/ui/banner.js
CHANGED
|
@@ -7,7 +7,7 @@ import { readFileSync, existsSync } from "node:fs";
|
|
|
7
7
|
import { join } from "node:path";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
9
|
import chalk from "chalk";
|
|
10
|
-
import { colors, separator, modeBadge } from "./theme.js";
|
|
10
|
+
import { colors, separator, modeBadge, getIcon } from "./theme.js";
|
|
11
11
|
import { getActiveProviders } from "../ai/providers.js";
|
|
12
12
|
import { MODES } from "../modes.js";
|
|
13
13
|
|
|
@@ -137,11 +137,11 @@ export function showBanner(currentMode = "titan") {
|
|
|
137
137
|
: "npm (@krishivpb60/aether-ai-cli)";
|
|
138
138
|
|
|
139
139
|
const rows = [
|
|
140
|
-
formatRow(` ${colors.muted("
|
|
141
|
-
formatRow(` ${colors.muted("
|
|
142
|
-
formatRow(` ${colors.muted("
|
|
143
|
-
formatRow(` ${colors.muted("
|
|
144
|
-
formatRow(` ${colors.muted("
|
|
140
|
+
formatRow(` ${colors.muted(getIcon("workspace", config) + "Workspace")}`, colors.text(workspaceValue)),
|
|
141
|
+
formatRow(` ${colors.muted(getIcon("mode", config) + "Mode")}`, modeRowValue),
|
|
142
|
+
formatRow(` ${colors.muted(getIcon("network", config) + "Network")}`, meshStatusText),
|
|
143
|
+
formatRow(` ${colors.muted(getIcon("engine", config) + "Engine")}`, colors.text(engineValue)),
|
|
144
|
+
formatRow(` ${colors.muted(getIcon("package", config) + "Packager")}`, colors.text(packagerText)),
|
|
145
145
|
];
|
|
146
146
|
|
|
147
147
|
console.log(`\n ⚡ ${colors.brand("AETHER COMMAND STATION v" + version)} • Welcome back, ${colors.accent(username)}`);
|
package/src/ui/dashboard.html
CHANGED
package/src/ui/theme.js
CHANGED
|
@@ -486,3 +486,29 @@ export async function interactiveMenu(headerText, items) {
|
|
|
486
486
|
stdin.on("data", handleKey);
|
|
487
487
|
});
|
|
488
488
|
}
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Returns either a premium Nerd Font glyph or a standard Unicode emoji fallback
|
|
492
|
+
* depending on whether NERD_FONTS is enabled in the configuration.
|
|
493
|
+
* @param {string} name - Icon name
|
|
494
|
+
* @param {object} config - Active configuration object
|
|
495
|
+
* @returns {string}
|
|
496
|
+
*/
|
|
497
|
+
export function getIcon(name, config) {
|
|
498
|
+
const useNerd = config?.NERD_FONTS === true || config?.NERD_FONTS === "true";
|
|
499
|
+
|
|
500
|
+
const icons = {
|
|
501
|
+
workspace: useNerd ? "\uf07c " : "📂 ",
|
|
502
|
+
mode: useNerd ? "\uf0e0 " : "🧠 ", // brain / envelope-like modes icon
|
|
503
|
+
network: useNerd ? "\uf6ff " : "🟢 ", // network icon
|
|
504
|
+
engine: useNerd ? "\uf013 " : "⚙️ ", // gear icon
|
|
505
|
+
package: useNerd ? "\uf1b2 " : "📦 ", // package icon
|
|
506
|
+
mic: useNerd ? "\uf130 " : "🎤 ", // microphone icon
|
|
507
|
+
git: useNerd ? "\uf113 " : "🌿 ", // git/leaf icon
|
|
508
|
+
dashboard: useNerd ? "\uf201 " : "📊 ", // chart icon
|
|
509
|
+
bolt: useNerd ? "\uf0e7 " : "⚡ ", // lightning bolt icon
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
return icons[name] || "";
|
|
513
|
+
}
|
|
514
|
+
|
package/test/config.test.js
CHANGED
|
@@ -148,6 +148,7 @@ test("Configuration Loading Suite", async (t) => {
|
|
|
148
148
|
assert.strictEqual(isValidConfigKey("GOOGLE_API_KEYS"), true);
|
|
149
149
|
assert.strictEqual(isValidConfigKey("THEME"), true);
|
|
150
150
|
assert.strictEqual(isValidConfigKey("CUSTOM_COMMANDS"), true);
|
|
151
|
+
assert.strictEqual(isValidConfigKey("NERD_FONTS"), true);
|
|
151
152
|
assert.strictEqual(isValidConfigKey("INVALID_KEY_NAME"), false);
|
|
152
153
|
});
|
|
153
154
|
|
package/test/ux.test.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { test, beforeEach, afterEach } from "node:test";
|
|
2
2
|
import assert from "node:assert";
|
|
3
3
|
import { ReadableStream } from "node:stream/web";
|
|
4
|
-
import { separator, clearStreamedText, StreamFilter, stripCodeFences, getActiveTheme, setTheme, getThemesList } from "../src/ui/theme.js";
|
|
4
|
+
import { separator, clearStreamedText, StreamFilter, stripCodeFences, getActiveTheme, setTheme, getThemesList, getIcon } from "../src/ui/theme.js";
|
|
5
5
|
import { createSpinner } from "../src/ui/spinner.js";
|
|
6
6
|
import { routePrompt } from "../src/ai/router.js";
|
|
7
7
|
import { getModeByName, MODES } from "../src/modes.js";
|
|
@@ -183,4 +183,20 @@ test("Cyberpunk UX and Streaming Suite", async (t) => {
|
|
|
183
183
|
const noFenceBlock = "console.log('hi');";
|
|
184
184
|
assert.strictEqual(stripCodeFences(noFenceBlock), "console.log('hi');");
|
|
185
185
|
});
|
|
186
|
+
|
|
187
|
+
await t.test("getIcon returns Nerd Font glyphs if enabled, else defaults to emojis", () => {
|
|
188
|
+
const nerdConfig = { NERD_FONTS: true };
|
|
189
|
+
const emojiConfig = { NERD_FONTS: false };
|
|
190
|
+
const defaultConfig = {};
|
|
191
|
+
|
|
192
|
+
// 1. Nerd Font Enabled
|
|
193
|
+
assert.strictEqual(getIcon("mic", nerdConfig), "\uf130 ");
|
|
194
|
+
assert.strictEqual(getIcon("git", nerdConfig), "\uf113 ");
|
|
195
|
+
assert.strictEqual(getIcon("dashboard", nerdConfig), "\uf201 ");
|
|
196
|
+
|
|
197
|
+
// 2. Nerd Font Disabled / Empty
|
|
198
|
+
assert.strictEqual(getIcon("mic", emojiConfig), "🎤 ");
|
|
199
|
+
assert.strictEqual(getIcon("git", emojiConfig), "🌿 ");
|
|
200
|
+
assert.strictEqual(getIcon("mic", defaultConfig), "🎤 ");
|
|
201
|
+
});
|
|
186
202
|
});
|