diff --git a/.github/workflows/code-quality.yml b/.github/workflows/code-quality.yml
new file mode 100644
index 0000000..763eaf5
--- /dev/null
+++ b/.github/workflows/code-quality.yml
@@ -0,0 +1,25 @@
+name: Code Quality
+
+on: [push, pull_request]
+
+jobs:
+  code-quality:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/checkout@v3
+    
+    - name: Install Rust
+      uses: actions-rs/toolchain@v1
+      with:
+        toolchain: nightly
+        override: true
+        components: clippy, rustfmt
+    
+    - name: Check formatting
+      run: cargo fmt -- --check
+    
+    - name: Run Clippy
+      run: cargo clippy -- -D warnings
+    
+    - name: Compilation Check
+      run: cargo check
\ No newline at end of file
diff --git a/engine/src/core/repl/commands.rs b/engine/src/core/repl/commands.rs
index d41fe5f..4c1a8d9 100644
--- a/engine/src/core/repl/commands.rs
+++ b/engine/src/core/repl/commands.rs
@@ -5,8 +5,9 @@ use parking_lot::Mutex;
 
 use super::COMMAND_LIST;
 use crate::core::repl::exec::evaluate_command;
-const MAX_RECURSION_DEPTH: usize = 500; // increasing this value WILL cause a stack overflow. attempt at your own risk -
-                                        // Caz
+// increasing this value WILL cause a stack overflow
+// attempt at your own risk - Caz
+const MAX_RECURSION_DEPTH: usize = 500;
 
 lazy_static! {
     static ref RECURSION_DEPTH: Mutex<usize> = parking_lot::Mutex::new(0);
diff --git a/engine/src/core/repl/exec.rs b/engine/src/core/repl/exec.rs
index eae0dc9..bda5252 100644
--- a/engine/src/core/repl/exec.rs
+++ b/engine/src/core/repl/exec.rs
@@ -9,9 +9,9 @@ use log::debug;
 use parking_lot::Mutex;
 use regex::Regex;
 use rustyline::{
-    error::ReadlineError, highlight::Highlighter, hint::HistoryHinter, history::DefaultHistory,
-    Cmd, Completer, ConditionalEventHandler, Editor, Event, EventContext, EventHandler, Helper,
-    Hinter, KeyEvent, RepeatCount, Validator,
+    completion::Completer, error::ReadlineError, highlight::Highlighter, hint::HistoryHinter,
+    history::DefaultHistory, Cmd, Completer, ConditionalEventHandler, Editor, Event, EventContext,
+    EventHandler, Helper, Hinter, KeyEvent, RepeatCount, Validator,
 };
 
 use crate::{
@@ -19,8 +19,44 @@ use crate::{
     utils::logger::LOGGER,
 };
 
+struct CommandCompleter;
+impl CommandCompleter {
+    fn new() -> Self {
+        CommandCompleter {}
+    }
+}
+
+impl Completer for CommandCompleter {
+    type Candidate = String;
+
+    fn complete(
+        &self,
+        line: &str,
+        pos: usize,
+        _ctx: &rustyline::Context<'_>,
+    ) -> rustyline::Result<(usize, Vec<Self::Candidate>)> {
+        let binding = COMMAND_LIST.commands.read();
+        let filtered_commands: Vec<_> = binding
+            .iter()
+            .filter(|command| command.name.starts_with(line))
+            .collect();
+
+        let completions: Vec<String> = filtered_commands
+            .iter()
+            .filter(|command| command.name.starts_with(&line[..pos]))
+            .map(|command| command.name[pos..].to_string())
+            .collect();
+        Ok((pos, completions))
+    }
+}
+
 #[derive(Completer, Helper, Hinter, Validator)]
-struct MyHelper(#[rustyline(Hinter)] HistoryHinter);
+struct MyHelper {
+    #[rustyline(Hinter)]
+    hinter: HistoryHinter,
+    #[rustyline(Completer)]
+    completer: CommandCompleter,
+}
 
 impl Highlighter for MyHelper {
     fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
@@ -142,6 +178,11 @@ fn tokenize(command: &str) -> Vec<String> {
     tokens
 }
 
+pub fn parse_command(input: &str) -> anyhow::Result<Vec<String>> {
+    let pattern = Regex::new(r"[;|\n]").unwrap();
+    let commands: Vec<String> = pattern.split(input).map(|s| String::from(s)).collect();
+    Ok(commands)
+}
 pub fn evaluate_command(input: &str) -> anyhow::Result<()> {
     if input.trim().is_empty() {
         println!("Empty command, skipping. type 'help' for a list of commands.");
@@ -176,7 +217,10 @@ pub fn evaluate_command(input: &str) -> anyhow::Result<()> {
 
 pub async fn handle_repl() -> anyhow::Result<()> {
     let mut rl = Editor::<MyHelper, DefaultHistory>::new()?;
-    rl.set_helper(Some(MyHelper(HistoryHinter::new())));
+    rl.set_helper(Some(MyHelper {
+        hinter: HistoryHinter::new(),
+        completer: CommandCompleter::new(),
+    }));
 
     rl.bind_sequence(
         KeyEvent::from('`'),
diff --git a/engine/src/core/repl/mod.rs b/engine/src/core/repl/mod.rs
index 6a935bc..698eb82 100644
--- a/engine/src/core/repl/mod.rs
+++ b/engine/src/core/repl/mod.rs
@@ -26,8 +26,22 @@ pub struct Command {
     function: Callable,
     pub arg_count: u8,
 }
-
+#[allow(private_interfaces)]
 impl Command {
+    pub fn new(
+        name: &'static str,
+        description: Option<&'static str>,
+        function: Callable,
+        arg_count: Option<u8>,
+    ) -> Self {
+        Command {
+            name,
+            description,
+            function,
+            arg_count: arg_count.unwrap_or(0),
+        }
+    }
+
     pub fn execute(&self, args: Option<Vec<String>>) -> anyhow::Result<()> {
         match &self.function {
             Callable::Simple(f) => {
@@ -69,21 +83,63 @@ pub struct CommandList {
     pub aliases: RwLock<HashMap<String, String>>,
 }
 
-fn check_similarity(target: &str, strings: &[String]) -> Option<String> {
-    strings
-        .iter()
-        .filter(|s| target.chars().zip(s.chars()).any(|(c1, c2)| c1 == c2))
-        .min_by_key(|s| {
-            let mut diff_count = 0;
-            for (c1, c2) in target.chars().zip(s.chars()) {
-                if c1 != c2 {
-                    diff_count += 1;
-                }
+fn hamming_distance(a: &str, b: &str) -> Option<usize> {
+    if a.len() != b.len() {
+        return None;
+    }
+    Some(
+        a.chars()
+            .zip(b.chars())
+            .filter(|(char_a, char_b)| char_a != char_b)
+            .count(),
+    )
+}
+
+fn edit_distance(a: &str, b: &str) -> usize {
+    let m = a.len();
+    let n = b.len();
+
+    let mut dp = vec![vec![0; n + 1]; m + 1];
+
+    for i in 0..=m {
+        for j in 0..=n {
+            if i == 0 {
+                dp[i][j] = j;
+            } else if j == 0 {
+                dp[i][j] = i;
+            } else if a.chars().nth(i - 1) == b.chars().nth(j - 1) {
+                dp[i][j] = dp[i - 1][j - 1];
+            } else {
+                dp[i][j] = 1 + dp[i - 1][j - 1].min(dp[i - 1][j]).min(dp[i][j - 1]);
             }
-            diff_count += target.len().abs_diff(s.len());
-            diff_count
-        })
-        .cloned()
+        }
+    }
+
+    dp[m][n]
+}
+
+fn check_similarity(target: &str, strings: &[String]) -> Option<String> {
+    let max_hamming_distance: usize = 2;
+    let max_edit_distance: usize = 2;
+    let mut best_match: Option<String> = None;
+    let mut best_distance = usize::MAX;
+
+    for s in strings {
+        if let Some(hamming_dist) = hamming_distance(target, s) {
+            if hamming_dist <= max_hamming_distance && hamming_dist < best_distance {
+                best_distance = hamming_dist;
+                best_match = Some(s.clone());
+            }
+        } else {
+            let edit_dist = edit_distance(target, s);
+            if edit_dist <= max_edit_distance && edit_dist < best_distance {
+                best_distance = edit_dist;
+                best_match = Some(s.clone());
+            }
+        }
+    }
+
+    best_match
 }
 
 impl CommandList {
@@ -153,6 +209,13 @@ impl CommandList {
                     );
                     Ok(())
                 }
+                (expected, None) => {
+                    eprintln!(
+                        "Command: '{}' expected {} arguments but received none",
+                        name, expected
+                    );
+                    Ok(())
+                }
                 (_, _) => command.execute(args),
             }
         } else {
@@ -172,7 +235,10 @@ impl CommandList {
                     eprintln!("Did you mean: '{}'?", similar.green().italic().bold());
                     Ok(())
                 }
-                None => Ok(()),
+                None => {
+                    println!("Type 'help' for a list of commands");
+                    Ok(())
+                }
             }
         }
     }
diff --git a/engine/src/main.rs b/engine/src/main.rs
index 4b2dc0e..767db02 100644
--- a/engine/src/main.rs
+++ b/engine/src/main.rs
@@ -1,5 +1,4 @@
 #![deny(clippy::unwrap_in_result)]
-
 use anyhow::Result;
 use log::LevelFilter;
 use plugin_api::plugin_imports::*;
diff --git a/engine/src/utils/logger.rs b/engine/src/utils/logger.rs
index b927556..765f0e8 100644
--- a/engine/src/utils/logger.rs
+++ b/engine/src/utils/logger.rs
@@ -30,7 +30,6 @@ impl DynamicLogger {
     pub fn write_to_file(&self, file_path: &str) {
         let file = OpenOptions::new()
             .create(true)
-            
             .append(true)
             .open(file_path)
             .expect("Failed to open log file");
diff --git a/subcrates/zephyr/src/lib.rs b/subcrates/zephyr/src/lib.rs
index b93cf3f..8b13789 100644
--- a/subcrates/zephyr/src/lib.rs
+++ b/subcrates/zephyr/src/lib.rs
@@ -1,14 +1 @@
-pub fn add(left: u64, right: u64) -> u64 {
-    left + right
-}
 
-#[cfg(test)]
-mod tests {
-    use super::*;
-
-    #[test]
-    fn it_works() {
-        let result = add(2, 2);
-        assert_eq!(result, 4);
-    }
-}
diff --git a/test.zensh b/test.zensh
index 0fbb7d4..f7725fc 100644
--- a/test.zensh
+++ b/test.zensh
@@ -1,4 +1,11 @@
-echo ping
-echo pong
-exec test.zensh
-break
\ No newline at end of file
+
+
+
+
+
+
+
+
+
+echo "Hello World"
+echo "hello world"; hello
\ No newline at end of file