Thank you for your interest in contributing! This guide will help you understand the project structure and how to add new features.
Source layout (the runnable app is produced under dist/ by npm run build; dist/ is gitignored).
P4RS3LT0NGV3/
├── package.json
├── favicon.svg
├── index.template.html # HTML shell; tool *script* tags updated by inject-tool-scripts
├── css/
│ ├── style.css
│ └── notification.css
├── js/
│ ├── app.js # Vue app entry
│ ├── config/
│ │ └── constants.js
│ ├── core/ # Shared logic (not tab-specific UI)
│ │ ├── decoder.js # Universal decode engine
│ │ ├── steganography.js # Emoji / invisible carriers
│ │ ├── toolRegistry.js # Registers tools, merges Vue data/methods
│ │ └── transformOptions.js
│ ├── data/ # Static data shipped with the app (see note below)
│ │ ├── anticlassifierPrompt.js
│ │ ├── emojiCompatibility.js
│ │ ├── endSequences.js
│ │ ├── glitchTokens.js
│ │ └── openrouterModels.js
│ ├── utils/
│ │ ├── clipboard.js
│ │ ├── emoji.js # window.EmojiUtils (uses window.emojiData when present)
│ │ ├── escapeParser.js
│ │ ├── focus.js
│ │ ├── glitchTokens.js
│ │ ├── history.js
│ │ ├── notifications.js
│ │ └── theme.js
│ └── tools/ # One *Tool.js per tab (extends Tool.js)
│ ├── Tool.js
│ ├── AntiClassifierTool.js
│ ├── BijectionTool.js
│ ├── DecodeTool.js
│ ├── EmojiTool.js
│ ├── GibberishTool.js
│ ├── MutationTool.js
│ ├── PromptCraftTool.js
│ ├── SplitterTool.js
│ ├── TokenadeTool.js
│ ├── TokenizerTool.js
│ ├── TransformTool.js
│ └── TranslateTool.js # hidden tab wiring; UI lives on Transform
├── src/
│ ├── emojiWordMap.js # Merged into generated emoji data at build time
│ └── transformers/ # Transformer sources → bundled to dist/js/bundles/
│ ├── BaseTransformer.js
│ ├── index.js # Generated by npm run build:index (gitignored)
│ ├── ancient/
│ ├── case/
│ ├── cipher/
│ ├── encoding/
│ ├── fantasy/
│ ├── format/
│ ├── special/
│ ├── technical/
│ ├── unicode/
│ └── visual/
├── templates/ # Injected into dist/index.html by inject-tool-templates
│ ├── anticlassifier.html
│ ├── bijection.html
│ ├── decoder.html
│ ├── fuzzer.html
│ ├── gibberish.html
│ ├── promptcraft.html
│ ├── splitter.html
│ ├── steganography.html
│ ├── tokenade.html
│ ├── tokenizer.html
│ ├── transforms.html
│ └── README.md
├── build/
│ ├── README.md
│ ├── build-index.js # Writes src/transformers/index.js
│ ├── build-transforms.js # Writes dist/js/bundles/transforms-bundle.js
│ ├── build-emoji-data.js # Writes dist/js/data/emojiData.js
│ ├── copy-static.js # Copies css/, js/, favicon → dist/
│ ├── fetch-glitch-data.js
│ ├── inject-tool-scripts.js # Discovers tools; updates index.template.html + toolRegistry
│ ├── inject-tool-templates.js # Builds dist/index.html from index.template.html + templates/
│ └── readme-transform-section.js # Maintainer helper for README transform list
├── tests/
│ ├── test_universal.js
│ └── test_steganography_options.js
├── docs/
│ ├── TOOL-SYSTEM.md
│ ├── TOOL_ARCHITECTURE.md
│ └── UI-COMPONENTS.md
├── README.md
└── CONTRIBUTING.md
dist/ # npm run build — gitignored
├── index.html # `npm run build:templates` → from index.template.html + templates/
├── css/ …
├── js/ …
│ ├── bundles/transforms-bundle.js
│ └── data/emojiData.js
Generated / ignored paths (also listed in .gitignore): dist/, src/transformers/index.js, legacy js/bundles/transforms-bundle.js, js/data/emojiData.js, root index.html if present. The build updates dist/index.html only; a root index.html is not produced by the current scripts.
js/core/— Shared business logic and infrastructure (not tab-specific)- Examples:
decoder.js(DecodeTool, decoder pipeline),steganography.js(EmojiTool, steg engine),toolRegistry.js(registers tools, merges Vue surface),transformOptions.js(shared transform UI helpers)
- Examples:
js/utils/— Cross-cutting helpers (clipboard,EmojiUtilsinemoji.js, notifications, theme, etc.)js/data/— Committed static payloads (models, prompts, glitch token data, end sequences,emojiCompatibility.js).emojiData.jsis not edited here — it is generated todist/js/data/emojiData.jsbynpm run build:emoji.src/—emojiWordMap.jsfeeds the emoji build;transformers/holds transformer modules- Generated bundle —
npm run build:transformswritesdist/js/bundles/transforms-bundle.js(a legacyjs/bundles/transforms-bundle.jspath may exist for older workflows and is gitignored) js/tools/— Vue integration: one*Tool.jsper tab (plusTranslateTool.js, which is hidden and wired from the Transform tab)- Example:
DecodeTool.jsuses the universal decode API fromcore/decoder.js
- Example:
- Transformers (
src/transformers/) - Text transformation logic (encoding/decoding) - Tools (
js/tools/) - UI features/tabs (Transform tab, Decoder tab, Emoji tab)
- Node.js (for running tests and builds)
- Modern web browser (for testing)
# Clone the repository
git clone <repo-url>
cd P4RS3LT0NGV3
# Install dependencies (if any)
npm install
# Build transformers bundle
npm run build
# Run tests
npm testTransformers are the core text transformation logic. See src/transformers/README.md for detailed instructions.
Quick Start:
-
Create a new file in the appropriate category directory:
src/transformers/cipher/my-cipher.js
-
Use the
BaseTransformerclass:import BaseTransformer from '../BaseTransformer.js'; export default new BaseTransformer({ name: 'My Cipher', priority: 60, // See priority guide in transformers/README.md category: 'ciphers', func: function(text) { // Encoding logic return encoded; }, reverse: function(text) { // Decoding logic return decoded; }, detector: function(text) { // Optional: pattern detection for universal decoder return /pattern/.test(text); } });
-
Rebuild the bundle:
npm run build
-
Test it:
- After
npm run build, opendist/index.htmlin a browser (or usenpm start→ http://localhost:8080 if you prefer) - Your transformer will appear in the Transform tab automatically
- Test encoding/decoding
- Test with the Universal Decoder
- After
-
Add tests (optional but recommended):
- Add test cases to
tests/test_universal.js - Run
npm testto verify
- Add test cases to
Important: Transformers are automatically discovered and bundled. No manual registration needed!
Tools represent UI features/tabs. Examples: Transform tab, Decoder tab, Emoji tab.
Steps:
-
Create a new tool class in
js/tools/:// js/tools/MyNewTool.js class MyNewTool extends Tool { constructor() { super({ id: 'myfeature', // Unique ID (used for tab switching) name: 'My Feature', // Display name icon: 'fa-star', // Font Awesome icon class title: 'My Feature (M)', // Tooltip with keyboard shortcut order: 5 // Display order (lower = earlier) }); } getVueData() { return { // Vue data properties for this tool myInput: '', myOutput: '' }; } getVueMethods() { return { // Vue methods for this tool doSomething: function() { // Your logic here } }; } getTabContentHTML() { return ` <!-- HTML template for this tool's tab --> <div class="my-feature-layout"> <textarea v-model="myInput"></textarea> <div>{{ myOutput }}</div> </div> `; } }
-
Run the build script to auto-register your tool:
npm run build:tools
This will:
- Auto-discover your new tool file
- Add script tag to
index.template.html - Generate registration code in
toolRegistry.js
-
If you created a template file, build templates:
npm run build:templates
-
Test it:
- After
npm run build, opendist/index.html(ornpm startat http://localhost:8080) - Your new tab should appear automatically
- Test all functionality
- After
See js/tools/Tool.js for the base class API and js/tools/TransformTool.js for a complete example.
Utilities are shared helper functions used across the app. Currently, utility functions are typically added directly to the modules that need them or as part of core modules.
If you need to create a new utility module:
-
Create a new file in
js/(root level) orjs/core/:// js/myUtility.js window.MyUtility = { doSomething: function(param) { // Your utility function return result; } };
-
Add a script tag to
index.template.html(beforeapp.js), thennpm run build:copy(ornpm run build) so it lands indist/index.html:<script src="js/myUtility.js"></script>
-
Use it in your code:
window.MyUtility.doSomething(value);
Guidelines:
- Keep utilities pure (no side effects when possible)
- Use
windownamespace for browser compatibility - Document with JSDoc comments
- Consider adding to existing modules if functionality is related
Note: Prefer js/utils/ for shared helpers (clipboard, emoji, escapeParser, focus, glitchTokens, history, notifications, theme). Use js/config/ for constants.
# Run all tests
npm test
# Run specific test suite
npm run test:universal # Universal decoder tests
npm run test:steg # Steganography options tests-
Transformer tests: Add to
tests/test_universal.js- Tests are automatically discovered
- Add limitations/expected behavior to the
limitationsobject if needed
-
Steganography tests: Add to
tests/test_steganography_options.js- Tests encoding/decoding round-trips with various option combinations
-
New test files: Create in
tests/directory- Use
path.resolve(__dirname, '..')to get project root - Use
path.join(projectRoot, '...')for file paths
- Use
- Use ES6+ features (arrow functions, const/let, template literals)
- Use meaningful variable names
- Add JSDoc comments for public functions
- Follow existing code style in the file you're editing
- Core modules (
js/core/) — Shared logic (decoder.js,steganography.js,toolRegistry.js,transformOptions.js) - App entry (
js/app.js) — Vue bootstrap and shell behavior - Tools (
js/tools/) — Tab UI layer (*Tool.js) - Templates (
templates/) — Tool markup injected intodist/index.html - Transformers (
src/transformers/) — Transform implementations; output isdist/js/bundles/transforms-bundle.js
- Files:
camelCase.jsfor utilities/tools,kebab-case.jsfor transformers - Classes:
PascalCase(e.g.,DecodeTool) - Functions:
camelCase(e.g.,runUniversalDecode) - Constants:
UPPER_SNAKE_CASE(e.g.,MAX_HISTORY_ITEMS)
npm run build:templatesThis:
- Reads the ordered list of tool templates from
templates/(seebuild/inject-tool-templates.js) - Injects them into
dist/index.htmlat the#tool-content-containermarker (fromindex.template.html) - Produces the static HTML file served from
dist/
When to run:
- After editing any template in
templates/ - Before committing template changes
- Directory creation: Scripts create
dist/(and subfolders) as needed - Full build:
npm run buildruns tools injection, copy, transformer index, transform bundle, emoji data, template injection (seepackage.jsonandbuild/README.md) - Individual builds: Each
npm run build:*step can be run on its own
Note: The browser loads transforms from dist/js/bundles/transforms-bundle.js after a successful npm run build:transforms (and npm run build:copy).
- Template changes not showing: Run
npm run build:templatesto rebuilddist/index.html, then refresh (or runnpm startafter a fullnpm run build) - Tool not showing: Check that:
npm run build:toolsran sotoolRegistry.jsandindex.template.htmlinclude the new tool- Script tag order in
index.template.html(loads beforeapp.js) - Template file exists in
templates/and is listed inbuild/inject-tool-templates.jswhen adding a new tab
- Tests failing: Check file paths use
path.join(projectRoot, '...')
- Open browser DevTools (F12)
- Check console for errors
- Use
window.transformsto see all transformers - Use
window.steganographyfor steganography helpers - Use
window.emojiData(after build) andwindow.EmojiUtils(js/utils/emoji.js) for emoji lists / splitting
- Project README:
README.md— Overview and user guide - Templates:
templates/README.md— Editing tool templates - Build process:
build/README.md— Build scripts - Tool system:
docs/TOOL-SYSTEM.md— Templates, injection, UI vocabulary - Tool architecture:
docs/TOOL_ARCHITECTURE.md - UI components:
docs/UI-COMPONENTS.md
- Code follows existing style
- Tests pass (
npm test) - Templates built (
npm run build:templates) if template files were edited - Tested in browser (
npm run build, then opendist/index.htmlornpm start) - No console errors
- Documentation updated (if needed)
- JSDoc comments added (for new functions)
- Check existing code for examples
- Review
docs/TOOL_ARCHITECTURE.mdanddocs/TOOL-SYSTEM.mdfor architecture details - Look at similar features to understand patterns
Thank you for contributing! 🎉