Files
GangGreenTemperTatum b8143127a3 add uv-powered agent cli
2026-03-29 08:44:22 -04:00

218 lines
6.7 KiB
JavaScript

#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const vm = require('vm');
const projectRoot = path.join(__dirname, '..');
const transformsRoot = path.join(projectRoot, 'src', 'transformers');
const transforms = require(path.join(projectRoot, 'src', 'transformers', 'loader-node.js'));
function buildRegistry() {
const skipFiles = new Set(['BaseTransformer.js', 'index.js', 'loader-node.js', 'README.md']);
const categories = fs.readdirSync(transformsRoot, { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map((entry) => entry.name)
.sort();
const registry = [];
for (const category of categories) {
const categoryPath = path.join(transformsRoot, category);
const files = fs.readdirSync(categoryPath)
.filter((file) => file.endsWith('.js') && !skipFiles.has(file))
.sort();
for (const file of files) {
const key = file.replace('.js', '').replace(/-/g, '_');
const transform = transforms[key];
if (!transform) {
continue;
}
registry.push({
key,
category,
name: transform.name,
priority: transform.priority ?? 0,
canDecode: Boolean(transform.reverse),
description: transform.description || '',
inputKind: transform.inputKind || 'textarea',
configurableOptions: (transform.configurableOptions || []).map((opt) => ({
id: opt.id,
label: opt.label,
type: opt.type,
default: opt.default,
min: opt.min,
max: opt.max,
step: opt.step,
options: opt.options || undefined
}))
});
}
}
return registry;
}
function getDefaultOptions(transform) {
if (!transform || !transform.configurableOptions || !transform.configurableOptions.length) {
return {};
}
const defaults = {};
for (const opt of transform.configurableOptions) {
let value = opt.default;
if (value === undefined || value === null) {
if (opt.type === 'boolean') {
value = false;
} else if (opt.type === 'select' && opt.options && opt.options.length) {
value = opt.options[0].value;
} else if (opt.type === 'number') {
value = 0;
} else {
value = '';
}
}
defaults[opt.id] = value;
}
return defaults;
}
function loadUniversalDecoder() {
const transformOptionsCode = fs.readFileSync(path.join(projectRoot, 'js', 'core', 'transformOptions.js'), 'utf8');
const decoderCode = fs.readFileSync(path.join(projectRoot, 'js', 'core', 'decoder.js'), 'utf8');
const emojiWordMapCode = fs.readFileSync(path.join(projectRoot, 'src', 'emojiWordMap.js'), 'utf8');
const emojiUtilsCode = fs.readFileSync(path.join(projectRoot, 'js', 'utils', 'emoji.js'), 'utf8');
const mockSteganography = {
hasEmojiInText: () => false,
decodeEmoji: () => null,
decodeInvisible: () => null
};
const sandbox = {
window: {
transforms,
steganography: mockSteganography,
emojiLibrary: {},
emojiKeywords: {},
emojiData: {}
},
console,
TextEncoder,
TextDecoder,
Intl,
btoa: (str) => Buffer.from(str, 'binary').toString('base64'),
atob: (str) => Buffer.from(str, 'base64').toString('binary')
};
vm.createContext(sandbox);
vm.runInContext(emojiUtilsCode, sandbox);
vm.runInContext(emojiWordMapCode, sandbox);
vm.runInContext(transformOptionsCode, sandbox);
vm.runInContext(decoderCode, sandbox);
return sandbox.universalDecode;
}
function normalizeError(error) {
if (error && typeof error.message === 'string') {
return error.message;
}
return String(error);
}
function readPayload() {
const raw = fs.readFileSync(0, 'utf8');
return raw ? JSON.parse(raw) : {};
}
function writeResult(result, exitCode = 0) {
process.stdout.write(`${JSON.stringify(result)}\n`);
process.exit(exitCode);
}
function main() {
const payload = readPayload();
const command = payload.command;
const registry = buildRegistry();
if (command === 'list') {
writeResult({ ok: true, transforms: registry });
}
const transformKey = payload.transform;
const transform = transformKey ? transforms[transformKey] : null;
if (command === 'inspect') {
if (!transform || !transformKey) {
writeResult({ ok: false, error: `Unknown transform: ${transformKey}` }, 1);
}
const meta = registry.find((entry) => entry.key === transformKey);
writeResult({
ok: true,
transform: {
...meta,
defaultOptions: getDefaultOptions(transform)
}
});
}
if (command === 'run') {
if (!transform || !transformKey) {
writeResult({ ok: false, error: `Unknown transform: ${transformKey}` }, 1);
}
const action = payload.action || 'encode';
const text = payload.text || '';
const options = {
...getDefaultOptions(transform),
...(payload.options || {})
};
try {
let output;
if (action === 'encode') {
output = transform.func(text, options);
} else if (action === 'decode') {
if (!transform.reverse) {
throw new Error(`${transform.name} does not support decode`);
}
output = transform.reverse(text, options);
} else if (action === 'preview') {
output = transform.preview(text, options);
} else {
throw new Error(`Unsupported action: ${action}`);
}
writeResult({
ok: true,
action,
transform: transformKey,
name: transform.name,
options,
output
});
} catch (error) {
writeResult({ ok: false, error: normalizeError(error) }, 1);
}
}
if (command === 'auto-decode') {
const decode = loadUniversalDecoder();
try {
const result = decode(payload.text || '', {});
writeResult({ ok: true, result });
} catch (error) {
writeResult({ ok: false, error: normalizeError(error) }, 1);
}
}
writeResult({ ok: false, error: `Unknown command: ${command}` }, 1);
}
main();