@krishivpb60/aether-ai-cli 1.1.5 → 1.1.7

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.
@@ -0,0 +1,62 @@
1
+ import { test } from "node:test";
2
+ import assert from "node:assert";
3
+ import { resolve, join } from "node:path";
4
+ import {
5
+ isSafeCommand,
6
+ isInsideWorkspace,
7
+ processAgentBlocks
8
+ } from "../src/agent.js";
9
+
10
+ test("Agent Autopilot Engine Suite", async (t) => {
11
+ await t.test("isSafeCommand classifies inspection commands as safe", () => {
12
+ assert.strictEqual(isSafeCommand("git status"), true);
13
+ assert.strictEqual(isSafeCommand("git diff"), true);
14
+ assert.strictEqual(isSafeCommand("ls"), true);
15
+ assert.strictEqual(isSafeCommand("dir -a"), true);
16
+ assert.strictEqual(isSafeCommand("npm test"), true);
17
+ assert.strictEqual(isSafeCommand("node -v"), true);
18
+ });
19
+
20
+ await t.test("isSafeCommand classifies destructive/unsafe commands as unsafe", () => {
21
+ assert.strictEqual(isSafeCommand("rm -rf src"), false);
22
+ assert.strictEqual(isSafeCommand("del /f /q *"), false);
23
+ assert.strictEqual(isSafeCommand("format c:"), false);
24
+ assert.strictEqual(isSafeCommand("npm run dev"), false);
25
+ });
26
+
27
+ await t.test("isInsideWorkspace verifies if path is inside current workspace", () => {
28
+ const ws = resolve(process.cwd());
29
+ assert.strictEqual(isInsideWorkspace("src/config.js"), true);
30
+ assert.strictEqual(isInsideWorkspace(join(ws, "package.json")), true);
31
+ assert.strictEqual(isInsideWorkspace("../../somefile.txt"), false);
32
+ });
33
+
34
+ await t.test("processAgentBlocks extracts and processes tools sequentially", async () => {
35
+ const aiOutput = `
36
+ I will read a file and run a command.
37
+ [READ_FILE: src/git.js]
38
+ And also run:
39
+ [RUN_COMMAND: node -v]
40
+ `;
41
+
42
+ const aiConfig = { AUTOPILOT: "safe" };
43
+ // Mock readline interface
44
+ const rl = {
45
+ pause: () => {},
46
+ resume: () => {},
47
+ question: (query, cb) => cb("y")
48
+ };
49
+
50
+ const results = await processAgentBlocks(aiOutput, aiConfig, rl);
51
+ assert.strictEqual(results.length, 2);
52
+
53
+ // First tool result should be READ_FILE
54
+ assert.strictEqual(results[0].tool, "READ_FILE");
55
+ assert.strictEqual(results[0].arg, "src/git.js");
56
+
57
+ // Second tool result should be RUN_COMMAND
58
+ assert.strictEqual(results[1].tool, "RUN_COMMAND");
59
+ assert.strictEqual(results[1].arg, "node -v");
60
+ assert.strictEqual(results[1].success, true);
61
+ });
62
+ });
@@ -25,6 +25,9 @@ const {
25
25
  loadHistory,
26
26
  saveHistory,
27
27
  clearHistory,
28
+ listSessions,
29
+ switchSession,
30
+ startNewSession,
28
31
  } = await import("../src/config.js");
29
32
 
30
33
  const { getAllConfigKeys } = await import("../src/ai/providers.js");
@@ -170,6 +173,30 @@ test("Configuration Loading Suite", async (t) => {
170
173
  assert.deepStrictEqual(cleared, []);
171
174
  });
172
175
 
176
+ await t.test("listSessions, switchSession, and startNewSession handle multi-session histories", async () => {
177
+ // 1. Start new session
178
+ const file1 = startNewSession();
179
+ await saveHistory([{ role: "user", content: "session 1" }], "research");
180
+
181
+ // 2. Start another new session
182
+ const file2 = startNewSession();
183
+ await saveHistory([{ role: "user", content: "session 2" }], "architect");
184
+
185
+ // 3. List sessions
186
+ const sessions = listSessions();
187
+ assert.ok(sessions.length >= 2);
188
+ // The most recent session (file2) should be first
189
+ assert.strictEqual(sessions[0].file, file2);
190
+ assert.strictEqual(sessions[0].mode, "architect");
191
+ assert.strictEqual(sessions[1].file, file1);
192
+ assert.strictEqual(sessions[1].mode, "research");
193
+
194
+ // 4. Switch session back to file1
195
+ switchSession(file1);
196
+ const loaded = await loadHistory();
197
+ assert.strictEqual(loaded[0].content, "session 1");
198
+ });
199
+
173
200
  await t.test("getAIConfig supports and loads CUSTOM_COMMANDS correctly", async () => {
174
201
  const testCommands = { "/explain": "Explain this:", "/refactor": "Refactor this:" };
175
202
  await saveConfig({
package/test/ux.test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { test, beforeEach, afterEach } from "node:test";
2
2
  import assert from "node:assert";
3
- import { separator, clearStreamedText, StreamFilter, getActiveTheme, setTheme, getThemesList } from "../src/ui/theme.js";
3
+ import { separator, clearStreamedText, StreamFilter, stripCodeFences, getActiveTheme, setTheme, getThemesList } from "../src/ui/theme.js";
4
4
  import { createSpinner } from "../src/ui/spinner.js";
5
5
  import { routePrompt } from "../src/ai/router.js";
6
6
  import { getModeByName, MODES } from "../src/modes.js";
@@ -167,4 +167,15 @@ test("Cyberpunk UX and Streaming Suite", async (t) => {
167
167
  assert.ok(output.includes("File creation request: test.txt"));
168
168
  assert.ok(!output.includes("This content is hidden"));
169
169
  });
170
+
171
+ await t.test("stripCodeFences should clean code blocks with backticks", () => {
172
+ const jsBlock = "```javascript\nconsole.log('hi');\n```";
173
+ assert.strictEqual(stripCodeFences(jsBlock), "console.log('hi');");
174
+
175
+ const htmlBlock = "```html\n<div>hello</div>\n```";
176
+ assert.strictEqual(stripCodeFences(htmlBlock), "<div>hello</div>");
177
+
178
+ const noFenceBlock = "console.log('hi');";
179
+ assert.strictEqual(stripCodeFences(noFenceBlock), "console.log('hi');");
180
+ });
170
181
  });