roadmap-kit 1.0.0 → 1.0.2

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.
@@ -1,16 +1,18 @@
1
1
  <!doctype html>
2
- <html lang="es" class="dark">
2
+ <html lang="es" data-theme="glass" class="light">
3
3
  <head>
4
4
  <meta charset="UTF-8" />
5
5
  <link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🗺️</text></svg>" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
- <title>ROADMAP // Terminal</title>
8
- <!-- Fonts: Orbitron for display, IBM Plex Mono for everything else -->
7
+ <title>ROADMAP-KIT</title>
8
+ <!-- Fonts for both themes -->
9
9
  <link rel="preconnect" href="https://fonts.googleapis.com">
10
10
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
- <link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=Orbitron:wght@400;500;600;700;800;900&family=Space+Grotesk:wght@300;400;500;600;700&display=swap" rel="stylesheet">
11
+ <!-- Matrix theme: Orbitron + IBM Plex Mono -->
12
+ <!-- Glass theme: Inter + Fira Code -->
13
+ <link href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@300;400;500;600;700&family=IBM+Plex+Mono:ital,wght@0,300;0,400;0,500;0,600;0,700;1,400&family=Inter:wght@300;400;500;600;700;800&family=Orbitron:wght@400;500;600;700;800;900&display=swap" rel="stylesheet">
12
14
  </head>
13
- <body class="bg-black text-slate-100 antialiased">
15
+ <body class="antialiased">
14
16
  <div id="root"></div>
15
17
  <script type="module" src="/src/main.jsx"></script>
16
18
  </body>
@@ -8,11 +8,11 @@ import Anthropic from '@anthropic-ai/sdk';
8
8
  import { spawn } from 'child_process';
9
9
 
10
10
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
11
- const ROADMAP_KIT_PATH = path.join(__dirname, '..');
11
+ const ROADMAP_KIT_PATH = process.env.PROJECT_ROOT || path.join(__dirname, '..');
12
12
  const ROADMAP_PATH = path.join(ROADMAP_KIT_PATH, 'roadmap.json');
13
13
  const AUTH_PATH = path.join(ROADMAP_KIT_PATH, 'auth.json');
14
14
  const VERSIONS_PATH = path.join(ROADMAP_KIT_PATH, 'versions.json');
15
- const PROJECT_ROOT = path.join(ROADMAP_KIT_PATH, '..'); // Parent of roadmap-kit
15
+ const PROJECT_ROOT = process.env.PROJECT_ROOT || path.join(ROADMAP_KIT_PATH, '..');
16
16
  const MAX_VERSIONS = 10;
17
17
 
18
18
  // ============ VERSION CONTROL ============
@@ -108,7 +108,9 @@ async function createDefaultAuthConfig() {
108
108
  settings: {
109
109
  requireAuth: true,
110
110
  sessionDuration: 86400000, // 24h in ms
111
- allowRegistration: false
111
+ allowRegistration: false,
112
+ defaultTheme: 'glass', // Default theme for new users
113
+ defaultColorMode: 'light' // Default color mode (light/dark)
112
114
  },
113
115
  users: [
114
116
  {
@@ -117,6 +119,8 @@ async function createDefaultAuthConfig() {
117
119
  email: adminEmail,
118
120
  password: hashedPassword,
119
121
  role: 'admin',
122
+ theme: 'glass', // User's preferred theme
123
+ colorMode: 'light', // User's preferred color mode (light/dark)
120
124
  createdAt: new Date().toISOString(),
121
125
  lastLogin: null
122
126
  }
@@ -165,11 +169,15 @@ function getSession(sessionId) {
165
169
  function createSession(authConfig, user) {
166
170
  const sessionId = generateSessionId();
167
171
  const duration = authConfig?.settings?.sessionDuration || 86400000;
172
+ const defaultTheme = authConfig?.settings?.defaultTheme || 'glass';
173
+ const defaultColorMode = authConfig?.settings?.defaultColorMode || 'light';
168
174
  sessions.set(sessionId, {
169
175
  userId: user.id,
170
176
  email: user.email,
171
177
  name: user.name,
172
178
  role: user.role,
179
+ theme: user.theme || defaultTheme,
180
+ colorMode: user.colorMode || defaultColorMode,
173
181
  createdAt: Date.now(),
174
182
  expiresAt: Date.now() + duration
175
183
  });
@@ -241,9 +249,11 @@ async function createServer() {
241
249
  try {
242
250
  const authConfig = await loadAuthConfig();
243
251
  const authEnabled = authConfig?.settings?.requireAuth ?? true;
252
+ const defaultTheme = authConfig?.settings?.defaultTheme || 'glass';
253
+ const defaultColorMode = authConfig?.settings?.defaultColorMode || 'light';
244
254
 
245
255
  if (!authEnabled) {
246
- return res.json({ authenticated: true, authEnabled: false, user: { role: 'admin', name: 'Anonymous' } });
256
+ return res.json({ authenticated: true, authEnabled: false, user: { role: 'admin', name: 'Anonymous', theme: defaultTheme, colorMode: defaultColorMode } });
247
257
  }
248
258
 
249
259
  const cookies = req.headers.cookie || '';
@@ -254,7 +264,7 @@ async function createServer() {
254
264
  res.json({
255
265
  authenticated: !!session,
256
266
  authEnabled: true,
257
- user: session ? { name: session.name, email: session.email, role: session.role } : null
267
+ user: session ? { name: session.name, email: session.email, role: session.role, theme: session.theme || defaultTheme, colorMode: session.colorMode || defaultColorMode } : null
258
268
  });
259
269
  } catch (err) {
260
270
  res.status(500).json({ error: err.message });
@@ -286,11 +296,13 @@ async function createServer() {
286
296
  await saveAuthConfig(authConfig);
287
297
 
288
298
  const { sessionId, duration } = createSession(authConfig, user);
299
+ const defaultTheme = authConfig?.settings?.defaultTheme || 'glass';
300
+ const defaultColorMode = authConfig?.settings?.defaultColorMode || 'light';
289
301
  res.setHeader('Set-Cookie', `roadmap_session=${sessionId}; Path=/; HttpOnly; SameSite=Strict; Max-Age=${duration / 1000}`);
290
302
  res.json({
291
303
  success: true,
292
304
  message: 'Login exitoso',
293
- user: { name: user.name, email: user.email, role: user.role }
305
+ user: { name: user.name, email: user.email, role: user.role, theme: user.theme || defaultTheme, colorMode: user.colorMode || defaultColorMode }
294
306
  });
295
307
  } catch (err) {
296
308
  console.error('Login error:', err);
@@ -436,7 +448,7 @@ async function createServer() {
436
448
  // API: Update own profile (any authenticated user)
437
449
  app.put('/api/auth/profile', authMiddleware, async (req, res) => {
438
450
  try {
439
- const { name, email, currentPassword, newPassword } = req.body;
451
+ const { name, email, currentPassword, newPassword, theme, colorMode } = req.body;
440
452
  const userId = req.user.userId;
441
453
 
442
454
  const user = findUserById(req.authConfig, userId);
@@ -466,6 +478,16 @@ async function createServer() {
466
478
 
467
479
  if (name) user.name = name;
468
480
 
481
+ // Update theme if provided
482
+ if (theme && ['glass', 'matrix'].includes(theme)) {
483
+ user.theme = theme;
484
+ }
485
+
486
+ // Update colorMode if provided
487
+ if (colorMode && ['light', 'dark'].includes(colorMode)) {
488
+ user.colorMode = colorMode;
489
+ }
490
+
469
491
  await saveAuthConfig(req.authConfig);
470
492
 
471
493
  // Update session with new info
@@ -473,11 +495,13 @@ async function createServer() {
473
495
  if (session) {
474
496
  session.name = user.name;
475
497
  session.email = user.email;
498
+ if (theme) session.theme = user.theme;
499
+ if (colorMode) session.colorMode = user.colorMode;
476
500
  }
477
501
 
478
502
  res.json({
479
503
  success: true,
480
- user: { id: user.id, name: user.name, email: user.email, role: user.role }
504
+ user: { id: user.id, name: user.name, email: user.email, role: user.role, theme: user.theme, colorMode: user.colorMode }
481
505
  });
482
506
  } catch (err) {
483
507
  console.error('Update profile error:', err);
@@ -518,7 +542,8 @@ async function createServer() {
518
542
  res.json(JSON.parse(data));
519
543
  } catch (err) {
520
544
  if (err.code === 'ENOENT') {
521
- res.status(404).json({ error: 'roadmap.json not found' });
545
+ // Return special response indicating roadmap doesn't exist (redirect to setup)
546
+ res.json({ exists: false, error: 'roadmap.json not found', redirectToSetup: true });
522
547
  } else {
523
548
  res.status(500).json({ error: err.message });
524
549
  }
@@ -849,7 +874,7 @@ NO incluyas explicaciones, solo el JSON. Asegúrate de que sea JSON válido.`;
849
874
  process.env.PATH
850
875
  ].filter(Boolean).join(':');
851
876
 
852
- const claude = spawn('claude', ['-p', prompt, '--output-format', 'text'], {
877
+ const claude = spawn('claude', ['-p', prompt, '--output-format', 'text', '--dangerously-skip-permissions'], {
853
878
  cwd: PROJECT_ROOT,
854
879
  env: { ...process.env, PATH: expandedPath },
855
880
  shell: true