This repository has been archived on 2026-04-03. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
core/packages/regex-tester/js/script.js
Jeffrey Smith 8580e1d93e
Some checks failed
CI/CD / detect-changes (push) Successful in 4s
CI/CD / test-frontend (push) Successful in 6s
CI/CD / test-go-pg (push) Failing after 2m15s
CI/CD / test-sqlite (push) Successful in 2m36s
CI/CD / build-and-deploy (push) Has been skipped
Feat v0.2.9 builtin retirement (#13)
Co-authored-by: Jeffrey Smith <jasafpro@gmail.com>
Co-committed-by: Jeffrey Smith <jasafpro@gmail.com>
2026-03-27 16:46:50 +00:00

103 lines
2.8 KiB
JavaScript

// ==========================================
// Regex Tester — Browser Extension
// ==========================================
// Tests regular expressions against input strings.
// Registers the regex_test tool so the LLM can verify
// patterns instead of guessing.
// ==========================================
Extensions.register({
id: 'regex-tester',
async init(ctx) {
const self = this;
ctx.tools.handle('regex_test', async (args) => {
return self._test(args.pattern, args.flags || '', args.inputs || []);
});
},
_test(pattern, flags, inputs) {
// Validate pattern
let regex;
try {
regex = new RegExp(pattern, flags);
} catch (e) {
return {
success: false,
error: `Invalid regex: ${e.message}`,
pattern,
flags,
};
}
const results = inputs.map(input => {
// Reset lastIndex for global/sticky patterns
regex.lastIndex = 0;
const isGlobal = regex.global;
const matches = [];
if (isGlobal) {
// Collect all matches for global flag
let match;
while ((match = regex.exec(input)) !== null) {
matches.push(this._formatMatch(match));
// Prevent infinite loops on zero-length matches
if (match[0].length === 0) regex.lastIndex++;
}
} else {
const match = regex.exec(input);
if (match) {
matches.push(this._formatMatch(match));
}
}
return {
input,
matched: matches.length > 0,
matchCount: matches.length,
matches,
};
});
const totalMatched = results.filter(r => r.matched).length;
return {
success: true,
pattern,
flags,
summary: `${totalMatched}/${inputs.length} inputs matched`,
results,
};
},
_formatMatch(match) {
const result = {
fullMatch: match[0],
index: match.index,
length: match[0].length,
};
// Named groups (ES2018)
if (match.groups) {
result.namedGroups = {};
for (const [name, value] of Object.entries(match.groups)) {
result.namedGroups[name] = value;
}
}
// Numbered capture groups
if (match.length > 1) {
result.groups = [];
for (let i = 1; i < match.length; i++) {
result.groups.push(match[i] !== undefined ? match[i] : null);
}
}
return result;
},
destroy() {}
});