@krishivpb60/aether-ai-cli 1.1.6 → 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.
- package/package.json +1 -1
- package/src/agent.js +417 -0
- package/src/chat.js +412 -99
- package/src/cli.js +88 -0
- package/src/config.js +187 -10
- package/src/file-parser.js +48 -1
- package/src/git.js +41 -0
- package/src/ui/theme.js +202 -5
- package/test/agent.test.js +62 -0
- package/test/config.test.js +27 -0
|
@@ -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
|
+
});
|
package/test/config.test.js
CHANGED
|
@@ -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({
|