fix: add input validation, date range checks, and security hardening

- validate-agents.js: reject invalid model names in agent frontmatter
- package-manager.js: validate script/binary names against shell injection
- session-manager.js: reject impossible month/day values in filenames
- utils.js: support options.all for replaceInFile string patterns
- strategic-compact/SKILL.md: fix hook matcher syntax and script reference
- install.sh: warn when overwriting existing rule customizations
- Add 24 new tests covering all validation and edge cases
This commit is contained in:
Affaan Mustafa
2026-02-12 17:32:04 -08:00
parent 35aed05903
commit 926eba97c5
10 changed files with 312 additions and 10 deletions

View File

@@ -546,6 +546,31 @@ function runTests() {
}
})) passed++; else failed++;
if (test('replaces all occurrences with string when options.all is true', () => {
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
try {
utils.writeFile(testFile, 'hello world hello again hello');
utils.replaceInFile(testFile, 'hello', 'goodbye', { all: true });
const content = utils.readFile(testFile);
assert.strictEqual(content, 'goodbye world goodbye again goodbye');
} finally {
fs.unlinkSync(testFile);
}
})) passed++; else failed++;
if (test('options.all is ignored for regex patterns', () => {
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
try {
utils.writeFile(testFile, 'foo bar foo');
// all option should be ignored for regex; only g flag matters
utils.replaceInFile(testFile, /foo/, 'qux', { all: true });
const content = utils.readFile(testFile);
assert.strictEqual(content, 'qux bar foo', 'Regex without g should still replace first only');
} finally {
fs.unlinkSync(testFile);
}
})) passed++; else failed++;
if (test('replaces with capture groups', () => {
const testFile = path.join(utils.getTempDir(), `utils-test-${Date.now()}.txt`);
try {