UNPKG

run402-mcp

Version:

MCP server for Run402 — full-stack backend infrastructure for AI agents: Postgres, auth, storage, serverless functions and atomic deploys. Paid with x402/MPP. Includes $0.03 image generation.

47 lines • 2.42 kB
import { loadDeployManifest, normalizeDeployManifest } from "./deploy-manifest.js"; import { stat, readFile } from "node:fs/promises"; import { dirname, resolve } from "node:path"; export const APPLICATION_MANIFESTS = ["run402.json", "run402.deploy.json", "app.json"]; /** Resolve one app locally. Never select a sibling or inherit a parent app. */ export async function resolveApplicationScope(input = {}) { const directory = resolve(input.cwd ?? process.cwd(), input.dir ?? "."); if (input.manifest) { const manifest = resolve(directory, input.manifest); return { app_root: dirname(manifest), manifest_path: manifest, selected: true }; } for (const name of APPLICATION_MANIFESTS) { const manifest = resolve(directory, name); try { if ((await stat(manifest)).isFile()) return { app_root: directory, manifest_path: manifest, selected: true }; } catch { /* Discovery is local and absence is reported by the caller. */ } } return { app_root: directory, manifest_path: null, selected: false }; } export function materializeTemplates(value, values) { if (typeof value === "string") { return value.replace(/\$\{([^}]+)\}/g, (_match, key) => values[key] ?? ""); } if (Array.isArray(value)) return value.map((item) => materializeTemplates(item, values)); if (value && typeof value === "object") { return Object.fromEntries(Object.entries(value).map(([key, nested]) => [ key, materializeTemplates(nested, values), ])); } return value; } export async function loadApplicationScanInput(manifestPath) { const raw = manifestPath.endsWith(".json") ? JSON.parse(await readFile(manifestPath, "utf8")) : null; const isApp = raw?.app && raw?.release; const buildDeferred = Boolean(isApp && raw.build?.commands?.length); if (buildDeferred) return { spec: {}, build_deferred: true }; const normalized = isApp ? await normalizeDeployManifest(materializeTemplates(raw.release, {}), { baseDir: dirname(manifestPath), manifestPath, defaultProject: "prj_up_preflight_placeholder", validateFiles: true }) : await loadDeployManifest(manifestPath, { defaultProject: "prj_up_preflight_placeholder", validateFiles: true }); return { spec: normalized.spec, build_deferred: false }; } //# sourceMappingURL=app-scope.js.map