helixevo 0.2.16 → 0.2.18

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.
@@ -44,6 +44,9 @@ function copyDashboardFiles(sourceDir: string, newVersion: string): void {
44
44
 
45
45
  // Write version marker
46
46
  writeFileSync(join(HELIX_DASHBOARD_DIR, '.helixevo-version'), newVersion)
47
+
48
+ // Also write .env.local — survives copyToHelix overwrites from old CLIs
49
+ writeFileSync(join(HELIX_DASHBOARD_DIR, '.env.local'), `HELIXEVO_VERSION=${newVersion}\n`)
47
50
  }
48
51
 
49
52
  export async function POST() {
@@ -56,23 +56,47 @@ export function UpdateBanner({ currentVersion }: { currentVersion: string }) {
56
56
  if (data.success) {
57
57
  setState('success')
58
58
  setNewVersion(data.version)
59
- // Trigger dashboard restart — the CLI will auto-relaunch
59
+
60
+ // Step 1: Tell server to restart (exits with code 75)
60
61
  setTimeout(async () => {
61
62
  try {
62
63
  await fetch('/api/restart', { method: 'POST' })
63
64
  } catch {}
64
- // Poll until the new server is ready, then reload
65
- const poll = setInterval(async () => {
65
+
66
+ // Step 2: Wait for old server to go DOWN (fetch should fail)
67
+ let serverDown = false
68
+ for (let i = 0; i < 20; i++) {
69
+ await new Promise(r => setTimeout(r, 1000))
70
+ try {
71
+ await fetch('/api/restart', { method: 'GET', signal: AbortSignal.timeout(1000) })
72
+ // Still up — keep waiting
73
+ } catch {
74
+ serverDown = true
75
+ break
76
+ }
77
+ }
78
+
79
+ // Step 3: Wait for new server to come UP
80
+ if (serverDown) {
81
+ await new Promise(r => setTimeout(r, 2000)) // give it time to start
82
+ }
83
+ for (let i = 0; i < 40; i++) {
84
+ await new Promise(r => setTimeout(r, 1500))
66
85
  try {
67
- const res = await fetch('/', { cache: 'no-store' })
86
+ const res = await fetch('/?_t=' + Date.now(), {
87
+ cache: 'no-store',
88
+ signal: AbortSignal.timeout(2000),
89
+ })
68
90
  if (res.ok) {
69
- clearInterval(poll)
70
- window.location.reload()
91
+ // Step 4: Hard reload with cache busting
92
+ window.location.href = window.location.pathname + '?updated=' + Date.now()
93
+ return
71
94
  }
72
95
  } catch {}
73
- }, 1500)
74
- // Stop polling after 60s
75
- setTimeout(() => clearInterval(poll), 60000)
96
+ }
97
+
98
+ // Fallback: force reload anyway
99
+ window.location.href = window.location.pathname + '?updated=' + Date.now()
76
100
  }, 1500)
77
101
  } else {
78
102
  setState('error')
@@ -5,12 +5,22 @@ import { fileURLToPath } from 'url'
5
5
  const __dirname = dirname(fileURLToPath(import.meta.url))
6
6
 
7
7
  function getVersion() {
8
- // 1. Check env var (set by CLI when spawning dashboard)
8
+ // 1. Check .env.local (written by upgrade API, survives old CLI overwrites)
9
+ const envLocal = join(__dirname, '.env.local')
10
+ if (existsSync(envLocal)) {
11
+ try {
12
+ const content = readFileSync(envLocal, 'utf-8')
13
+ const match = content.match(/HELIXEVO_VERSION=(.+)/)
14
+ if (match?.[1]?.trim()) return match[1].trim()
15
+ } catch {}
16
+ }
17
+
18
+ // 2. Check env var (set by CLI when spawning dashboard)
9
19
  if (process.env.HELIXEVO_VERSION && process.env.HELIXEVO_VERSION !== '0.0.0') {
10
20
  return process.env.HELIXEVO_VERSION
11
21
  }
12
22
 
13
- // 2. Check .helixevo-version marker (written by copyToHelix for npm users)
23
+ // 3. Check .helixevo-version marker (written by copyToHelix)
14
24
  const markerFile = join(__dirname, '.helixevo-version')
15
25
  if (existsSync(markerFile)) {
16
26
  try {
@@ -19,7 +29,7 @@ function getVersion() {
19
29
  } catch {}
20
30
  }
21
31
 
22
- // 3. Check parent package.json (dev: dashboard/ -> repo root)
32
+ // 4. Check parent package.json (dev: dashboard/ -> repo root)
23
33
  const candidates = [
24
34
  join(__dirname, '..', 'package.json'),
25
35
  join(__dirname, 'package.json'),
package/dist/cli.js CHANGED
@@ -12405,15 +12405,22 @@ function launchDashboard(dir, openBrowser) {
12405
12405
  console.log(`
12406
12406
  \uD83D\uDD04 Restarting dashboard after update...
12407
12407
  `);
12408
- const newDir = prepareDashboard() ?? dir;
12409
- ensureSkillGraph();
12410
- let updatedVersion = currentVersion;
12411
- try {
12412
- updatedVersion = execSync2("helixevo --version 2>/dev/null", { encoding: "utf-8" }).trim() || currentVersion;
12413
- } catch {}
12414
- console.log(` \uD83C\uDF10 HelixEvo Dashboard v${updatedVersion} at http://localhost:3847
12408
+ setTimeout(() => {
12409
+ const nextCache = join15(dir, ".next");
12410
+ if (existsSync10(nextCache)) {
12411
+ try {
12412
+ rmSync2(nextCache, { recursive: true });
12413
+ } catch {}
12414
+ }
12415
+ ensureSkillGraph();
12416
+ let updatedVersion = currentVersion;
12417
+ try {
12418
+ updatedVersion = execSync2("helixevo --version 2>/dev/null", { encoding: "utf-8" }).trim() || currentVersion;
12419
+ } catch {}
12420
+ console.log(` \uD83C\uDF10 HelixEvo Dashboard v${updatedVersion} at http://localhost:3847
12415
12421
  `);
12416
- launchDashboard(newDir, false);
12422
+ launchDashboard(dir, false);
12423
+ }, 2000);
12417
12424
  } else {
12418
12425
  process.exit(code ?? 0);
12419
12426
  }
@@ -12475,12 +12482,19 @@ function getInstalledDashboardVersion() {
12475
12482
  }
12476
12483
  }
12477
12484
  function copyToHelix(sourceDir) {
12485
+ let sourceVersion = VERSION;
12486
+ try {
12487
+ const srcRoot = join15(sourceDir, "..", "package.json");
12488
+ const pkg2 = JSON.parse(readFileSync8(srcRoot, "utf-8"));
12489
+ if (pkg2.name === "helixevo" && pkg2.version)
12490
+ sourceVersion = pkg2.version;
12491
+ } catch {}
12478
12492
  const installedVersion = getInstalledDashboardVersion();
12479
- if (installedVersion === VERSION) {
12493
+ if (installedVersion === sourceVersion) {
12480
12494
  return HELIX_DASHBOARD_DIR;
12481
12495
  }
12482
12496
  if (installedVersion) {
12483
- console.log(` Updating dashboard: v${installedVersion} → v${VERSION}`);
12497
+ console.log(` Updating dashboard: v${installedVersion} → v${sourceVersion}`);
12484
12498
  } else {
12485
12499
  console.log(" Setting up dashboard at ~/.helix/dashboard...");
12486
12500
  }
@@ -12497,7 +12511,7 @@ function copyToHelix(sourceDir) {
12497
12511
  }
12498
12512
  const items = readdirSync2(sourceDir, { withFileTypes: true });
12499
12513
  for (const item of items) {
12500
- if (item.name === "node_modules" || item.name === ".next" || item.name === "package-lock.json")
12514
+ if (item.name === "node_modules" || item.name === ".next" || item.name === "package-lock.json" || item.name === ".env.local")
12501
12515
  continue;
12502
12516
  const src = join15(sourceDir, item.name);
12503
12517
  const dest = join15(HELIX_DASHBOARD_DIR, item.name);
@@ -12514,7 +12528,7 @@ function copyToHelix(sourceDir) {
12514
12528
  const nextCache = join15(HELIX_DASHBOARD_DIR, ".next");
12515
12529
  if (existsSync10(nextCache))
12516
12530
  rmSync2(nextCache, { recursive: true });
12517
- writeFileSync9(join15(HELIX_DASHBOARD_DIR, ".helixevo-version"), VERSION);
12531
+ writeFileSync9(join15(HELIX_DASHBOARD_DIR, ".helixevo-version"), sourceVersion);
12518
12532
  return HELIX_DASHBOARD_DIR;
12519
12533
  }
12520
12534
  function ensureSkillGraph() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helixevo",
3
- "version": "0.2.16",
3
+ "version": "0.2.18",
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": {