Improve agent autonomy and diff view readability
Agent behavior improvements: - Add project context detection (tsconfig.json, pom.xml, etc.) - Enforce validation after changes (tsc --noEmit, mvn compile, etc.) - Run tests automatically - never ask "do you want me to run tests" - Complete full loop: create → type-check → test → confirm - Add command detection for direct execution (run tree, run ls) Diff view improvements: - Use darker backgrounds for added/removed lines - Add diffLineBgAdded, diffLineBgRemoved, diffLineText theme colors - Improve text visibility with white text on dark backgrounds - Update both React/Ink and SolidJS diff components Streaming fixes: - Fix tool call argument accumulation using OpenAI index field - Fix streaming content display after tool calls - Add consecutive error tracking to prevent token waste Other changes: - ESC to abort operations, Ctrl+C to exit - Fix model selection when provider changes in cascade mode - Add debug logging for troubleshooting - Move tests to root tests/ folder - Fix banner test GRADIENT_COLORS reference
This commit is contained in:
152
test/bash-matcher.test.ts
Normal file
152
test/bash-matcher.test.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
/**
|
||||
* Unit tests for Bash Pattern Matcher
|
||||
*/
|
||||
|
||||
import { describe, it, expect } from "bun:test";
|
||||
|
||||
import {
|
||||
matchesBashPattern,
|
||||
isBashAllowedByIndex,
|
||||
findMatchingBashPatterns,
|
||||
generateBashPattern,
|
||||
extractCommandPrefix,
|
||||
} from "@services/permissions/matchers/bash";
|
||||
import { buildPatternIndex } from "@services/permissions/pattern-index";
|
||||
import type { PermissionPattern } from "@/types/permissions";
|
||||
|
||||
describe("Bash Pattern Matcher", () => {
|
||||
describe("matchesBashPattern", () => {
|
||||
it("should match exact command with wildcard args", () => {
|
||||
const pattern: PermissionPattern = {
|
||||
tool: "Bash",
|
||||
command: "git",
|
||||
args: "*",
|
||||
};
|
||||
|
||||
expect(matchesBashPattern("git", pattern)).toBe(true);
|
||||
expect(matchesBashPattern("git status", pattern)).toBe(true);
|
||||
expect(matchesBashPattern("git commit -m 'msg'", pattern)).toBe(true);
|
||||
});
|
||||
|
||||
it("should not match different command", () => {
|
||||
const pattern: PermissionPattern = {
|
||||
tool: "Bash",
|
||||
command: "git",
|
||||
args: "*",
|
||||
};
|
||||
|
||||
expect(matchesBashPattern("npm install", pattern)).toBe(false);
|
||||
expect(matchesBashPattern("gitx status", pattern)).toBe(false);
|
||||
});
|
||||
|
||||
it("should match command with specific args prefix", () => {
|
||||
const pattern: PermissionPattern = {
|
||||
tool: "Bash",
|
||||
command: "git",
|
||||
args: "status*",
|
||||
};
|
||||
|
||||
expect(matchesBashPattern("git status", pattern)).toBe(true);
|
||||
expect(matchesBashPattern("git status --short", pattern)).toBe(true);
|
||||
expect(matchesBashPattern("git commit", pattern)).toBe(false);
|
||||
});
|
||||
|
||||
it("should match exact args", () => {
|
||||
const pattern: PermissionPattern = {
|
||||
tool: "Bash",
|
||||
command: "npm",
|
||||
args: "install",
|
||||
};
|
||||
|
||||
expect(matchesBashPattern("npm install", pattern)).toBe(true);
|
||||
expect(matchesBashPattern("npm install lodash", pattern)).toBe(false);
|
||||
});
|
||||
|
||||
it("should reject non-Bash patterns", () => {
|
||||
const pattern: PermissionPattern = {
|
||||
tool: "Read",
|
||||
path: "*",
|
||||
};
|
||||
|
||||
expect(matchesBashPattern("ls", pattern)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("isBashAllowedByIndex", () => {
|
||||
it("should check against index patterns", () => {
|
||||
const index = buildPatternIndex(["Bash(git:*)", "Bash(npm install:*)"]);
|
||||
|
||||
expect(isBashAllowedByIndex("git status", index)).toBe(true);
|
||||
expect(isBashAllowedByIndex("git commit", index)).toBe(true);
|
||||
expect(isBashAllowedByIndex("npm install lodash", index)).toBe(true);
|
||||
expect(isBashAllowedByIndex("npm run build", index)).toBe(false);
|
||||
expect(isBashAllowedByIndex("rm -rf /", index)).toBe(false);
|
||||
});
|
||||
|
||||
it("should return false for empty index", () => {
|
||||
const index = buildPatternIndex([]);
|
||||
|
||||
expect(isBashAllowedByIndex("git status", index)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("findMatchingBashPatterns", () => {
|
||||
it("should find all matching patterns", () => {
|
||||
const index = buildPatternIndex([
|
||||
"Bash(git:*)",
|
||||
"Bash(git status:*)",
|
||||
"Bash(npm:*)",
|
||||
]);
|
||||
|
||||
const matches = findMatchingBashPatterns("git status", index);
|
||||
|
||||
expect(matches.length).toBe(2);
|
||||
expect(matches.map((m) => m.raw)).toContain("Bash(git:*)");
|
||||
expect(matches.map((m) => m.raw)).toContain("Bash(git status:*)");
|
||||
});
|
||||
|
||||
it("should return empty for no matches", () => {
|
||||
const index = buildPatternIndex(["Bash(git:*)"]);
|
||||
|
||||
const matches = findMatchingBashPatterns("npm install", index);
|
||||
|
||||
expect(matches).toHaveLength(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe("generateBashPattern", () => {
|
||||
it("should generate pattern for multi-word commands", () => {
|
||||
expect(generateBashPattern("git status")).toBe("Bash(git status:*)");
|
||||
expect(generateBashPattern("npm install lodash")).toBe(
|
||||
"Bash(npm install:*)",
|
||||
);
|
||||
expect(generateBashPattern("docker run nginx")).toBe(
|
||||
"Bash(docker run:*)",
|
||||
);
|
||||
});
|
||||
|
||||
it("should generate pattern for single commands", () => {
|
||||
expect(generateBashPattern("ls")).toBe("Bash(ls:*)");
|
||||
expect(generateBashPattern("pwd")).toBe("Bash(pwd:*)");
|
||||
});
|
||||
|
||||
it("should handle commands with many args", () => {
|
||||
expect(generateBashPattern("git commit -m 'message'")).toBe(
|
||||
"Bash(git commit:*)",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("extractCommandPrefix", () => {
|
||||
it("should extract multi-word prefix", () => {
|
||||
expect(extractCommandPrefix("git status")).toBe("git status");
|
||||
expect(extractCommandPrefix("npm install lodash")).toBe("npm install");
|
||||
expect(extractCommandPrefix("bun test --watch")).toBe("bun test");
|
||||
});
|
||||
|
||||
it("should extract single word for non-recognized commands", () => {
|
||||
expect(extractCommandPrefix("ls -la")).toBe("ls");
|
||||
expect(extractCommandPrefix("cat file.txt")).toBe("cat");
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user