UNPKG

@mesh-tech/mesh-cli

Version:

CLI for Mesh platform development utilities

74 lines (73 loc) 2.42 kB
import { createHash } from "node:crypto"; import { existsSync, readFileSync, readdirSync } from "node:fs"; import { dirname, isAbsolute, join, relative } from "node:path"; export const WORKFLOW_PACKAGE_DIRS = [ "packages/agent-sdk/src", "packages/workflow-interpreter/src", "packages/agent-contracts/src", ]; const EXCLUDE = /(^|\/)(node_modules|dist|__tests__)(\/|$)|\.(test|spec)\.[cm]?tsx?$/; export function findRepoRoot(startDir) { let dir = startDir; for (;;) { if (existsSync(join(dir, "pnpm-workspace.yaml"))) return dir; const parent = dirname(dir); if (parent === dir) return startDir; dir = parent; } } export function workflowSourceDirs(repoRoot, extraDirs = []) { const pkgDirs = WORKFLOW_PACKAGE_DIRS.map((d) => join(repoRoot, d)).filter((d) => existsSync(d)); if (pkgDirs.length > 0) return pkgDirs; return extraDirs.filter((d) => existsSync(d)); } export function resolveWorkerSourceDirs(repoRoot, services = {}) { const dirs = []; for (const [name, svc] of Object.entries(services)) { if (/worker/i.test(name) && svc?.src) { dirs.push(isAbsolute(svc.src) ? svc.src : join(repoRoot, svc.src)); } } return dirs; } export function computeWorkflowFingerprint(dirs, relativeTo) { const files = []; for (const dir of dirs) { let rels; try { rels = readdirSync(dir, { recursive: true }); } catch { continue; } for (const rel of rels) { const p = String(rel); if (/\.(ts|tsx)$/.test(p) && !EXCLUDE.test(p)) files.push(join(dir, p)); } } files.sort(); if (files.length === 0) return ""; const h = createHash("sha256"); for (const f of files) { try { const content = readFileSync(f); h.update(relativeTo ? relative(relativeTo, f) : f); h.update("\0"); h.update(content); h.update("\0"); } catch { } } return h.digest("hex").slice(0, 16); } export function fingerprintWorkflowSource(appRoot, services = {}) { const repoRoot = findRepoRoot(appRoot); const workerDirs = resolveWorkerSourceDirs(repoRoot, services); return computeWorkflowFingerprint(workflowSourceDirs(repoRoot, workerDirs), repoRoot); }