helixevo 0.2.41 → 0.3.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.
- package/CHANGELOG.md +28 -0
- package/README.md +24 -8
- package/dashboard/app/commands/page.tsx +23 -4
- package/dashboard/app/evolution/page.tsx +58 -37
- package/dashboard/app/guide/page.tsx +43 -3
- package/dashboard/app/network/client.tsx +125 -1
- package/dashboard/app/network/page.tsx +3 -1
- package/dashboard/app/page.tsx +57 -1
- package/dashboard/app/projects/client.tsx +21 -2
- package/dashboard/app/projects/page.tsx +29 -2
- package/dashboard/app/research/client.tsx +67 -1
- package/dashboard/app/research/page.tsx +3 -2
- package/dashboard/lib/data.ts +443 -1
- package/dist/cli.js +734 -179
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to HelixEvo are documented here.
|
|
4
4
|
|
|
5
|
+
## [0.3.1] - 2026-03-23
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
- `helixevo dashboard` now recovers cleanly when the preferred port is occupied: it reuses a known managed dashboard if one is already running there, otherwise it falls forward to the next open port instead of failing with `EADDRINUSE`
|
|
9
|
+
- Added `helixevo dashboard --port <port>` so operators can choose a preferred starting port while preserving automatic fallback behavior
|
|
10
|
+
- Background dashboard stop/reuse logic now tracks the actual assigned port, so `helixevo dashboard --stop` works correctly even after fallback to a non-default port
|
|
11
|
+
|
|
12
|
+
## [0.3.0] - 2026-03-23
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- Ontology foundation for skills, projects, tasks, capabilities, relations, operations, invariants, and ontology-aware graph summaries
|
|
16
|
+
- Native and derived evolution evidence artifacts with provenance-aware persistence in `~/.helix/evolution-artifacts.jsonl`
|
|
17
|
+
- Native and derived activation traces with provenance-aware persistence in `~/.helix/activation-traces.jsonl`
|
|
18
|
+
- Native and derived pressure signals with provenance-aware persistence in `~/.helix/pressure-signals.jsonl`
|
|
19
|
+
- Co-evolution dashboard summaries that surface project hotspots, role pressure, recurring gap motifs, and routed recommendation counts
|
|
20
|
+
- Premium dashboard brain views across Overview, Evolution, Skill Network, Projects, and Research
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
- HelixEvo is now documented and surfaced more explicitly as a co-evolving skill and project brain rather than only a skill manager
|
|
24
|
+
- README and dashboard Guide now document the ontology / activation / artifact / pressure model and updated dashboard surfaces
|
|
25
|
+
- Projects page now shows project pressure hotspots and per-project capability pressure context
|
|
26
|
+
- Research page now includes a "Current pressure handoff" view so discovery work is grounded in current adaptation demand
|
|
27
|
+
- Skill Network page now includes a compact co-evolution pressure summary panel
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
- Claude invocation now retries without an inherited `CLAUDE_CODE_OAUTH_TOKEN` when that override is stale but local Claude auth is valid
|
|
31
|
+
- Local runtime `events.jsonl` is now ignored to keep mutable telemetry out of normal product commits
|
|
32
|
+
|
|
5
33
|
## [0.2.41] - 2026-03-23
|
|
6
34
|
|
|
7
35
|
### Added
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# HelixEvo
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Co-evolving skill and project brain for AI agents. HelixEvo captures failures, traces activations, models pressure, evolves skills through multi-judge evaluation, and maintains a Pareto frontier of optimal skill configurations.
|
|
4
4
|
|
|
5
5
|
## How it works
|
|
6
6
|
|
|
@@ -22,6 +22,8 @@ Every proposed change goes through:
|
|
|
22
22
|
- **[Claude CLI](https://docs.anthropic.com/en/docs/claude-code)** — installed and authenticated
|
|
23
23
|
- Requires a **Claude Max plan** subscription
|
|
24
24
|
- HelixEvo uses `claude --print` for all LLM operations (no API key needed)
|
|
25
|
+
- Prefer `claude auth login` managed credentials over exporting a hardcoded `CLAUDE_CODE_OAUTH_TOKEN`
|
|
26
|
+
- HelixEvo now retries once without an inherited `CLAUDE_CODE_OAUTH_TOKEN` if that override is stale but local Claude auth is valid
|
|
25
27
|
|
|
26
28
|
Verify prerequisites:
|
|
27
29
|
```bash
|
|
@@ -82,12 +84,13 @@ helixevo dashboard
|
|
|
82
84
|
| `helixevo health` | Network health: cohesion, coverage, balance, transfer |
|
|
83
85
|
| `helixevo init` | Import existing skills + generate skill tests |
|
|
84
86
|
| `helixevo capture <session>` | Extract failures from a session file |
|
|
87
|
+
| `helixevo project-setup <path>` | Analyze a project, match skills, and surface capability gaps |
|
|
85
88
|
| `helixevo evolve` | Evolve skills from captured failures |
|
|
86
89
|
| `helixevo generalize` | Promote cross-project patterns ↑ |
|
|
87
90
|
| `helixevo specialize --project <name>` | Create project-specific skills ↓ |
|
|
88
91
|
| `helixevo graph` | View skill network in terminal |
|
|
89
92
|
| `helixevo research` | Proactive web research for skill improvement |
|
|
90
|
-
| `helixevo dashboard` | Open web dashboard
|
|
93
|
+
| `helixevo dashboard [--port <n>]` | Open web dashboard, preferring localhost:3847 and falling forward if occupied |
|
|
91
94
|
| `helixevo status` | Show system health |
|
|
92
95
|
| `helixevo report` | Generate evolution report |
|
|
93
96
|
|
|
@@ -124,10 +127,13 @@ All data is stored in `~/.helix/`:
|
|
|
124
127
|
~/.helix/
|
|
125
128
|
├── config.json # Configuration
|
|
126
129
|
├── failures.jsonl # Captured failures
|
|
130
|
+
├── activation-traces.jsonl # Native + derived activation traces
|
|
131
|
+
├── pressure-signals.jsonl # Native + derived adaptation pressure
|
|
132
|
+
├── evolution-artifacts.jsonl # Evolution evidence artifacts per proposal/iteration
|
|
127
133
|
├── frontier.json # Pareto frontier (top-k configurations)
|
|
128
134
|
├── evolution-history.json # All evolution runs + proposals
|
|
129
135
|
├── skill-tests.jsonl # Regression test cases
|
|
130
|
-
├── skill-graph.json # Cached network (nodes + edges)
|
|
136
|
+
├── skill-graph.json # Cached network (nodes + edges + ontology version)
|
|
131
137
|
├── canary-registry.json # Active canary deployments
|
|
132
138
|
├── knowledge-buffer.json # Research discoveries + drafts
|
|
133
139
|
├── general/ # Skills (SKILL.md files)
|
|
@@ -143,14 +149,18 @@ The dashboard provides an interactive view of your skill ecosystem:
|
|
|
143
149
|
|
|
144
150
|
```bash
|
|
145
151
|
helixevo dashboard
|
|
146
|
-
#
|
|
152
|
+
# Prefers http://localhost:3847 and falls forward if that port is occupied
|
|
153
|
+
|
|
154
|
+
helixevo dashboard --port 3900
|
|
155
|
+
# Prefer port 3900 first
|
|
147
156
|
```
|
|
148
157
|
|
|
149
158
|
**Tabs:**
|
|
150
|
-
- **Overview** —
|
|
151
|
-
- **Skill Network** — Interactive graph
|
|
152
|
-
- **
|
|
153
|
-
- **
|
|
159
|
+
- **Overview** — Premium control cockpit with frontier signals, brain foundation, semantic backbone, and pressure counts
|
|
160
|
+
- **Skill Network** — Interactive graph, premium inspector, and co-evolution pressure routing signals
|
|
161
|
+
- **Projects** — Project intake studio, live project analysis, gap routing, and per-project pressure hotspots
|
|
162
|
+
- **Evolution** — Timeline of evolution runs with judge scores, artifact provenance, and activation-aware context
|
|
163
|
+
- **Research** — Knowledge buffer plus a live “why research now” handoff from current pressure and recurring gaps
|
|
154
164
|
- **Frontier** — Pareto frontier with 4-dimension scores + canary status
|
|
155
165
|
|
|
156
166
|
The dashboard requires Next.js dependencies. On first run:
|
|
@@ -183,6 +193,12 @@ Failures → Cluster → Propose → Replay → Multi-Judge → Regression → C
|
|
|
183
193
|
(discoveries + drafts from rejected proposals)
|
|
184
194
|
```
|
|
185
195
|
|
|
196
|
+
**Brain foundation:**
|
|
197
|
+
- **Ontology** defines the stable semantic kernel for skills, projects, tasks, capabilities, artifacts, and mutations.
|
|
198
|
+
- **Activation traces** record which skills and gaps were active during capture and project analysis.
|
|
199
|
+
- **Pressure signals** turn failures and project gaps into explicit adaptation demand.
|
|
200
|
+
- **Evolution artifacts** preserve proposal-level evidence so the dashboard can show what changed, why, and with what provenance.
|
|
201
|
+
|
|
186
202
|
**Three-layer hierarchy:**
|
|
187
203
|
- **System** — Global agent behaviors
|
|
188
204
|
- **Domain** — Cross-project patterns (generalized skills)
|
|
@@ -223,23 +223,42 @@ const COMMANDS: CommandInfo[] = [
|
|
|
223
223
|
needsLLM: true,
|
|
224
224
|
note: 'Typically not needed if using "watch" mode, which captures automatically.',
|
|
225
225
|
},
|
|
226
|
+
{
|
|
227
|
+
name: 'project-setup',
|
|
228
|
+
description: 'Analyze a local project, match it against your current skills, identify capability gaps, persist a project profile, and emit activation traces plus pressure signals for the dashboard brain surfaces.',
|
|
229
|
+
usage: 'helixevo project-setup <path> [options]',
|
|
230
|
+
examples: [
|
|
231
|
+
{ cmd: 'helixevo project-setup .', desc: 'Analyze the current repository and persist a project profile' },
|
|
232
|
+
{ cmd: 'helixevo project-setup ~/myapp', desc: 'Analyze a local project folder by path' },
|
|
233
|
+
{ cmd: 'helixevo project-setup ~/myapp --dry-run', desc: 'Preview the analysis without saving profile data' },
|
|
234
|
+
],
|
|
235
|
+
options: [
|
|
236
|
+
{ flag: '--dry-run', desc: 'Run analysis without saving the project profile or pressure data' },
|
|
237
|
+
{ flag: '--verbose', desc: 'Show additional context and matched-skill reasoning' },
|
|
238
|
+
],
|
|
239
|
+
category: 'system',
|
|
240
|
+
needsLLM: true,
|
|
241
|
+
note: 'This powers the Projects intake workflow and now feeds activation traces plus project-analysis pressure into the dashboard.',
|
|
242
|
+
},
|
|
226
243
|
{
|
|
227
244
|
name: 'dashboard',
|
|
228
|
-
description: 'Launch the web dashboard at http://localhost:3847. When a newer npm version is available, HelixEvo
|
|
245
|
+
description: 'Launch the web dashboard at http://localhost:3847 by default. When that port is occupied, HelixEvo now reuses a known managed dashboard or falls forward to the next open port instead of failing. When a newer npm version is available, HelixEvo also auto-updates itself before opening the dashboard unless you opt out.',
|
|
229
246
|
usage: 'helixevo dashboard [options]',
|
|
230
247
|
examples: [
|
|
231
|
-
{ cmd: 'helixevo dashboard', desc: 'Auto-update to the latest version if needed, then open the dashboard' },
|
|
248
|
+
{ cmd: 'helixevo dashboard', desc: 'Auto-update to the latest version if needed, then open the dashboard on 3847 or the next open port' },
|
|
232
249
|
{ cmd: 'helixevo dashboard --background', desc: 'Run the dashboard in the background after the same update check' },
|
|
250
|
+
{ cmd: 'helixevo dashboard --port 3900', desc: 'Prefer port 3900 first, then fall forward if that port is occupied' },
|
|
233
251
|
{ cmd: 'helixevo dashboard --no-auto-update', desc: 'Open the dashboard immediately without checking npm for updates' },
|
|
234
252
|
],
|
|
235
253
|
options: [
|
|
236
254
|
{ flag: '--background', desc: 'Run the dashboard detached from the terminal' },
|
|
237
|
-
{ flag: '--stop', desc: 'Stop a background dashboard process' },
|
|
255
|
+
{ flag: '--stop', desc: 'Stop a managed background dashboard process' },
|
|
256
|
+
{ flag: '--port <port>', desc: 'Preferred port to try first (default: 3847)' },
|
|
238
257
|
{ flag: '--no-auto-update', desc: 'Skip the automatic update check before launch' },
|
|
239
258
|
],
|
|
240
259
|
category: 'system',
|
|
241
260
|
needsLLM: false,
|
|
242
|
-
note: 'You are currently using the dashboard.
|
|
261
|
+
note: 'You are currently using the dashboard. It now prefers 3847, reuses a known managed dashboard when one is already running there, and otherwise falls forward to the next open port.',
|
|
243
262
|
},
|
|
244
263
|
]
|
|
245
264
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadHistory } from '@/lib/data'
|
|
1
|
+
import { loadEvolutionArtifacts, loadHistory } from '@/lib/data'
|
|
2
2
|
import { MetricCard } from '@/components/metric-card'
|
|
3
3
|
import { PageHero } from '@/components/page-hero'
|
|
4
4
|
import { SectionFrame } from '@/components/section-frame'
|
|
@@ -7,11 +7,15 @@ export const dynamic = 'force-dynamic'
|
|
|
7
7
|
|
|
8
8
|
export default function EvolutionPage() {
|
|
9
9
|
const history = loadHistory()
|
|
10
|
+
const artifacts = loadEvolutionArtifacts()
|
|
10
11
|
const iterations = [...history.iterations].reverse()
|
|
11
12
|
const totalProposals = iterations.flatMap((iteration) => iteration.proposals)
|
|
12
13
|
const accepted = totalProposals.filter((proposal) => proposal.outcome === 'accepted').length
|
|
13
14
|
const rejected = totalProposals.filter((proposal) => proposal.outcome === 'rejected').length
|
|
14
15
|
const avgAcceptance = totalProposals.length > 0 ? Math.round((accepted / totalProposals.length) * 100) : 0
|
|
16
|
+
const nativeArtifacts = artifacts.filter((artifact) => artifact.provenance === 'native-evolution').length
|
|
17
|
+
const derivedArtifacts = artifacts.filter((artifact) => artifact.provenance === 'derived-history').length
|
|
18
|
+
const artifactByProposal = new Map(artifacts.map((artifact) => [artifact.proposalId, artifact]))
|
|
15
19
|
|
|
16
20
|
return (
|
|
17
21
|
<div style={{ display: 'grid', gap: 22 }}>
|
|
@@ -23,15 +27,15 @@ export default function EvolutionPage() {
|
|
|
23
27
|
{ label: `${iterations.length} runs`, tone: 'purple' },
|
|
24
28
|
{ label: `${accepted} accepted`, tone: 'green' },
|
|
25
29
|
{ label: `${rejected} rejected`, tone: 'red' },
|
|
26
|
-
{ label: `${
|
|
30
|
+
{ label: `${artifacts.length} evidence artifacts`, tone: 'blue' },
|
|
27
31
|
]}
|
|
28
32
|
/>
|
|
29
33
|
|
|
30
34
|
<div className="grid-4">
|
|
31
35
|
<MetricCard label="Runs" value={iterations.length} sublabel="Completed evolution loops" tone="purple" icon="◎" />
|
|
36
|
+
<MetricCard label="Native artifacts" value={nativeArtifacts} sublabel={`${derivedArtifacts} compatibility-derived`} tone="blue" icon="◇" />
|
|
32
37
|
<MetricCard label="Accepted" value={accepted} sublabel="Promotions that survived judging" tone="green" icon="✓" />
|
|
33
|
-
<MetricCard label="
|
|
34
|
-
<MetricCard label="Acceptance rate" value={`${avgAcceptance}%`} sublabel="Across all recorded proposals" tone="blue" icon="↗" />
|
|
38
|
+
<MetricCard label="Acceptance rate" value={`${avgAcceptance}%`} sublabel="Across all recorded proposals" tone="yellow" icon="↗" />
|
|
35
39
|
</div>
|
|
36
40
|
|
|
37
41
|
<SectionFrame
|
|
@@ -78,47 +82,64 @@ export default function EvolutionPage() {
|
|
|
78
82
|
</div>
|
|
79
83
|
) : null}
|
|
80
84
|
|
|
81
|
-
{iteration.proposals.map((proposal) =>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
<
|
|
85
|
+
{iteration.proposals.map((proposal) => {
|
|
86
|
+
const artifact = artifactByProposal.get(proposal.id)
|
|
87
|
+
|
|
88
|
+
return (
|
|
89
|
+
<div key={proposal.id} className="proposal-card" style={{ borderLeft: `3px solid ${proposal.outcome === 'accepted' ? 'var(--green)' : 'var(--red)'}` }}>
|
|
90
|
+
<div style={{ padding: '14px 16px' }}>
|
|
91
|
+
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, marginBottom: 10 }}>
|
|
92
|
+
<div>
|
|
93
|
+
<div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
|
|
94
|
+
<span className={`badge ${proposal.outcome === 'accepted' ? 'badge-green' : 'badge-red'}`}>{proposal.outcome}</span>
|
|
95
|
+
<span style={{ fontSize: 15, fontWeight: 800, letterSpacing: '-0.02em' }}>{proposal.targetSkill}</span>
|
|
96
|
+
<span className="badge badge-gray">{proposal.action}</span>
|
|
97
|
+
{artifact ? (
|
|
98
|
+
<span className={`badge ${artifact.provenance === 'native-evolution' ? 'badge-blue' : 'badge-gray'}`}>
|
|
99
|
+
{artifact.provenance === 'native-evolution' ? 'native artifact' : 'derived artifact'}
|
|
100
|
+
</span>
|
|
101
|
+
) : null}
|
|
102
|
+
</div>
|
|
103
|
+
<div style={{ marginTop: 8, color: 'var(--text-secondary)', fontSize: 12.5, lineHeight: 1.65 }}>
|
|
104
|
+
{proposal.description.slice(0, 260)}
|
|
105
|
+
{proposal.description.length > 260 ? '…' : ''}
|
|
106
|
+
</div>
|
|
90
107
|
</div>
|
|
91
|
-
<div style={{
|
|
92
|
-
{
|
|
93
|
-
{proposal.
|
|
108
|
+
<div style={{ minWidth: 92, textAlign: 'right' }}>
|
|
109
|
+
<div style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '0.08em' }}>Regression</div>
|
|
110
|
+
<div style={{ marginTop: 6, fontSize: 22, fontWeight: 850, lineHeight: 1, color: proposal.regressionResult.total > 0 && proposal.regressionResult.passed === proposal.regressionResult.total ? 'var(--green)' : 'var(--text)' }}>
|
|
111
|
+
{proposal.regressionResult.total > 0 ? `${proposal.regressionResult.passed}/${proposal.regressionResult.total}` : '—'}
|
|
112
|
+
</div>
|
|
94
113
|
</div>
|
|
95
114
|
</div>
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
{
|
|
100
|
-
|
|
115
|
+
|
|
116
|
+
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 10 }}>
|
|
117
|
+
{[
|
|
118
|
+
{ label: 'Task', score: proposal.judges.taskCompletion.score, color: 'var(--green)' },
|
|
119
|
+
{ label: 'Align', score: proposal.judges.correctionAlignment.score, color: 'var(--blue)' },
|
|
120
|
+
{ label: 'Side-effects', score: proposal.judges.sideEffectCheck.score, color: 'var(--purple)' },
|
|
121
|
+
].map((judge) => (
|
|
122
|
+
<span key={judge.label} className="score-pill" style={{ color: judge.score >= 7 ? judge.color : 'var(--red)' }}>
|
|
123
|
+
{judge.label} {judge.score}/10
|
|
124
|
+
</span>
|
|
125
|
+
))}
|
|
101
126
|
</div>
|
|
102
|
-
</div>
|
|
103
127
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
{judge.label} {judge.score}/10
|
|
112
|
-
</span>
|
|
113
|
-
))}
|
|
114
|
-
</div>
|
|
128
|
+
{artifact ? (
|
|
129
|
+
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', marginBottom: 10 }}>
|
|
130
|
+
{artifact.clusterType ? <span className="badge badge-gray">cluster {artifact.clusterType}</span> : null}
|
|
131
|
+
{artifact.trigger ? <span className="badge badge-gray">trigger {artifact.trigger}</span> : null}
|
|
132
|
+
{artifact.iterationId ? <span className="badge badge-gray">{artifact.iterationId}</span> : null}
|
|
133
|
+
</div>
|
|
134
|
+
) : null}
|
|
115
135
|
|
|
116
|
-
|
|
117
|
-
|
|
136
|
+
<div style={{ color: 'var(--text-dim)', fontSize: 11.5, lineHeight: 1.55 }}>
|
|
137
|
+
{proposal.outcomeReason}
|
|
138
|
+
</div>
|
|
118
139
|
</div>
|
|
119
140
|
</div>
|
|
120
|
-
|
|
121
|
-
)
|
|
141
|
+
)
|
|
142
|
+
})}
|
|
122
143
|
</div>
|
|
123
144
|
</article>
|
|
124
145
|
</div>
|
|
@@ -340,6 +340,11 @@ export default function GuidePage() {
|
|
|
340
340
|
</div>
|
|
341
341
|
</div>
|
|
342
342
|
</div>
|
|
343
|
+
<Callout type="tip">
|
|
344
|
+
HelixEvo now exposes a visible <strong>brain foundation</strong> in the dashboard: ontology-backed summaries,
|
|
345
|
+
activation traces, evolution artifacts, and pressure signals all feed the Overview, Skill Network, Projects,
|
|
346
|
+
Research, and Evolution surfaces.
|
|
347
|
+
</Callout>
|
|
343
348
|
</Section>
|
|
344
349
|
|
|
345
350
|
{/* ─── Quick Start ─── */}
|
|
@@ -347,6 +352,7 @@ export default function GuidePage() {
|
|
|
347
352
|
<Callout type="info">
|
|
348
353
|
<strong>Prerequisites:</strong> Node.js 18+, <a href="https://bun.sh">Bun</a> (for building),
|
|
349
354
|
and <a href="https://docs.anthropic.com/en/docs/claude-code">Claude CLI</a> with a Claude Max plan.
|
|
355
|
+
Prefer <code>claude auth login</code> managed credentials over exporting a hardcoded <code>CLAUDE_CODE_OAUTH_TOKEN</code>.
|
|
350
356
|
</Callout>
|
|
351
357
|
|
|
352
358
|
<Step n={1} title="Install HelixEvo">
|
|
@@ -389,8 +395,14 @@ helixevo graph
|
|
|
389
395
|
# Open this dashboard
|
|
390
396
|
helixevo dashboard
|
|
391
397
|
|
|
398
|
+
# Prefer a different port if you want
|
|
399
|
+
helixevo dashboard --port 3900
|
|
400
|
+
|
|
392
401
|
# Check system health
|
|
393
402
|
helixevo status`}</Code>
|
|
403
|
+
<p className="guide-text-sm">
|
|
404
|
+
The dashboard prefers port <code>3847</code>. If that port is already occupied, HelixEvo now reuses a known managed dashboard or falls forward to the next open port instead of failing immediately.
|
|
405
|
+
</p>
|
|
394
406
|
</Step>
|
|
395
407
|
</Section>
|
|
396
408
|
|
|
@@ -450,8 +462,8 @@ helixevo status`}</Code>
|
|
|
450
462
|
},
|
|
451
463
|
{
|
|
452
464
|
cmd: 'helixevo dashboard',
|
|
453
|
-
desc: 'Open the interactive web dashboard
|
|
454
|
-
flags: ['--background', '--stop', '--no-auto-update'],
|
|
465
|
+
desc: 'Open the interactive web dashboard. HelixEvo prefers localhost:3847, reuses a known managed dashboard if one is already there, and otherwise falls forward to the next open port. Before launch, it also checks npm for a newer version and auto-updates itself unless you opt out.',
|
|
466
|
+
flags: ['--background', '--stop', '--port <port>', '--no-auto-update'],
|
|
455
467
|
},
|
|
456
468
|
{
|
|
457
469
|
cmd: 'helixevo status',
|
|
@@ -491,6 +503,26 @@ helixevo status`}</Code>
|
|
|
491
503
|
</p>
|
|
492
504
|
<ArchitectureDiagram />
|
|
493
505
|
|
|
506
|
+
<h3 className="guide-h3">Brain Foundation</h3>
|
|
507
|
+
<div className="grid-2" style={{ gap: 12, marginBottom: 20 }}>
|
|
508
|
+
<div className="guide-dimension-card" style={{ borderLeftColor: 'var(--blue)' }}>
|
|
509
|
+
<div style={{ fontSize: 11, fontWeight: 700, color: 'var(--blue)', textTransform: 'uppercase', letterSpacing: 1 }}>Ontology</div>
|
|
510
|
+
<div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>Defines the stable semantic kernel for skills, projects, tasks, capabilities, artifacts, and mutations.</div>
|
|
511
|
+
</div>
|
|
512
|
+
<div className="guide-dimension-card" style={{ borderLeftColor: 'var(--green)' }}>
|
|
513
|
+
<div style={{ fontSize: 11, fontWeight: 700, color: 'var(--green)', textTransform: 'uppercase', letterSpacing: 1 }}>Activation traces</div>
|
|
514
|
+
<div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>Capture which skills and gaps were active during failure analysis and project analysis.</div>
|
|
515
|
+
</div>
|
|
516
|
+
<div className="guide-dimension-card" style={{ borderLeftColor: 'var(--purple)' }}>
|
|
517
|
+
<div style={{ fontSize: 11, fontWeight: 700, color: 'var(--purple)', textTransform: 'uppercase', letterSpacing: 1 }}>Evolution artifacts</div>
|
|
518
|
+
<div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>Preserve proposal-level evidence so the dashboard can show what changed, why, and with which provenance.</div>
|
|
519
|
+
</div>
|
|
520
|
+
<div className="guide-dimension-card" style={{ borderLeftColor: 'var(--yellow)' }}>
|
|
521
|
+
<div style={{ fontSize: 11, fontWeight: 700, color: 'var(--yellow)', textTransform: 'uppercase', letterSpacing: 1 }}>Pressure signals</div>
|
|
522
|
+
<div style={{ fontSize: 12, color: 'var(--text-dim)', marginTop: 4 }}>Turn failures and project gaps into explicit adaptation demand, routing attention into Network, Projects, and Research.</div>
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
|
|
494
526
|
<h3 className="guide-h3">Three-Layer Hierarchy</h3>
|
|
495
527
|
<p className="guide-text">
|
|
496
528
|
Skills are organized into three layers. The <code>generalize</code> command promotes patterns upward,
|
|
@@ -874,10 +906,13 @@ generation: 3
|
|
|
874
906
|
<Code title="~/.helix/ directory structure">{`~/.helix/
|
|
875
907
|
├── config.json # Configuration
|
|
876
908
|
├── failures.jsonl # Captured failure records (append-only)
|
|
909
|
+
├── activation-traces.jsonl # Native + derived activation traces
|
|
910
|
+
├── pressure-signals.jsonl # Native + derived adaptation pressure
|
|
911
|
+
├── evolution-artifacts.jsonl # Proposal/iteration evidence artifacts
|
|
877
912
|
├── frontier.json # Pareto frontier (top-K programs)
|
|
878
913
|
├── evolution-history.json # All evolution iterations + proposals
|
|
879
914
|
├── skill-tests.jsonl # Regression test cases (append-only)
|
|
880
|
-
├── skill-graph.json # Cached network (nodes + edges)
|
|
915
|
+
├── skill-graph.json # Cached network (nodes + edges + ontology version)
|
|
881
916
|
├── canary-registry.json # Active canary deployments
|
|
882
917
|
├── knowledge-buffer.json # Research discoveries + drafts
|
|
883
918
|
├── general/ # Skills (SKILL.md files)
|
|
@@ -984,6 +1019,11 @@ generation: 3
|
|
|
984
1019
|
HelixEvo uses <code>claude --print</code> with configurable models (default: <code>sonnet</code>).
|
|
985
1020
|
No API key is needed — it requires a Claude Max plan subscription. Judges and proposals can use different models.
|
|
986
1021
|
</FAQItem>
|
|
1022
|
+
<FAQItem q="What if Claude says my OAuth token expired?">
|
|
1023
|
+
First run <code>claude auth login</code> to refresh local Claude credentials. Avoid exporting a hardcoded
|
|
1024
|
+
<code> CLAUDE_CODE_OAUTH_TOKEN</code> in your shell profile. HelixEvo also retries once without an inherited
|
|
1025
|
+
token override when local Claude auth is healthy.
|
|
1026
|
+
</FAQItem>
|
|
987
1027
|
<FAQItem q="Can I use HelixEvo with other AI agents?">
|
|
988
1028
|
Yes. HelixEvo manages standard SKILL.md files with YAML frontmatter. Any agent that reads SKILL.md
|
|
989
1029
|
files can benefit from HelixEvo's evolution pipeline.
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
} from '@xyflow/react'
|
|
13
13
|
import '@xyflow/react/dist/style.css'
|
|
14
14
|
import SkillFlowNode from '@/components/SkillFlowNode'
|
|
15
|
+
import { SectionFrame } from '@/components/section-frame'
|
|
15
16
|
|
|
16
17
|
// ─── Types ──────────────────────────────────────────────────────
|
|
17
18
|
|
|
@@ -33,6 +34,23 @@ interface ProjectData {
|
|
|
33
34
|
name: string; failures: any[]; skills: string[]
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
interface ProjectPressureSummary {
|
|
38
|
+
projectId: string
|
|
39
|
+
totalSignals: number
|
|
40
|
+
nativeSignals: number
|
|
41
|
+
derivedSignals: number
|
|
42
|
+
highPrioritySignals: number
|
|
43
|
+
topCapabilities: string[]
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface CoEvolutionSummary {
|
|
47
|
+
pressureSignals: { total: number; native: number; derived: number }
|
|
48
|
+
topProjects: ProjectPressureSummary[]
|
|
49
|
+
rolePressure: { generalist: number; specialist: number; hybrid: number }
|
|
50
|
+
crossProjectGapAreas: { area: string; projects: string[]; count: number }[]
|
|
51
|
+
activeRecommendations: { action: 'research' | 'specialize' | 'create'; count: number }[]
|
|
52
|
+
}
|
|
53
|
+
|
|
36
54
|
interface Props {
|
|
37
55
|
allNodes: SkillNode[]
|
|
38
56
|
generalized: SkillNode[]
|
|
@@ -42,6 +60,7 @@ interface Props {
|
|
|
42
60
|
evolutionBySkill: Record<string, EvolutionEntry[]>
|
|
43
61
|
skillContents: Record<string, string>
|
|
44
62
|
projects: ProjectData[]
|
|
63
|
+
coevolution: CoEvolutionSummary
|
|
45
64
|
stats: { nodes: number; edges: number; clusters: number; generalized: number; evolved: number; original: number }
|
|
46
65
|
}
|
|
47
66
|
|
|
@@ -84,7 +103,7 @@ function actionBtnStyle(color?: string): React.CSSProperties {
|
|
|
84
103
|
// ─── Main Component ─────────────────────────────────────────────
|
|
85
104
|
|
|
86
105
|
export default function NetworkClient({
|
|
87
|
-
allNodes, generalized, evolved, original, edges: graphEdges, evolutionBySkill, skillContents, projects, stats
|
|
106
|
+
allNodes, generalized, evolved, original, edges: graphEdges, evolutionBySkill, skillContents, projects, coevolution, stats
|
|
88
107
|
}: Props) {
|
|
89
108
|
const [view, setView] = useState<SubView>('graph')
|
|
90
109
|
const [selectedSkill, setSelectedSkill] = useState<string | null>(null)
|
|
@@ -264,6 +283,111 @@ export default function NetworkClient({
|
|
|
264
283
|
</div>
|
|
265
284
|
</div>
|
|
266
285
|
|
|
286
|
+
<SectionFrame
|
|
287
|
+
eyebrow="Co-evolution signals"
|
|
288
|
+
title="Pressure and transfer foundation"
|
|
289
|
+
description="A compact view of where current project demand is pushing on the network, which cognitive roles are implicated, and which gap motifs are repeating across projects."
|
|
290
|
+
tone="blue"
|
|
291
|
+
>
|
|
292
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(180px, 1fr))', gap: 16, marginBottom: 16 }}>
|
|
293
|
+
<div className="metric-card metric-card-blue">
|
|
294
|
+
<div className="metric-card-header">
|
|
295
|
+
<div>
|
|
296
|
+
<div className="metric-card-label">Pressure signals</div>
|
|
297
|
+
<div className="metric-card-value">{coevolution.pressureSignals.total}</div>
|
|
298
|
+
</div>
|
|
299
|
+
<div className="metric-card-icon">◎</div>
|
|
300
|
+
</div>
|
|
301
|
+
<div className="metric-card-sublabel">{coevolution.pressureSignals.native} native • {coevolution.pressureSignals.derived} derived</div>
|
|
302
|
+
</div>
|
|
303
|
+
<div className="metric-card metric-card-purple">
|
|
304
|
+
<div className="metric-card-header">
|
|
305
|
+
<div>
|
|
306
|
+
<div className="metric-card-label">Generalist pressure</div>
|
|
307
|
+
<div className="metric-card-value">{coevolution.rolePressure.generalist}</div>
|
|
308
|
+
</div>
|
|
309
|
+
<div className="metric-card-icon">◎</div>
|
|
310
|
+
</div>
|
|
311
|
+
<div className="metric-card-sublabel">Pressure touching reusable abstractions</div>
|
|
312
|
+
</div>
|
|
313
|
+
<div className="metric-card metric-card-green">
|
|
314
|
+
<div className="metric-card-header">
|
|
315
|
+
<div>
|
|
316
|
+
<div className="metric-card-label">Specialist pressure</div>
|
|
317
|
+
<div className="metric-card-value">{coevolution.rolePressure.specialist}</div>
|
|
318
|
+
</div>
|
|
319
|
+
<div className="metric-card-icon">◉</div>
|
|
320
|
+
</div>
|
|
321
|
+
<div className="metric-card-sublabel">Project-local demand pushing on specialist skills</div>
|
|
322
|
+
</div>
|
|
323
|
+
<div className="metric-card metric-card-yellow">
|
|
324
|
+
<div className="metric-card-header">
|
|
325
|
+
<div>
|
|
326
|
+
<div className="metric-card-label">Cross-project gap motifs</div>
|
|
327
|
+
<div className="metric-card-value">{coevolution.crossProjectGapAreas.length}</div>
|
|
328
|
+
</div>
|
|
329
|
+
<div className="metric-card-icon">⇄</div>
|
|
330
|
+
</div>
|
|
331
|
+
<div className="metric-card-sublabel">Recurring gap areas spanning multiple projects</div>
|
|
332
|
+
</div>
|
|
333
|
+
</div>
|
|
334
|
+
|
|
335
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'minmax(0, 1.4fr) minmax(0, 1fr)', gap: 16 }}>
|
|
336
|
+
<div style={{ padding: '16px 18px', borderRadius: 20, border: '1px solid var(--border)', background: 'rgba(255,255,255,0.72)' }}>
|
|
337
|
+
<div className="section-label" style={{ marginBottom: 10 }}>Top project hotspots</div>
|
|
338
|
+
{coevolution.topProjects.length === 0 ? (
|
|
339
|
+
<div className="signal-text">No project pressure signals yet — pressure will appear here once failures and project analysis records accumulate.</div>
|
|
340
|
+
) : (
|
|
341
|
+
<div style={{ display: 'grid', gap: 10 }}>
|
|
342
|
+
{coevolution.topProjects.map((project) => (
|
|
343
|
+
<div key={project.projectId} style={{ display: 'flex', justifyContent: 'space-between', gap: 12, alignItems: 'flex-start', padding: '12px 14px', borderRadius: 16, background: 'rgba(97,93,86,0.06)', border: '1px solid var(--border)' }}>
|
|
344
|
+
<div>
|
|
345
|
+
<div style={{ fontSize: 13, fontWeight: 700, color: 'var(--text)' }}>{project.projectId}</div>
|
|
346
|
+
<div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginTop: 4 }}>
|
|
347
|
+
{project.highPrioritySignals} high-priority • {project.nativeSignals} native • {project.derivedSignals} derived
|
|
348
|
+
</div>
|
|
349
|
+
{project.topCapabilities.length > 0 ? (
|
|
350
|
+
<div style={{ display: 'flex', gap: 6, flexWrap: 'wrap', marginTop: 8 }}>
|
|
351
|
+
{project.topCapabilities.map((capability) => (
|
|
352
|
+
<span key={capability} className="badge badge-gray">{capability}</span>
|
|
353
|
+
))}
|
|
354
|
+
</div>
|
|
355
|
+
) : null}
|
|
356
|
+
</div>
|
|
357
|
+
<div style={{ fontSize: 24, fontWeight: 850, color: project.highPrioritySignals > 0 ? 'var(--red)' : 'var(--blue)' }}>{project.totalSignals}</div>
|
|
358
|
+
</div>
|
|
359
|
+
))}
|
|
360
|
+
</div>
|
|
361
|
+
)}
|
|
362
|
+
</div>
|
|
363
|
+
|
|
364
|
+
<div style={{ padding: '16px 18px', borderRadius: 20, border: '1px solid var(--border)', background: 'rgba(255,255,255,0.72)' }}>
|
|
365
|
+
<div className="section-label" style={{ marginBottom: 10 }}>Emergent routing signals</div>
|
|
366
|
+
<div style={{ display: 'grid', gap: 10 }}>
|
|
367
|
+
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap' }}>
|
|
368
|
+
{coevolution.activeRecommendations.length > 0 ? coevolution.activeRecommendations.map((entry) => (
|
|
369
|
+
<span key={entry.action} className={`hero-chip hero-chip-${entry.action === 'research' ? 'blue' : entry.action === 'specialize' ? 'green' : 'purple'}`}>
|
|
370
|
+
{entry.action} × {entry.count}
|
|
371
|
+
</span>
|
|
372
|
+
)) : <span className="badge badge-gray">No routed actions yet</span>}
|
|
373
|
+
</div>
|
|
374
|
+
{coevolution.crossProjectGapAreas.length > 0 ? (
|
|
375
|
+
<div style={{ display: 'grid', gap: 8 }}>
|
|
376
|
+
{coevolution.crossProjectGapAreas.slice(0, 4).map((entry) => (
|
|
377
|
+
<div key={entry.area} style={{ padding: '12px 14px', borderRadius: 16, background: 'rgba(97,93,86,0.06)', border: '1px solid var(--border)' }}>
|
|
378
|
+
<div style={{ fontSize: 12.5, fontWeight: 700, color: 'var(--text)' }}>{entry.area}</div>
|
|
379
|
+
<div style={{ fontSize: 11.5, color: 'var(--text-dim)', marginTop: 4 }}>{entry.count} projects • {entry.projects.join(', ')}</div>
|
|
380
|
+
</div>
|
|
381
|
+
))}
|
|
382
|
+
</div>
|
|
383
|
+
) : (
|
|
384
|
+
<div className="signal-text">Cross-project gap motifs will appear here when the same capability pressure is seen across multiple projects.</div>
|
|
385
|
+
)}
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
</div>
|
|
389
|
+
</SectionFrame>
|
|
390
|
+
|
|
267
391
|
{/* Create Skill Panel */}
|
|
268
392
|
{creating && (
|
|
269
393
|
<div className="card" style={{ marginBottom: 20 }}>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadGraph, loadSkillContent, loadHistory, listProjects, getProjectSkills } from '@/lib/data'
|
|
1
|
+
import { loadCoEvolutionSummary, loadGraph, loadSkillContent, loadHistory, listProjects, getProjectSkills } from '@/lib/data'
|
|
2
2
|
import NetworkClient from './client'
|
|
3
3
|
|
|
4
4
|
export const dynamic = 'force-dynamic'
|
|
@@ -6,6 +6,7 @@ export const dynamic = 'force-dynamic'
|
|
|
6
6
|
export default function SkillNetworkPage() {
|
|
7
7
|
const graph = loadGraph()
|
|
8
8
|
const history = loadHistory()
|
|
9
|
+
const coevolution = loadCoEvolutionSummary()
|
|
9
10
|
const projects = listProjects()
|
|
10
11
|
|
|
11
12
|
const generalized = graph.nodes.filter(n =>
|
|
@@ -62,6 +63,7 @@ export default function SkillNetworkPage() {
|
|
|
62
63
|
evolutionBySkill={evolutionBySkill}
|
|
63
64
|
skillContents={skillContents}
|
|
64
65
|
projects={projectData}
|
|
66
|
+
coevolution={coevolution}
|
|
65
67
|
stats={{
|
|
66
68
|
nodes: graph.nodes.length,
|
|
67
69
|
edges: graph.edges.length,
|