 85bf1341f3
			
		
	
	85bf1341f3
	
	
	
		
			
			Frontend Enhancements: - Complete React TypeScript frontend with modern UI components - Distributed workflows management interface with real-time updates - Socket.IO integration for live agent status monitoring - Agent management dashboard with cluster visualization - Project management interface with metrics and task tracking - Responsive design with proper error handling and loading states Backend Infrastructure: - Distributed coordinator for multi-agent workflow orchestration - Cluster management API with comprehensive agent operations - Enhanced database models for agents and projects - Project service for filesystem-based project discovery - Performance monitoring and metrics collection - Comprehensive API documentation and error handling Documentation: - Complete distributed development guide (README_DISTRIBUTED.md) - Comprehensive development report with architecture insights - System configuration templates and deployment guides The platform now provides a complete web interface for managing the distributed AI cluster with real-time monitoring, workflow orchestration, and agent coordination capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			318 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			318 lines
		
	
	
		
			9.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* eslint-disable no-console */
 | |
| import commander from "commander";
 | |
| import {glob} from "glob";
 | |
| import {exists, mkdir, readdir, readFile, stat, writeFile} from "mz/fs";
 | |
| import {dirname, join, relative} from "path";
 | |
| 
 | |
| import { transform} from "./index";
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| export default function run() {
 | |
|   commander
 | |
|     .description(`Sucrase: super-fast Babel alternative.`)
 | |
|     .usage("[options] <srcDir>")
 | |
|     .option(
 | |
|       "-d, --out-dir <out>",
 | |
|       "Compile an input directory of modules into an output directory.",
 | |
|     )
 | |
|     .option(
 | |
|       "-p, --project <dir>",
 | |
|       "Compile a TypeScript project, will read from tsconfig.json in <dir>",
 | |
|     )
 | |
|     .option("--out-extension <extension>", "File extension to use for all output files.", "js")
 | |
|     .option("--exclude-dirs <paths>", "Names of directories that should not be traversed.")
 | |
|     .option("-q, --quiet", "Don't print the names of converted files.")
 | |
|     .option("-t, --transforms <transforms>", "Comma-separated list of transforms to run.")
 | |
|     .option("--disable-es-transforms", "Opt out of all ES syntax transforms.")
 | |
|     .option("--jsx-runtime <string>", "Transformation mode for the JSX transform.")
 | |
|     .option("--production", "Disable debugging information from JSX in output.")
 | |
|     .option(
 | |
|       "--jsx-import-source <string>",
 | |
|       "Automatic JSX transform import path prefix, defaults to `React.Fragment`.",
 | |
|     )
 | |
|     .option(
 | |
|       "--jsx-pragma <string>",
 | |
|       "Classic JSX transform element creation function, defaults to `React.createElement`.",
 | |
|     )
 | |
|     .option(
 | |
|       "--jsx-fragment-pragma <string>",
 | |
|       "Classic JSX transform fragment component, defaults to `React.Fragment`.",
 | |
|     )
 | |
|     .option("--keep-unused-imports", "Disable automatic removal of type-only imports/exports.")
 | |
|     .option("--preserve-dynamic-import", "Don't transpile dynamic import() to require.")
 | |
|     .option(
 | |
|       "--inject-create-require-for-import-require",
 | |
|       "Use `createRequire` when transpiling TS `import = require` to ESM.",
 | |
|     )
 | |
|     .option(
 | |
|       "--enable-legacy-typescript-module-interop",
 | |
|       "Use default TypeScript ESM/CJS interop strategy.",
 | |
|     )
 | |
|     .option("--enable-legacy-babel5-module-interop", "Use Babel 5 ESM/CJS interop strategy.")
 | |
|     .parse(process.argv);
 | |
| 
 | |
|   if (commander.project) {
 | |
|     if (
 | |
|       commander.outDir ||
 | |
|       commander.transforms ||
 | |
|       commander.args[0] ||
 | |
|       commander.enableLegacyTypescriptModuleInterop
 | |
|     ) {
 | |
|       console.error(
 | |
|         "If TypeScript project is specified, out directory, transforms, source " +
 | |
|           "directory, and --enable-legacy-typescript-module-interop may not be specified.",
 | |
|       );
 | |
|       process.exit(1);
 | |
|     }
 | |
|   } else {
 | |
|     if (!commander.outDir) {
 | |
|       console.error("Out directory is required");
 | |
|       process.exit(1);
 | |
|     }
 | |
| 
 | |
|     if (!commander.transforms) {
 | |
|       console.error("Transforms option is required.");
 | |
|       process.exit(1);
 | |
|     }
 | |
| 
 | |
|     if (!commander.args[0]) {
 | |
|       console.error("Source directory is required.");
 | |
|       process.exit(1);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const options = {
 | |
|     outDirPath: commander.outDir,
 | |
|     srcDirPath: commander.args[0],
 | |
|     project: commander.project,
 | |
|     outExtension: commander.outExtension,
 | |
|     excludeDirs: commander.excludeDirs ? commander.excludeDirs.split(",") : [],
 | |
|     quiet: commander.quiet,
 | |
|     sucraseOptions: {
 | |
|       transforms: commander.transforms ? commander.transforms.split(",") : [],
 | |
|       disableESTransforms: commander.disableEsTransforms,
 | |
|       jsxRuntime: commander.jsxRuntime,
 | |
|       production: commander.production,
 | |
|       jsxImportSource: commander.jsxImportSource,
 | |
|       jsxPragma: commander.jsxPragma || "React.createElement",
 | |
|       jsxFragmentPragma: commander.jsxFragmentPragma || "React.Fragment",
 | |
|       keepUnusedImports: commander.keepUnusedImports,
 | |
|       preserveDynamicImport: commander.preserveDynamicImport,
 | |
|       injectCreateRequireForImportRequire: commander.injectCreateRequireForImportRequire,
 | |
|       enableLegacyTypeScriptModuleInterop: commander.enableLegacyTypescriptModuleInterop,
 | |
|       enableLegacyBabel5ModuleInterop: commander.enableLegacyBabel5ModuleInterop,
 | |
|     },
 | |
|   };
 | |
| 
 | |
|   buildDirectory(options).catch((e) => {
 | |
|     process.exitCode = 1;
 | |
|     console.error(e);
 | |
|   });
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| async function findFiles(options) {
 | |
|   const outDirPath = options.outDirPath;
 | |
|   const srcDirPath = options.srcDirPath;
 | |
| 
 | |
|   const extensions = options.sucraseOptions.transforms.includes("typescript")
 | |
|     ? [".ts", ".tsx"]
 | |
|     : [".js", ".jsx"];
 | |
| 
 | |
|   if (!(await exists(outDirPath))) {
 | |
|     await mkdir(outDirPath);
 | |
|   }
 | |
| 
 | |
|   const outArr = [];
 | |
|   for (const child of await readdir(srcDirPath)) {
 | |
|     if (["node_modules", ".git"].includes(child) || options.excludeDirs.includes(child)) {
 | |
|       continue;
 | |
|     }
 | |
|     const srcChildPath = join(srcDirPath, child);
 | |
|     const outChildPath = join(outDirPath, child);
 | |
|     if ((await stat(srcChildPath)).isDirectory()) {
 | |
|       const innerOptions = {...options};
 | |
|       innerOptions.srcDirPath = srcChildPath;
 | |
|       innerOptions.outDirPath = outChildPath;
 | |
|       const innerFiles = await findFiles(innerOptions);
 | |
|       outArr.push(...innerFiles);
 | |
|     } else if (extensions.some((ext) => srcChildPath.endsWith(ext))) {
 | |
|       const outPath = outChildPath.replace(/\.\w+$/, `.${options.outExtension}`);
 | |
|       outArr.push({
 | |
|         srcPath: srcChildPath,
 | |
|         outPath,
 | |
|       });
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return outArr;
 | |
| }
 | |
| 
 | |
| async function runGlob(options) {
 | |
|   const tsConfigPath = join(options.project, "tsconfig.json");
 | |
| 
 | |
|   let str;
 | |
|   try {
 | |
|     str = await readFile(tsConfigPath, "utf8");
 | |
|   } catch (err) {
 | |
|     console.error("Could not find project tsconfig.json");
 | |
|     console.error(`  --project=${options.project}`);
 | |
|     console.error(err);
 | |
|     process.exit(1);
 | |
|   }
 | |
|   const json = JSON.parse(str);
 | |
| 
 | |
|   const foundFiles = [];
 | |
| 
 | |
|   const files = json.files;
 | |
|   const include = json.include;
 | |
| 
 | |
|   const absProject = join(process.cwd(), options.project);
 | |
|   const outDirs = [];
 | |
| 
 | |
|   if (!(await exists(options.outDirPath))) {
 | |
|     await mkdir(options.outDirPath);
 | |
|   }
 | |
| 
 | |
|   if (files) {
 | |
|     for (const file of files) {
 | |
|       if (file.endsWith(".d.ts")) {
 | |
|         continue;
 | |
|       }
 | |
|       if (!file.endsWith(".ts") && !file.endsWith(".js")) {
 | |
|         continue;
 | |
|       }
 | |
| 
 | |
|       const srcFile = join(absProject, file);
 | |
|       const outFile = join(options.outDirPath, file);
 | |
|       const outPath = outFile.replace(/\.\w+$/, `.${options.outExtension}`);
 | |
| 
 | |
|       const outDir = dirname(outPath);
 | |
|       if (!outDirs.includes(outDir)) {
 | |
|         outDirs.push(outDir);
 | |
|       }
 | |
| 
 | |
|       foundFiles.push({
 | |
|         srcPath: srcFile,
 | |
|         outPath,
 | |
|       });
 | |
|     }
 | |
|   }
 | |
|   if (include) {
 | |
|     for (const pattern of include) {
 | |
|       const globFiles = await glob(join(absProject, pattern));
 | |
|       for (const file of globFiles) {
 | |
|         if (!file.endsWith(".ts") && !file.endsWith(".js")) {
 | |
|           continue;
 | |
|         }
 | |
|         if (file.endsWith(".d.ts")) {
 | |
|           continue;
 | |
|         }
 | |
| 
 | |
|         const relativeFile = relative(absProject, file);
 | |
|         const outFile = join(options.outDirPath, relativeFile);
 | |
|         const outPath = outFile.replace(/\.\w+$/, `.${options.outExtension}`);
 | |
| 
 | |
|         const outDir = dirname(outPath);
 | |
|         if (!outDirs.includes(outDir)) {
 | |
|           outDirs.push(outDir);
 | |
|         }
 | |
| 
 | |
|         foundFiles.push({
 | |
|           srcPath: file,
 | |
|           outPath,
 | |
|         });
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (const outDirPath of outDirs) {
 | |
|     if (!(await exists(outDirPath))) {
 | |
|       await mkdir(outDirPath);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // TODO: read exclude
 | |
| 
 | |
|   return foundFiles;
 | |
| }
 | |
| 
 | |
| async function updateOptionsFromProject(options) {
 | |
|   /**
 | |
|    * Read the project information and assign the following.
 | |
|    *  - outDirPath
 | |
|    *  - transform: imports
 | |
|    *  - transform: typescript
 | |
|    *  - enableLegacyTypescriptModuleInterop: true/false.
 | |
|    */
 | |
| 
 | |
|   const tsConfigPath = join(options.project, "tsconfig.json");
 | |
| 
 | |
|   let str;
 | |
|   try {
 | |
|     str = await readFile(tsConfigPath, "utf8");
 | |
|   } catch (err) {
 | |
|     console.error("Could not find project tsconfig.json");
 | |
|     console.error(`  --project=${options.project}`);
 | |
|     console.error(err);
 | |
|     process.exit(1);
 | |
|   }
 | |
|   const json = JSON.parse(str);
 | |
|   const sucraseOpts = options.sucraseOptions;
 | |
|   if (!sucraseOpts.transforms.includes("typescript")) {
 | |
|     sucraseOpts.transforms.push("typescript");
 | |
|   }
 | |
| 
 | |
|   const compilerOpts = json.compilerOptions;
 | |
|   if (compilerOpts.outDir) {
 | |
|     options.outDirPath = join(process.cwd(), options.project, compilerOpts.outDir);
 | |
|   }
 | |
|   if (compilerOpts.esModuleInterop !== true) {
 | |
|     sucraseOpts.enableLegacyTypeScriptModuleInterop = true;
 | |
|   }
 | |
|   if (compilerOpts.module === "commonjs") {
 | |
|     if (!sucraseOpts.transforms.includes("imports")) {
 | |
|       sucraseOpts.transforms.push("imports");
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| async function buildDirectory(options) {
 | |
|   let files;
 | |
|   if (options.outDirPath && options.srcDirPath) {
 | |
|     files = await findFiles(options);
 | |
|   } else if (options.project) {
 | |
|     await updateOptionsFromProject(options);
 | |
|     files = await runGlob(options);
 | |
|   } else {
 | |
|     console.error("Project or Source directory required.");
 | |
|     process.exit(1);
 | |
|   }
 | |
| 
 | |
|   for (const file of files) {
 | |
|     await buildFile(file.srcPath, file.outPath, options);
 | |
|   }
 | |
| }
 | |
| 
 | |
| async function buildFile(srcPath, outPath, options) {
 | |
|   if (!options.quiet) {
 | |
|     console.log(`${srcPath} -> ${outPath}`);
 | |
|   }
 | |
|   const code = (await readFile(srcPath)).toString();
 | |
|   const transformedCode = transform(code, {...options.sucraseOptions, filePath: srcPath}).code;
 | |
|   await writeFile(outPath, transformedCode);
 | |
| }
 |