helixevo 0.2.21 → 0.2.22

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.
@@ -50,6 +50,7 @@ export default function Overview() {
50
50
  hasSkills={graph.nodes.length > 0}
51
51
  hasFailures={failures.length > 0}
52
52
  hasEdges={graph.edges.length > 0}
53
+ unresolvedCount={s.failures.unresolved}
53
54
  />
54
55
  </div>
55
56
 
@@ -62,6 +63,49 @@ export default function Overview() {
62
63
  <StatCard value={frontier.programs.length} label="Frontier" color="var(--text-secondary)" sub={`/${frontier.capacity} capacity`} accent="▲" />
63
64
  </div>
64
65
 
66
+ {/* Unresolved Failures */}
67
+ {failures.filter(f => !f.resolved).length > 0 && (
68
+ <div className="card" style={{ marginBottom: 20 }}>
69
+ <div className="card-body">
70
+ <div className="card-header-label">
71
+ Unresolved Corrections ({failures.filter(f => !f.resolved).length})
72
+ </div>
73
+ <div style={{ fontSize: 12, color: 'var(--text-dim)', marginBottom: 14, lineHeight: 1.5 }}>
74
+ These are corrections you made that haven&apos;t been incorporated into skills yet.
75
+ Click <strong style={{ color: 'var(--text)' }}>Evolve</strong> above to improve skills based on these corrections.
76
+ </div>
77
+ <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
78
+ {failures.filter(f => !f.resolved).slice(0, 5).map((f, i) => (
79
+ <div key={`${f.id}-${i}`} style={{
80
+ padding: '10px 14px', borderRadius: 'var(--radius)',
81
+ background: 'var(--bg-section)',
82
+ borderLeft: '3px solid var(--yellow)',
83
+ }}>
84
+ <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--text)', marginBottom: 3 }}>
85
+ {f.userRequest.slice(0, 100)}{f.userRequest.length > 100 ? '...' : ''}
86
+ </div>
87
+ <div style={{ fontSize: 11, color: 'var(--text-dim)', lineHeight: 1.4 }}>
88
+ Correction: {f.correction.slice(0, 120)}{f.correction.length > 120 ? '...' : ''}
89
+ </div>
90
+ <div style={{ display: 'flex', gap: 6, marginTop: 6 }}>
91
+ <span className="badge badge-yellow">{f.correctionType}</span>
92
+ {f.project && <span className="badge badge-gray">{f.project}</span>}
93
+ <span style={{ fontSize: 10, color: 'var(--text-muted)' }}>
94
+ {new Date(f.timestamp).toLocaleDateString()}
95
+ </span>
96
+ </div>
97
+ </div>
98
+ ))}
99
+ {failures.filter(f => !f.resolved).length > 5 && (
100
+ <div style={{ fontSize: 11, color: 'var(--text-muted)', textAlign: 'center', padding: '6px 0' }}>
101
+ +{failures.filter(f => !f.resolved).length - 5} more corrections
102
+ </div>
103
+ )}
104
+ </div>
105
+ </div>
106
+ </div>
107
+ )}
108
+
65
109
  <div className="grid-2">
66
110
  {/* Frontier */}
67
111
  <div className="card">
@@ -6,13 +6,15 @@ interface OverviewActionsProps {
6
6
  hasFailures: boolean
7
7
  hasSkills: boolean
8
8
  hasEdges: boolean
9
+ unresolvedCount: number
9
10
  }
10
11
 
11
- export function OverviewActions({ hasFailures, hasSkills, hasEdges }: OverviewActionsProps) {
12
+ export function OverviewActions({ hasFailures, hasSkills, hasEdges, unresolvedCount }: OverviewActionsProps) {
12
13
  const actions = [
13
14
  {
14
15
  id: 'graph-rebuild',
15
16
  label: 'Organize Skills',
17
+ subtitle: 'Map how your skills relate to each other — finds dependencies, enhancements, and conflicts between them.',
16
18
  command: 'graph-rebuild',
17
19
  icon: 'M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1',
18
20
  color: 'var(--purple)',
@@ -23,6 +25,7 @@ export function OverviewActions({ hasFailures, hasSkills, hasEdges }: OverviewAc
23
25
  {
24
26
  id: 'generalize',
25
27
  label: 'Generalize',
28
+ subtitle: 'Find common patterns across multiple skills and create higher-level abstract skills from them.',
26
29
  command: 'generalize',
27
30
  icon: 'M5 10l7-7m0 0l7 7m-7-7v18',
28
31
  color: 'var(--blue)',
@@ -32,17 +35,21 @@ export function OverviewActions({ hasFailures, hasSkills, hasEdges }: OverviewAc
32
35
  },
33
36
  {
34
37
  id: 'evolve',
35
- label: 'Evolve',
38
+ label: `Evolve${unresolvedCount > 0 ? ` (${unresolvedCount} pending)` : ''}`,
39
+ subtitle: hasFailures
40
+ ? `Improve skills based on ${unresolvedCount} correction${unresolvedCount !== 1 ? 's' : ''} you've made. Each correction teaches the system what went wrong.`
41
+ : 'Improve skills based on your corrections. Use Craft Agent normally — corrections are captured automatically.',
36
42
  command: 'evolve',
37
43
  icon: 'M13 7h8m0 0v8m0-8l-8 8-4-4-6 6',
38
44
  color: 'var(--green)',
39
45
  description: 'Evolve skills based on captured failures',
40
46
  disabled: !hasFailures,
41
- disabledReason: 'No failures captured yet — use Craft Agent and corrections will be captured automatically',
47
+ disabledReason: 'No corrections captured yet — use Craft Agent normally, and when you correct its output, those corrections are captured automatically.',
42
48
  },
43
49
  {
44
50
  id: 'health',
45
51
  label: 'Health Check',
52
+ subtitle: 'Analyze your skill network for gaps, imbalances, and areas that need attention.',
46
53
  command: 'health',
47
54
  icon: 'M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z',
48
55
  color: 'var(--yellow)',
@@ -53,16 +60,18 @@ export function OverviewActions({ hasFailures, hasSkills, hasEdges }: OverviewAc
53
60
  {
54
61
  id: 'graph-optimize',
55
62
  label: 'Optimize',
63
+ subtitle: 'Find skills that should be merged, split, or flagged as conflicting with each other.',
56
64
  command: 'graph-optimize',
57
65
  icon: 'M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15',
58
66
  color: 'var(--text-secondary)',
59
67
  description: 'Detect merge/split/conflict opportunities in the skill network',
60
68
  disabled: !hasEdges,
61
- disabledReason: 'Run "Organize Skills" first to build relationships',
69
+ disabledReason: 'Run "Organize Skills" first to build relationships between skills.',
62
70
  },
63
71
  {
64
72
  id: 'research',
65
73
  label: 'Research',
74
+ subtitle: 'Search the web for new techniques and best practices, then draft new skills from discoveries.',
66
75
  command: 'research',
67
76
  icon: 'M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z',
68
77
  color: 'var(--purple)',
@@ -5,6 +5,7 @@ import { useState, useRef } from 'react'
5
5
  interface Action {
6
6
  id: string
7
7
  label: string
8
+ subtitle?: string
8
9
  command: string
9
10
  icon: string
10
11
  color: string
@@ -98,7 +99,7 @@ export function QuickActions({ actions }: QuickActionsProps) {
98
99
 
99
100
  return (
100
101
  <>
101
- <div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
102
+ <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(220px, 1fr))', gap: 10 }}>
102
103
  {actions.map(action => (
103
104
  <button
104
105
  key={action.id}
@@ -106,8 +107,8 @@ export function QuickActions({ actions }: QuickActionsProps) {
106
107
  disabled={action.disabled || (running !== null && running !== action.id)}
107
108
  title={action.disabled ? action.disabledReason : action.description}
108
109
  style={{
109
- display: 'flex', alignItems: 'center', gap: 6,
110
- padding: '8px 14px',
110
+ display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 6,
111
+ padding: '12px 14px',
111
112
  background: action.disabled ? 'var(--bg-section)' : 'var(--bg-card)',
112
113
  border: `1px solid ${running === action.id && state === 'running' ? action.color : 'var(--border)'}`,
113
114
  borderRadius: 'var(--radius)',
@@ -117,23 +118,34 @@ export function QuickActions({ actions }: QuickActionsProps) {
117
118
  cursor: action.disabled ? 'not-allowed' : 'pointer',
118
119
  opacity: (running !== null && running !== action.id) ? 0.5 : 1,
119
120
  transition: 'all 0.15s',
121
+ textAlign: 'left',
120
122
  }}
121
123
  >
122
- {running === action.id && state === 'running' ? (
123
- <span style={{
124
- width: 14, height: 14, border: '2px solid var(--border)',
125
- borderTopColor: action.color, borderRadius: '50%',
126
- animation: 'actionSpin 0.8s linear infinite',
127
- flexShrink: 0,
128
- }} />
129
- ) : (
130
- <svg width="14" height="14" viewBox="0 0 24 24" fill="none"
131
- stroke={action.disabled ? 'var(--text-muted)' : action.color}
132
- strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
133
- <path d={action.icon} />
134
- </svg>
124
+ <div style={{ display: 'flex', alignItems: 'center', gap: 6, width: '100%' }}>
125
+ {running === action.id && state === 'running' ? (
126
+ <span style={{
127
+ width: 14, height: 14, border: '2px solid var(--border)',
128
+ borderTopColor: action.color, borderRadius: '50%',
129
+ animation: 'actionSpin 0.8s linear infinite',
130
+ flexShrink: 0,
131
+ }} />
132
+ ) : (
133
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none"
134
+ stroke={action.disabled ? 'var(--text-muted)' : action.color}
135
+ strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
136
+ <path d={action.icon} />
137
+ </svg>
138
+ )}
139
+ {action.label}
140
+ </div>
141
+ {action.subtitle && (
142
+ <div style={{
143
+ fontSize: 11, fontWeight: 400, lineHeight: 1.45,
144
+ color: action.disabled ? 'var(--text-muted)' : 'var(--text-dim)',
145
+ }}>
146
+ {action.disabled ? action.disabledReason : action.subtitle}
147
+ </div>
135
148
  )}
136
- {action.label}
137
149
  </button>
138
150
  ))}
139
151
  </div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helixevo",
3
- "version": "0.2.21",
3
+ "version": "0.2.22",
4
4
  "description": "Self-evolving skill ecosystem for AI agents. Skills and projects co-evolve through multi-judge evaluation and a Pareto frontier.",
5
5
  "type": "module",
6
6
  "bin": {