From 93dce3d62e61fda51d5d4f6a00617965788505c2 Mon Sep 17 00:00:00 2001 From: Paul Bakaus Date: Thu, 20 Aug 2026 11:38:20 -0700 Subject: [PATCH] Centralize framework detection probes Reuse the shared dependency and ordered file-probe helpers in the SvelteKit and TanStack live adapters, removing duplicate package parsing and path search. AI assistance: prepared by OpenAI Codex under maintainer pbakaus standing scheduled architecture-refactor authorization. --- skill/scripts/live/sveltekit-adapter.mjs | 42 +++++++++--------------- skill/scripts/live/tanstack-adapter.mjs | 29 +++------------- 2 files changed, 19 insertions(+), 52 deletions(-) diff --git a/skill/scripts/live/sveltekit-adapter.mjs b/skill/scripts/live/sveltekit-adapter.mjs index e94c54f1e..b96e955a6 100644 --- a/skill/scripts/live/sveltekit-adapter.mjs +++ b/skill/scripts/live/sveltekit-adapter.mjs @@ -11,6 +11,8 @@ import crypto from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; +import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs'; + export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte'; export const SVELTE_LAYOUT_MARKER_OPEN = ''; export const SVELTE_LAYOUT_MARKER_CLOSE = ''; @@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) { && fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%'); if (!hasTemplateMarkers) return null; - const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js')) - || fs.existsSync(path.join(cwd, 'svelte.config.mjs')) - || fs.existsSync(path.join(cwd, 'svelte.config.cjs')) - || fs.existsSync(path.join(cwd, 'svelte.config.ts')); - const hasKitPackage = packageHasSvelteKit(cwd); + const hasSvelteConfig = Boolean(firstExistingFile(cwd, [ + 'svelte.config.js', + 'svelte.config.mjs', + 'svelte.config.cjs', + 'svelte.config.ts', + ])); + const hasKitPackage = hasAnyDependency(cwd, [ + '@sveltejs/kit', + '@sveltejs/vite-plugin-svelte', + 'svelte', + ]); if (!hasSvelteConfig && !hasKitPackage) return null; return { @@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) { } function findSvelteKitLayout(cwd) { - const candidates = [ + return firstExistingFile(cwd, [ 'src/routes/+layout.svelte', 'src/routes/(app)/+layout.svelte', - ]; - for (const rel of candidates) { - if (fs.existsSync(path.join(cwd, rel))) return rel; - } - return 'src/routes/+layout.svelte'; + ]) || 'src/routes/+layout.svelte'; } function defaultSvelteLayout() { return `\n\n{@render children?.()}\n`; } -function packageHasSvelteKit(cwd) { - const file = path.join(cwd, 'package.json'); - if (!fs.existsSync(file)) return false; - try { - const pkg = JSON.parse(fs.readFileSync(file, 'utf-8')); - const deps = { - ...(pkg.dependencies || {}), - ...(pkg.devDependencies || {}), - ...(pkg.peerDependencies || {}), - }; - return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte); - } catch { - return false; - } -} - function fileIncludes(file, text) { try { return fs.readFileSync(file, 'utf-8').includes(text); diff --git a/skill/scripts/live/tanstack-adapter.mjs b/skill/scripts/live/tanstack-adapter.mjs index 4a1c81a97..b53978f4f 100644 --- a/skill/scripts/live/tanstack-adapter.mjs +++ b/skill/scripts/live/tanstack-adapter.mjs @@ -19,6 +19,8 @@ import fs from 'node:fs'; import path from 'node:path'; + +import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs'; import { buildLiveScriptSrc } from './frameworks/script-src.mjs'; export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}'; @@ -42,8 +44,8 @@ const START_PACKAGES = [ ]; export function detectTanStackStartProject(cwd = process.cwd()) { - if (!packageHasTanStackStart(cwd)) return null; - const rootRoute = findRootRouteFile(cwd); + if (!hasAnyDependency(cwd, START_PACKAGES)) return null; + const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES); if (!rootRoute) return null; const ext = path.extname(rootRoute); @@ -218,29 +220,6 @@ function isManagedComponent(content) { return String(content || '').includes('impeccable-live-tanstack'); } -function findRootRouteFile(cwd) { - for (const rel of ROOT_ROUTE_CANDIDATES) { - if (fs.existsSync(path.join(cwd, rel))) return rel; - } - return null; -} - -function packageHasTanStackStart(cwd) { - const file = path.join(cwd, 'package.json'); - if (!fs.existsSync(file)) return false; - try { - const pkg = JSON.parse(fs.readFileSync(file, 'utf-8')); - const deps = { - ...(pkg.dependencies || {}), - ...(pkg.devDependencies || {}), - ...(pkg.peerDependencies || {}), - }; - return START_PACKAGES.some((name) => Boolean(deps[name])); - } catch { - return false; - } -} - function relativeImportSpecifier(fromFile, toFile) { const rel = path.posix.relative( path.posix.dirname(fromFile.split(path.sep).join('/')),