diff --git a/bats/dshlib.c b/bats/dshlib.c
new file mode 100644
index 0000000000000000000000000000000000000000..d8544273d948a1f7cb6db9fb18ab5f783c82290e
--- /dev/null
+++ b/bats/dshlib.c
@@ -0,0 +1,163 @@
+#include "dshlib.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <sys/wait.h>
+
+//---------------------------------------------------------------------
+// Helper: trim_whitespace
+// Removes leading and trailing whitespace from a string.
+static char *trim_whitespace(char *str) {
+    while (isspace((unsigned char)*str))
+        str++;
+    if (*str == '\0')
+        return str;
+    char *end = str + strlen(str) - 1;
+    while (end > str && isspace((unsigned char)*end))
+        end--;
+    *(end + 1) = '\0';
+    return str;
+}
+
+//---------------------------------------------------------------------
+// Helper: parse_cmd_buff
+//
+// Parses the input command line stored in buf into tokens placed into
+// the cmd_buff_t structure. It follows these rules:
+//   - All leading and trailing spaces are removed.
+//   - Duplicate spaces are eliminated outside quoted strings.
+//   - Quoted strings (using double quotes) are treated as a single token,
+//     preserving any spaces within them.
+//
+// This function modifies the input buffer by inserting '\0' terminators.
+// Returns 0 on success and -1 on error.
+static int parse_cmd_buff(char *buf, cmd_buff_t *cb) {
+    cb->argc = 0;
+    char *p = buf;
+
+    while (*p != '\0') {
+        // Skip any spaces.
+        while (*p && isspace((unsigned char)*p))
+            p++;
+        if (*p == '\0')
+            break;
+
+        char *token;
+        if (*p == '\"') { // Quoted token.
+            p++;             // Skip the opening quote.
+            token = p;
+            // Advance until closing quote or end-of-string.
+            while (*p && *p != '\"')
+                p++;
+            if (*p == '\"') {
+                *p = '\0';  // Terminate token.
+                p++;        // Skip the closing quote.
+            }
+        } else { // Non-quoted token.
+            token = p;
+            while (*p && !isspace((unsigned char)*p))
+                p++;
+            if (*p != '\0') {
+                *p = '\0';
+                p++;
+            }
+        }
+        // Store the token if we haven’t exceeded the maximum.
+        if (cb->argc < CMD_ARGV_MAX)
+            cb->argv[cb->argc++] = token;
+        else {
+            fprintf(stderr, "Error: Too many arguments\n");
+            return -1;
+        }
+    }
+    return 0;
+}
+
+//---------------------------------------------------------------------
+// Function: exec_local_cmd_loop
+//
+// Implements the shell’s main loop. It:
+//   - Prompts the user with SH_PROMPT.
+//   - Reads a line of input using fgets().
+//   - Trims all leading/trailing spaces.
+//   - Parses the line into arguments (handling duplicate spaces and quoted strings).
+//   - If the command is EXIT_CMD, the loop exits.
+//   - If the command is "cd", it calls the built-in cd command logic.
+//   - Otherwise, it forks a child process that executes the command using execvp().
+//   - The parent waits for the child process to finish.
+int exec_local_cmd_loop(void) {
+    char input[SH_CMD_MAX];
+    cmd_buff_t cb;
+    
+    // Allocate memory for the raw command buffer.
+    cb._cmd_buffer = malloc(SH_CMD_MAX);
+    if (!cb._cmd_buffer) {
+        perror("malloc");
+        return -1;
+    }
+
+    while (1) {
+        printf("%s", SH_PROMPT);
+
+        if (fgets(input, sizeof(input), stdin) == NULL) {
+            printf("\n");
+            break;
+        }
+        // Remove trailing newline.
+        input[strcspn(input, "\n")] = '\0';
+        // Trim the input.
+        char *trimmed = trim_whitespace(input);
+        if (strcmp(trimmed, EXIT_CMD) == 0)
+            break;
+
+        // Copy the trimmed input into our command buffer.
+        strncpy(cb._cmd_buffer, trimmed, SH_CMD_MAX);
+        cb._cmd_buffer[SH_CMD_MAX - 1] = '\0';
+
+        // Parse the command buffer into tokens.
+        if (parse_cmd_buff(cb._cmd_buffer, &cb) != 0) {
+            fprintf(stderr, "Error parsing command\n");
+            continue;
+        }
+
+        // If no command was entered, print a warning and prompt again.
+        if (cb.argc == 0) {
+            printf("%s", CMD_WARN_NO_CMD);
+            continue;
+        }
+
+        // Built-in cd command:
+        if (strcmp(cb.argv[0], "cd") == 0) {
+            // If no argument, do nothing.
+            if (cb.argc < 2) {
+                /* do nothing */
+            } else if (cb.argc == 2) {
+                if (chdir(cb.argv[1]) != 0)
+                    perror("cd");
+            } else {
+                fprintf(stderr, "cd: too many arguments\n");
+            }
+            continue;
+        }
+
+        // Fork and execute an external command.
+        pid_t pid = fork();
+        if (pid < 0) {
+            perror("fork");
+            continue;
+        }
+        if (pid == 0) { // Child process.
+            cb.argv[cb.argc] = NULL;  // NULL-terminate the argument list.
+            execvp(cb.argv[0], cb.argv);
+            perror("execvp");
+            exit(1);
+        } else { // Parent process.
+            int status;
+            waitpid(pid, &status, 0);
+        }
+    }
+    free(cb._cmd_buffer);
+    return 0;
+}
\ No newline at end of file