Feat v0.2.9 builtin extension retirement
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Failing after 2m26s
CI/CD / test-sqlite (pull_request) Successful in 2m41s
CI/CD / build-and-deploy (pull_request) Has been skipped
Some checks failed
CI/CD / detect-changes (pull_request) Successful in 4s
CI/CD / test-frontend (pull_request) Successful in 5s
CI/CD / test-go-pg (pull_request) Failing after 2m26s
CI/CD / test-sqlite (pull_request) Successful in 2m41s
CI/CD / build-and-deploy (pull_request) Has been skipped
Stop auto-seeding 6 chat-centric extensions on startup. Move them to standard packages with js/ layout and "requires": ["chat"] metadata. Delete SeedBuiltinPackages, seed tests, Dockerfile COPY, and extensions/builtin/ directory. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
102
packages/regex-tester/js/script.js
Normal file
102
packages/regex-tester/js/script.js
Normal file
@@ -0,0 +1,102 @@
|
||||
// ==========================================
|
||||
// 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() {}
|
||||
});
|
||||
Reference in New Issue
Block a user