fix: generate smart wildcard patterns for complex bash commands
When users approve long piped/chained commands (e.g., cd /path && git diff | head -100), the system now generates intelligent wildcard patterns instead of exact matches. This allows similar commands to be cached properly. Changes: - Parse complex commands containing &&, |, or ; to extract significant patterns - Generate wildcards like Bash(cd /path && git diff:*) for git commands - Generate wildcards like Bash(npm run lint:*) for npm commands - Add tests for long command pattern generation Fixes the issue where approving git diff | head would not also allow git diff | tail 👾 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta <noreply@letta.com>
This commit is contained in:
@@ -353,3 +353,45 @@ test("Unknown tool suggests session-only", () => {
|
||||
expect(context.defaultScope).toBe("session");
|
||||
expect(context.safetyLevel).toBe("moderate");
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Long Command Bugs
|
||||
// ============================================================================
|
||||
|
||||
test("Long complex bash commands should generate smart wildcard patterns", () => {
|
||||
// Bug: When command is >40 chars, analyzer saves exact match instead of wildcard
|
||||
// Example: "cd /path && git diff file.ts | head -100"
|
||||
// Should generate: "Bash(cd /path && git diff:*)" to also match "... | tail -30"
|
||||
|
||||
const longCommand =
|
||||
"cd /Users/test/project && git diff src/file.ts | head -100";
|
||||
|
||||
const context = analyzeApprovalContext(
|
||||
"Bash",
|
||||
{ command: longCommand },
|
||||
"/Users/test/project",
|
||||
);
|
||||
|
||||
// Should extract "git diff" pattern, not save full command
|
||||
expect(context.recommendedRule).toBe(
|
||||
"Bash(cd /Users/test/project && git diff:*)",
|
||||
);
|
||||
// Button text should reflect the wildcard pattern
|
||||
expect(context.approveAlwaysText).not.toContain("...");
|
||||
});
|
||||
|
||||
test("Very long non-git commands should generate prefix-based wildcards", () => {
|
||||
// For commands that don't match known patterns (npm, git, etc)
|
||||
// we should still be smarter than exact match
|
||||
const longCommand = "cd /Users/test/project && npm run lint 2>&1 | tail -20";
|
||||
|
||||
const context = analyzeApprovalContext(
|
||||
"Bash",
|
||||
{ command: longCommand },
|
||||
"/Users/test/project",
|
||||
);
|
||||
|
||||
// Should generate wildcard for "npm run lint"
|
||||
expect(context.recommendedRule).toBe("Bash(npm run lint:*)");
|
||||
expect(context.approveAlwaysText).toContain("npm run lint");
|
||||
});
|
||||
|
||||
@@ -44,6 +44,47 @@ test("Glob within working directory is auto-allowed", () => {
|
||||
expect(result.decision).toBe("allow");
|
||||
});
|
||||
|
||||
// ============================================================================
|
||||
// Long Command Caching Tests
|
||||
// ============================================================================
|
||||
|
||||
test("Long bash commands should use wildcard patterns, not exact match", () => {
|
||||
// This is the bug: when you approve a long command like
|
||||
// "cd /path && git diff file.ts | head -100"
|
||||
// it should also match
|
||||
// "cd /path && git diff file.ts | tail -30"
|
||||
// But currently it saves an exact match instead of a wildcard
|
||||
|
||||
const longCommand1 =
|
||||
"cd /Users/test/project && git diff src/file.ts | head -100";
|
||||
const longCommand2 =
|
||||
"cd /Users/test/project && git diff src/file.ts | tail -30";
|
||||
|
||||
// After approving the first command with a wildcard pattern
|
||||
const permissions: PermissionRules = {
|
||||
allow: ["Bash(cd /Users/test/project && git diff:*)"],
|
||||
deny: [],
|
||||
ask: [],
|
||||
};
|
||||
|
||||
// Both should match
|
||||
const result1 = checkPermission(
|
||||
"Bash",
|
||||
{ command: longCommand1 },
|
||||
permissions,
|
||||
"/Users/test/project",
|
||||
);
|
||||
expect(result1.decision).toBe("allow");
|
||||
|
||||
const result2 = checkPermission(
|
||||
"Bash",
|
||||
{ command: longCommand2 },
|
||||
permissions,
|
||||
"/Users/test/project",
|
||||
);
|
||||
expect(result2.decision).toBe("allow");
|
||||
});
|
||||
|
||||
test("Grep within working directory is auto-allowed", () => {
|
||||
const result = checkPermission(
|
||||
"Grep",
|
||||
|
||||
Reference in New Issue
Block a user