opentwig 1.0.7 → 1.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/AGENTS.md +172 -0
  2. package/API.md +582 -0
  3. package/CODE_OF_CONDUCT.md +91 -0
  4. package/CONTRIBUTING.md +312 -0
  5. package/README.md +164 -7
  6. package/SECURITY.md +56 -0
  7. package/THEME_DEVELOPMENT.md +388 -0
  8. package/package.json +19 -4
  9. package/src/constants.js +14 -2
  10. package/src/index.js +14 -2
  11. package/src/live-ui/editor.js +174 -0
  12. package/src/live-ui/preview.js +77 -0
  13. package/src/live-ui/sidebar.js +525 -0
  14. package/src/utils/escapeHTML.js +10 -0
  15. package/src/utils/favicon.js +20 -0
  16. package/src/utils/generateOGImage.js +51 -10
  17. package/src/utils/loadConfig.js +3 -1
  18. package/src/utils/parseArgs.js +33 -2
  19. package/src/utils/readImageAsBase64.js +16 -4
  20. package/src/utils/setupWatcher.js +69 -0
  21. package/src/utils/showHelp.js +15 -2
  22. package/src/utils/startLiveServer.js +221 -0
  23. package/src/utils/websocketServer.js +53 -0
  24. package/theme/dark/style.css +1 -0
  25. package/theme/default/index.js +12 -8
  26. package/validateConfig.js +59 -0
  27. package/vitest.config.js +20 -0
  28. package/website/README.md +42 -0
  29. package/website/components.json +16 -0
  30. package/website/eslint.config.js +36 -0
  31. package/website/package-lock.json +4136 -0
  32. package/website/package.json +41 -0
  33. package/website/shadcn-svelte.md +118 -0
  34. package/website/src/app.d.ts +13 -0
  35. package/website/src/lib/components/ui/badge/badge.svelte +50 -0
  36. package/website/src/lib/components/ui/badge/index.ts +2 -0
  37. package/website/src/lib/components/ui/button/button.svelte +82 -0
  38. package/website/src/lib/components/ui/button/index.ts +17 -0
  39. package/website/src/lib/components/ui/card/card-action.svelte +20 -0
  40. package/website/src/lib/components/ui/card/card-content.svelte +15 -0
  41. package/website/src/lib/components/ui/card/card-description.svelte +20 -0
  42. package/website/src/lib/components/ui/card/card-footer.svelte +20 -0
  43. package/website/src/lib/components/ui/card/card-header.svelte +23 -0
  44. package/website/src/lib/components/ui/card/card-title.svelte +20 -0
  45. package/website/src/lib/components/ui/card/card.svelte +23 -0
  46. package/website/src/lib/components/ui/card/index.ts +25 -0
  47. package/website/src/lib/components/ui/separator/index.ts +7 -0
  48. package/website/src/lib/components/ui/separator/separator.svelte +21 -0
  49. package/website/src/lib/components/ui/tooltip/index.ts +19 -0
  50. package/website/src/lib/components/ui/tooltip/tooltip-content.svelte +52 -0
  51. package/website/src/lib/components/ui/tooltip/tooltip-portal.svelte +7 -0
  52. package/website/src/lib/components/ui/tooltip/tooltip-provider.svelte +7 -0
  53. package/website/src/lib/components/ui/tooltip/tooltip-trigger.svelte +7 -0
  54. package/website/src/lib/components/ui/tooltip/tooltip.svelte +7 -0
  55. package/website/src/lib/index.ts +1 -0
  56. package/website/src/lib/utils.ts +13 -0
  57. package/website/src/routes/+layout.svelte +23 -0
  58. package/website/src/routes/+page.server.ts +82 -0
  59. package/website/src/routes/+page.svelte +892 -0
  60. package/website/static/robots.txt +3 -0
  61. package/website/svelte.config.js +31 -0
  62. package/website/vite.config.ts +5 -0
package/AGENTS.md ADDED
@@ -0,0 +1,172 @@
1
+ # OpenTwig Agent Guidelines
2
+
3
+ This file provides guidelines for agentic coding assistants working on the OpenTwig codebase.
4
+
5
+ ## Build / Lint / Test Commands
6
+
7
+ ```bash
8
+ # Run the CLI tool
9
+ npm start
10
+
11
+ # Run a single test file
12
+ npm test -- src/utils/parseArgs.test.js
13
+
14
+ # Run tests matching a pattern
15
+ npm test -- -t "should validate"
16
+
17
+ # Run tests once (CI mode)
18
+ npm run test:run
19
+
20
+ # Run tests with coverage
21
+ npm run test:coverage
22
+
23
+ # Start live preview mode
24
+ npm run live
25
+
26
+ # CLI options
27
+ npm start -- --help
28
+ npm start -- --init
29
+ ```
30
+
31
+ ## Project Overview
32
+
33
+ OpenTwig is a Node.js CLI tool that generates static "link in bio" pages. Uses CommonJS modules. Generates HTML, CSS, QR codes, and Open Graph images from JSON config.
34
+
35
+ **Core technologies:** Node.js (v14+), CommonJS, PostCSS, Sharp, Vitest
36
+
37
+ ## Code Style Guidelines
38
+
39
+ ### Module System
40
+ - **Use CommonJS exclusively** - no ES6 imports/exports
41
+ - Import: `const module = require('./path/to/module');`
42
+ - Export: `module.exports = functionName;` or `module.exports = { name, value };`
43
+ - Main entry point includes shebang: `#! /usr/bin/env node` and `'use strict';`
44
+
45
+ ### File Organization
46
+ - **Single function per file** preferred in `src/utils/`
47
+ - Use descriptive filenames in camelCase (e.g., `buildPage.js`)
48
+ - Utilities in `src/utils/`, constants in `src/constants.js`
49
+ - Theme structure: `theme/{themeName}/index.js`, `style.css`, `components/`
50
+
51
+ ### Naming Conventions
52
+ - **Variables/Functions**: camelCase (`const buildPage = async (config) => {}`)
53
+ - **Constants**: UPPER_SNAKE_CASE (`const OUTPUT_FILES = { HTML: 'index.html' }`)
54
+ - **Files**: camelCase for JS files (e.g., `loadConfig.js`)
55
+
56
+ ### Code Patterns
57
+
58
+ **Function exports:**
59
+ ```javascript
60
+ module.exports = async function(config) {
61
+ // implementation
62
+ };
63
+ ```
64
+
65
+ **Async/await with error handling:**
66
+ ```javascript
67
+ const buildPage = async (config) => {
68
+ try {
69
+ const theme = loadTheme(config);
70
+ return { html: await generateHTML(config, theme), theme };
71
+ } catch (error) {
72
+ throw new Error(`Failed to build page: ${error.message}`);
73
+ }
74
+ };
75
+ ```
76
+
77
+ **Template literals for HTML:**
78
+ ```javascript
79
+ module.exports = function({title, name}) {
80
+ return `<!DOCTYPE html>
81
+ <html>
82
+ <head><title>${escapeHTML(title)}</title></head>
83
+ <body><h1>${escapeHTML(name)}</h1></body>
84
+ </html>`;
85
+ };
86
+ ```
87
+
88
+ ### Error Handling
89
+ - Always use try-catch for async functions
90
+ - Log errors with `console.error()`
91
+ - Use `process.exit(1)` on fatal errors, `process.exit(0)` on success
92
+ - Prefix error messages with context from `src/constants.js`
93
+
94
+ ### Security
95
+ - Always escape HTML output using `escapeHTML()` utility
96
+ - Always escape XML for OG images using `escapeXml()` utility
97
+ - Validate config fields in `configDefaults.js`
98
+ - Sanitize all user-generated content
99
+
100
+ ### Documentation
101
+ - Add JSDoc comments for functions with @param and @returns
102
+ - Add module-level docstrings describing purpose
103
+
104
+ ```javascript
105
+ /**
106
+ * Load theme configuration from theme directory
107
+ * @param {Object} config - User configuration object
108
+ * @returns {Function} Theme template function
109
+ */
110
+ module.exports = function(config) { ... };
111
+ ```
112
+
113
+ ### Formatting
114
+ - **JavaScript**: 4-space indentation
115
+ - **CSS**: 2-space indentation
116
+ - Use meaningful variable names
117
+ - Keep functions focused and small
118
+ - Prefer template literals over string concatenation
119
+ - No trailing whitespace
120
+
121
+ ### Constants
122
+ Centralize all constants in `src/constants.js`:
123
+ - File paths and names
124
+ - CLI options
125
+ - Messages (ERROR_PREFIX, SUCCESS_PREFIX, etc.)
126
+ - Default values
127
+
128
+ ### File Paths
129
+ - Use `path.join()` for path construction
130
+ - Use `path.dirname(require.main.filename)` for package directory (NPX compatibility)
131
+ - Use `process.cwd()` for current working directory
132
+ - Check file existence with `fs.existsSync()` before operations
133
+
134
+ ## Testing Guidelines
135
+
136
+ Tests use Vitest with ESM imports for test utilities and CommonJS require for modules:
137
+
138
+ ```javascript
139
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
140
+
141
+ describe('functionName', () => {
142
+ it('should do something', () => {
143
+ const module = require('./module');
144
+ expect(result).toBe(expected);
145
+ });
146
+ });
147
+ ```
148
+
149
+ ## Key Files Reference
150
+
151
+ - `src/index.js` - Main CLI entry point
152
+ - `src/constants.js` - Centralized constants
153
+ - `src/utils/` - Utility functions (one function per file)
154
+ - `theme/` - Theme templates
155
+ - `src/live-ui/` - Live editor UI
156
+
157
+ ## Output Files
158
+
159
+ All generated files go to `dist/`:
160
+ - `index.html` - Main page
161
+ - `style.css` - Processed CSS
162
+ - `avatar.{ext}` - User avatar
163
+ - `og-image.jpg` - Open Graph image
164
+ - `qr.svg` - QR code
165
+
166
+ ## When Making Changes
167
+
168
+ 1. **Always read the file first** - Use the Read tool before editing
169
+ 2. **Follow existing patterns** - Mimic code style and structure
170
+ 3. **Test thoroughly** - Run `npm run test:run` after changes
171
+ 4. **Add JSDoc comments** - Document new functions
172
+ 5. **Keep it simple** - One function per file, focused responsibilities