diff --git a/.gitignore b/.gitignore index e6dfd5f..d419c91 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,6 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json # Finder (MacOS) folder config .DS_Store + +# app symlinks (created on boot) +apps/*/current diff --git a/apps/basic/current b/apps/basic/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/basic/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/apps/clock/current b/apps/clock/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/clock/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/apps/code/current b/apps/code/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/code/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/apps/cron/current b/apps/cron/current deleted file mode 120000 index a874989..0000000 --- a/apps/cron/current +++ /dev/null @@ -1 +0,0 @@ -20260201-000000 \ No newline at end of file diff --git a/apps/env/current b/apps/env/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/env/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/apps/profile/current b/apps/profile/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/profile/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/apps/risk/current b/apps/risk/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/risk/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/apps/todo/current b/apps/todo/current deleted file mode 120000 index 5da1387..0000000 --- a/apps/todo/current +++ /dev/null @@ -1 +0,0 @@ -20260130-181927 \ No newline at end of file diff --git a/apps/truisms/current b/apps/truisms/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/truisms/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/apps/versions/current b/apps/versions/current deleted file mode 120000 index 1a45961..0000000 --- a/apps/versions/current +++ /dev/null @@ -1 +0,0 @@ -20260130-000000 \ No newline at end of file diff --git a/src/server/apps.ts b/src/server/apps.ts index e857449..e749955 100644 --- a/src/server/apps.ts +++ b/src/server/apps.ts @@ -1,7 +1,7 @@ import type { App as SharedApp, AppState } from '@types' import type { Subprocess } from 'bun' import { DEFAULT_EMOJI } from '@types' -import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, unlinkSync, writeFileSync } from 'fs' +import { appendFileSync, existsSync, mkdirSync, readdirSync, readFileSync, realpathSync, renameSync, symlinkSync, unlinkSync, writeFileSync } from 'fs' import { join, resolve } from 'path' import { appLog, hostLog, setApps } from './tui' @@ -84,6 +84,7 @@ export function initApps() { initPortPool() setupShutdownHandlers() rotateLogs() + createAppSymlinks() discoverApps() runApps() } @@ -292,6 +293,37 @@ function allAppDirs() { .sort() } +function createAppSymlinks() { + for (const app of readdirSync(APPS_DIR, { withFileTypes: true })) { + if (!app.isDirectory()) continue + const appDir = join(APPS_DIR, app.name) + const currentPath = join(appDir, 'current') + if (existsSync(currentPath)) continue + + // Find valid version directories + const versions = readdirSync(appDir, { withFileTypes: true }) + .filter(e => { + if (!e.isDirectory()) return false + const pkgPath = join(appDir, e.name, 'package.json') + if (!existsSync(pkgPath)) return false + try { + const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8')) + return !!pkg.scripts?.toes + } catch { + return false + } + }) + .map(e => e.name) + .sort() + .reverse() + + const latest = versions[0] + if (latest) { + symlinkSync(latest, currentPath) + } + } +} + function discoverApps() { for (const dir of allAppDirs()) { const { pkg, error } = loadApp(dir)