Title: Feature: Enhanced CLI Setup Wizard & Developer Experience · Issue #98 · JavaScriptSolidServer/JavaScriptSolidServer · GitHub
Open Graph Title: Feature: Enhanced CLI Setup Wizard & Developer Experience · Issue #98 · JavaScriptSolidServer/JavaScriptSolidServer
X Title: Feature: Enhanced CLI Setup Wizard & Developer Experience · Issue #98 · JavaScriptSolidServer/JavaScriptSolidServer
Description: Summary Enhance the jss init command and add complementary CLI tools to provide a polished, professional setup experience. This covers interactive setup improvements, validation, diagnostics, and output generation. Difficulty: 35/100 Est...
Open Graph Description: Summary Enhance the jss init command and add complementary CLI tools to provide a polished, professional setup experience. This covers interactive setup improvements, validation, diagnostics, and o...
X Description: Summary Enhance the jss init command and add complementary CLI tools to provide a polished, professional setup experience. This covers interactive setup improvements, validation, diagnostics, and o...
Opengraph URL: https://github.com/JavaScriptSolidServer/JavaScriptSolidServer/issues/98
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Feature: Enhanced CLI Setup Wizard \u0026 Developer Experience","articleBody":"## Summary\n\nEnhance the `jss init` command and add complementary CLI tools to provide a polished, professional setup experience. This covers interactive setup improvements, validation, diagnostics, and output generation.\n\n**Difficulty**: 35/100 \n**Estimated Effort**: 3-5 days \n**Dependencies**: #97 (presets)\n\n---\n\n## Current State\n\nThe existing `jss init` command (`bin/jss.js:181-244`) is functional but basic:\n\n```bash\n$ jss init\n\n JavaScript Solid Server Setup\n\nPort (3000): \nData directory (./data): \nEnable content negotiation (Turtle support)? [y/N]: \nEnable WebSocket notifications? [y/N]: \nConfigure SSL? [y/N]: \nEnable built-in Identity Provider? [y/N]: \n\nConfiguration saved to: ./config.json\nData directory created: ./data\n\nRun `jss start` to start the server.\n```\n\n### Current Limitations\n\n| Issue | Impact |\n|-------|--------|\n| No preset selection | Users must configure everything manually |\n| No input validation | Invalid ports, non-existent paths accepted |\n| No visual feedback | Plain text, no colors or progress indication |\n| No post-setup verification | No way to verify config works |\n| Limited feature coverage | Only covers ~5 of 30+ options |\n| No output generation | Can't generate docker-compose, systemd, nginx configs |\n| Basic readline prompts | No autocomplete, no list selection |\n\n---\n\n## Proposed Enhancements\n\n### 1. Preset-First Flow\n\n```\n$ jss init\n\n ╭──────────────────────────────────────────╮\n │ JavaScript Solid Server Setup │\n │ v0.0.81 │\n ╰──────────────────────────────────────────╯\n\n? Choose a configuration preset:\n ❯ personal - Single-user production server\n community - Multi-user with open registration\n private - Multi-user with invite-only access\n federation - Full ActivityPub + Nostr support\n minimal - Development and testing\n developer - All features enabled\n custom - Configure everything manually\n\nUsing preset: personal ✓\n\n? Customize settings? (y/N): y\n```\n\n### 2. Improved Prompts with Validation\n\n```\n? Port (443): 80\n ⚠ Port 80 requires root privileges. Continue? (y/N): n\n? Port (443): 8443 ✓\n\n? Data directory (./data): /var/jss/data\n ✓ Directory exists and is writable\n\n? Domain name: example.com\n ✓ Valid domain format\n\n? SSL certificate path: ./ssl/cert.pem\n ✗ File not found: ./ssl/cert.pem\n ? Create self-signed certificate? (y/N): y\n ✓ Generated self-signed certificate (valid 365 days)\n ⚠ Self-signed certificates will show browser warnings\n```\n\n### 3. Feature Selection with Descriptions\n\n```\n? Select additional features: (space to toggle, enter to confirm)\n ◉ Identity Provider (IdP)\n └─ Email/password authentication, account management\n ◯ WebSocket Notifications \n └─ Real-time updates for Solid apps\n ◉ Content Negotiation\n └─ Turtle/RDF support for Linked Data\n ◯ Mashlib Data Browser\n └─ Built-in file manager UI\n ◯ ActivityPub Federation\n └─ Connect with Mastodon, Plesk, etc.\n ◯ Nostr Relay\n └─ Decentralized social protocol support\n ◯ Git HTTP Backend\n └─ Host git repositories in pods\n```\n\n### 4. Summary \u0026 Confirmation\n\n```\n ╭──────────────────────────────────────────╮\n │ Configuration Summary │\n ╰──────────────────────────────────────────╯\n\n Preset: personal\n Port: 8443\n Data Dir: /var/jss/data\n Domain: example.com\n SSL: ✓ Enabled (self-signed)\n \n Features:\n ✓ Identity Provider\n ✓ Content Negotiation\n ✗ WebSocket Notifications\n ✗ ActivityPub\n ✗ Nostr\n\n Quota: 10GB per pod\n\n? Save configuration? (Y/n): y\n\n ✓ Configuration saved to: ./config.json\n ✓ Data directory created: /var/jss/data\n ✓ SSL certificates generated\n\n Next steps:\n 1. Start the server: jss start -c ./config.json\n 2. Verify setup: jss doctor -c ./config.json\n 3. View your server: https://example.com:8443\n```\n\n---\n\n## New Commands\n\n### `jss doctor` - Configuration Diagnostics\n\nVerify configuration and system readiness.\n\n```bash\n$ jss doctor -c ./config.json\n\n ╭──────────────────────────────────────────╮\n │ JSS Doctor - Configuration Check │\n ╰──────────────────────────────────────────╯\n\n Configuration\n ✓ Config file found: ./config.json\n ✓ Config syntax valid\n ✓ Using preset: personal\n\n Network\n ✓ Port 8443 is available\n ✓ Host 0.0.0.0 is valid\n ⚠ Port 8443 may require firewall configuration\n\n Storage\n ✓ Data directory exists: /var/jss/data\n ✓ Directory is writable\n ✓ 45GB free disk space\n\n SSL/TLS\n ✓ Certificate found: ./ssl/cert.pem\n ✓ Private key found: ./ssl/key.pem\n ✓ Certificate valid until: 2025-12-01\n ⚠ Self-signed certificate detected\n\n Features\n ✓ IdP: Enabled\n ✓ Content Negotiation: Enabled\n ✗ Notifications: Disabled\n ✗ Federation: Disabled\n\n ──────────────────────────────────────────\n Result: 12 checks passed, 2 warnings, 0 errors\n \n Your configuration looks good! Run `jss start` to begin.\n```\n\n#### Doctor Checks\n\n| Category | Check |\n|----------|-------|\n| **Config** | File exists, valid JSON, no unknown keys |\n| **Network** | Port available, valid host, firewall hints |\n| **Storage** | Directory exists, writable, disk space |\n| **SSL** | Files exist, valid format, expiration date, chain valid |\n| **Features** | Required dependencies met, valid combinations |\n| **System** | Node.js version, memory available |\n\n---\n\n### `jss generate` - Output File Generation\n\nGenerate deployment configuration files.\n\n```bash\n$ jss generate docker -c ./config.json\n\n Generated: docker-compose.yml\n \n Usage:\n docker-compose up -d\n docker-compose logs -f\n```\n\n#### Supported Outputs\n\n**Docker Compose**\n```bash\n$ jss generate docker -c ./config.json -o docker-compose.yml\n```\n\n```yaml\nversion: '3.8'\nservices:\n jss:\n image: ghcr.io/javascriptsolidserver/jss:latest\n ports:\n - \"8443:8443\"\n volumes:\n - ./data:/app/data\n - ./ssl:/app/ssl:ro\n environment:\n - JSS_PORT=8443\n - JSS_ROOT=/app/data\n - JSS_SSL_KEY=/app/ssl/key.pem\n - JSS_SSL_CERT=/app/ssl/cert.pem\n - JSS_IDP=true\n - JSS_CONNEG=true\n restart: unless-stopped\n```\n\n**Systemd Service**\n```bash\n$ jss generate systemd -c ./config.json -o jss.service\n```\n\n```ini\n[Unit]\nDescription=JavaScript Solid Server\nAfter=network.target\n\n[Service]\nType=simple\nUser=jss\nWorkingDirectory=/opt/jss\nExecStart=/usr/bin/jss start -c /etc/jss/config.json\nRestart=on-failure\nRestartSec=10\n\n[Install]\nWantedBy=multi-user.target\n```\n\n**Nginx Reverse Proxy**\n```bash\n$ jss generate nginx -c ./config.json --domain example.com\n```\n\n```nginx\nserver {\n listen 443 ssl http2;\n server_name example.com;\n\n ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;\n ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;\n\n location / {\n proxy_pass http://127.0.0.1:3000;\n proxy_http_version 1.1;\n proxy_set_header Upgrade $http_upgrade;\n proxy_set_header Connection \"upgrade\";\n proxy_set_header Host $host;\n proxy_set_header X-Real-IP $remote_addr;\n proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n proxy_set_header X-Forwarded-Proto $scheme;\n }\n}\n```\n\n**Caddy**\n```bash\n$ jss generate caddy -c ./config.json --domain example.com\n```\n\n```\nexample.com {\n reverse_proxy localhost:3000\n}\n```\n\n**Environment File**\n```bash\n$ jss generate env -c ./config.json -o .env\n```\n\n```bash\nJSS_PORT=8443\nJSS_ROOT=./data\nJSS_SSL_KEY=./ssl/key.pem\nJSS_SSL_CERT=./ssl/cert.pem\nJSS_IDP=true\nJSS_CONNEG=true\n```\n\n---\n\n### `jss migrate` - Configuration Migration\n\nMigrate configuration from older versions or other servers.\n\n```bash\n$ jss migrate --from node-solid-server --input .solid/config.json\n\n ╭──────────────────────────────────────────╮\n │ Configuration Migration │\n ╰──────────────────────────────────────────╯\n\n Source: Node Solid Server config\n \n Migrating settings:\n ✓ port: 8443\n ✓ serverUri → computed from port\n ✓ root → root\n ✓ sslKey → sslKey\n ✓ sslCert → sslCert\n ⚠ webid: true → idp: true (similar feature)\n ✗ multiuser: skipped (different implementation)\n \n Saved to: ./config.json\n \n ⚠ Manual review recommended for:\n - User accounts (not migrated)\n - ACL files (may need updates)\n```\n\n---\n\n## Implementation Details\n\n### Library Recommendations\n\n| Library | Purpose | Size |\n|---------|---------|------|\n| **@inquirer/prompts** | Modern interactive prompts | ~50KB |\n| **chalk** | Terminal colors | ~20KB |\n| **ora** | Spinners for async operations | ~15KB |\n| **boxen** | Boxes for headers | ~10KB |\n| **cli-table3** | Tables for summaries | ~15KB |\n\n**Alternative: Zero-dependency approach**\nUse built-in `readline` with ANSI escape codes for colors. Larger code but no dependencies.\n\n### Prompt Types Needed\n\n```javascript\nimport {\n select, // Preset selection\n checkbox, // Feature toggles\n input, // Text input with validation\n confirm, // Yes/no questions\n password // Hidden input (for tokens)\n} from '@inquirer/prompts';\n```\n\n### Validation Functions\n\n```javascript\nconst validators = {\n port: (value) =\u003e {\n const port = parseInt(value);\n if (isNaN(port) || port \u003c 1 || port \u003e 65535) {\n return 'Port must be between 1 and 65535';\n }\n if (port \u003c 1024) {\n return 'warning:Port below 1024 requires root privileges';\n }\n return true;\n },\n \n directory: async (value) =\u003e {\n const dir = path.resolve(value);\n try {\n await fs.access(path.dirname(dir), fs.constants.W_OK);\n return true;\n } catch {\n return 'Parent directory is not writable';\n }\n },\n \n domain: (value) =\u003e {\n const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,61}[a-zA-Z0-9](?:\\.[a-zA-Z]{2,})+$/;\n if (!domainRegex.test(value) \u0026\u0026 value !== 'localhost') {\n return 'Invalid domain format';\n }\n return true;\n },\n \n sslCert: async (value) =\u003e {\n try {\n const cert = await fs.readFile(value, 'utf8');\n if (!cert.includes('BEGIN CERTIFICATE')) {\n return 'File does not appear to be a PEM certificate';\n }\n return true;\n } catch {\n return 'File not found or not readable';\n }\n }\n};\n```\n\n### Error Handling\n\n```javascript\n// Graceful Ctrl+C handling\nprocess.on('SIGINT', () =\u003e {\n console.log('\\n\\nSetup cancelled.');\n process.exit(0);\n});\n\n// Wrap prompts in try/catch\ntry {\n const answers = await runWizard();\n} catch (error) {\n if (error.name === 'ExitPromptError') {\n console.log('\\nSetup cancelled.');\n process.exit(0);\n }\n throw error;\n}\n```\n\n---\n\n## Industry Comparison\n\n| Tool | Setup Experience |\n|------|------------------|\n| **npm init** | Simple prompts, `-y` for defaults, generates package.json |\n| **yarn create** | Runs create-* packages, delegates to framework CLIs |\n| **vite create** | Select framework → variant → done, very fast |\n| **create-next-app** | Name → TypeScript? → ESLint? → Tailwind? → src/? → App Router? |\n| **create-react-app** | Just project name, everything else automatic |\n| **Prisma init** | Datasource selection, generates schema file |\n| **Docker init** | Detect project type, generate Dockerfile + compose |\n| **Mastodon setup** | `rake mastodon:setup` - domain, DB, SMTP, admin account |\n\n### Best Practices Observed\n\n1. **Preset/template first** (Vite, Next.js) - Offer starting points\n2. **Sensible defaults** (CRA) - Work out of box with minimal input\n3. **Validation with recovery** (Inquirer) - Don't fail, offer alternatives\n4. **Summary before commit** (Prisma) - Show what will be created\n5. **Next steps guidance** (all) - Tell user what to do after\n6. **Skip option** (`-y` flag) - Allow non-interactive mode\n\n---\n\n## Command Summary\n\n| Command | Purpose | Priority |\n|---------|---------|----------|\n| `jss init` | Interactive setup wizard (enhanced) | P0 |\n| `jss doctor` | Validate configuration and system | P1 |\n| `jss generate docker` | Generate docker-compose.yml | P1 |\n| `jss generate systemd` | Generate systemd service file | P2 |\n| `jss generate nginx` | Generate nginx config | P2 |\n| `jss generate caddy` | Generate Caddyfile | P2 |\n| `jss generate env` | Export config as .env | P2 |\n| `jss migrate` | Migrate from other configs | P3 |\n| `jss presets` | List/show presets (from #97) | P1 |\n\n---\n\n## Difficulty Breakdown\n\n| Component | Difficulty | Notes |\n|-----------|------------|-------|\n| Enhanced prompts (inquirer) | 20/100 | Library does heavy lifting |\n| Input validation | 15/100 | Straightforward checks |\n| Visual improvements (chalk, boxen) | 10/100 | Simple additions |\n| `jss doctor` command | 30/100 | Many checks to implement |\n| `jss generate docker` | 20/100 | Template + variable substitution |\n| `jss generate systemd` | 15/100 | Simple template |\n| `jss generate nginx/caddy` | 20/100 | Need to handle edge cases |\n| `jss migrate` | 40/100 | Need to understand other formats |\n| **Total** | 35/100 | |\n\n---\n\n## Testing Plan\n\n1. **Interactive tests** (manual): Run through wizard with various inputs\n2. **Non-interactive tests**: `jss init -y` with env vars\n3. **Validation tests**: Invalid inputs, edge cases\n4. **Generation tests**: Compare output against expected templates\n5. **Doctor tests**: Mock various system states\n\n```javascript\ndescribe('jss init', () =\u003e {\n it('should accept preset flag', async () =\u003e {\n const config = await runInit({ preset: 'personal', yes: true });\n expect(config.singleUser).toBe(true);\n expect(config.idp).toBe(true);\n });\n\n it('should validate port range', async () =\u003e {\n const result = validators.port('70000');\n expect(result).toContain('between 1 and 65535');\n });\n});\n\ndescribe('jss doctor', () =\u003e {\n it('should detect unavailable port', async () =\u003e {\n // Start something on port 3000\n const checks = await runDoctor({ port: 3000 });\n expect(checks.network.portAvailable).toBe(false);\n });\n});\n\ndescribe('jss generate', () =\u003e {\n it('should generate valid docker-compose', async () =\u003e {\n const output = await generateDocker(sampleConfig);\n const parsed = yaml.parse(output);\n expect(parsed.services.jss).toBeDefined();\n });\n});\n```\n\n---\n\n## Related Issues\n\n- #97 - Configuration presets (prerequisite for preset selection)\n- #95 - Web-based onboarding wizard (complementary)\n- #96 - Admin control panel (config viewer uses similar display logic)\n\n---\n\n## Open Questions\n\n1. Should we use `@inquirer/prompts` (modern, ESM) or `inquirer` (legacy, CJS compatible)?\n2. Should `jss doctor` attempt fixes or just report issues?\n3. Should generated files include comments explaining each setting?\n4. Should `jss init` offer to run `jss doctor` automatically after setup?\n5. How to handle `jss init` in Docker environments (non-interactive)?\n\n---\n\n## References\n\n- [Inquirer.js](https://github.com/SBoudrias/Inquirer.js) - Interactive prompts\n- [Chalk](https://github.com/chalk/chalk) - Terminal colors\n- [Ora](https://github.com/sindresorhus/ora) - Spinners\n- [Commander.js](https://github.com/tj/commander.js) - CLI framework (already used)\n- [Vite Create](https://vitejs.dev/guide/#scaffolding-your-first-vite-project) - Example of good CLI UX\n- [Docker Init](https://docs.docker.com/engine/reference/commandline/init/) - Config generation example","author":{"url":"https://github.com/melvincarvalho","@type":"Person","name":"melvincarvalho"},"datePublished":"2026-01-19T13:10:11.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/98/JavaScriptSolidServer/issues/98"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:88ebe05e-0a1a-8a5b-3bb7-d06c309ba499 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | D6A6:85EB9:46781D:60AB80:69774E14 |
| html-safe-nonce | 553fe44153b3eecb9d99bce2f51d2e73973dd6707d2581300ddd3963464a834d |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJENkE2Ojg1RUI5OjQ2NzgxRDo2MEFCODA6Njk3NzRFMTQiLCJ2aXNpdG9yX2lkIjoiODk1NDc2MTIyMzQwNDQ3Mzg3NiIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 5629d36afada3911800f38db0016ad7b2dbd8e0490278a44970931db285d36f3 |
| hovercard-subject-tag | issue:3829669115 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/JavaScriptSolidServer/JavaScriptSolidServer/98/issue_layout |
| twitter:image | https://opengraph.githubassets.com/2d13c712ec81bd23914d61cb144c55446981e446de03b07dc00b831e8c224b20/JavaScriptSolidServer/JavaScriptSolidServer/issues/98 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/2d13c712ec81bd23914d61cb144c55446981e446de03b07dc00b831e8c224b20/JavaScriptSolidServer/JavaScriptSolidServer/issues/98 |
| og:image:alt | Summary Enhance the jss init command and add complementary CLI tools to provide a polished, professional setup experience. This covers interactive setup improvements, validation, diagnostics, and o... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | melvincarvalho |
| hostname | github.com |
| expected-hostname | github.com |
| None | 3310064f35a62c06a4024ba37f41c06836f39376a095c2dfd2c4b693c34965be |
| turbo-cache-control | no-preview |
| go-import | github.com/JavaScriptSolidServer/JavaScriptSolidServer git https://github.com/JavaScriptSolidServer/JavaScriptSolidServer.git |
| octolytics-dimension-user_id | 205442424 |
| octolytics-dimension-user_login | JavaScriptSolidServer |
| octolytics-dimension-repository_id | 958025407 |
| octolytics-dimension-repository_nwo | JavaScriptSolidServer/JavaScriptSolidServer |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 958025407 |
| octolytics-dimension-repository_network_root_nwo | JavaScriptSolidServer/JavaScriptSolidServer |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 67d5f8d1d53c3cc4f49fc3bb8029933c3dc219e6 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width