diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000..d504035bd --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,22 @@ +{ + "parser": "@typescript-eslint/parser", + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "plugins": ["@typescript-eslint", "prettier"], + "rules": { + "prettier/prettier": "error", + "@typescript-eslint/no-unused-vars": [ + "error", + { "argsIgnorePattern": "^_" } + ], + "@typescript-eslint/explicit-module-boundary-types": "off", + "@typescript-eslint/no-explicit-any": "warn" + }, + "env": { + "node": true, + "jest": true + } +} diff --git a/.gitignore b/.gitignore index 2c38ccae0..36dd608fb 100644 --- a/.gitignore +++ b/.gitignore @@ -72,3 +72,48 @@ results.*.json codegen-examples/examples/swebench_agent_run/results/* codegen-examples/examples/swebench_agent_run/predictions/* codegen-examples/examples/swebench_agent_run/logs/* + +# Existing Python-related ignores +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# TypeScript-specific ignores +node_modules/ +dist/ +coverage/ +.nyc_output/ +*.tsbuildinfo +.npm +.eslintcache +.env +.env.test +.env.local +.env.development.local +.env.test.local +.env.production.local + +# Editor directories and files +.idea/ +.vscode/ +*.swp +*.swo +*~ +.DS_Store diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000..919b5490c --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "semi": true, + "trailingComma": "all", + "singleQuote": true, + "printWidth": 100, + "tabWidth": 2, + "useTabs": false +} diff --git a/TYPESCRIPT_MIGRATION.md b/TYPESCRIPT_MIGRATION.md new file mode 100644 index 000000000..b925f0add --- /dev/null +++ b/TYPESCRIPT_MIGRATION.md @@ -0,0 +1,105 @@ +# TypeScript Migration Plan for Codegen + +This document outlines the plan for migrating the Codegen codebase from Python to TypeScript. + +## Overview + +The Codegen repository is currently a Python-based project with approximately 1165 Python files. This migration will convert the codebase to TypeScript, which will provide benefits such as static typing, better IDE support, and a more modern development experience. + +## Migration Strategy + +Given the size and complexity of the codebase, we'll adopt a phased approach to the migration: + +### Phase 1: Setup and Infrastructure (Current PR) + +- Set up TypeScript configuration (tsconfig.json) +- Configure ESLint and Prettier for code quality +- Set up Jest for testing +- Create initial package.json with dependencies +- Implement a basic CLI structure to mirror the Python CLI + +### Phase 2: Core Functionality Migration + +- Identify and migrate core modules first +- Focus on the SDK and essential utilities +- Create TypeScript equivalents of Python classes and functions +- Implement type definitions for all data structures + +### Phase 3: CLI Commands Migration + +- Migrate each CLI command one by one +- Ensure backward compatibility with existing command-line usage +- Add comprehensive tests for each command + +### Phase 4: Advanced Features Migration + +- Migrate language server protocol (LSP) functionality +- Implement tree-sitter integration for code parsing +- Migrate code analysis and transformation features + +### Phase 5: Testing and Validation + +- Ensure comprehensive test coverage +- Validate functionality against the Python version +- Performance testing and optimization + +### Phase 6: Documentation and Release + +- Update documentation to reflect TypeScript usage +- Create migration guides for users +- Release the TypeScript version + +## Directory Structure + +The TypeScript version will follow a similar structure to the Python version: + +``` +src/ + cli/ # CLI commands and utilities + sdk/ # Core SDK functionality + lsp/ # Language Server Protocol implementation + utils/ # Utility functions + types/ # TypeScript type definitions + parsers/ # Code parsing functionality + transformers/ # Code transformation utilities +``` + +## Dependencies + +The TypeScript version will use the following key dependencies: + +- `commander` for CLI functionality +- `tree-sitter` and related parsers for code analysis +- `axios` for HTTP requests +- `fs-extra` for enhanced file system operations +- TypeScript and related development tools + +## Challenges and Considerations + +1. **Python-specific Libraries**: Some Python libraries may not have direct TypeScript equivalents. We'll need to find alternatives or implement custom solutions. + +1. **Performance**: Ensure the TypeScript version maintains or improves upon the performance of the Python version. + +1. **Interoperability**: During the migration, we may need to maintain interoperability between Python and TypeScript components. + +1. **Testing**: Comprehensive testing will be crucial to ensure functionality is preserved. + +## Next Steps + +1. Review and merge this initial setup PR +1. Begin identifying core modules for migration +1. Create a detailed roadmap with milestones for each phase +1. Set up CI/CD for the TypeScript version + +## Contributing to the Migration + +Contributors can help with the migration by: + +1. Identifying Python modules that can be migrated to TypeScript +1. Creating TypeScript equivalents of Python functions and classes +1. Writing tests for migrated functionality +1. Reviewing PRs related to the migration + +## Timeline + +The migration is expected to take several months, with regular releases of partially migrated functionality. The goal is to have a fully functional TypeScript version by the end of 2025. diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 000000000..296b7fea3 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,10 @@ +module.exports = { + preset: "ts-jest", + testEnvironment: "node", + roots: ["/src"], + testMatch: ["**/__tests__/**/*.ts?(x)", "**/?(*.)+(spec|test).ts?(x)"], + moduleNameMapper: { + "^@/(.*)$": "/src/$1", + }, + collectCoverageFrom: ["src/**/*.{ts,tsx}", "!src/**/*.d.ts"], +}; diff --git a/package.json b/package.json index cd7830acd..135b1f744 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,48 @@ { + "name": "codegen", + "version": "0.1.0", "private": true, + "description": "TypeScript version of Codegen - Scriptable interface to a powerful, multi-lingual language server", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "scripts": { + "build": "tsc", + "start": "node dist/index.js", + "dev": "ts-node src/index.ts", + "test": "jest", + "lint": "eslint . --ext .ts,.tsx", + "format": "prettier --write \"src/**/*.{ts,tsx}\"", + "clean": "rimraf dist" + }, + "dependencies": { + "commander": "^11.1.0", + "tree-sitter": "^0.20.6", + "tree-sitter-python": "^0.20.4", + "tree-sitter-typescript": "^0.20.3", + "tree-sitter-javascript": "^0.20.1", + "axios": "^1.6.2", + "chalk": "^5.3.0", + "dotenv": "^16.3.1", + "fast-glob": "^3.3.2", + "fs-extra": "^11.2.0", + "lodash": "^4.17.21" + }, + "devDependencies": { + "@types/jest": "^29.5.10", + "@types/lodash": "^4.14.202", + "@types/node": "^20.10.0", + "@typescript-eslint/eslint-plugin": "^6.13.1", + "@typescript-eslint/parser": "^6.13.1", + "eslint": "^8.54.0", + "eslint-config-prettier": "^9.0.0", + "eslint-plugin-prettier": "^5.0.1", + "jest": "^29.7.0", + "prettier": "^3.1.0", + "rimraf": "^5.0.5", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.1", + "typescript": "^5.3.2" + }, "release": { "branches": ["develop"], "plugins": [ diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 000000000..70e956fef --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,49 @@ +import { Command } from "commander"; +import { version } from "../package.json"; +import { configCommand } from "./cli/commands/config"; +import { createCommand } from "./cli/commands/create"; +import { deployCommand } from "./cli/commands/deploy"; +import { expertCommand } from "./cli/commands/expert"; +import { initCommand } from "./cli/commands/init"; +import { listCommand } from "./cli/commands/list"; +import { loginCommand } from "./cli/commands/login"; +import { logoutCommand } from "./cli/commands/logout"; +import { lspCommand } from "./cli/commands/lsp"; +import { notebookCommand } from "./cli/commands/notebook"; +import { profileCommand } from "./cli/commands/profile"; +import { resetCommand } from "./cli/commands/reset"; +import { runCommand } from "./cli/commands/run"; +import { runOnPrCommand } from "./cli/commands/run-on-pr"; +import { serveCommand } from "./cli/commands/serve"; +import { startCommand } from "./cli/commands/start"; +import { styleDebugCommand } from "./cli/commands/style-debug"; +import { updateCommand } from "./cli/commands/update"; + +export async function main(): Promise { + const program = new Command(); + + program.version(version, "-v, --version", "Output the current version"); + program.name("codegen"); + + // Register commands + program.addCommand(configCommand()); + program.addCommand(createCommand()); + program.addCommand(deployCommand()); + program.addCommand(expertCommand()); + program.addCommand(initCommand()); + program.addCommand(listCommand()); + program.addCommand(loginCommand()); + program.addCommand(logoutCommand()); + program.addCommand(lspCommand()); + program.addCommand(notebookCommand()); + program.addCommand(profileCommand()); + program.addCommand(resetCommand()); + program.addCommand(runCommand()); + program.addCommand(runOnPrCommand()); + program.addCommand(serveCommand()); + program.addCommand(startCommand()); + program.addCommand(styleDebugCommand()); + program.addCommand(updateCommand()); + + await program.parseAsync(process.argv); +} diff --git a/src/cli/commands/config/index.ts b/src/cli/commands/config/index.ts new file mode 100644 index 000000000..6a9a71ffc --- /dev/null +++ b/src/cli/commands/config/index.ts @@ -0,0 +1,32 @@ +import { Command } from "commander"; + +export function configCommand(): Command { + const command = new Command("config"); + + command + .description("Configure Codegen settings") + .option("-l, --list", "List all configuration settings") + .option("-s, --set ", "Set a configuration value") + .option("-g, --get ", "Get a configuration value") + .option("-u, --unset ", "Unset a configuration value") + .action((options) => { + if (options.list) { + console.log("Listing all configuration settings..."); + // Implementation would go here + } else if (options.set) { + const [key, value] = options.set.split("="); + console.log(`Setting ${key} to ${value}...`); + // Implementation would go here + } else if (options.get) { + console.log(`Getting value for ${options.get}...`); + // Implementation would go here + } else if (options.unset) { + console.log(`Unsetting ${options.unset}...`); + // Implementation would go here + } else { + command.help(); + } + }); + + return command; +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 000000000..4a8b95a36 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,8 @@ +#!/usr/bin/env node + +import { main } from "./cli"; + +main().catch((error) => { + console.error("Error:", error); + process.exit(1); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 000000000..038998194 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,21 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "outDir": "dist", + "declaration": true, + "sourceMap": true, + "rootDir": "src", + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*.ts", "src/**/*.tsx"], + "exclude": ["node_modules", "dist", "**/*.test.ts"] +}