helixevo 0.2.38 → 0.2.40

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,7 +1,10 @@
1
1
  'use client'
2
2
 
3
- import { useState } from 'react'
3
+ import { useMemo, useState } from 'react'
4
+ import { MetricCard } from '@/components/metric-card'
5
+ import { PageHero } from '@/components/page-hero'
4
6
  import { QuickActions } from '@/components/quick-actions'
7
+ import { SectionFrame } from '@/components/section-frame'
5
8
 
6
9
  interface CommandInfo {
7
10
  name: string
@@ -233,198 +236,272 @@ const COMMANDS: CommandInfo[] = [
233
236
  },
234
237
  ]
235
238
 
236
- const CATEGORIES: { id: string; label: string; color: string }[] = [
237
- { id: 'core', label: 'Core Workflow', color: 'var(--purple)' },
238
- { id: 'evolution', label: 'Evolution', color: 'var(--green)' },
239
- { id: 'network', label: 'Network & Research', color: 'var(--blue)' },
240
- { id: 'analysis', label: 'Analysis & Reports', color: 'var(--yellow)' },
241
- { id: 'system', label: 'System', color: 'var(--text-secondary)' },
239
+ const WORKFLOW = [
240
+ { label: 'init', desc: 'Import skills', tone: 'purple' as const },
241
+ { label: 'watch', desc: 'Capture corrections', tone: 'blue' as const },
242
+ { label: 'evolve', desc: 'Improve skills', tone: 'green' as const },
243
+ { label: 'generalize', desc: 'Abstract patterns', tone: 'purple' as const },
244
+ { label: 'graph --rebuild', desc: 'Map relationships', tone: 'yellow' as const },
245
+ { label: 'health', desc: 'Assess quality', tone: 'blue' as const },
242
246
  ]
243
247
 
248
+ const CATEGORIES: Array<{
249
+ id: CommandInfo['category']
250
+ label: string
251
+ tone: 'neutral' | 'purple' | 'green' | 'blue' | 'yellow'
252
+ description: string
253
+ }> = [
254
+ { id: 'core', label: 'Core workflow', tone: 'purple', description: 'The commands that initialize HelixEvo and keep it learning continuously.' },
255
+ { id: 'evolution', label: 'Evolution', tone: 'green', description: 'Mutation, promotion, and specialization controls for active skill improvement.' },
256
+ { id: 'network', label: 'Network & research', tone: 'blue', description: 'Graph maintenance, discovery, and relationship mapping across the skill ecosystem.' },
257
+ { id: 'analysis', label: 'Analysis & reports', tone: 'yellow', description: 'Operational reads on system quality, trends, reports, and health.' },
258
+ { id: 'system', label: 'System', tone: 'neutral', description: 'Supporting commands for capture, dashboard access, and environment-level actions.' },
259
+ ]
260
+
261
+ function toneColor(tone: 'neutral' | 'purple' | 'green' | 'blue' | 'yellow') {
262
+ if (tone === 'purple') return 'var(--purple)'
263
+ if (tone === 'green') return 'var(--green)'
264
+ if (tone === 'blue') return 'var(--blue)'
265
+ if (tone === 'yellow') return 'var(--yellow)'
266
+ return 'var(--text-secondary)'
267
+ }
268
+
244
269
  export default function CommandsPage() {
245
- const [expandedCmd, setExpandedCmd] = useState<string | null>(null)
270
+ const [expandedCmd, setExpandedCmd] = useState<string | null>('watch')
271
+
272
+ const stats = useMemo(() => {
273
+ const llmCommands = COMMANDS.filter(command => command.needsLLM).length
274
+ const runnableCommands = COMMANDS.filter(command => command.runnable).length
275
+ const optionFlags = COMMANDS.reduce((sum, command) => sum + (command.options?.length ?? 0), 0)
276
+ return { llmCommands, runnableCommands, optionFlags }
277
+ }, [])
246
278
 
247
279
  return (
248
280
  <div>
249
- <div className="page-header">
250
- <h1 className="page-title">Commands</h1>
251
- <p className="page-desc">
252
- All CLI commands available in HelixEvo click any command for details and examples, or run directly from here
253
- </p>
281
+ <PageHero
282
+ eyebrow="Command center"
283
+ title="Commands"
284
+ description="The complete HelixEvo CLI surfaceorganized by workflow, annotated by purpose, and ready to run from the dashboard when supported."
285
+ chips={[
286
+ { label: `${COMMANDS.length} commands`, tone: 'blue' },
287
+ { label: `${stats.llmCommands} need LLM access`, tone: 'purple' },
288
+ { label: `${stats.runnableCommands} runnable here`, tone: 'green' },
289
+ { label: `${stats.optionFlags} documented flags`, tone: 'yellow' },
290
+ ]}
291
+ actions={
292
+ <div className="hero-note-card">
293
+ <div className="hero-note-label">Recommended operating loop</div>
294
+ <div className="hero-note-title">Init → Watch → Evolve → Generalize → Graph → Health</div>
295
+ <div className="hero-note-copy">Use the Commands page as the practical bridge between HelixEvo’s CLI and the premium dashboard cockpit.</div>
296
+ </div>
297
+ }
298
+ />
299
+
300
+ <div className="grid-4" style={{ marginBottom: 24 }}>
301
+ <MetricCard label="CLI surface" value={COMMANDS.length} sublabel="Documented HelixEvo commands across core, evolution, network, analysis, and system layers." tone="blue" />
302
+ <MetricCard label="Live actions" value={stats.runnableCommands} sublabel="Commands with dashboard launch actions wired through the quick action system." tone="green" />
303
+ <MetricCard label="LLM-dependent" value={stats.llmCommands} sublabel="Commands that rely on model-backed evaluation, generation, or analysis." tone="purple" />
304
+ <MetricCard label="Flags documented" value={stats.optionFlags} sublabel="Total option flags surfaced across the current command reference." tone="yellow" />
254
305
  </div>
255
306
 
256
- {/* Typical workflow */}
257
- <div className="card" style={{ marginBottom: 24, padding: '16px 20px' }}>
258
- <div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text)', marginBottom: 8 }}>Typical Workflow</div>
259
- <div style={{ display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap', fontSize: 12 }}>
260
- {[
261
- { label: 'init', desc: 'Import skills' },
262
- { label: 'watch', desc: 'Capture corrections' },
263
- { label: 'evolve', desc: 'Improve skills' },
264
- { label: 'generalize', desc: 'Abstract patterns' },
265
- { label: 'graph --rebuild', desc: 'Map relationships' },
266
- { label: 'health', desc: 'Assess quality' },
267
- ].map((step, i) => (
268
- <span key={step.label} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
269
- <span style={{
270
- background: 'var(--purple-light)', color: 'var(--purple)',
271
- padding: '4px 10px', borderRadius: 'var(--radius)',
272
- fontFamily: 'var(--font-mono)', fontWeight: 600,
307
+ <SectionFrame
308
+ eyebrow="Workflow framing"
309
+ title="Typical operating sequence"
310
+ description="A high-signal path through the CLI when standing HelixEvo up and then keeping it improving over time."
311
+ tone="purple"
312
+ >
313
+ <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
314
+ {WORKFLOW.map((step, index) => (
315
+ <div key={step.label} style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
316
+ <div style={{
317
+ display: 'inline-flex',
318
+ alignItems: 'center',
319
+ gap: 8,
320
+ padding: '10px 14px',
321
+ borderRadius: 999,
322
+ border: '1px solid var(--border)',
323
+ background: 'rgba(255,255,255,0.72)',
324
+ boxShadow: 'var(--shadow-xs)',
273
325
  }}>
274
- {step.label}
275
- </span>
276
- <span style={{ color: 'var(--text-dim)' }}>{step.desc}</span>
277
- {i < 5 && <span style={{ color: 'var(--text-muted)', margin: '0 4px' }}>&rarr;</span>}
278
- </span>
326
+ <span className={`hero-chip hero-chip-${step.tone}`}>{step.label}</span>
327
+ <span style={{ fontSize: 12, color: 'var(--text-dim)' }}>{step.desc}</span>
328
+ </div>
329
+ {index < WORKFLOW.length - 1 ? <span style={{ color: 'var(--text-muted)', fontSize: 15 }}>→</span> : null}
330
+ </div>
279
331
  ))}
280
332
  </div>
281
- </div>
333
+ </SectionFrame>
282
334
 
283
- {/* Commands by category */}
284
- {CATEGORIES.map(cat => {
285
- const cmds = COMMANDS.filter(c => c.category === cat.id)
286
- if (cmds.length === 0) return null
335
+ {CATEGORIES.map(category => {
336
+ const commands = COMMANDS.filter(command => command.category === category.id)
337
+ if (commands.length === 0) return null
287
338
 
288
339
  return (
289
- <div key={cat.id} style={{ marginBottom: 24 }}>
290
- <div style={{
291
- fontSize: 11, fontWeight: 700, color: cat.color,
292
- textTransform: 'uppercase', letterSpacing: 1.2, marginBottom: 10,
293
- }}>
294
- {cat.label}
295
- </div>
340
+ <SectionFrame
341
+ key={category.id}
342
+ eyebrow={`${commands.length} command${commands.length === 1 ? '' : 's'}`}
343
+ title={category.label}
344
+ description={category.description}
345
+ tone={category.tone}
346
+ className="section-frame-tight"
347
+ >
348
+ <div style={{ display: 'grid', gap: 12 }}>
349
+ {commands.map(command => {
350
+ const isExpanded = expandedCmd === command.name
351
+ const categoryColor = toneColor(category.tone)
296
352
 
297
- <div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
298
- {cmds.map(cmd => {
299
- const isExpanded = expandedCmd === cmd.name
300
353
  return (
301
- <div key={cmd.name} className="card" style={{
354
+ <article key={command.name} className="card" style={{
302
355
  overflow: 'hidden',
303
- border: isExpanded ? `1px solid ${cat.color}40` : undefined,
356
+ borderColor: isExpanded ? `${categoryColor}30` : undefined,
357
+ boxShadow: isExpanded ? 'var(--shadow-md)' : undefined,
304
358
  }}>
305
- {/* Command header — clickable */}
306
- <div
307
- onClick={() => setExpandedCmd(isExpanded ? null : cmd.name)}
359
+ <button
360
+ onClick={() => setExpandedCmd(isExpanded ? null : command.name)}
308
361
  style={{
309
- padding: '12px 16px',
362
+ width: '100%',
363
+ padding: '16px 18px',
364
+ border: 'none',
365
+ background: isExpanded ? 'linear-gradient(180deg, rgba(255,255,255,0.92), rgba(245,241,236,0.82))' : 'transparent',
366
+ display: 'flex',
367
+ justifyContent: 'space-between',
368
+ alignItems: 'flex-start',
369
+ gap: 16,
310
370
  cursor: 'pointer',
311
- display: 'flex', justifyContent: 'space-between', alignItems: 'center',
371
+ textAlign: 'left',
312
372
  }}
313
373
  >
314
- <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
315
- <code style={{
316
- fontFamily: 'var(--font-mono)', fontSize: 13, fontWeight: 700,
317
- color: cat.color,
318
- }}>
319
- {cmd.name}
320
- </code>
321
- <span style={{ fontSize: 12, color: 'var(--text-secondary)' }}>
322
- {cmd.description.split('.')[0]}
323
- </span>
324
- {cmd.needsLLM && (
325
- <span style={{
326
- fontSize: 9, fontWeight: 600, padding: '2px 6px',
327
- background: 'var(--purple-light)', color: 'var(--purple)',
328
- borderRadius: 4,
329
- }}>LLM</span>
330
- )}
374
+ <div style={{ flex: 1, minWidth: 0 }}>
375
+ <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginBottom: 8 }}>
376
+ <code style={{ fontFamily: 'var(--font-mono)', fontSize: 14, fontWeight: 700, color: categoryColor }}>
377
+ {command.name}
378
+ </code>
379
+ <span className={`hero-chip hero-chip-${category.tone}`}>{category.label}</span>
380
+ {command.needsLLM ? <span className="hero-chip hero-chip-purple">LLM</span> : <span className="hero-chip hero-chip-neutral">local</span>}
381
+ {command.runnable ? <span className="hero-chip hero-chip-green">runnable</span> : null}
382
+ </div>
383
+ <div style={{ fontSize: 12.5, color: 'var(--text-secondary)', lineHeight: 1.65, maxWidth: 860 }}>
384
+ {command.description}
385
+ </div>
331
386
  </div>
332
- <span style={{
333
- color: 'var(--text-muted)', fontSize: 12,
334
- transform: isExpanded ? 'rotate(180deg)' : 'none',
335
- transition: 'transform 0.2s',
336
- }}>▼</span>
337
- </div>
338
-
339
- {/* Expanded details */}
340
- {isExpanded && (
341
387
  <div style={{
342
- padding: '0 16px 16px',
343
- borderTop: '1px solid var(--border-subtle)',
388
+ flexShrink: 0,
389
+ width: 30,
390
+ height: 30,
391
+ borderRadius: 999,
392
+ background: 'rgba(97,93,86,0.08)',
393
+ border: '1px solid var(--border)',
394
+ color: 'var(--text-muted)',
395
+ display: 'flex',
396
+ alignItems: 'center',
397
+ justifyContent: 'center',
398
+ transform: isExpanded ? 'rotate(180deg)' : 'none',
399
+ transition: 'transform 0.2s ease',
400
+ marginTop: 2,
344
401
  }}>
345
- {/* Description */}
346
- <p style={{ fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.6, marginTop: 12, marginBottom: 14 }}>
347
- {cmd.description}
348
- </p>
402
+
403
+ </div>
404
+ </button>
349
405
 
350
- {/* Usage */}
351
- <div style={{ marginBottom: 14 }}>
352
- <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 6 }}>Usage</div>
353
- <code style={{
354
- display: 'block', padding: '8px 12px',
355
- background: 'var(--bg-section)', borderRadius: 'var(--radius)',
356
- fontFamily: 'var(--font-mono)', fontSize: 12, color: 'var(--text)',
357
- }}>
358
- $ {cmd.usage}
359
- </code>
360
- </div>
406
+ {isExpanded ? (
407
+ <div style={{ padding: '0 18px 18px', borderTop: '1px solid var(--border-subtle)' }}>
408
+ <div className="grid-2" style={{ alignItems: 'start', gap: 16, marginTop: 16 }}>
409
+ <div style={{ display: 'grid', gap: 14 }}>
410
+ <div>
411
+ <div style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.9, marginBottom: 6 }}>Usage</div>
412
+ <code style={{
413
+ display: 'block',
414
+ padding: '12px 14px',
415
+ background: 'rgba(97,93,86,0.07)',
416
+ borderRadius: 16,
417
+ border: '1px solid var(--border)',
418
+ fontFamily: 'var(--font-mono)',
419
+ fontSize: 12,
420
+ color: 'var(--text)',
421
+ }}>
422
+ $ {command.usage}
423
+ </code>
424
+ </div>
361
425
 
362
- {/* Options */}
363
- {cmd.options && cmd.options.length > 0 && (
364
- <div style={{ marginBottom: 14 }}>
365
- <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 6 }}>Options</div>
366
- <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
367
- {cmd.options.map(opt => (
368
- <div key={opt.flag} style={{ display: 'flex', gap: 12, fontSize: 12, padding: '4px 0' }}>
369
- <code style={{
370
- fontFamily: 'var(--font-mono)', color: 'var(--purple)',
371
- fontWeight: 600, minWidth: 180, flexShrink: 0,
372
- }}>{opt.flag}</code>
373
- <span style={{ color: 'var(--text-dim)' }}>{opt.desc}</span>
426
+ {command.options && command.options.length > 0 ? (
427
+ <div>
428
+ <div style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.9, marginBottom: 6 }}>Options</div>
429
+ <div style={{ display: 'grid', gap: 8 }}>
430
+ {command.options.map(option => (
431
+ <div key={option.flag} style={{
432
+ padding: '10px 12px',
433
+ borderRadius: 14,
434
+ background: 'rgba(255,255,255,0.72)',
435
+ border: '1px solid var(--border)',
436
+ }}>
437
+ <code style={{ display: 'block', fontFamily: 'var(--font-mono)', color: 'var(--purple)', fontSize: 11.5, fontWeight: 700, marginBottom: 4 }}>
438
+ {option.flag}
439
+ </code>
440
+ <div style={{ fontSize: 12, color: 'var(--text-dim)', lineHeight: 1.55 }}>{option.desc}</div>
441
+ </div>
442
+ ))}
374
443
  </div>
375
- ))}
376
- </div>
377
- </div>
378
- )}
444
+ </div>
445
+ ) : null}
379
446
 
380
- {/* Examples */}
381
- <div style={{ marginBottom: cmd.runnable ? 14 : 0 }}>
382
- <div style={{ fontSize: 10, fontWeight: 600, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 6 }}>Examples</div>
383
- <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
384
- {cmd.examples.map((ex, i) => (
385
- <div key={i} style={{
386
- padding: '8px 12px',
387
- background: 'var(--bg-section)', borderRadius: 'var(--radius)',
447
+ {command.note ? (
448
+ <div style={{
449
+ padding: '12px 14px',
450
+ background: 'var(--yellow-light)',
451
+ border: '1px solid var(--yellow-border)',
452
+ borderRadius: 16,
453
+ color: 'var(--yellow)',
454
+ fontSize: 12,
455
+ lineHeight: 1.6,
388
456
  }}>
389
- <code style={{ fontFamily: 'var(--font-mono)', fontSize: 11, color: 'var(--text)', fontWeight: 600 }}>
390
- $ {ex.cmd}
391
- </code>
392
- <div style={{ fontSize: 11, color: 'var(--text-dim)', marginTop: 2 }}>{ex.desc}</div>
457
+ <strong style={{ display: 'block', marginBottom: 4 }}>Operational note</strong>
458
+ {command.note}
393
459
  </div>
394
- ))}
460
+ ) : null}
395
461
  </div>
396
- </div>
397
462
 
398
- {/* Note */}
399
- {cmd.note && (
400
- <div style={{
401
- padding: '8px 12px', marginBottom: cmd.runnable ? 14 : 0,
402
- background: 'var(--yellow-light)', borderRadius: 'var(--radius)',
403
- fontSize: 11, color: 'var(--yellow)', fontWeight: 500,
404
- borderLeft: '3px solid var(--yellow)',
405
- }}>
406
- {cmd.note}
407
- </div>
408
- )}
463
+ <div style={{ display: 'grid', gap: 14 }}>
464
+ <div>
465
+ <div style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.9, marginBottom: 6 }}>Examples</div>
466
+ <div style={{ display: 'grid', gap: 8 }}>
467
+ {command.examples.map((example, index) => (
468
+ <div key={`${command.name}-example-${index}`} style={{
469
+ padding: '12px 14px',
470
+ borderRadius: 16,
471
+ background: 'rgba(255,255,255,0.72)',
472
+ border: '1px solid var(--border)',
473
+ }}>
474
+ <code style={{ display: 'block', fontFamily: 'var(--font-mono)', fontSize: 11.5, color: 'var(--text)', fontWeight: 700, marginBottom: 4 }}>
475
+ $ {example.cmd}
476
+ </code>
477
+ <div style={{ fontSize: 12, color: 'var(--text-dim)', lineHeight: 1.55 }}>{example.desc}</div>
478
+ </div>
479
+ ))}
480
+ </div>
481
+ </div>
409
482
 
410
- {/* Run button */}
411
- {cmd.runnable && (
412
- <QuickActions actions={[{
413
- id: cmd.runnable.command,
414
- label: cmd.runnable.label,
415
- command: cmd.runnable.command,
416
- icon: cmd.runnable.icon,
417
- color: cmd.runnable.color,
418
- description: `Run: helixevo ${cmd.name}`,
419
- }]} />
420
- )}
483
+ {command.runnable ? (
484
+ <div>
485
+ <div style={{ fontSize: 10.5, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 0.9, marginBottom: 8 }}>Launch from dashboard</div>
486
+ <QuickActions actions={[{
487
+ id: command.runnable.command,
488
+ label: command.runnable.label,
489
+ command: command.runnable.command,
490
+ icon: command.runnable.icon,
491
+ color: command.runnable.color,
492
+ description: `Run: helixevo ${command.name}`,
493
+ }]} />
494
+ </div>
495
+ ) : null}
496
+ </div>
497
+ </div>
421
498
  </div>
422
- )}
423
- </div>
499
+ ) : null}
500
+ </article>
424
501
  )
425
502
  })}
426
503
  </div>
427
- </div>
504
+ </SectionFrame>
428
505
  )
429
506
  })}
430
507
  </div>