Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .github/funding.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,5 @@

github: warengonzaga
buy_me_a_coffee: warengonzaga

# Your support means a lot to me to continue the development of open source project like this.
# Sponsoring this project means a lot to me. Your support helps me to continue building great open-source projects just like this.
# Sponsoring this project means a lot to me. Your support helps me to continue building great open-source projects just like this.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ This project is inspired by the following projects:
- [aicommits](https://github.com/Nutlope/aicommits) - A CLI that writes your git commit messages for you with AI.
- [ai-commit](https://github.com/insulineru/ai-commit) - Make commits easier with ChatGPT, Gitmoji and Conventional Commits.
- [opencommit](https://github.com/di-sukharev/opencommit) - About
Auto-generate impressive commits with AI in 1 second.
Auto-generate impressive commits with AI in 1 second.
- [tgpt](https://github.com/aandrew-me/tgpt) - AI Chatbots in terminal without needing API keys.

## βš™οΈ Project Activity

![activity](https://repobeats.axiom.co/api/embed/b89d4c52ac63656f8148143516edd0db0d85788d.svg "Repobeats analytics image")
![activity](https://repobeats.axiom.co/api/embed/b89d4c52ac63656f8148143516edd0db0d85788d.svg 'Repobeats analytics image')

## 🎯 Contributing

Expand Down
22 changes: 11 additions & 11 deletions code_of_conduct.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
- Focusing on what is best not just for us as individuals, but for the
overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
- Other conduct which could reasonably be considered inappropriate in a
professional setting

## Enforcement Responsibilities
Expand Down Expand Up @@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
Expand Down
2 changes: 1 addition & 1 deletion contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ There are many ways to contribute to this open source project. Any contributions

### 🧬 Development

If you can write a code then create a pull request to this repo and I will review your code. Please consider to submit your pull request to the ```dev``` branch. I will auto reject if you submit your pull request to the ```main``` branch.
If you can write a code then create a pull request to this repo and I will review your code. Please consider to submit your pull request to the `dev` branch. I will auto reject if you submit your pull request to the `main` branch.

#### πŸ”§ Setup

Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"build": "babel --out-dir=dist source",
"dev": "babel --out-dir=dist --watch source",
"clean": "npm run clean:linux",
"clean:linux": "rm -rf dist",
"clean:windows": "rmdir /s /q dist",
"clean:linux": "rm -rf dist || echo Directory not found, skipping removal",
"clean:windows": "rmdir /s /q dist || echo Directory not found, skipping removal",
"setup": "npm run setup:linux",
"setup:linux": "npm run clean:linux && npm run build && npm i -g .",
"setup:windows": "npm run clean:windows && npm run build",
Expand All @@ -47,6 +47,7 @@
"ink-select-input": "^6.0.0",
"is-git-repository": "^2.0.0",
"meow": "^11.0.0",
"ollama": "^0.5.9",
"openai": "^4.28.4",
"react": "^18.2.0",
"readline": "^1.3.0"
Expand Down
46 changes: 2 additions & 44 deletions source/app.js
Original file line number Diff line number Diff line change
@@ -1,48 +1,6 @@
import React from 'react';
import {Text, Newline} from 'ink';
import BigText from 'ink-big-text';
import Gradient from 'ink-gradient';
import isGit from 'is-git-repository';
import isCommitterSet from './utils/errors.js';
import info from './utils/info.js';
import askForCommitMessage from './utils/commit.js';
import { getOpenAIKey, setOpenAIKey, deleteOPenAIKey } from './utils/api.js';
import Logo from './utils/logo.js';

export default function App({flags}) {
if(flags.setopenai) {
setOpenAIKey(flags.setopenai);
}
if(flags.delopenai) {
deleteOPenAIKey();
}
if (!getOpenAIKey()) {
console.log('Please provide an OpenAI API key.');
console.log('You can get one from https://platform.openai.com/account/api-keys')
console.log('Run `magicc --setopenai=<api-key>` to save your API key and try again.');
} else {
console.log('You have an OpenAI API key, you can now generate a commit message.');
const gitCheck = isGit();
const committerCheck = isCommitterSet();
if (gitCheck && committerCheck) {
askForCommitMessage();
} else {
console.log('This is not a git repository.');
}
}
return (
<>
<Gradient name='passion'>
<BigText text='Magicc' />
<Text>You can do `magicc`, you can build anything that you desire. πŸͺ„</Text>
</Gradient>
<Text>
Version: <Text color='green'>{info('version')}</Text> |
Author: <Text color='blue'>{info('author')}</Text><Newline/>
<Text>
Need Help? <Text color="cyan">magicc --help</Text>
</Text><Newline/>
==================================================
</Text>
</>
);
return <Logo flags={flags} />;
}
10 changes: 6 additions & 4 deletions source/cli.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
#!/usr/bin/env node
import React from 'react';
import {render} from 'ink';
import meow from 'meow';
import App from './app.js';
import Logo from './utils/logo.js';
import {render} from 'ink';

render(<Logo />, {patchConsole: false});

const cli = meow(
`
Usage
`Usage
$ magicc

Options
Expand All @@ -33,4 +35,4 @@ const cli = meow(
},
);

render(<App flags={cli.flags}/>);
render(<App flags={cli.flags} />, {patchConsole: false});
36 changes: 36 additions & 0 deletions source/models/ollama.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Ollama from 'ollama'; // Import the Ollama model
import config from '../utils/config.json';

async function ollamaModel(model, flags, diffContent) {
try {
// Use the prompt from the config file emoji and send to Ollama
const categoryResponse = await Ollama.chat({
messages: [
{role: 'system', content: config.commitConfig.emoji},
{role: 'user', content: diffContent},
],
model,
});
// Use the prompt from the config file message and send to Ollama

const messageResponse = await Ollama.chat({
messages: [
{role: 'system', content: config.commitConfig.message},
{role: 'user', content: diffContent},
],
model,
});
console.log('categoryResponse', categoryResponse);
console.log('messageResponse', messageResponse);
return {
category: categoryResponse?.message?.content,
message: messageResponse?.message?.content,
};
} catch (error) {
throw new Error(
'Failed to connect to local Ollama instance. To start Ollama, first download it at https://ollama.ai.',
);
}
}

export default ollamaModel;
54 changes: 54 additions & 0 deletions source/models/openai.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import OpenAI from 'openai';
import config from '../utils/config.json';
import dotenv from 'dotenv';

import {getOpenAIKey, setOpenAIKey, deleteOPenAIKey} from '../utils/api.js';

dotenv.config();

async function openAiModel(model, flags, diffContent) {
if (flags.setopenai) {
setOpenAIKey(flags.setopenai);
}
if (flags.delopenai) {
deleteOPenAIKey();
}
if (!getOpenAIKey()) {
return {
message:
'Please provide an OpenAI API key.\n' +
'You can get one from https://platform.openai.com/account/api-keys\n' +
'Run `magicc --setopenai=<api-key>` to save your API key and try again.',
};
} else {
console.log(
'You have an OpenAI API key, you can now generate a commit message.',
);

const apiKey = await getOpenAIKey();
const openai = new OpenAI({apiKey: apiKey});

const category = await openai.chat.completions.create({
messages: [
{role: 'system', content: config.commitConfig.emoji},
{role: 'user', content: diffContent},
],
model,
});
// use the prmopt from the config file message and send to openai
const message = await openai.chat.completions.create({
messages: [
{role: 'system', content: config.commitConfig.message},
{role: 'user', content: diffContent},
],
model,
});

return {
category: category.choices[0].message.content,
message: message.choices[0].message.content,
};
}
}

export default openAiModel;
66 changes: 33 additions & 33 deletions source/utils/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,46 @@ import Conf from 'conf';
const config = new Conf({projectName: 'magicc'});

async function isValidOpenAIKey(apiKey) {
try {
const response = await fetch('https://api.openai.com/v1/models', {
headers: {
'Authorization': `Bearer ${apiKey}`
}
});
try {
const response = await fetch('https://api.openai.com/v1/models', {
headers: {
Authorization: `Bearer ${apiKey}`,
},
});

if (response.status === 200) {
return true;
} else if (response.status === 401) {
console.error('Invalid API key');
return false;
} else {
console.error('Unexpected response status:', response.status);
return false;
}
} catch (error) {
console.error('Error while validating API key:', error);
return false;
}
if (response.status === 200) {
return true;
} else if (response.status === 401) {
console.error('Invalid API key');
return false;
} else {
console.error('Unexpected response status:', response.status);
return false;
}
} catch (error) {
console.error('Error while validating API key:', error);
return false;
}
}

const setOpenAIKey = (key) => {
isValidOpenAIKey(key).then(isValid => {
if (isValid) {
console.log('API key is valid');
config.set('openai', key);
} else {
console.log('API key is invalid');
}
});
const setOpenAIKey = key => {
isValidOpenAIKey(key).then(isValid => {
if (isValid) {
console.log('API key is valid');
config.set('openai', key);
} else {
console.log('API key is invalid');
}
});
};

const getOpenAIKey = () => {
return config.get('openai');
}
return config.get('openai');
};

const deleteOPenAIKey = () => {
config.delete('openai');
console.log('OpenAI API key deleted.');
}
config.delete('openai');
console.log('OpenAI API key deleted.');
};

export {setOpenAIKey, getOpenAIKey, deleteOPenAIKey};
Loading