Skip to content

Commit

Permalink
Aadd documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Paulooh007 committed Nov 20, 2023
1 parent 244625f commit 37992bc
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 93 deletions.
92 changes: 91 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,91 @@
# code4me.ai
<p align="center">

<img src="code4me_banner.jpeg" alt="Code4Me.ai Logo" height=312 width=760/>

</p>

## Code4Me.AI
Imagine an AI-powered tool just within your IDE that turns your ideas into code through natural language—our VS Code extension does precisely that. The Code4Me.ai extension not only aids in code generation and auto-debugging but also excels in generating unit tests and crafting quality documentation, boosting productivity and development speed by 10x for both novices and expert developers alike.

## Feature Summary
<p align="center">

<img src="images/features.png" alt="Alt text" height=500 width=760>

</p>

### You're still in control!

Stay in control and in the loop: Code4Me.ai not only generates code but also presents it just like a Git diff. This way, you can review, tweak, or directly accept the AI-crafted code, ensuring it perfectly aligns with what you want.

<p align="center">

<img src="images/diff.png" alt="Alt text" height=500 width=760>

</p>

## How to install

<details>
<summary>Installation guide</summary>

## 1. Download the .vsix File
- The `.vsix` file for `Code4Me.ai` is available in this GitHub repository.
- You can either clone the repository or download it as a ZIP file.
- To clone, use: `git clone [Repository URL]`
- Or download the ZIP file
## 2. Open Visual Studio Code
- Launch Visual Studio Code on your computer.

## 3. Access the Extensions View
- Click on the Extensions icon in the Activity Bar on the side of the window.
- In the Extensions view, click on the `...` (More Actions) button at the top right.
- Select `Install from VSIX...` from the dropdown menu.

<p align="center">

<img src="images/vsix.png" alt="Alt text" height=200 width=300>

</p>

## 4. Locate and Select the .vsix File
- Navigate to where you cloned/downloaded the repo in the file dialog.
- Select the `.vsix` file and click `Open`.
- VS Code will now install the extension.

## 5. Reload/Restart VS Code
- You may need to reload VS Code to activate the extension.
- Click the `Reload` button if prompted, or restart VS Code.

## 8. Verify Installation
- Check the Extensions view to ensure the extension is listed as installed.

## 9. OpenAI Key
- On the first use you'll be prompted to add your openai api key.

</details>


## How it works 🛠️⚙️

<p align="center">

<img src="images/system.jpeg" alt="Alt text" height=360 width=760>

</p>

1. **Grab the Current Code:**

First, our tool looks at what you're working on. It takes the code from the open file in your editor. If the file is new and empty, that's okay too—our AI can handle that.

2. **Your Instructions**

Next, you tell the tool what you need. You can type this in a box at the bottom left of the AI Coding panel. We've also got some common tasks ready to go, like adding packages or making tests.

3. **AI Does Its Thing (OpenAI Completions API)**

Then, we send your instructions and the code to the AI. It starts working and keeps going until it's done writing the code you need.

4. **You Check the Code**

Finally, you get to see the new code next to your old one, just like when you look at changes in Git. If you like what you see, hit accept, and the new code gets added to your file. Simple as that!
Binary file added code4me-0.0.2.vsix
Binary file not shown.
Binary file added code4me_banner.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added icon-small.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/diff.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/features.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/install.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/system.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/vsix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "Code4Me.ai",
"name": "code4me",
"displayName": "Code4Me.ai",
"description": "Code4Me.ai is a VS Code extension that uses OpenAI's gpt models to generate code from natural language.",
"version": "0.0.1",
"description": "codeformeai is a VS Code extension that uses OpenAI's gpt models to generate code from natural language.",
"version": "0.0.2",
"publisher": "Team Afri-Can",
"icon": "icon-small.jpg",
"repository": {
"type": "git",
"url": "https://github.com/Paulooh007/code4me.ai/blob/main/LICENSE"
"url": "https://github.com/Paulooh007/code4me.ai"
},
"engines": {
"vscode": "^1.65.0"
Expand All @@ -29,7 +29,7 @@
{
"type": "webview",
"id": "codegen.editing",
"name": "Code4Me.ai"
"name": "codeformeai"
}
]
},
Expand Down
94 changes: 52 additions & 42 deletions src/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,16 @@ import * as generator from './generator';
import * as vscode from 'vscode';
import * as fs from 'fs';
import { getState } from './state';
import * as path from 'path';




const doneText = '[x]';
const generatedFolder = '/.ai/';
const generatedFolder = '.ai';
const apiKeyName = 'openaiApiKey';


async function getPendingCommands(commands: string[]): Promise<string[]> {
return commands.filter(command => {
return !command.includes(doneText);
Expand All @@ -22,11 +27,18 @@ async function markCommandAsDone(command: any, filePath: string) {

async function saveResult(currentFolder: string, result: string, outputFileName: string): Promise<string> {
return new Promise((resolve, reject) => {
if (!fs.existsSync(currentFolder + generatedFolder)) {
fs.mkdirSync(currentFolder + generatedFolder, { recursive: true });
const generatedFolderPath = path.join(currentFolder, generatedFolder); // Construct the path using path.join

// Check if the generated folder exists, if not, create it
if (!fs.existsSync(generatedFolderPath)) {
fs.mkdirSync(generatedFolderPath, { recursive: true });
}
let files = fs.readdirSync(currentFolder + generatedFolder);

// Read the existing files in the generated folder
let files = fs.readdirSync(generatedFolderPath);
let index = 0;

// Iterate through the files to find the highest index
for (let i = 0; i < files.length; i++) {
if (files[i].endsWith('.codegen')) {
let fileName = files[i].split('.')[0];
Expand All @@ -37,13 +49,15 @@ async function saveResult(currentFolder: string, result: string, outputFileName:
}
}

let filePath = currentFolder + generatedFolder + outputFileName;
// Construct the full path for the new file
let filePath = path.join(generatedFolderPath, outputFileName);

// Write the result to the new file
fs.writeFile(filePath, result, (err) => {
if (err) {
reject(err);
reject(err); // Reject the promise if an error occurs
}
resolve(filePath);
resolve(filePath); // Resolve the promise with the new file path
});
});
}
Expand Down Expand Up @@ -86,7 +100,6 @@ async function generateNextCode(state: any) {
try {
console.log("processing.cmd: ", processing.command);
code = await generator.generateCode(processing.command, processing.files[processing.index]);
// console.log("processing.cmd: ", processing.command);`
console.log("CODE: ", code);
} catch(e) {
vscode.window.showErrorMessage('Error generating code. ' + e);
Expand All @@ -103,72 +116,69 @@ async function generateNextCode(state: any) {
// Check if file exists in current folder if exists show diff else show code
let currentFolder = processing.currentFolder;
let filePath = processing.files[processing.index];
if (!filePath.startsWith('/')) {
filePath = currentFolder + '/' + filePath;
if (!path.isAbsolute(filePath)) {
filePath = path.join(currentFolder, filePath);
}
let fileName = filePath.split('/').pop();
let fileName = path.basename(filePath);

let generatedFilePath = null;
if (fs.existsSync(filePath)) {
generatedFilePath = await saveResult(currentFolder, code, fileName);
await vscode.commands.executeCommand('vscode.diff', vscode.Uri.file(filePath), vscode.Uri.file(generatedFilePath));
} else {
generatedFilePath = await saveToFileAndShowResult(processing.currentFolder, code, fileName);
generatedFilePath = await saveToFileAndShowResult(currentFolder, code, fileName);
}
processing.codeFilePath = generatedFilePath;
state.set('processing', processing);
state.nextItem();
return true;
}


export async function cancel(state: any) {
let processing = state.get('processing');
if (processing && processing.codeFilePath) {
// Move to generated subfolder (same level as original)
let filePath = processing.codeFilePath;
let fileName = filePath.split('/').pop();
let folder = filePath.split('/').slice(0, -1).join('/');
let generatedFolder = folder + '/generated/';
let fileName = path.basename(filePath);
let folder = path.dirname(filePath);
let generatedFolder = path.join(folder, 'generated');

if (!fs.existsSync(generatedFolder)) {
fs.mkdirSync(generatedFolder, { recursive: true });
}
let newFilePath = generatedFolder+ fileName;

let newFilePath = path.join(generatedFolder, fileName);
fs.renameSync(filePath, newFilePath);
}

vscode.commands.executeCommand('workbench.action.closeActiveEditor');
state.stopLooping();
}

function applyChanges(processingState: any) {
// If file exists, replace it with the generated code else create a new file and paste the code
let currentFolder = processingState.currentFolder;
let file = processingState.files[processingState.index - 1];
let filePath = file;
if (!filePath.startsWith('/')) {
filePath = currentFolder + '/' + filePath;
}
let filePath = path.isAbsolute(file) ? file : path.join(currentFolder, file);
let code = fs.readFileSync(processingState.codeFilePath, 'utf8');
// Move processingState.codeFilePath to subfolder generated on the same level as the file
let codeFileFolder = processingState.codeFilePath.split('/');
codeFileFolder.pop();
codeFileFolder.push('generated');
codeFileFolder = codeFileFolder.join('/');

// Move processingState.codeFilePath to subfolder 'generated' on the same level as the file
let codeFileFolder = path.join(path.dirname(processingState.codeFilePath), 'generated');

if (!fs.existsSync(codeFileFolder)) {
fs.mkdirSync(codeFileFolder, { recursive: true });
}
let codeFileName = processingState.codeFilePath.split('/').pop();
let codeFilePath = codeFileFolder + '/' + codeFileName;

let codeFileName = path.basename(processingState.codeFilePath);
let codeFilePath = path.join(codeFileFolder, codeFileName);
fs.renameSync(processingState.codeFilePath, codeFilePath);

if (fs.existsSync(filePath)) {
// Replace the file with the generated code
fs.writeFileSync(filePath, code);
} else {
// Create file folder recursively if not exists
let fileFolder = filePath.split('/');
fileFolder.pop();
let folderPath = fileFolder.join('/');
let folderPath = path.dirname(filePath);
if (!fs.existsSync(folderPath)) {
fs.mkdirSync(folderPath, { recursive: true });
}
Expand Down Expand Up @@ -203,12 +213,14 @@ export async function accept(state: any) {
async function startHumanAILoop(command: any, currentFolder: string, state: any) {
command.folder = currentFolder;
if (command.type === 'test') {
let fileName = command.file.split('/').pop();
let testsFolder = currentFolder + '/tests/';
let unitTestFile = testsFolder + fileName;
let fileName = path.basename(command.file);
let testsFolder = path.join(currentFolder, 'tests');
let unitTestFile = path.join(testsFolder, fileName);

if (!fs.existsSync(testsFolder)) {
fs.mkdirSync(testsFolder, { recursive: true });
}

// Create empty file (if not exists)
if (!fs.existsSync(unitTestFile)) {
fs.writeFileSync(unitTestFile, '');
Expand All @@ -218,27 +230,25 @@ async function startHumanAILoop(command: any, currentFolder: string, state: any)
'state': 'files',
'command': command,
'currentFolder': currentFolder,
'files': [
unitTestFile
],
'files': [unitTestFile],
'index': 0
});
state.bar.loading.show();
await accept(state);
return;

} else if (command.type === 'edit') {
state.set('processing', {
'state': 'files',
'command': command,
'currentFolder': currentFolder,
'files': [
command.file
],
'files': [command.file],
'index': 0
});
state.bar.loading.show();
await accept(state);
return;

} else {
let result = await generator.generateFilesToModify(command);
await saveToFileAndShowResult(currentFolder, result.code, 'files.md');
Expand All @@ -261,11 +271,11 @@ export async function generate(context: vscode.ExtensionContext, state: any, cur
return;
}

let currentFolder = currentFile.substring(0, currentFile.lastIndexOf('/'));
let currentFolder = path.dirname(currentFile);
let inputText = fs.readFileSync(currentFile, 'utf8');
let commands = await parser.parse(inputText);
let pendingCommands = await getPendingCommands(commands);
// Show message box to the user if there are no pending commands

if (pendingCommands.length === 0) {
vscode.window.showInformationMessage('No pending commands');
return;
Expand Down
Loading

0 comments on commit 37992bc

Please sign in to comment.