Repository: sirji-ai/sirji (language: python)

Issue:
Content reading



Discussion / hints:

Fix patch:
diff --git a/.gitignore b/.gitignore
index baab043e..4206ad2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,3 @@
-workspace
-
 # Bytecode files generated by Python
 __pycache__/
 *.pyc
@@ -26,6 +24,4 @@ dist
 .pytest_cache
 
 # Dev scripts
-read_all.py
-
-.sirji
\ No newline at end of file
+read_all.py
\ No newline at end of file
diff --git a/README.md b/README.md
index 44cbff74..64827d69 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 </p>
 
 <p align="center">
-  <em>Sirji is an Open Source AI Software Development Agent.</em>
+  <em>Sirji is an agentic AI framework for software development.</em>
 </p>
 
 <p align="center">
@@ -24,25 +24,28 @@
 
 ## Sirji
 
-Sirji is an agentic AI framework that helps developers solve software problems faster. These problems can range from building greenfield web applications to resolving GitHub issues, writing test cases, generating documentation, conducting code reviews, and much more.
+Sirji as an open-source framework where various AI agents collaborate via a messaging protocol to solve a given software problem. Problems range from building greenfield web apps to solving GitHub issues, writing test cases, and generating documentation.
 
-Right now, we have implemented Sirji as a VS Code extension. It lives where developers work. It provides an interactive chat interface, through which you can submit your problem statement and provide feedback. It takes advantage of the capabilities of VS Code, including the Editor, Terminal, and Project Explorer.
+Sirji uses either the standard or user-generated recipe, that lists prescribed tasks and tips for solving a particular problem. Recipe also indicates which agent should perform each task.
 
-Additionally, Sirji sets up your local or remote development environment by installing system-level packages and programming language-specific dependencies. It also executes the generated code in your local or remote development environment.
+An Agent in the Sirji framework is a modular AI component that performs a specific task based on a custom pseudo code. The community can create a custom agent either by modifying an already existing agent or write entirely new agent with entirely different pseudo code.
 
-In the next release, we will be making Sirji extendable, building it as a framework where the community can write custom agents having specialized skills, which would generate better results than a generic agent.
+Sirji is currently implemented as a Visual Studio Code extension. This extension provides an interactive chat interface right within your IDE through which you can submit your problem statement and give feedback to Sirji.
 
-## Why Do Developers Need Sirji?
+The extension leverages the capabilities of VS Code, including the Editor, Terminal, and Project Explorer.
 
-As developers, we aim to dedicate more time to high-impact activities, such as understanding requirements, finalizing architecture, and designing database schemas. We also strive to liberate ourselves from writing routine code—like models, migrations, and routes—and from the ongoing task of keeping test cases and documentation up to date.
+Additionally, Sirji sets up your local or remote development environment by installing system-level packages and programming language-specific dependencies. It executes the generated code in your local or remote development environment.
 
-When adopting a new tech stack, it often takes time to familiarize ourselves with its concepts. Moreover, we frequently encounter runtime issues, such as missing packages or modules and errors that, while typically simple to resolve, are time-consuming.
+## Prerequisites
 
-We are enthusiastic users and fans of GitHub Copilot, which assists us in writing code and resolving issues. However, Copilot’s contextual awareness is quite limited. To use it, we must first open the specific code file requiring changes and then activate Copilot. This becomes cumbersome in large projects spanning multiple repositories, particularly if developers are unsure where to begin. Additionally, Copilot is limited to the context of the current file, unless other files are explicitly mentioned in the comments.
+Make sure you have installed all of the following prerequisites on your machine:
 
-Furthermore, Copilot does not facilitate the process of getting code to run on our machines, which can require considerable effort and distract from more impactful tasks.
+- Visual Studio Code (>= 1.80.2)
+- Node.js (>= 18) and npm (>= 8.19)
+- Python (>= 3.10) - Make sure `python --version` runs without error.
+- tee command - Make sure `which tee` runs without error.
 
-These are all the problems and limitations we want to solve with Sirji, and in the process, build something that we will use ourselves.
+Also, you will need an OpenAI API key to access the GPT-4o model.
 
 ## Demo Video
 
@@ -52,48 +55,75 @@ Watch on YouTube: <a href="https://www.youtube.com/watch?v=r1wJHLUDVTo" target="
 
 <a href="https://www.youtube.com/watch?v=r1wJHLUDVTo" target="_blank"><img src="https://github.com/sirji-ai/sirji/assets/7627517/a21804a7-06d5-4974-ae94-bb72870b93fd" alt="Tic Tac Toe game by Sirji"></a>
 
-## Prerequisites
+## Installation
 
-Sirji has been tested on **macOS** only for now. We know there are certain OS-specific functionalities that we will soon generalize ([Issue #44](https://github.com/sirji-ai/sirji/issues/44)).
+You can start using Sirji by installing this [extension](https://marketplace.visualstudio.com/items?itemName=TrueSparrow.sirji) from the Visual Studio Marketplace.
 
-Make sure you have installed all of the following prerequisites on your machine:
+## Architecture
 
-- Visual Studio Code (>= 1.80.2)
-- Node.js (>= 18) and npm (>= 8.19)
-- Python (>= 3.10) - Make sure `python --version` runs without error.
-- tee command - Make sure `which tee` runs without error.
+Let's go step by step in understanding the architecture.
 
-Also, you will need an OpenAI API key to access the GPT-4 Turbo model.
+### Agent
 
-## Installation
+An Agent in the Sirji framework is a modular AI component that performs a specific task based on a custom pseudo code.
 
-You can start using Sirji by installing this [extension](https://marketplace.visualstudio.com/items?itemName=TrueSparrow.sirji) from the Visual Studio Marketplace.
+An agent defines its skills in an agent.yml file. This file lists the skills of the agent and the pseudo code to follow for each skill. It also specifies the LLM provider and model to be used for inference. Additionally, it lists the sub-agents that can be invoked from within the agent to complete certain parts of the task.
 
-## Architecture
+### Recipe (recipe.json)
 
-Sirji gets the work done using it's following agents:
+A Recipe is a file that lists prescribed tasks and tips for solving a particular problem. It also indicates which agent should perform each task. The tips provide guidance for addressing issues that arise when tasks are performed out of the prescribed order. Each tip specifies the task and the agent responsible for it.
 
-- The **Planning Agent** takes a problem statement and breaks it down into steps.
-- The **Coding Agent** proceeds step by step through the generated steps to solve the problem programmatically.
-- The **Research Agent** utilizes RAG (Retrieval-Augmented Generation) and gets trained on URLs and search terms. It can later use this acquired knowledge to answer questions posed by the Coding Agent.
-- The **Executor Agent** is responsible for Filesystem CRUD, executing commands, and installing dependencies. The Executor Agent is implemented directly within the extension and is written in TypeScript.
+### Orchestrator
 
-### Architecture Diagram
+The Orchestrator is the central component in the Sirji framework, responsible for managing the flow and execution of tasks across different agents as per the recipe.
+
+### Agent Sessions
+An agent can be invoked in either a fresh session or asked to continue an existing session. When invoked in a new session, it starts with a new system prompt and does not retain the context from the previous session. Sessions help keep the context focused on specific tasks.
 
-<img width="100%" alt="VS Code Extension - Architecture" src="https://github.com/sirji-ai/sirji/assets/7627517/0cee6e34-a42a-4db0-81db-d2f930132465">
+### Messaging Protocol
+The messaging protocol defines how the response from an LLM inference for an agent should appear. It specifies the recipient-specific allowed Response Templates. These Response Templates also adhere to an interface that mandates the presence of keys: FROM, TO, BODY, SUMMARY, and ACTION. The BODY may contain an ACTION-specific information schema.
+
+### Project Folder
+The Project Folder is the primary directory for accessing all user-specific project files, including code files, documentation, and other relevant resources. When initializing Sirji, the user selects this folder as the primary workspace for the project.
+
+### Agent Output Folder
+The Agent Output Folder is designated for storing the results and data outputs generated by the agents. This folder is different from the project folder and this ensures that operational data is kept separate from project files.
+
+#### Agent Output Index
+The Agent Output Index is an index file for the Agent Output Folder that keeps track of all files written by agents in that folder along with the a brief description of the file contents.
 
 ### PyPI Packages
 
-The Planning Agent, Coding Agent, and Research Agent are developed within the Python package [`sirji-agents`](https://pypi.org/project/sirji-agents/) (located in the `agents` folder of this monorepo). <a href="https://pypi.org/project/sirji-agents/"><img src="https://img.shields.io/pypi/v/sirji-agents.svg" alt="Sirji Agents on PyPI" height="15"></a>
+We have published following 3 PyPI packages, implementing different responsibilities. These packages are invoked by Python Adapter Scripts, which are spawned by the extension.
+
+#### sirji-agents <a href="https://pypi.org/project/sirji-agents/"><img src="https://img.shields.io/pypi/v/sirji-agents.svg" alt="Sirji Agents on PyPI" height="15"></a>
 
-Communication among these agents is facilitated through a defined message protocol. The Message Factory (responsible for creating, reading, updating, and deleting messages according to the message protocol) and the permissions matrix are developed in the Python package [`sirji-messages`](https://pypi.org/project/sirji-messages/) (located in the `messages` folder of this monorepo).<a href="https://pypi.org/project/sirji-messages/"><img src="https://img.shields.io/pypi/v/sirji-messages.svg" alt="Sirji Messages on PyPI" height="15"></a>
+[`sirji-agents`](https://pypi.org/project/sirji-agents/) (located in the `agents` folder of this monorepo) is a PyPI package that implements the following components of the Sirji AI agentic framework:
+- **Orchestrator**: The Orchestrator is the central component in the Sirji framework, responsible for managing the flow and execution of tasks across different agents.
+- **Generic Agent**: Run time composable class providing the agent functionality as per the pseudo code provided in the agent.yml file.
+- **Research Agent**: Utilizes RAG (Retrieval-Augmented Generation) and gets trained on URLs and search terms.
 
-The tools for crawling URLs (converting them into markdowns), searching for terms on Google, and a custom logger are developed within the Python package [`sirji-tools`](https://pypi.org/project/sirji-tools/) (located in the `tools` folder of this monorepo). <a href="https://pypi.org/project/sirji-tools/"><img src="https://img.shields.io/pypi/v/sirji-tools.svg" alt="Sirji Tools on PyPI" height="15"></a>
+#### sirji-messages <a href="https://pypi.org/project/sirji-messages/"><img src="https://img.shields.io/pypi/v/sirji-messages.svg" alt="Sirji Messages on PyPI" height="15"></a>
 
-All these packages are invoked by Python Adapter Scripts, which are spawned by the extension.
+[`sirji-messages`](https://pypi.org/project/sirji-messages/) (located in the `messages` folder of this monorepo) is a PyPI package that implements the Sirji messaging protocol with the following highlights:
+- **Message Factory**: A factory that provides a Message class for a given action.
+- **Message Parser**: Parse structured message strings into Python dictionaries for easy access to the message components.
+- **Allowed Response Templates**: Provides the part of the system prompt describing allowed Response Templates for a given agent pair.
+- **Custom Exceptions**: A set of custom exceptions thrown by the message parser.
+- **Enums for Agents and Actions**: Provides easy auto-completion while writing code.
+
+#### sirji-tools <a href="https://pypi.org/project/sirji-tools/"><img src="https://img.shields.io/pypi/v/sirji-tools.svg" alt="Sirji Tools on PyPI" height="15"></a>
+
+[`sirji-tools`](https://pypi.org/project/sirji-tools/) (located in the `tools` folder of this monorepo) implements these tools:
+- Crawling (downloading web pages to markdown files)
+- Searching on Google
+- Custom Logging
+
+### Architecture Diagram
+![Sirji - Architecture Diagram](https://github.com/sirji-ai/sirji/assets/7627517/9068c6d1-a11b-4589-b09e-ad494334fd6b)
 
 ## Roadmap
-We are calling our next release the ‘Core’ Release (ONGOING. ETA - May 20).
+We are calling our next release the ‘Core’ Release (ONGOING).
 
 Here is the link to the ‘Core’ release’s roadmap: https://github.com/orgs/sirji-ai/projects/5
 
@@ -102,9 +132,6 @@ This is a significant release focused on the following key areas:
 - **Improve reliability**: The first version of the VS Code extension improved usability, but after using it ourselves for a while, we identified several issues and limitations ranging from incomplete solutions to a lack of web debugging capabilities. We are addressing these issues to make Sirji more reliable in solving software problems.
 - **Custom agents and recipes**: We are developing the framework to enable users to create and use custom agents and recipes (instructions on how the agents interact). This involves enhancing the orchestration functionality and refactoring existing base agents.
 
-### Architecture Diagram (Post Core Release)
-![Sirji - Architecture Diagram](https://github.com/sirji-ai/sirji/assets/7627517/9068c6d1-a11b-4589-b09e-ad494334fd6b)
-
 ## Contributing
 
 We welcome contributions to Sirji! If you're interested in helping improve this VS Code extension, please take a look at our [Contributing Guidelines](./CONTRIBUTING.md) for more information on how to get started.
diff --git a/agents/README.md b/agents/README.md
index bdc4367e..b66f1a8c 100644
--- a/agents/README.md
+++ b/agents/README.md
@@ -3,7 +3,7 @@
 </p>
 
 <p align="center">
-  <em>Sirji is an Open Source AI Software Development Agent.</em>
+  <em>Sirji is an agentic AI framework for software development.</em>
 </p>
 
 <p align="center">
@@ -25,19 +25,15 @@
 
 ## Sirji Agents
 
-`sirji-agents` is a PyPI package that implements three key agents for Sirji:
-
-- Coding Agent
-- Planning Agent
-- Research Agent
-
-It Utilizes:
+`sirji-agents` is a PyPI package that implements the following components of the Sirji AI agentic framework:
+- **Orchestrator**: The Orchestrator is the central component in the Sirji framework, responsible for managing the flow and execution of tasks across different agents.
+- **Generic Agent**: Run time composable class providing the agent functionality as per the pseudo code provided in the agent.yml file.
+- **Research Agent**: Utilizes RAG (Retrieval-Augmented Generation) and gets trained on URLs and search terms.
 
+By default, it utilizes:
 - OpenAI Chat Completions API
 - OpenAI Assistants API
 
-This package communicates with models and RAG assistants.
-
 ## Installation
 
 ### Setup Virtual Environment
@@ -67,19 +63,118 @@ playwright install
 
 ### Environment Variables
 
-Ensure that following environment variables are set:
+Ensure that the following environment variables are set:
 
 ```zsh
-export SIRJI_WORKSPACE="Absolute folder path for Sirji to use as it's workspace. Note that a .sirji folder will be created inside it."
-export SIRJI_RUN_ID='Unique alphanumeric ID for each run. Note that a sub folder named by this ID will be created inside of .sirji folder to store logs, etc.'
+export SIRJI_PROJECT="Absolute folder path for Sirji to use as its project folder."
+export SIRJI_INSTALLATION_DIR='Absolute path of the Sirji installation directory.'
+export SIRJI_RUN_PATH='Folder path containing run related logs, etc.'
 export SIRJI_OPENAI_API_KEY='OpenAI API key for Chat Completions API and Assistants API'
-export SIRJI_MODEL_PROVIDER='Model Provider to be used for LLM inference. Defaults to "openai"'
-export SIRJI_MODEL='Model to be used for LLM inference. Defaults to "gpt-4-turbo"'
-export SIRJI_MODEL_PROVIDER_API_KEY='API key to be use for LLM inference'
+export SIRJI_MODEL_PROVIDER='Model Provider to be used for LLM inference. Defaults to "openai".'
+export SIRJI_MODEL='Model to be used for LLM inference. Defaults to "gpt-4o".'
+export SIRJI_MODEL_PROVIDER_API_KEY='API key to be used for LLM inference.'
+```
+
+### Orchestrator
+
+The Orchestrator is the central component in the Sirji framework, responsible for managing the flow and execution of tasks across different agents.
+
+```python
+# Following is a sample recipe
+recipe = {
+  "prescribed_tasks": [
+    {
+      "task": "Write epics and user stories.",
+      "agent": "PRODUCT_MANAGER"
+    },
+    {
+      "task": "Write architecture components.",
+      "agent": "ARCHITECT"
+    },
+    {
+      "task": "Implement the epic & user stories using the architecture components.",
+      "agent": "CODER"
+    }
+  ],
+  "tips": [
+    {
+      "deviation": "Architecture components are not in sync with the epics and user stories.",
+      "agent": "PRODUCT_MANAGER",
+      "task": "Make the epics and user stories consistent with the architecture components."
+    }
+  ]
+}
+
+from sirji_agents import Orchestrator
+
+agent = Orchestrator(recipe)
+
+# History is the array of LLM conversations till now
+history = []
+
+# Input message string
+message_str = ""
+response_message, history, prompt_tokens, completion_tokens = agent.message(message_str, history)
+```
+
+### Generic Agent
+
+Run time composable class providing the agent functionality as per the pseudo code provided in the agent.yml file.
+
+```python
+# Convert the agent.yml file to a Python dictionary
+config = {
+  "id": "CODER",
+  "name": "Coding Agent",
+  "llm": {
+    "provider": "openai",
+    "model": "gpt-4o"
+  },
+  "skills": [
+    {
+      "skill": "Developing end-to-end working code for the epic & user stories, making use of the finalized architecture components.",
+      "sub_tasks": [
+        "Read problem statement, epics & user stories and architecture components from agent output folder.",
+        "Write concrete code and not just conceptualize or outline or simulate it.",
+        "Follow secure software development practices while generating code.",
+        "Ensure that you don't create any file/folder outside of project folder, i.e. './'",
+        "Install programming language-specific packages or libraries in local folders, utilizing tools such as venv for installing Python dependencies and package.json for managing Node.js dependencies.",
+        "Verify whether a system-level command is already installed to avoid triggering the installation of packages that are already in place.",
+        "Always execute the code and evaluate the response output. If the response has errors, solve them before moving ahead."
+      ]
+    }
+  ]
+}
+
+agent_output_folder_index = {
+  "SIRJI/problem.txt": {
+    "description": "Problem statement from the user.",
+    "created_by": "SIRJI"
+  },
+  "PRODUCT_MANAGER/finalized_epics_user_stories.txt": {
+    "description": "Finalized Epics and User Stories for the Tic-Tac-Toe game with AI opponent.",
+    "created_by": "PRODUCT_MANAGER"
+  },
+  "ARCHITECT/finalized_architecture_components.txt": {
+    "description": "Finalized architecture components for the Tic-Tac-Toe game with AI opponent.",
+    "created_by": "ARCHITECT"
+  }
+}
+
+from sirji_agents import GenericAgent
+
+agent = GenericAgent(config, agent_output_folder_index)
+
+history = []
+message_str = "***\nFROM: ORCHESTRATOR\nTO: CODER\nACTION: INVOKE_AGENT\nSUMMARY: Implement the epic & user stories using the architecture components.\nBODY:\nPImplement the epic & user stories using the architecture components.\n***"
+
+response_message, history, prompt_tokens, completion_tokens = agent.message(message_str, history)
 ```
 
 ### Research Agent
 
+The Research Agent utilizes RAG (Retrieval-Augmented Generation) and gets trained on URLs and search terms.
+
 ### Initialization
 
 ```python
@@ -103,7 +198,16 @@ Some example message handling usages are given below.
 from sirji_messages import MessageFactory, ActionEnum
 
 message_class = MessageFactory[ActionEnum.TRAIN_USING_URL.name]
-message_str = message_class().generate({"url": "https://finance.yahoo.com/quote/API/"})
+
+body = {
+    "URL": "https://www.w3schools.com/python/python_json.asp"
+}
+
+message_str = message_class().generate({
+            "from_agent_id": "Id of the agent, who is invoking the action",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": body
+        })
 
 researcher.message(message_str)
 ```
@@ -114,60 +218,16 @@ researcher.message(message_str)
 from sirji_messages import MessageFactory, ActionEnum
 
 message_class = MessageFactory[ActionEnum.INFER.name]
-message_str = message_class().generate({"details": "How to use yahoo finance api?"})
-
+infer_query = "What is the capital of India?"
+message_str = message_class().generate({
+            "from_agent_id": "Id of the agent, who is invoking the action",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": infer_query
+        })  
+        
 response, total_tokens = researcher.message(message_str)
 ```
 
-### Coding Agent
-
-```python
-from sirji_agents import CodingAgent
-
-# Initialize Coding Agent
-coder = CodingAgent()
-
-# Construct a message for problem statement
-from sirji_messages import MessageFactory, ActionEnum
-message_class = MessageFactory[ActionEnum.PROBLEM_STATEMENT.name]
-message_str = message_class().generate({"details": "Create a python executable file to find out the factorial of a number"})
-
-# At the beginning, history is empty
-coder_history = []
-
-# call the Coder and update the history variable
-response_message, coder_history, prompt_tokens, completion_tokens = coder.message(message_str, coder_history)
-
-# Now in the new history:
-# coder_history[0] is the system prompt
-# coder_history[1] is the message from User to Coder passing the problem statement
-# coder_history[2] is the response from the LLM inference
-
-# Persist the history variable for future use.
-```
-
-### Planning Agent
-
-```python
-from sirji_agents import PlanningAgent
-
-# Initialize Planning Agent
-planner = PlanningAgent()
-
-# Construct a message for generate steps message
-from sirji_messages import MessageFactory, ActionEnum
-message_class = MessageFactory[ActionEnum.GENERATE_STEPS.name]
-message_str = message_class().generate({"details": "Create a python executable file to find out the factorial of a number"})
-
-# In the actual flow, this message_str will be obtained as a response from Coder.
-
-# At the beginning, history is empty
-planner_history = []
-
-# call the Planner and update the history variable
-response_message, planner_history, prompt_tokens, completion_tokens = planner.message(message_str, planner_history)
-```
-
 ## For Contributors
 
 1. Fork and clone the repository.
@@ -187,7 +247,7 @@ playwright install
 
 ## Running Tests and Coverage Analysis
 
-TODO
+TODO - Introduce test cases.
 
 ## License
 
diff --git a/agents/requirements.txt b/agents/requirements.txt
index 0ba0059b..ef0f2ce9 100644
--- a/agents/requirements.txt
+++ b/agents/requirements.txt
@@ -1,3 +1,3 @@
-sirji-messages==0.0.14
-sirji-tools==0.0.9
+sirji-messages==0.0.18
+sirji-tools==0.0.12
 openai==1.14.1
diff --git a/agents/setup.py b/agents/setup.py
index 4a06225d..15eeb459 100644
--- a/agents/setup.py
+++ b/agents/setup.py
@@ -2,9 +2,9 @@
 
 setup(
     name='sirji-agents',
-    version='0.0.21',
+    version='0.0.26',
     author='Sirji',
-    description='Research, Coding and Planning agents used by Sirji.',
+    description='Orchestrator, Generic Agent, and Research Agent components of the Sirji AI agentic framework.',
     license='MIT',
     long_description=open('README.md').read(),
     long_description_content_type='text/markdown',
diff --git a/agents/sirji_agents/__init__.py b/agents/sirji_agents/__init__.py
index 3ec41b9c..bc72bbaa 100644
--- a/agents/sirji_agents/__init__.py
+++ b/agents/sirji_agents/__init__.py
@@ -1,10 +1,9 @@
 from .researcher import ResearchAgent
-from .llm.coder import CodingAgent
-from .llm.planner import PlanningAgent
-
+from .llm.orchestrator import Orchestrator
+from .llm.generic import GenericAgent
 
 __all__ = [
     'ResearchAgent',
-    'CodingAgent',
-    'PlanningAgent'
+    'Orchestrator',
+    'GenericAgent'
 ]
diff --git a/agents/sirji_agents/llm/base.py b/agents/sirji_agents/llm/base.py
deleted file mode 100644
index 595e4c7f..00000000
--- a/agents/sirji_agents/llm/base.py
+++ /dev/null
@@ -1,89 +0,0 @@
-from openai import OpenAI
-import os
-
-from sirji_messages import AgentSystemPromptFactory, message_parse, MessageParsingError, MessageValidationError
-from .model_providers.factory import LLMProviderFactory 
-
-class SingletonMeta(type):
-    """Singleton Meta Class for ensuring one instance creation."""
-    _instances = {}
-
-    def __call__(cls, *args, **kwargs):
-        if cls not in cls._instances:
-            cls._instances[cls] = super().__call__(*args, **kwargs)
-        return cls._instances[cls]
-
-
-class LLMAgentBase(metaclass=SingletonMeta):
-    def __init__(self, agent_enum, logger):
-        
-        self.agent_enum = agent_enum
-        self.logger = logger
-
-    def message(self, input_message, history=[]):
-        conversation = self.__prepare_conversation(input_message, history)
-
-        self.logger.info(f"Incoming: \n{input_message}")
-        self.logger.info("Calling OpenAI Chat Completions API\n")
-
-        response_message, prompt_tokens, completion_tokens = self.__get_response(conversation)
-
-        return response_message, conversation, prompt_tokens, completion_tokens
-
-    def __prepare_conversation(self, input_message, history):
-        conversation = []
-
-        if not history:
-            prompt_class = AgentSystemPromptFactory[self.agent_enum.name]
-            conversation.append(
-                {"role": "system", "content": prompt_class().system_prompt()})
-        else:
-            conversation = history
-
-        parsed_input_message = message_parse(input_message)
-        conversation.append({"role": "user", "content": input_message, "parsed_content": parsed_input_message})
-
-        return conversation
-
-    def __get_response(self, conversation):
-        
-        retry_llm_count = 0
-        response_message = ''
-        prompt_tokens = 0
-        completion_tokens = 0
-
-        while(True):
-            response_message, current_prompt_tokens, current_completion_tokens = self.__call_llm(conversation)
-            
-            prompt_tokens += current_prompt_tokens
-            completion_tokens += current_completion_tokens
-            try:
-                # Attempt parsing
-                parsed_response_message = message_parse(response_message)
-                conversation.append({"role": "assistant", "content": response_message, "parsed_content": parsed_response_message})
-                break
-            except (MessageParsingError, MessageValidationError) as e:
-            # Handling both MessageParsingError and MessageValidationError similarly
-                self.logger.info("Error while parsing the message.\n")
-                retry_llm_count += 1
-                if retry_llm_count > 2:
-                    raise e
-                self.logger.info(f"Requesting LLM to resend the message in correct format.\n")
-                conversation.append({"role": "assistant", "content": response_message, "parsed_content": {}})
-                conversation.append({"role": "user", "content": "The last message was not as per the allowed message formats. Please resend it with proper formatting."})
-            except Exception as e:
-                self.logger.info(f"Generic error while parsing message. Error: {e}\n")
-                raise e
-            
-            
-        return response_message, prompt_tokens, completion_tokens
-    
-    def __call_llm(self, conversation):
-        history = []
-
-        for message in conversation:
-            history.append({"role": message['role'], "content": message['content']})
-
-        model_provider = LLMProviderFactory.get_instance()
-
-        return model_provider.get_response(history, self.logger)
diff --git a/agents/sirji_agents/llm/coder.py b/agents/sirji_agents/llm/coder.py
deleted file mode 100644
index 524fb3ab..00000000
--- a/agents/sirji_agents/llm/coder.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from sirji_messages import AgentEnum
-from sirji_tools.logger import c_logger as logger
-
-from .base import LLMAgentBase
-
-
-class CodingAgent(LLMAgentBase):
-    def __init__(self):
-        super().__init__(AgentEnum.CODER, logger)
diff --git a/agents/sirji_agents/llm/generic.py b/agents/sirji_agents/llm/generic.py
new file mode 100644
index 00000000..5ed13637
--- /dev/null
+++ b/agents/sirji_agents/llm/generic.py
@@ -0,0 +1,209 @@
+import textwrap
+import os
+import json
+
+# TODO - log file should be dynamically created based on agent ID
+from sirji_tools.logger import p_logger as logger
+
+from sirji_messages import message_parse, MessageParsingError, MessageValidationError, ActionEnum, AgentEnum, allowed_response_templates
+from .model_providers.factory import LLMProviderFactory
+
+class GenericAgent():
+    def __init__(self, config, agent_output_folder_index, file_summaries=None):
+
+        logger.info('---------inside generic agent-----------')
+        logger.info(config)
+        logger.info(agent_output_folder_index)
+        
+        self.config = config
+        self.agent_output_folder_index = agent_output_folder_index
+        self.file_summaries = file_summaries
+
+    def message(self, input_message, history=[]):
+        conversation = self.__prepare_conversation(input_message, history)
+
+        logger.info(f"Incoming: \n{input_message}")
+        logger.info("Calling OpenAI Chat Completions API\n")
+
+        response_message, prompt_tokens, completion_tokens = self.__get_response(conversation)
+
+        return response_message, conversation, prompt_tokens, completion_tokens
+
+    def __prepare_conversation(self, input_message, history):
+        conversation = []
+
+        if not history:
+            conversation.append(
+                {"role": "system", "content": self.system_prompt()})
+        else:
+            conversation = history
+        
+        parsed_input_message = message_parse(input_message)
+        conversation.append({"role": "user", "content": input_message, "parsed_content": parsed_input_message})
+        
+        return conversation
+
+    def __get_response(self, conversation):
+        retry_llm_count = 0
+        response_message = ''
+        prompt_tokens = 0
+        completion_tokens = 0
+
+        while(True):
+            response_message, current_prompt_tokens, current_completion_tokens = self.__call_llm(conversation)
+            
+            prompt_tokens += current_prompt_tokens
+            completion_tokens += current_completion_tokens
+            try:
+                # Attempt parsing
+                parsed_response_message = message_parse(response_message)
+                conversation.append({"role": "assistant", "content": response_message, "parsed_content": parsed_response_message})
+                break
+            except (MessageParsingError, MessageValidationError) as e:
+            # Handling both MessageParsingError and MessageValidationError similarly
+                logger.info("Error while parsing the message.\n")
+                retry_llm_count += 1
+                if retry_llm_count > 2:
+                    raise e
+                logger.info(f"Requesting LLM to resend the message in correct format.\n")
+                conversation.append({"role": "assistant", "content": response_message, "parsed_content": {}})
+                conversation.append({"role": "user", "content": "Error in processing your last response. Your response must conform strictly to one of the allowed Response Templates, as it will be processed programmatically and only these templates are recognized. Your response must be enclosed within '***' at the beginning and end, without any additional text above or below these markers. Not conforming above rules will lead to response processing errors."})
+            except Exception as e:
+                logger.info(f"Generic error while parsing message. Error: {e}\n")
+                raise e
+            
+            
+        return response_message, prompt_tokens, completion_tokens
+    
+    def __call_llm(self, conversation):
+        history = []
+
+        for message in conversation:
+            history.append({"role": message['role'], "content": message['content']})
+
+        model_provider = LLMProviderFactory.get_instance()
+
+        return model_provider.get_response(history, logger)
+
+    def system_prompt(self):
+        initial_intro = textwrap.dedent(f"""
+            You are an agent named "{self.config['name']}", a component of the Sirji AI agentic framework.
+            Your Agent ID: {self.config['id']}
+            Your OS (refered as SIRJI_OS later): {os.name}""")
+        
+        response_specifications = textwrap.dedent(f"""
+            Your Response:
+            - Your response must conform strictly to one of the allowed Response Templates, as it will be processed programmatically and only these templates are recognized.
+            - Your response must be enclosed within '***' at the beginning and end, without any additional text above or below these markers.
+            - Not conforming above rules will lead to response processing errors.""")
+
+        # Todo: Use action names from ActionEnum
+        understanding_the_folders = textwrap.dedent(f"""
+            Project Folder:
+            - The Project Folder is your primary directory for accessing all user-specific project files, including code files, documentation, and other relevant resources.
+            - When initializing Sirji, the SIRJI_USER selects this folder as the primary workspace for the project. You should refer to this folder exclusively for accessing and modifying project-specific files.
+            
+            Agent Output Folder:
+            - The Agent Output Folder is designated for storing the results and data outputs generated by the agents (like you) of Sirji.
+            - Ensure you do not confuse this folder with the Project Folder; remember, no project source files are stored here.
+            - This folder is different from the project folder and this ensures that operational data is kept separate from project files.
+            
+            Agent Output Index:
+            - The Agent Output Index is an index file for the Agent Output Folder that keeps track of all files written by agents in that folder along with the a brief description of the file contents.""")
+
+        instructions = textwrap.dedent(f"""
+            Instructions:
+            - You have the skill which match with the task's requirements.
+            - Upon being invoked, identify which of your skills match the requirements of the task.
+            - Execute the sub-tasks associated with each of these matching skills.
+            - Do not respond with two actions in the same response. Respond with one action at a time.
+            - Always use CREATE_AGENT_OUTPUT_FILE and READ_AGENT_OUTPUT_FILES to write and read files to and from the agent output folder.                                             
+            """)
+
+        formatted_skills = self.__format_skills()
+        allowed_response_templates_str = textwrap.dedent("""
+            Allowed Response Templates:
+            Below are all the possible allowed "Response Template" formats for each of the allowed recipients. You must always respond using one of them.
+            """)
+        
+        if "sub_agents" in self.config and self.config["sub_agents"]:
+            for sub_agent in self.config["sub_agents"]:
+            
+                allowed_response_templates_str += textwrap.dedent(f"""
+                    Allowed Response Templates to {sub_agent['id']}:
+                    For invoking the {sub_agent['id']}, in a fresh session, use the following response template. Please respond with the following, including the starting and ending '***', with no commentary above or below.
+                    
+                    Response template:
+                    ***
+                    FROM: {{Your Agent ID}}
+                    TO: {sub_agent['id']}
+                    ACTION: INVOKE_AGENT
+                    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+                    BODY:
+                    {{Purpose of invocation.}}
+                    ***""") + '\n'
+                
+                allowed_response_templates_str += textwrap.dedent(f"""
+                    For invoking the {sub_agent['id']}, continuing over the existing session session, use the following response template. Please respond with the following, including the starting and ending '***', with no commentary above or below.
+                    
+                    Response template:
+                    ***
+                    FROM: {{Your Agent ID}}
+                    TO: {sub_agent['id']}
+                    ACTION: INVOKE_AGENT_EXISTING_SESSION
+                    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+                    BODY:
+                    {{Purpose of invocation.}}
+                    ***""") + '\n'
+
+        allowed_response_templates_str += '\n' + allowed_response_templates(AgentEnum.ANY, AgentEnum.SIRJI_USER) + '\n'
+        allowed_response_templates_str += '\n' +  allowed_response_templates(AgentEnum.ANY, AgentEnum.EXECUTOR) + '\n'
+        allowed_response_templates_str += '\n' + allowed_response_templates(AgentEnum.ANY, AgentEnum.CALLER) + '\n'
+    
+        current_agent_output_index = f"Current contents of Agent Output Index:\n{json.dumps(self.agent_output_folder_index, indent=4)}"
+
+        current_project_folder_structure = f"Recursive structure of the project folder:\n{os.environ.get('SIRJI_PROJECT_STRUCTURE')}"
+
+        file_summaries = 'Here are the concise summaries of the responsibilities and functionalities for each file currently present in the project folder:\n'
+        if self.file_summaries is not None:
+            file_summaries += f"File Summaries:\n{self.file_summaries}"
+
+        return f"{initial_intro}\n{response_specifications}{understanding_the_folders}\n{instructions}\n{formatted_skills}\n{allowed_response_templates_str}\n\n{current_agent_output_index}\n\n{current_project_folder_structure}\n\n{file_summaries}".strip()
+    
+    def __format_skills(self):
+        output_text = ""
+        
+        # Check if 'definitions' exists in the config and is not empty
+        if "definitions" in self.config and self.config["definitions"]:
+            output_text += "The definitions to be used for executing sub-tasks of your skills:\n"
+
+            for key, value in self.config["definitions"].items():
+                output_text += f"- {key}: {value}\n"
+        
+            output_text += "\n"
+        
+        # Check if 'rules' exists in the config and is not empty
+        if "rules" in self.config and self.config["rules"]:
+            output_text += "The rules that must be followed for executing sub-tasks of your skills:\n"
+            for rule in self.config["rules"]:
+                output_text += f"- {rule}\n"
+        
+            output_text += "\n"
+
+        output_text += "Here are your skills details:\n\n"
+        
+        # Check if 'skills' exists in the config and is not empty
+        if "skills" in self.config and self.config["skills"]:
+            for skill in self.config["skills"]:
+                output_text += f"Skill: {skill['skill']}\n"
+
+                if "sub_tasks" in skill and skill["sub_tasks"]:
+                    output_text += "Subtasks:\n"
+                    for sub_task in skill["sub_tasks"]:
+                        output_text += f"- {sub_task}\n"
+                    output_text += "\n"
+                elif "pseudo_code" in skill and skill['pseudo_code']:
+                    output_text += f"Pseudo code which you must follow:\n{skill['pseudo_code']}"
+
+        return output_text
+
diff --git a/agents/sirji_agents/llm/model_providers/factory.py b/agents/sirji_agents/llm/model_providers/factory.py
index 45cc6dac..74c68f9f 100644
--- a/agents/sirji_agents/llm/model_providers/factory.py
+++ b/agents/sirji_agents/llm/model_providers/factory.py
@@ -7,13 +7,14 @@ class LLMProviderFactory:
     def get_instance():
         # Reading from environment variables and setting defaults.
         provider_name = os.environ.get('SIRJI_MODEL_PROVIDER', 'openai').lower()
-        model = os.environ.get('SIRJI_MODEL', 'gpt-4-turbo')
+        model = os.environ.get('SIRJI_MODEL', 'gpt-4o')
         api_key = os.environ.get('SIRJI_MODEL_PROVIDER_API_KEY', os.environ.get('SIRJI_OPENAI_API_KEY'))
 
         if not api_key:
             raise EnvironmentError("SIRJI_MODEL_PROVIDER_API_KEY is not set in environment variables.")
         
         if provider_name == 'openai':
+            print('Model used:', model)
             return OpenAIProvider(api_key, model)
         else:
             raise ValueError(f"Unsupported LLM provider: {provider_name}")
\ No newline at end of file
diff --git a/agents/sirji_agents/llm/orchestrator.py b/agents/sirji_agents/llm/orchestrator.py
new file mode 100644
index 00000000..3036ab70
--- /dev/null
+++ b/agents/sirji_agents/llm/orchestrator.py
@@ -0,0 +1,119 @@
+import textwrap
+import os
+
+# TODO - log file should be dynamically created based on agent ID
+from sirji_tools.logger import p_logger as logger
+
+from sirji_messages import message_parse, MessageParsingError, MessageValidationError, ActionEnum, AgentEnum, allowed_response_templates
+from .model_providers.factory import LLMProviderFactory
+
+class Orchestrator():
+    def __init__(self, recipe):
+        
+        self.recipe = recipe
+
+    def message(self, input_message, history=[]):
+        conversation = self.__prepare_conversation(input_message, history)
+
+        logger.info(f"Incoming: \n{input_message}")
+        logger.info("Calling OpenAI Chat Completions API\n")
+
+        response_message, prompt_tokens, completion_tokens = self.__get_response(conversation)
+
+        return response_message, conversation, prompt_tokens, completion_tokens
+
+    def __prepare_conversation(self, input_message, history):
+        conversation = []
+
+        logger.info(history)
+
+        if not history:
+            conversation.append(
+                {"role": "system", "content": self.system_prompt()})
+        else:
+            conversation = history
+            parsed_input_message = message_parse(input_message)
+            conversation.append({"role": "user", "content": input_message, "parsed_content": parsed_input_message})
+
+        return conversation
+
+    def __get_response(self, conversation):
+        retry_llm_count = 0
+        response_message = ''
+        prompt_tokens = 0
+        completion_tokens = 0
+
+        while(True):
+            response_message, current_prompt_tokens, current_completion_tokens = self.__call_llm(conversation)
+            
+            prompt_tokens += current_prompt_tokens
+            completion_tokens += current_completion_tokens
+            try:
+                # Attempt parsing
+                parsed_response_message = message_parse(response_message)
+                conversation.append({"role": "assistant", "content": response_message, "parsed_content": parsed_response_message})
+                break
+            except (MessageParsingError, MessageValidationError) as e:
+            # Handling both MessageParsingError and MessageValidationError similarly
+                logger.info("Error while parsing the message.\n")
+                retry_llm_count += 1
+                if retry_llm_count > 2:
+                    raise e
+                logger.info(f"Requesting LLM to resend the message in correct format.\n")
+                conversation.append({"role": "assistant", "content": response_message, "parsed_content": {}})
+                conversation.append({"role": "user", "content": "Error obtained in processing your last response. Your response must conform strictly to one of the allowed Response Templates, as it will be processed programmatically and only these templates are recognized. Your response must be enclosed within '***' at the beginning and end, without any additional text above or below these markers. Not conforming above rules will lead to response processing errors."})
+            except Exception as e:
+                logger.info(f"Generic error while parsing message. Error: {e}\n")
+                raise e
+            
+            
+        return response_message, prompt_tokens, completion_tokens
+    
+    def __call_llm(self, conversation):
+        history = []
+
+        for message in conversation:
+            history.append({"role": message['role'], "content": message['content']})
+
+        model_provider = LLMProviderFactory.get_instance()
+
+        return model_provider.get_response(history, logger)
+
+    def system_prompt(self):
+        initial_intro = textwrap.dedent(f"""
+            You are an agent named "Orchestration Agent", a component of the Sirji AI agentic framework.
+            Your Agent ID: ORCHESTRATOR
+            Your OS (refered as SIRJI_OS later): {os.name}""")
+
+        instructions = textwrap.dedent(f"""
+            Instructions:
+            - Manage the task workflow by interpreting the "recipe", which outlines a series of prescribed tasks.
+            - Proceed sequentially over the prescribed tasks.
+            - For each task, invoke the agent specified in the recipe alogside the task, explaining the task in the BODY of the invocation.
+            """)
+
+        formatted_recipe = self.__format_recipe()
+
+        allowed_response_templates_str = textwrap.dedent(f"""
+            Allowed Response Templates:""")
+        
+        allowed_response_templates_str += '\n' + allowed_response_templates(AgentEnum.ORCHESTRATOR, AgentEnum.SIRJI_USER) + '\n'
+        allowed_response_templates_str += '\n' +  allowed_response_templates(AgentEnum.ORCHESTRATOR, AgentEnum.ANY) + '\n'
+
+        return f"{initial_intro}\n{instructions}\n{formatted_recipe}{allowed_response_templates_str}".strip()
+    def __format_recipe(self):
+        formatted = "Recipe:\n"
+        # Adding prescribed tasks with enumeration
+        formatted += "- Prescribed tasks\n"
+        for index, task in enumerate(self.recipe["prescribed_tasks"], start=1):
+            formatted += f"   {index}. {task['task']}\n"
+            formatted += f"      Agent to invoke: {task['agent']}\n"
+        
+        # Adding tips
+        if "tips" in self.recipe and self.recipe["tips"]:
+            formatted += "- Tips:\n"
+            for tip in self.recipe["tips"]:
+                formatted += f"   - {tip['tip']}\n"
+                formatted += f"      Agent to invoke: {tip['agent']}\n"
+        
+        return formatted
diff --git a/agents/sirji_agents/llm/planner.py b/agents/sirji_agents/llm/planner.py
deleted file mode 100644
index 44b1efcc..00000000
--- a/agents/sirji_agents/llm/planner.py
+++ /dev/null
@@ -1,9 +0,0 @@
-from sirji_messages import AgentEnum
-from sirji_tools.logger import p_logger as logger
-
-from .base import LLMAgentBase
-
-
-class PlanningAgent(LLMAgentBase):
-    def __init__(self):
-        super().__init__(AgentEnum.PLANNER, logger)
diff --git a/agents/sirji_agents/researcher/README.md b/agents/sirji_agents/researcher/README.md
index 579c915a..1aa59f61 100644
--- a/agents/sirji_agents/researcher/README.md
+++ b/agents/sirji_agents/researcher/README.md
@@ -21,4 +21,4 @@ In this part, the LLM model is called to infer using a prompt that has both the
 
 ## Fun Fact
 
-When developing the Researcher module, we needed to go through the OpenAI Assistants API documentation. This documentation was outside the knowledge of our LLM (gpt-4-turbo). So the model was not able to assist us in development. Rather than going through the documentation manually, we thought of using the Sirji approach to research. We manually indexed (manual, since the automated process is what we needed to develop) a new assistant with the PDF prints of the documentation. After this indexing, the assistant helped us to write the Researcher. This also proved to us that the Sirji way of research works!
+When developing the Researcher module, we needed to go through the OpenAI Assistants API documentation. This documentation was outside the knowledge of our LLM (gpt-4o). So the model was not able to assist us in development. Rather than going through the documentation manually, we thought of using the Sirji approach to research. We manually indexed (manual, since the automated process is what we needed to develop) a new assistant with the PDF prints of the documentation. After this indexing, the assistant helped us to write the Researcher. This also proved to us that the Sirji way of research works!
diff --git a/agents/sirji_agents/researcher/embeddings/openai_assistant.py b/agents/sirji_agents/researcher/embeddings/openai_assistant.py
index a1eeafdb..761df9b7 100644
--- a/agents/sirji_agents/researcher/embeddings/openai_assistant.py
+++ b/agents/sirji_agents/researcher/embeddings/openai_assistant.py
@@ -37,7 +37,7 @@ def __init__(self, init_payload={}):
             # Provide a way to output this updated init_payload
             logger.info(f"New assistant created with ID: {self.assistant_id}")
 
-        self.index_file_path = os.path.join(self._get_workspace_folder(), '.sirji', self._get_run_id_folder(), 'researcher', 'file_index.json')
+        self.index_file_path = os.path.join(self._get_run_path(), 'researcher', 'file_index.json')
 
         # Load or initialize the index file
         self.index_data = self._load_or_initialize_index_file()
@@ -82,18 +82,18 @@ def retrieve_context(self, problem_statement):
         """
         return ""
 
-    def _get_workspace_folder(self):
-        workspace = os.environ.get("SIRJI_WORKSPACE")
-        if workspace is None:
+    def _get_project_folder(self):
+        project_folder = os.environ.get("SIRJI_PORJECT")
+        if project_folder is None:
             raise ValueError(
-                "SIRJI_WORKSPACE is not set as an environment variable")
-        return workspace
+                "SIRJI_PORJECT is not set as an environment variable")
+        return project_folder
 
-    def _get_run_id_folder(self):
-        run_id = os.environ.get("SIRJI_RUN_ID")
+    def _get_run_path(self):
+        run_id = os.environ.get("SIRJI_RUN_PATH")
         if run_id is None:
             raise ValueError(
-                "SIRJI_RUN_ID is not set as an environment variable")
+                "SIRJI_RUN_PATH is not set as an environment variable")
         return run_id
     
     def _create_assistant(self):
@@ -105,7 +105,7 @@ def _create_assistant(self):
             name="Research Assistant",
             instructions="As a research assistant, your task is to address problem statements programmatically. In your response, include code examples, GitHub URLs, relevant external URLs based on your trained knowledge. Also, if knowledge on additional terms is needed, mention them in your response. Avoid providing fabricated information if uncertain.",
             tools=[{"type": "retrieval"}],
-            model="gpt-4-turbo",
+            model="gpt-4o",
         )
 
         logger.info("Completed creating a new assistant")
diff --git a/agents/sirji_agents/researcher/inferer/openai_assistant.py b/agents/sirji_agents/researcher/inferer/openai_assistant.py
index 13314dda..56ebe500 100644
--- a/agents/sirji_agents/researcher/inferer/openai_assistant.py
+++ b/agents/sirji_agents/researcher/inferer/openai_assistant.py
@@ -89,7 +89,7 @@ def _fetch_response(self):
         run = self.client.beta.threads.runs.create(
             thread_id=self.init_payload['thread_id'],
             assistant_id=self.assistant_id,
-            model="gpt-4-turbo",
+            model="gpt-4o",
             tools=[{"type": "retrieval"}]
         )
 
diff --git a/agents/sirji_agents/researcher/researcher.py b/agents/sirji_agents/researcher/researcher.py
index 709f3a7d..410aae1d 100644
--- a/agents/sirji_agents/researcher/researcher.py
+++ b/agents/sirji_agents/researcher/researcher.py
@@ -23,7 +23,7 @@ def __init__(self, embeddings_type, inferer_type, init_payload={}):
         self._inferer = InfererFactory.get_instance(
             inferer_type, self.init_payload)
 
-        self._research_folder = os.path.join(self._get_workspace_folder(), '.sirji', self._get_run_id_folder(), "researcher")
+        self._research_folder = os.path.join(self._get_run_path(), "researcher")
 
         logger.info("Completed initializing researcher")
 
@@ -39,19 +39,19 @@ def message(self, input_message):
         elif action == ActionEnum.INFER.name:
             return self._handle_infer(parsed_message)
         
-    def _get_workspace_folder(self):
-        workspace = os.environ.get("SIRJI_WORKSPACE")
-        if workspace is None:
+    def _get_project_folder(self):
+        project_folder = os.environ.get("SIRJI_PROJECT")
+        if project_folder is None:
             raise ValueError(
-                "SIRJI_WORKSPACE is not set as an environment variable")
-        return workspace
+                "SIRJI_PROJECT is not set as an environment variable")
+        return project_folder
     
-    def _get_run_id_folder(self):
-        run_id = os.environ.get("SIRJI_RUN_ID")
-        if run_id is None:
+    def _get_run_path(self):
+        run_path = os.environ.get("SIRJI_RUN_PATH")
+        if run_path is None:
             raise ValueError(
-                "SIRJI_RUN_ID is not set as an environment variable")
-        return run_id
+                "SIRJI_RUN_PATH is not set as an environment variable")
+        return run_path
 
     def _handle_train_using_search_term(self, parsed_message):
         """Private method to handle training using a search term."""
diff --git a/messages/README.md b/messages/README.md
index cc9af05b..1bd37bc9 100644
--- a/messages/README.md
+++ b/messages/README.md
@@ -3,7 +3,7 @@
 </p>
 
 <p align="center">
-  <em>Sirji is an Open Source AI Software Development Agent.</em>
+  <em>Sirji is an agentic AI framework for software development.</em>
 </p>
 
 <p align="center">
@@ -25,11 +25,13 @@
 
 ## Sirji Messages
 
-`sirji-messages` is a PyPI package that implements the Sirji message protocol with following highlights:
+`sirji-messages` is a PyPI package that implements the Sirji messaging protocol with the following highlights:
 
-- Message Factory
-- Permissions Matrix (for defining message actions allowed between two agents)
-- System prompt generation
+- **Message Factory**: A factory that provides a Message class for a given action.
+- **Message Parser**: Parse structured message strings into Python dictionaries for easy access to the message components.
+- **Allowed Response Templates**: Provides the part of the system prompt describing allowed Response Templates for a given agent pair.
+- **Custom Exceptions**: A set of custom exceptions thrown by the message parser.
+- **Enums for Agents and Actions**: Provides easy auto-completion while writing code.
 
 ## Installation
 
@@ -52,6 +54,27 @@ pip install sirji-messages
 
 ## Usage
 
+### Message Factory
+
+A factory that provides a Message class for a given action.
+
+```python
+from sirji_messages import MessageFactory, ActionEnum
+
+# Message class instantiation from an action enum
+message_class = MessageFactory[ActionEnum.RESPONSE.name]
+print(f"Sample RESPONSE message:\n{message_class().sample()}")
+
+# Generate message using passed template variables
+message_str = message_class().generate({
+            "from_agent_id": "EXECUTOR",
+            "to_agent_id": "CODER",
+            "summary": "Empty",
+            "body": "Done."})
+            
+print(f"Generated RESPONSE message:\n{message_str}")
+```
+
 ### Message Parsing
 
 Parse structured message strings into Python dictionaries for easy access to the message components.
@@ -60,31 +83,29 @@ Parse structured message strings into Python dictionaries for easy access to the
 from sirji_messages import message_parse
 
 # Example message string to parse
-message_str = """```
-FROM: CODER
-TO: USER
-ACTION: INFORM
-DETAILS: Welcome to sirji-messages. Here's how you can start.
-```"""
+message_str = """***
+FROM: EXECUTOR
+TO: CODER
+ACTION: RESPONSE
+SUMMARY: Welcome to sirji-messages
+BODY: Welcome to sirji-messages. Here's how you can start.
+***"""
 
 # Parsing the message
 message = message_parse(message_str)
 print(message)
 ````
 
-### Permission Validation
+### Allowed Response Templates
 
-Determine if a specified action is allowed between two agents based on predefined permission rules.
+Provides the part of the system prompt describing allowed Response Templates for a given agent pair.
 
 ```python
-from sirji_messages import permissions_dict, validate_permission, AgentEnum
-
-# Example check if a CODER can QUESTION a USER
-is_allowed = validate_permission("CODER", "USER", "QUESTION")
-print(f"Is allowed: {is_allowed}")
+from sirji_messages import allowed_response_templates, AgentEnum
 
-# Get a direct look at permissions dictionary for CODER sending to USER
-print(permissions_dict[(AgentEnum.CODER, AgentEnum.USER)])
+# Generate allowed response templates
+response_templates_str = allowed_response_templates(AgentEnum.ANY, AgentEnum.EXECUTOR)
+print(response_templates_str)
 ```
 
 ### Handling Custom Exceptions
@@ -103,7 +124,7 @@ except MessageValidationError as e:
     print(f"Validation Error: {e}")
 ```
 
-### Enums for Intuitive References
+### Enums for Agents and Actions
 
 Use enums (`ActionEnum`, `AgentEnum`) to reference actions and agent types programmatically, enhancing code clarity and reducing errors.
 
@@ -111,35 +132,15 @@ Use enums (`ActionEnum`, `AgentEnum`) to reference actions and agent types progr
 from sirji_messages import ActionEnum, AgentEnum
 
 # Example usage of enums for action and agent reference
-action = ActionEnum.ACKNOWLEDGE
-agent = AgentEnum.CODER
+action = ActionEnum.INVOKE_AGENT
+agent = AgentEnum.ORCHESTRATOR
 
 # Accessing enum properties
 print(f"Action: {action.name}, Agent: {agent.full_name}")
 
 # Access to enums using [] is also possible
-action = ActionEnum['ACKNOWLEDGE']
-agent = AgentEnum['CODER']
-```
-
-### Factories for Dynamic Message and Prompt Creation
-
-Utilize factories (`MessageFactory`, `AgentSystemPromptFactory`) to instantiate message and prompt classes dynamically based on enums. It simplifies creating custom messages or retrieving specific system prompts without hardcoding class names.
-
-```python
-from sirji_messages import MessageFactory, ActionEnum, AgentSystemPromptFactory, AgentEnum
-
-# Message class instantiation from an action enum
-message_class = MessageFactory[ActionEnum.INFORM.name]
-print(f"Sample INFORM message:\n{message_class().sample()}")
-
-# Generate message using passed template variables
-generated_messages = message_class().generate({"details": "Some sample information."})
-print(f"Generated INFORM message:\n{generated_messages}")
-
-# System prompt class instantiation from an agent enum
-prompt_class = AgentSystemPromptFactory[AgentEnum.CODER.name]
-print(f"CODER system prompt: {prompt_class().system_prompt()}")
+action = ActionEnum['INVOKE_AGENT']
+agent = AgentEnum['ORCHESTRATOR']
 ```
 
 ## For Contributors
diff --git a/messages/setup.py b/messages/setup.py
index 89efc7de..351f14bd 100644
--- a/messages/setup.py
+++ b/messages/setup.py
@@ -2,7 +2,7 @@
 
 setup(
     name='sirji-messages',
-    version='0.0.14',
+    version='0.0.18',
     author='Sirji',
     description='Sirji messaging protocol implementation to create, validate and parse messages.',
     license='MIT',
diff --git a/messages/sirji_messages/__init__.py b/messages/sirji_messages/__init__.py
index 4fabd39a..8c617bf7 100644
--- a/messages/sirji_messages/__init__.py
+++ b/messages/sirji_messages/__init__.py
@@ -1,10 +1,10 @@
 from .action_enum import ActionEnum
 from .agent_enum import AgentEnum
 from .messages.factory import MessageFactory
-from .system_prompts.factory import AgentSystemPromptFactory
 from .custom_exceptions import MessageParsingError, MessageValidationError
 from .permissions import validate_permission, permissions_dict
 from .parser import parse as message_parse
+from .helper import allowed_response_templates
 
 
 __all__ = [
@@ -16,5 +16,5 @@
     'MessageValidationError',
     'validate_permission',
     'permissions_dict',
-    'AgentSystemPromptFactory',
+    'allowed_response_templates'
 ]
diff --git a/messages/sirji_messages/action_enum.py b/messages/sirji_messages/action_enum.py
index 383da6a3..3c2ce0f5 100644
--- a/messages/sirji_messages/action_enum.py
+++ b/messages/sirji_messages/action_enum.py
@@ -2,26 +2,32 @@
 
 
 class ActionEnum(Enum):
-    ACKNOWLEDGE = auto()
     ANSWER = auto()
+    INVOKE_AGENT = auto()
+    INVOKE_AGENT_EXISTING_SESSION = auto()
     EXECUTE_COMMAND = auto()
+    APPEND_TO_AGENT_OUTPUT_INDEX = auto()
+    READ_AGENT_OUTPUT_INDEX = auto()
     RUN_SERVER = auto()
-    CREATE_FILE = auto()
+    CREATE_PROJECT_FILE = auto()
+    CREATE_AGENT_OUTPUT_FILE = auto()
     GENERATE_STEPS = auto()
     PROBLEM_STATEMENT = auto()
     INFER = auto()
     INFORM = auto()
-    INSTALL_PACKAGE = auto()
     OUTPUT = auto()
     QUESTION = auto()
     RESPONSE = auto()
     SOLUTION_COMPLETE = auto()
-    STEP_COMPLETED = auto()
-    STEP_STARTED = auto()
     STEPS = auto()
     TRAIN_USING_SEARCH_TERM = auto()
     TRAIN_USING_URL = auto()
     FEEDBACK = auto()
     TRAINING_OUTPUT = auto()
-    READ_FILE = auto()
-    READ_DIR = auto()
+    READ_PROJECT_FILES = auto()
+    READ_AGENT_OUTPUT_FILES = auto()
+    FIND_AND_REPLACE = auto()
+    INSERT_TEXT = auto()
+    EXTRACT_DEPENDENCIES = auto()
+    FIND_AND_REPLACE_IN_PROJECT = auto()
+    SEARCH_FILE_IN_PROJECT = auto()
diff --git a/messages/sirji_messages/agent_enum.py b/messages/sirji_messages/agent_enum.py
index c0807606..e9c9e905 100644
--- a/messages/sirji_messages/agent_enum.py
+++ b/messages/sirji_messages/agent_enum.py
@@ -8,8 +8,11 @@ def __new__(cls, value, name):
         member.full_name = name
         return member
 
+    ORCHESTRATOR = (0, "Orchestrator")
     CODER = (1, "Coding Agent")
     PLANNER = (2, "Planning Agent")
     EXECUTOR = (3, "Execution Agent")
     RESEARCHER = (4, "Research Agent")
-    USER = (5, "End User")
+    SIRJI_USER = (5, "End User")
+    ANY = (6, "Any Agent")
+    CALLER = (7, "Caller Agent")
diff --git a/messages/sirji_messages/helper.py b/messages/sirji_messages/helper.py
new file mode 100644
index 00000000..caddab3b
--- /dev/null
+++ b/messages/sirji_messages/helper.py
@@ -0,0 +1,33 @@
+from sirji_messages import permissions_dict, AgentEnum, MessageFactory
+
+def allowed_response_templates(from_agent, to_agent):
+    response_template = ''
+
+    if from_agent != AgentEnum.ORCHESTRATOR and from_agent != AgentEnum.CALLER:
+        response_template += f'Allowed Response Templates TO {to_agent.name}:\n'
+
+    if (from_agent, to_agent) == (AgentEnum.ANY, AgentEnum.CALLER):
+        response_template += f'Respond to the agent which invoked you, at the end of task completion. Please respond with the following, including the starting and ending \'***\', with no commentary above or below.'
+    elif (from_agent, to_agent) == (AgentEnum.ORCHESTRATOR, AgentEnum.ANY):
+        response_template += f'To invoke an agent, please respond with the text below, including the starting and ending \'***\', and ensure there is no commentary above or below:'
+    else:
+        response_template += f'Invoke the {to_agent.name} for the following functions. Please respond with the following, including the starting and ending \'***\', with no commentary above or below.'
+
+    action_list = permissions_dict[(from_agent, to_agent)]
+
+    for index, action in enumerate(action_list):
+        message_class = MessageFactory[action.name]
+        response_template += f'\n\nFunction {index + 1}. {message_class().description()}\n'
+        instructions = message_class().instructions()
+        if instructions:
+            response_template += '\nInstructions:\n'
+            for instruction in instructions:
+                response_template += f'- {instruction}\n'
+        
+        if (from_agent, to_agent) == (AgentEnum.ANY, AgentEnum.CALLER):
+            print('Inside if statement')
+            response_template += f'\nResponse template:{message_class().generate({"from_agent_id": "{{Your Agent ID}}", "to_agent_id": "{{Agent ID of the invoker agent}}", "summary": "Empty", "body": "{{Task update. Whether the task was done successfully or not. Any other details which you might think are necessary for the agent which invoked you to know of.}}"})}'
+        else:
+            response_template += f'\nResponse template:{message_class().sample()}'
+
+    return response_template
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/acknowledge.py b/messages/sirji_messages/messages/actions/acknowledge.py
deleted file mode 100644
index df49b173..00000000
--- a/messages/sirji_messages/messages/actions/acknowledge.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class AcknowledgeMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.ACKNOWLEDGE.name
-        self.from_agent = AgentEnum.USER.name
-        self.to_agent = AgentEnum.CODER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-            DETAILS: Sure.
-            """)
-
-    def sample(self):
-        return self.generate({})
-
-    def description(self):
-        return "The message acknowledgment:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/answer.py b/messages/sirji_messages/messages/actions/answer.py
deleted file mode 100644
index 37fc2e37..00000000
--- a/messages/sirji_messages/messages/actions/answer.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class AnswerMessage(BaseMessages):
-    def __init__(self):
-        self.action = ActionEnum.ANSWER.name
-        self.from_agent = AgentEnum.USER.name
-        self.to_agent = AgentEnum.CODER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Multiline answer to the asked question."
-        })
-
-    def description(self):
-        return "The answer to the asked question:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/append_to_agent_output_index.py b/messages/sirji_messages/messages/actions/append_to_agent_output_index.py
new file mode 100644
index 00000000..986b2222
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/append_to_agent_output_index.py
@@ -0,0 +1,29 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class AppendToAgentOutputIndexMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.APPEND_TO_AGENT_OUTPUT_INDEX.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            File path: {{file path of the agent output file relative to the Agent Output Folder}}
+            ---
+            {{Description of the agent output file, to be used by other agents to know what it is about}}""")})
+
+    def description(self):
+        return "Register to the Agent Output Index"
+    
+    def instructions(self):
+        return [ "Ensure to register new agent output files to the Agent Output Index.",
+                 "The file path must be in the following format: '{{Your Agent ID}}/{{file name}}'."]
diff --git a/messages/sirji_messages/messages/actions/base.py b/messages/sirji_messages/messages/actions/base.py
index 38a7d437..e2ae0fc5 100644
--- a/messages/sirji_messages/messages/actions/base.py
+++ b/messages/sirji_messages/messages/actions/base.py
@@ -1,16 +1,8 @@
 import textwrap
 from abc import ABC, abstractmethod
 
-
 class BaseMessages(ABC):
 
-    @abstractmethod
-    def template_payload_part(self):
-        """
-        Message template's payload part which is custom to the message action.
-        """
-        pass
-
     @abstractmethod
     def sample(self):
         """
@@ -25,27 +17,35 @@ def description(self):
         """
         pass
 
-    @staticmethod
     @abstractmethod
-    def custom_properties():
+    def instructions(self):
         """
-        List of custom properties of the message.
+        Instructions for the message.
         """
         pass
 
     def generate(self, obj):
-        return self.template().format(**obj)
-
-    def template_prefix_part(self):
-        return textwrap.dedent(f"""
-            ```
-            FROM: {self.from_agent}
-            TO: {self.to_agent}
-            ACTION: {self.action}""")
-
-    def template_suffix_part(self):
-        return textwrap.dedent(f"""```
-            """)
 
+        try:
+            if self.to_agent:
+                obj["to_agent_id"] = self.to_agent
+        except AttributeError:
+            pass
+
+        try:
+            if self.from_agent:
+                obj["from_agent_id"] = self.from_agent
+        except AttributeError:
+            pass
+            
+        return self.template().format(**obj)
+    
     def template(self):
-        return self.template_prefix_part() + self.template_payload_part() + self.template_suffix_part()
+        return textwrap.dedent(f"""
+            ***
+            FROM: {{from_agent_id}}
+            TO: {{to_agent_id}}
+            ACTION: {self.action}
+            SUMMARY: {{summary}}
+            BODY: {{body}}
+            ***""")
diff --git a/messages/sirji_messages/messages/actions/create_agent_output_file.py b/messages/sirji_messages/messages/actions/create_agent_output_file.py
new file mode 100644
index 00000000..818fc619
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/create_agent_output_file.py
@@ -0,0 +1,28 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+class CreateAgentOutputFileMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.CREATE_AGENT_OUTPUT_FILE.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            File path: {{file path}}
+            ---
+            {{file contents}}""")})
+
+    def description(self):
+        return "Create a File Inside Agent Output Folder"
+    
+    def instructions(self):
+        return [ "The file path must be in the following format: '{{Your Agent ID}}/{{file name}}'."]
+
diff --git a/messages/sirji_messages/messages/actions/create_file.py b/messages/sirji_messages/messages/actions/create_file.py
deleted file mode 100644
index c8372f4c..00000000
--- a/messages/sirji_messages/messages/actions/create_file.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class CreateFileMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.CREATE_FILE.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.EXECUTOR.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          FILENAME: {file_name}
-          CONTENT:
-          {content}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "file_name": "File name along with the path relative to the workspace root folder.",
-            "content": "Multiline file content. It should start from a new line."
-        })
-
-    def description(self):
-        return "To create a file (with content):"
-
-    @staticmethod
-    def custom_properties():
-        return ['FILENAME', 'CONTENT']
diff --git a/messages/sirji_messages/messages/actions/create_project_file.py b/messages/sirji_messages/messages/actions/create_project_file.py
new file mode 100644
index 00000000..d502d014
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/create_project_file.py
@@ -0,0 +1,30 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class CreateProjectFileMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.CREATE_PROJECT_FILE.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            File path: {{file path}}
+            ---
+            {{file contents}}""")})
+
+    def description(self):
+        return "Create a File Inside Project Folder Only"
+    
+    def instructions(self):
+        return [ "The file path must be relative to the project root.",
+                 "The file contents should never be enclosed within ``` starting and ending markers."]
+
diff --git a/messages/sirji_messages/messages/actions/execute_command.py b/messages/sirji_messages/messages/actions/execute_command.py
index 21232725..13698b8f 100644
--- a/messages/sirji_messages/messages/actions/execute_command.py
+++ b/messages/sirji_messages/messages/actions/execute_command.py
@@ -8,24 +8,20 @@ class ExecuteCommandMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.EXECUTE_COMMAND.name
-        self.from_agent = AgentEnum.CODER.name
         self.to_agent = AgentEnum.EXECUTOR.name
 
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          COMMAND: {command}
-          """)
-
     def sample(self):
         return self.generate({
-            "command": "Command to execute, considering workspace root folder as current working directory."
-        })
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            {{command}}""")})
 
     def description(self):
-        return "To execute a command:"
-
-    @staticmethod
-    def custom_properties():
-        return ['COMMAND']
+        return "Execute a Command, Install Packages, or Install Dependencies"
+    
+    def instructions(self):
+        return [ "The command must use the project root as the current working directory.",
+                 "The command must be sufficiently chained. For example, 'source venv/bin/activate && pip install openai', 'cd server && npm run start'."]
diff --git a/messages/sirji_messages/messages/actions/extract_dependencies.py b/messages/sirji_messages/messages/actions/extract_dependencies.py
new file mode 100644
index 00000000..28401792
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/extract_dependencies.py
@@ -0,0 +1,26 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+class ExtractDependenciesMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.EXTRACT_DEPENDENCIES.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            {{Array of file paths}}""")})
+
+    def description(self):
+        return "Extract Dependencies of The Specified Files"
+    
+    def instructions(self):
+        return [ "The file path must be relative to the project root."]
+
diff --git a/messages/sirji_messages/messages/actions/feedback.py b/messages/sirji_messages/messages/actions/feedback.py
deleted file mode 100644
index c172af81..00000000
--- a/messages/sirji_messages/messages/actions/feedback.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class FeedbackMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.FEEDBACK.name
-        self.from_agent = AgentEnum.USER.name
-        self.to_agent = AgentEnum.CODER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Feedback on the solution provided."
-        })
-
-    def description(self):
-        return "Feedback on the solution provided:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/find_and_replace.py b/messages/sirji_messages/messages/actions/find_and_replace.py
new file mode 100644
index 00000000..d6b4305f
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/find_and_replace.py
@@ -0,0 +1,32 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+
+from .base import BaseMessages
+
+class FindAndReplace(BaseMessages):
+  
+      def __init__(self):
+          self.action = ActionEnum.FIND_AND_REPLACE.name
+          self.to_agent = AgentEnum.EXECUTOR.name
+  
+          super().__init__()
+  
+      def sample(self):
+          return self.generate({
+              "from_agent_id": "{{Your Agent ID}}",
+              "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+              "body": textwrap.dedent("""
+                FILE_PATH: {{File path}}                        
+                --- 
+                FIND: {{Find this text}}    
+                ---                   
+                REPLACE: {{Replace with this text}}
+                ---
+            """)})
+  
+      def description(self):
+          return "Find and Replace text in a file"
+  
+      def instructions(self):
+          return []
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/find_and_replace_in_project.py b/messages/sirji_messages/messages/actions/find_and_replace_in_project.py
new file mode 100644
index 00000000..dee5d76e
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/find_and_replace_in_project.py
@@ -0,0 +1,29 @@
+import textwrap
+from sirji_messages import AgentEnum, ActionEnum
+
+from .base import BaseMessages
+
+class FindAndReplaceInProjectMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.FIND_AND_REPLACE_IN_PROJECT.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            Find: {{Find this text}}
+            ---                        
+            Replace: {{Replace with this text}}
+            ---
+            Directory: {{Directory path}}""")})
+
+    def description(self):
+        return "Find and Replace text in all files in a directory and all its subdirectories"
+
+    def instructions(self):
+        return []
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/generate_steps.py b/messages/sirji_messages/messages/actions/generate_steps.py
deleted file mode 100644
index f1ed749f..00000000
--- a/messages/sirji_messages/messages/actions/generate_steps.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class GenerateStepsMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.GENERATE_STEPS.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.PLANNER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Problem statement (PS) here."
-        })
-
-    def description(self):
-        return "Generate steps for the problem statement (PS):"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/infer.py b/messages/sirji_messages/messages/actions/infer.py
index c20e4ab8..610fe35d 100644
--- a/messages/sirji_messages/messages/actions/infer.py
+++ b/messages/sirji_messages/messages/actions/infer.py
@@ -8,24 +8,19 @@ class InferMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.INFER.name
-        self.from_agent = AgentEnum.CODER.name
         self.to_agent = AgentEnum.RESEARCHER.name
 
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
     def sample(self):
         return self.generate({
-            "details": "Question to extract answers, code examples, GitHub URLs, relevant external URLs from the trained content."
-        })
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            {{Infer query}}""")})
 
     def description(self):
-        return "Ask questions on the trained content:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
+        return "Ask questions on the trained content"
+    
+    def instructions(self):
+        return []
diff --git a/messages/sirji_messages/messages/actions/inform.py b/messages/sirji_messages/messages/actions/inform.py
deleted file mode 100644
index 431807bc..00000000
--- a/messages/sirji_messages/messages/actions/inform.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class InformMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.INFORM.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.USER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Details of your decisions or choices."
-        })
-
-    def description(self):
-        return "To inform about your decisions or choices:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/insert_text.py b/messages/sirji_messages/messages/actions/insert_text.py
new file mode 100644
index 00000000..2b7988ce
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/insert_text.py
@@ -0,0 +1,34 @@
+
+import textwrap;
+from sirji_messages import AgentEnum, ActionEnum;
+
+from .base import BaseMessages;
+
+class InsertText(BaseMessages):
+    
+    def __init__(self):
+        self.action = ActionEnum.INSERT_TEXT.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+        
+        super().__init__()
+    
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            FILE_PATH: {{File path}}
+            ---
+            FIND: {{Text to find}}
+            ---
+            INSERT_POSITION: {{'above' or 'below'}}
+            ---
+            TEXT_TO_INSERT: {{Text to insert}}
+            ---
+            """)})
+    
+    def description(self):
+        return "Insert text into a file at a specific line number"
+    
+    def instructions(self):
+        return []
diff --git a/messages/sirji_messages/messages/actions/install_package.py b/messages/sirji_messages/messages/actions/install_package.py
deleted file mode 100644
index ac5f27ce..00000000
--- a/messages/sirji_messages/messages/actions/install_package.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class InstallPackageMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.INSTALL_PACKAGE.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.EXECUTOR.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          COMMAND: {command}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "command": "Command to execute, considering workspace root folder as current working directory."
-        })
-
-    def description(self):
-        return "To install a package or library:"
-
-    @staticmethod
-    def custom_properties():
-        return ['COMMAND']
diff --git a/messages/sirji_messages/messages/actions/invoke_agent.py b/messages/sirji_messages/messages/actions/invoke_agent.py
new file mode 100644
index 00000000..42fc1417
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/invoke_agent.py
@@ -0,0 +1,26 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class InvokeAgentMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.INVOKE_AGENT.name
+        self.from_agent = AgentEnum.ORCHESTRATOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "to_agent_id": "{{To Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            {{Purpose of invocation}}""")})
+
+    def description(self):
+        return "Invoke an agent in a fresh session"
+    
+    def instructions(self):
+        return []
diff --git a/messages/sirji_messages/messages/actions/invoke_agent_existing_session.py b/messages/sirji_messages/messages/actions/invoke_agent_existing_session.py
new file mode 100644
index 00000000..42532428
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/invoke_agent_existing_session.py
@@ -0,0 +1,26 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class InvokeAgentExistingSessionMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.INVOKE_AGENT_EXISTING_SESSION.name
+        self.from_agent = AgentEnum.ORCHESTRATOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "to_agent_id": "{{To Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            {{Purpose of invocation}}""")})
+
+    def description(self):
+        return "Invoke an agent continuing on the existing session"
+    
+    def instructions(self):
+        return []
diff --git a/messages/sirji_messages/messages/actions/output.py b/messages/sirji_messages/messages/actions/output.py
deleted file mode 100644
index f099d4c0..00000000
--- a/messages/sirji_messages/messages/actions/output.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class OutputMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.OUTPUT.name
-        self.from_agent = AgentEnum.EXECUTOR.name
-        self.to_agent = AgentEnum.CODER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS:
-          {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Multilined response."
-        })
-
-    def description(self):
-        return "The response output:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/problem_statement.py b/messages/sirji_messages/messages/actions/problem_statement.py
deleted file mode 100644
index 1891ba64..00000000
--- a/messages/sirji_messages/messages/actions/problem_statement.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class ProblemStatementMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.PROBLEM_STATEMENT.name
-        self.from_agent = AgentEnum.USER.name
-        self.to_agent = AgentEnum.CODER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "The problem statement (PS) that needs to be solved programmatically."
-        })
-
-    def description(self):
-        return "The problem statement (PS) that needs to be solved programmatically:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/question.py b/messages/sirji_messages/messages/actions/question.py
index 70ebf808..7d117b03 100644
--- a/messages/sirji_messages/messages/actions/question.py
+++ b/messages/sirji_messages/messages/actions/question.py
@@ -8,24 +8,19 @@ class QuestionMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.QUESTION.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.USER.name
+        self.to_agent = AgentEnum.SIRJI_USER.name
 
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
     def sample(self):
         return self.generate({
-            "details": "A concise question to understand the problem statement better."
-        })
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "Empty",
+            "body": textwrap.dedent("""
+            {{Question}}""")})
 
     def description(self):
-        return "Ask questions to understand the problem statement better:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
+        return "Ask a question"
+    
+    def instructions(self):
+        return []
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/read_agent_output_files.py b/messages/sirji_messages/messages/actions/read_agent_output_files.py
new file mode 100644
index 00000000..c8419603
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/read_agent_output_files.py
@@ -0,0 +1,26 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class ReadAgentOutputFilesMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.READ_AGENT_OUTPUT_FILES.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            File paths: {{Array of file paths}}""")})
+    
+    def description(self):
+        return "Read Multiple Files From Agent Output Folder"
+    
+    def instructions(self):
+        return [ "The file paths must be in the following format: '{{Your Agent ID}}/{{file name}}'."]
diff --git a/messages/sirji_messages/messages/actions/read_agent_output_index.py b/messages/sirji_messages/messages/actions/read_agent_output_index.py
new file mode 100644
index 00000000..74e56fbd
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/read_agent_output_index.py
@@ -0,0 +1,26 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class ReadAgentOutputIndexMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.READ_AGENT_OUTPUT_INDEX.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            Empty""")})
+
+    def description(self):
+        return "Read Agent Output Index"
+
+    def instructions(self):
+        return []
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/read_dir.py b/messages/sirji_messages/messages/actions/read_dir.py
deleted file mode 100644
index eb2eef38..00000000
--- a/messages/sirji_messages/messages/actions/read_dir.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class ReadDirMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.READ_DIR.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.EXECUTOR.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DIRPATH: {dir_path}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "dir_path": "Name of a directory alongwith the path relative to the workspace root folder.",
-        })
-
-    def description(self):
-        return "To read the content from all files in a directory and all its subdirectories at once (separated by a divider):"
-
-    @staticmethod
-    def custom_properties():
-        return ['DIRPATH']
diff --git a/messages/sirji_messages/messages/actions/read_file.py b/messages/sirji_messages/messages/actions/read_file.py
deleted file mode 100644
index b78a4496..00000000
--- a/messages/sirji_messages/messages/actions/read_file.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class ReadFileMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.READ_FILE.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.EXECUTOR.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          FILENAME: {file_name}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "file_name": "File name along with the path relative to the workspace root folder.",
-        })
-
-    def description(self):
-        return "To read a file:"
-
-    @staticmethod
-    def custom_properties():
-        return ['FILENAME']
diff --git a/messages/sirji_messages/messages/actions/read_project_files.py b/messages/sirji_messages/messages/actions/read_project_files.py
new file mode 100644
index 00000000..c6429582
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/read_project_files.py
@@ -0,0 +1,26 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class ReadProjectFilesMessage(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.READ_PROJECT_FILES.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            File paths: {{Array of file paths}}""")})
+    
+    def description(self):
+        return "Read Multiple Files From Project Folder Only"
+    
+    def instructions(self):
+        return [ "The file paths must be relative to the project root."]
diff --git a/messages/sirji_messages/messages/actions/response.py b/messages/sirji_messages/messages/actions/response.py
index 2dac77ff..b391ba1e 100644
--- a/messages/sirji_messages/messages/actions/response.py
+++ b/messages/sirji_messages/messages/actions/response.py
@@ -8,25 +8,19 @@ class ResponseMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.RESPONSE.name
-        self.from_agent = AgentEnum.RESEARCHER.name
-        self.to_agent = AgentEnum.CODER.name
-
+    
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS:
-          {details}
-          """)
-
     def sample(self):
         return self.generate({
-            "details": "Multilined response."
-        })
+            "from_agent_id": "{{Agent Id of the agent sending the response}}",
+            "to_agent_id": "{{Your Agent ID}}",
+            "summary": "Empty",
+            "body": textwrap.dedent("""
+            {{Response}}""")})
 
     def description(self):
-        return "The response output:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
+        return "The response output"
+    
+    def instructions(self):
+        return []
diff --git a/messages/sirji_messages/messages/actions/run_server.py b/messages/sirji_messages/messages/actions/run_server.py
index 72f6801c..497bea09 100644
--- a/messages/sirji_messages/messages/actions/run_server.py
+++ b/messages/sirji_messages/messages/actions/run_server.py
@@ -8,24 +8,22 @@ class RunServerMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.RUN_SERVER.name
-        self.from_agent = AgentEnum.CODER.name
         self.to_agent = AgentEnum.EXECUTOR.name
 
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          COMMAND: {command}
-          """)
-
     def sample(self):
         return self.generate({
-            "command": "Command to start server process. This command should be relative to the workspace root folder."
-        })
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            {{command}}""")})
 
     def description(self):
-        return "To start server process:"
+        return "Run a Server or a Continuous Running Process"
+    
+    def instructions(self):
+        return [ "The command must use the project root as the current working directory.",
+                 "The command must be sufficiently chained. For example, 'source my_env.sh && npm start'."]
+
 
-    @staticmethod
-    def custom_properties():
-        return ['COMMAND']
diff --git a/messages/sirji_messages/messages/actions/search_file_in_project.py b/messages/sirji_messages/messages/actions/search_file_in_project.py
new file mode 100644
index 00000000..1fdecb46
--- /dev/null
+++ b/messages/sirji_messages/messages/actions/search_file_in_project.py
@@ -0,0 +1,28 @@
+import textwrap
+
+from sirji_messages import AgentEnum, ActionEnum
+from .base import BaseMessages
+
+
+class SearchFileInProject(BaseMessages):
+
+    def __init__(self):
+        self.action = ActionEnum.SEARCH_FILE_IN_PROJECT.name
+        self.to_agent = AgentEnum.EXECUTOR.name
+
+        super().__init__()
+
+    def sample(self):
+        return self.generate({
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            Search: {{Search term}}
+            ---
+            Directory: {{Directory path}}""")})
+
+    def description(self):
+        return "Search for a file in a directory and all its subdirectories"
+
+    def instructions(self):
+        return []
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/solution_complete.py b/messages/sirji_messages/messages/actions/solution_complete.py
index bf57a1ff..126f975d 100644
--- a/messages/sirji_messages/messages/actions/solution_complete.py
+++ b/messages/sirji_messages/messages/actions/solution_complete.py
@@ -8,24 +8,19 @@ class SolutionCompleteMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.SOLUTION_COMPLETE.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.USER.name
+        self.to_agent = AgentEnum.SIRJI_USER.name
 
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
     def sample(self):
         return self.generate({
-            "details": "A concise message to inform that the solution is complete."
-        })
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            {{Summarize what all was done for getting the solution.}}""")})
 
     def description(self):
-        return "To inform that the solution to the problem is complete:"
+        return "Inform About Solution Completed"
 
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
+    def instructions(self):
+        return []
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/step_completed.py b/messages/sirji_messages/messages/actions/step_completed.py
deleted file mode 100644
index 2fb9143b..00000000
--- a/messages/sirji_messages/messages/actions/step_completed.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class StepCompletedMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.STEP_COMPLETED.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.USER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Example details 'Step # completed'."
-        })
-
-    def description(self):
-        return "Inform when a step is complete, before moving to the next step:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/step_started.py b/messages/sirji_messages/messages/actions/step_started.py
deleted file mode 100644
index dbfa93c2..00000000
--- a/messages/sirji_messages/messages/actions/step_started.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class StepStartedMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.STEP_STARTED.name
-        self.from_agent = AgentEnum.CODER.name
-        self.to_agent = AgentEnum.USER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS: {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Example details 'Step # started'."
-        })
-
-    def description(self):
-        return "Inform the step you are about to start on:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/actions/steps.py b/messages/sirji_messages/messages/actions/steps.py
deleted file mode 100644
index 0cb6f80a..00000000
--- a/messages/sirji_messages/messages/actions/steps.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class StepsMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.STEPS.name
-        self.from_agent = AgentEnum.PLANNER.name
-        self.to_agent = AgentEnum.CODER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS:
-          {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "List of steps to solve the problem. Each step must start with 'Step #: ....'."
-        })
-
-    def description(self):
-        return "List of steps required to solve the problem:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/train_using_search_term.py b/messages/sirji_messages/messages/actions/train_using_search_term.py
index fe0a548f..9ab9ae24 100644
--- a/messages/sirji_messages/messages/actions/train_using_search_term.py
+++ b/messages/sirji_messages/messages/actions/train_using_search_term.py
@@ -8,24 +8,19 @@ class TrainUsingSearchTermMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.TRAIN_USING_SEARCH_TERM.name
-        self.from_agent = AgentEnum.CODER.name
         self.to_agent = AgentEnum.RESEARCHER.name
 
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          TERM: {term}
-          """)
-
     def sample(self):
         return self.generate({
-            "term": "The search term that needs to be crawled and trained on."
-        })
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            Term: {{search term}}""")})
 
     def description(self):
-        return "Train using a search term:"
+        return "Train using a search term"
 
-    @staticmethod
-    def custom_properties():
-        return ['TERM']
+    def instructions(self):
+        return []
\ No newline at end of file
diff --git a/messages/sirji_messages/messages/actions/train_using_url.py b/messages/sirji_messages/messages/actions/train_using_url.py
index 2810133d..a9cd8e2c 100644
--- a/messages/sirji_messages/messages/actions/train_using_url.py
+++ b/messages/sirji_messages/messages/actions/train_using_url.py
@@ -8,24 +8,19 @@ class TrainUsingUrlMessage(BaseMessages):
 
     def __init__(self):
         self.action = ActionEnum.TRAIN_USING_URL.name
-        self.from_agent = AgentEnum.CODER.name
         self.to_agent = AgentEnum.RESEARCHER.name
 
         super().__init__()
 
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          URL: {url}
-          """)
-
     def sample(self):
         return self.generate({
-            "url": "The URL that needs to be crawled, parsed, and trained to answer questions."
-        })
+            "from_agent_id": "{{Your Agent ID}}",
+            "summary": "{{Display a concise summary to the user, describing the action using the present continuous tense.}}",
+            "body": textwrap.dedent("""
+            URL: {{url}}""")})
 
     def description(self):
-        return "Train using a URL:"
-
-    @staticmethod
-    def custom_properties():
-        return ['URL']
+        return "Train using a URL"
+    
+    def instructions(self):
+        return []
diff --git a/messages/sirji_messages/messages/actions/training_output.py b/messages/sirji_messages/messages/actions/training_output.py
deleted file mode 100644
index e2808df8..00000000
--- a/messages/sirji_messages/messages/actions/training_output.py
+++ /dev/null
@@ -1,32 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum, ActionEnum
-from .base import BaseMessages
-
-
-class TrainingOutputMessage(BaseMessages):
-
-    def __init__(self):
-        self.action = ActionEnum.TRAINING_OUTPUT.name
-        self.from_agent = AgentEnum.RESEARCHER.name
-        self.to_agent = AgentEnum.CODER.name
-
-        super().__init__()
-
-    def template_payload_part(self):
-        return textwrap.dedent("""
-          DETAILS:
-          {details}
-          """)
-
-    def sample(self):
-        return self.generate({
-            "details": "Multilined training output."
-        })
-
-    def description(self):
-        return "The training output:"
-
-    @staticmethod
-    def custom_properties():
-        return ['DETAILS']
diff --git a/messages/sirji_messages/messages/factory.py b/messages/sirji_messages/messages/factory.py
index 46d2a7b4..d40db320 100644
--- a/messages/sirji_messages/messages/factory.py
+++ b/messages/sirji_messages/messages/factory.py
@@ -1,29 +1,25 @@
 from sirji_messages import ActionEnum
 
 # Import all the message classes
-from .actions.acknowledge import AcknowledgeMessage
-from .actions.answer import AnswerMessage
 from .actions.execute_command import ExecuteCommandMessage
 from .actions.run_server import RunServerMessage
-from .actions.create_file import CreateFileMessage
-from .actions.generate_steps import GenerateStepsMessage
-from .actions.problem_statement import ProblemStatementMessage
+from .actions.create_project_file import CreateProjectFileMessage
+from .actions.create_agent_output_file import CreateAgentOutputFileMessage
 from .actions.infer import InferMessage
-from .actions.inform import InformMessage
-from .actions.install_package import InstallPackageMessage
-from .actions.output import OutputMessage
 from .actions.question import QuestionMessage
 from .actions.response import ResponseMessage
 from .actions.solution_complete import SolutionCompleteMessage
-from .actions.step_completed import StepCompletedMessage
-from .actions.step_started import StepStartedMessage
-from .actions.steps import StepsMessage
 from .actions.train_using_search_term import TrainUsingSearchTermMessage
 from .actions.train_using_url import TrainUsingUrlMessage
-from .actions.feedback import FeedbackMessage
-from .actions.training_output import TrainingOutputMessage
-from .actions.read_dir import ReadDirMessage
-from .actions.read_file import ReadFileMessage
+from .actions.read_project_files import ReadProjectFilesMessage
+from .actions.read_agent_output_files import ReadAgentOutputFilesMessage
+from .actions.append_to_agent_output_index import AppendToAgentOutputIndexMessage
+from .actions.read_agent_output_index import ReadAgentOutputIndexMessage
+from .actions.invoke_agent import InvokeAgentMessage
+from .actions.invoke_agent_existing_session import InvokeAgentExistingSessionMessage
+from .actions.find_and_replace import FindAndReplace
+from .actions.insert_text import InsertText
+from .actions.extract_dependencies import ExtractDependenciesMessage
 
 
 class MetaMessageFactory(type):
@@ -42,28 +38,24 @@ class MessageFactory(metaclass=MetaMessageFactory):
 
     # Map ActionTypes to their respective message classes
     _message_map = {
-        ActionEnum.ACKNOWLEDGE: AcknowledgeMessage,
-        ActionEnum.ANSWER: AnswerMessage,
+        ActionEnum.INVOKE_AGENT: InvokeAgentMessage,
+        ActionEnum.INVOKE_AGENT_EXISTING_SESSION: InvokeAgentExistingSessionMessage,
         ActionEnum.EXECUTE_COMMAND: ExecuteCommandMessage,
         ActionEnum.RUN_SERVER: RunServerMessage,
-        ActionEnum.CREATE_FILE: CreateFileMessage,
-        ActionEnum.GENERATE_STEPS: GenerateStepsMessage,
-        ActionEnum.PROBLEM_STATEMENT: ProblemStatementMessage,
+        ActionEnum.CREATE_PROJECT_FILE: CreateProjectFileMessage,
+        ActionEnum.CREATE_AGENT_OUTPUT_FILE: CreateAgentOutputFileMessage,
         ActionEnum.INFER: InferMessage,
-        ActionEnum.INFORM: InformMessage,
-        ActionEnum.INSTALL_PACKAGE: InstallPackageMessage,
-        ActionEnum.OUTPUT: OutputMessage,
         ActionEnum.QUESTION: QuestionMessage,
         ActionEnum.RESPONSE: ResponseMessage,
         ActionEnum.SOLUTION_COMPLETE: SolutionCompleteMessage,
-        ActionEnum.STEP_COMPLETED: StepCompletedMessage,
-        ActionEnum.STEP_STARTED: StepStartedMessage,
-        ActionEnum.STEPS: StepsMessage,
         ActionEnum.TRAIN_USING_SEARCH_TERM: TrainUsingSearchTermMessage,
         ActionEnum.TRAIN_USING_URL: TrainUsingUrlMessage,
-        ActionEnum.FEEDBACK: FeedbackMessage,
-        ActionEnum.TRAINING_OUTPUT: TrainingOutputMessage,
-        ActionEnum.READ_DIR: ReadDirMessage,
-        ActionEnum.READ_FILE: ReadFileMessage
+        ActionEnum.READ_PROJECT_FILES: ReadProjectFilesMessage,
+        ActionEnum.READ_AGENT_OUTPUT_FILES: ReadAgentOutputFilesMessage,
+        ActionEnum.APPEND_TO_AGENT_OUTPUT_INDEX: AppendToAgentOutputIndexMessage,
+        ActionEnum.READ_AGENT_OUTPUT_INDEX: ReadAgentOutputIndexMessage,
+        ActionEnum.FIND_AND_REPLACE: FindAndReplace,
+        ActionEnum.INSERT_TEXT: InsertText,
+        ActionEnum.EXTRACT_DEPENDENCIES: ExtractDependenciesMessage
     }
 
diff --git a/messages/sirji_messages/parser.py b/messages/sirji_messages/parser.py
index a0927579..4f4238f3 100644
--- a/messages/sirji_messages/parser.py
+++ b/messages/sirji_messages/parser.py
@@ -1,118 +1,66 @@
-from .messages.factory import MessageFactory
 from .custom_exceptions import MessageParsingError, MessageValidationError
 from .action_enum import ActionEnum
-from sirji_messages import validate_permission
 
+message_properties = ['FROM', 'TO', 'ACTION', 'SUMMARY', 'BODY']
 
 def parse(input_message):
     input_message = _discard_format_deviations(input_message)
     lines = _validate_message(input_message)
-    message_info = _extract_message_info(lines)
-    payload = "\n".join(lines[3:])
-    custom_properties = MessageFactory[message_info["ACTION"]].custom_properties()
-
-    payload_dict = _parse_payload(payload, custom_properties)
-
-    parsed_message = {"FROM": message_info["FROM"], "TO": message_info["TO"],
-                      "ACTION": message_info["ACTION"], **payload_dict}
-
-    if parsed_message.get("ACTION") == ActionEnum.STEPS.name:
-        parsed_message = {
-            **parsed_message, "PARSED_STEPS": _parse_steps(parsed_message)}
+    parsed_message = _parse_message("\n".join(lines))
+    parsed_message['BODY'] = parsed_message['BODY'].lstrip("\n")
+    # Check if the message has all the required properties.
+    for prop in message_properties:
+        if prop not in parsed_message:
+            raise MessageParsingError(f"Message does not contain {prop} property")
+           
+    if parsed_message['ACTION'] not in ActionEnum.__members__:
+        raise MessageValidationError(f"Action {parsed_message['ACTION']} is not recognized")
 
     return parsed_message
 
 def _discard_format_deviations(input_message):
     input_message = input_message.strip()
 
-    # Locate the positions of the first and last backticks (`).
-    start_index = input_message.find("```")
-    end_index = input_message.rfind("```")
+    # Locate the positions of the first and last "***" in the message.
+    start_index = input_message.find("***")
+    end_index = input_message.rfind("***")
 
     # Extract the message prefix, message, and message suffix.
     message_prefix = input_message[:start_index].strip()
-    # Including backticks as part of the message content.
+    # Including "***" as part of the message content.
     message_content = input_message[start_index:end_index+3].strip()
     message_suffix = input_message[end_index+3:].strip()
 
-    return message_content
+    print(message_content)
 
+    return message_content
 
 def _validate_message(message):
     message = message.strip()
-    if not (message.startswith("```") and message.endswith("```")):
-        raise MessageValidationError("Message must start and end with ```")
+    if not (message.startswith("***") and message.endswith("***")):
+        raise MessageValidationError("Message must start and end with ***")
     message = message[3:-3].strip()
     lines = message.split("\n")
-    if len(lines) < 4:
+    if len(lines) < 5:
         raise MessageValidationError(
             "Message does not meet the minimum length requirement")
     return lines
 
 
-def _extract_message_info(lines):
-    try:
-        message_info = {line.split(":", 1)[0].strip(): line.split(":", 1)[
-            1].strip() for line in lines[:3]}
-    except (IndexError, ValueError):
-        raise MessageParsingError(
-            "Message metadata (FROM, TO, ACTION) is improperly formed")
-
-    from_str = message_info.get("FROM")
-    to_str = message_info.get("TO")
-    action_str = message_info.get("ACTION")
-
-    if not all([from_str, to_str, action_str]):
-        raise MessageValidationError(
-            "FROM, TO, and ACTION fields are required")
-    if not validate_permission(from_str, to_str, action_str):
-        raise MessageValidationError(
-            f"{from_str} is not allowed to send {action_str} action to {to_str}")
-
-    return message_info
-
-
-def _parse_payload(payload, custom_properties):
-    payload_dict = {}
+def _parse_message(raw_message):
+    parsed_message_dict = {}
     last_key = None
-    for line in payload.split("\n"):
+    for line in raw_message.split("\n"):
         if ":" in line:
             key, value = [part.strip() for part in line.split(":", 1)]
-            if key in custom_properties:
-                payload_dict[key] = value
+            if key in message_properties:
+                if key not in parsed_message_dict:
+                    parsed_message_dict[key] = value
+                else:
+                    parsed_message_dict[key] += "\n" + value
                 last_key = key
             elif last_key:
-                payload_dict[last_key] += "\n" + line
+                parsed_message_dict[last_key] += "\n" + line
         elif last_key:
-            payload_dict[last_key] += "\n" + line
-    return payload_dict
-
-
-def _parse_steps(parsed_message):
-    details = parsed_message.get("DETAILS", "")
-    parsed_steps = []
-    
-    if any(line.strip().startswith("Step") for line in details.split("\n")): 
-        current_step_number = None
-        current_step_description = ""
-        for line in details.split("\n"):
-            line = line.strip() 
-            if line.startswith("Step"):
-                if current_step_number is not None:
-                    parsed_steps.append(
-                        {"step": current_step_number.strip(), "description": current_step_description.strip()})
-                current_step_number, current_step_description = [part.strip() for part in line.split(":", 1)]
-            else:
-                current_step_description += f"\n{line}"
-        if current_step_number is not None:
-            parsed_steps.append({"step": current_step_number.strip(),
-                                "description": current_step_description.strip()})
-    else:
-        step_number = 1
-        for line in details.split("\n"):
-            line = line.strip()
-            if line:  
-                parsed_steps.append({"step": f"Step {step_number}", "description": line})
-                step_number += 1
-
-    return parsed_steps
\ No newline at end of file
+            parsed_message_dict[last_key] += "\n" + line
+    return parsed_message_dict
\ No newline at end of file
diff --git a/messages/sirji_messages/permissions.py b/messages/sirji_messages/permissions.py
index 7590aa6e..5e766228 100644
--- a/messages/sirji_messages/permissions.py
+++ b/messages/sirji_messages/permissions.py
@@ -4,46 +4,36 @@
 # Key: (from_agent, to_agent)
 # Value: set of allowed actions between the agents
 permissions_dict = {
-    (AgentEnum.CODER, AgentEnum.EXECUTOR): {
-        ActionEnum.CREATE_FILE,
+    (AgentEnum.ANY, AgentEnum.EXECUTOR): {
+        ActionEnum.CREATE_PROJECT_FILE,
+        ActionEnum.CREATE_AGENT_OUTPUT_FILE,
         ActionEnum.EXECUTE_COMMAND,
         ActionEnum.RUN_SERVER,
-        ActionEnum.INSTALL_PACKAGE,
-        ActionEnum.READ_FILE,
-        ActionEnum.READ_DIR
+        ActionEnum.READ_PROJECT_FILES,
+        ActionEnum.READ_AGENT_OUTPUT_FILES,
+        ActionEnum.APPEND_TO_AGENT_OUTPUT_INDEX,
+        ActionEnum.READ_AGENT_OUTPUT_INDEX,
+        ActionEnum.FIND_AND_REPLACE,
+        ActionEnum.INSERT_TEXT,
+        ActionEnum.EXTRACT_DEPENDENCIES
     },
-    (AgentEnum.CODER, AgentEnum.PLANNER): (
-        ActionEnum.GENERATE_STEPS
-    ),
-    (AgentEnum.CODER, AgentEnum.RESEARCHER): (
-        ActionEnum.TRAIN_USING_URL,
-        ActionEnum.INFER
-    ),
-    (AgentEnum.CODER, AgentEnum.USER): (
-        ActionEnum.QUESTION,
-        ActionEnum.STEP_STARTED,
-        ActionEnum.STEP_COMPLETED,
+    (AgentEnum.ANY, AgentEnum.SIRJI_USER): {
+        ActionEnum.QUESTION
+    },
+    (AgentEnum.ANY, AgentEnum.CALLER): {
+        ActionEnum.RESPONSE
+    },
+    (AgentEnum.ORCHESTRATOR, AgentEnum.SIRJI_USER): {
         ActionEnum.SOLUTION_COMPLETE
-    ),
-    (AgentEnum.EXECUTOR, AgentEnum.CODER): (
-        ActionEnum.OUTPUT
-    ),
-    (AgentEnum.PLANNER, AgentEnum.CODER): (
-        ActionEnum.STEPS
-    ),
-    (AgentEnum.RESEARCHER, AgentEnum.CODER): (
-        ActionEnum.RESPONSE,
-        ActionEnum.TRAINING_OUTPUT
-    ),
-    (AgentEnum.USER, AgentEnum.CODER): (
-        ActionEnum.PROBLEM_STATEMENT,
-        ActionEnum.ANSWER,
-        ActionEnum.ACKNOWLEDGE,
-        ActionEnum.FEEDBACK
-    )
+    },
+    (AgentEnum.ORCHESTRATOR, AgentEnum.ANY): {
+        ActionEnum.INVOKE_AGENT,
+        ActionEnum.INVOKE_AGENT_EXISTING_SESSION
+    }
 }
 
 
+
 def validate_permission(from_str, to_str, action_str):
     try:
         # Convert the string representations to corresponding enum values
diff --git a/messages/sirji_messages/system_prompts/__init__.py b/messages/sirji_messages/system_prompts/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/messages/sirji_messages/system_prompts/agents/__init__.py b/messages/sirji_messages/system_prompts/agents/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/messages/sirji_messages/system_prompts/agents/base.py b/messages/sirji_messages/system_prompts/agents/base.py
deleted file mode 100644
index 7db5484e..00000000
--- a/messages/sirji_messages/system_prompts/agents/base.py
+++ /dev/null
@@ -1,141 +0,0 @@
-from abc import ABC, abstractmethod
-
-from sirji_messages import MessageFactory, ActionEnum
-
-
-class AgentSystemPromptBase(ABC):
-
-    def system_prompt(self):
-        system_prompt = ""
-        system_prompt += f"{self.intro()}\n"
-
-        system_prompt += "Your job is to:"
-        system_prompt += f"{self.responsibilities()}\n"
-
-        system_prompt += f"{self.can_interact_with()}"
-
-        system_prompt += f"{self.other_agents_capabilities()}"
-
-        system_prompt += f"{self.interactions()}"
-
-        system_prompt += f"{self.ending_prompt()}"
-
-        # print(system_prompt)
-
-        return system_prompt
-
-    @abstractmethod
-    def short_name(self):
-        """
-        Agent short name - taken from correct agent enum.
-        """
-        pass
-
-    @abstractmethod
-    def intro(self):
-        """
-        Agent intro.
-        """
-        pass
-
-    @abstractmethod
-    def responsibilities(self):
-        """
-        Agent responsibilities.
-        """
-        pass
-
-    @abstractmethod
-    def capabilities(self):
-        """
-        Agent capabilties.
-        """
-        pass
-
-    @abstractmethod
-    def ending_prompt(self):
-        """
-        Agent ending message for the system prompt.
-        """
-        pass
-
-    def can_interact_with(self):
-        can_interact_with_message = ""
-
-        other_agents = self.get_other_agents()
-
-        if not other_agents:
-            return can_interact_with_message
-
-        can_interact_with_message += f"You can interact with:\n"
-        for agent_enum in other_agents:
-            can_interact_with_message += f"- {agent_enum.full_name} ({agent_enum.name}).\n"
-
-        can_interact_with_message += "\n"
-
-        return can_interact_with_message
-
-    def other_agents_capabilities(self):
-        other_agents_capabilities_message = ""
-
-        other_agents = self.get_other_agents()
-
-        if not other_agents:
-            return other_agents_capabilities_message
-
-        for agent_enum in other_agents:
-            other_agents_capabilities_message += f"{agent_enum.name} can:"
-
-            from sirji_messages.system_prompts.factory import AgentSystemPromptFactory
-
-            other_agents_capabilities_message += f"{AgentSystemPromptFactory[agent_enum.name]().capabilities()}\n\n"
-
-        return other_agents_capabilities_message
-
-    def interactions(self):
-        interactions_message = "Allowed responses and their formats are described below.\n\n"
-
-        # We create a helper function to reduce redundancy
-        def append_action_messages(actions, heading):
-            action_message = heading
-
-            # Check if 'actions' is a single ActionEnum object and not an iterable (list, set, etc.)
-            if isinstance(actions, ActionEnum):
-                actions = [actions]  # Convert it into a list
-
-            for count, action_enum in enumerate(actions, start=1):
-                message_obj = MessageFactory[action_enum.name]()
-                action_message += f"{count}. {message_obj.description()}\n{message_obj.sample()}\n"
-
-            return action_message
-
-        from sirji_messages import permissions_dict
-
-        # Iterating through each key-value pair in the permissions_dict
-        for agents, actions in permissions_dict.items():
-            from_agent, to_agent = agents  # Unpacking the key which is a tuple of two agents
-
-            # Dynamically determining which messages to append based on the agent's role
-            if self.short_name() == from_agent.name:
-                heading = f"The allowed responses that you can send to the {to_agent.name} are:\n\n"
-                interactions_message += append_action_messages(
-                    actions, heading)
-            elif self.short_name() == to_agent.name:
-                heading = f"The allowed responses from the {from_agent.name} to you are:\n\n"
-                interactions_message += append_action_messages(
-                    actions, heading)
-
-        return interactions_message
-
-    def get_other_agents(self):
-        other_agents = set()
-        from sirji_messages import permissions_dict
-        for agents, _ in permissions_dict.items():
-            from_agent, to_agent = agents  # Unpacking the key which is a tuple of two agents
-
-            if self.short_name() == from_agent.name:
-                other_agents.add(to_agent)
-            elif self.short_name() == to_agent.name:
-                other_agents.add(from_agent)
-
-        return other_agents
diff --git a/messages/sirji_messages/system_prompts/agents/coder.py b/messages/sirji_messages/system_prompts/agents/coder.py
deleted file mode 100644
index 53dca16d..00000000
--- a/messages/sirji_messages/system_prompts/agents/coder.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import textwrap
-import os
-
-from sirji_messages import AgentEnum, ActionEnum
-
-from .base import AgentSystemPromptBase
-
-
-class CoderSystemPrompt(AgentSystemPromptBase):
-
-    def name(self):
-        return AgentEnum.CODER.full_name
-
-    def short_name(self):
-        return AgentEnum.CODER.name
-
-    def intro(self):
-        return textwrap.dedent(f"""
-          You are a {self.name()} ({self.short_name()}), an expert software engineer skilled in writing code across various areas. Your expertise includes multiple backend programming languages, frontend technologies, DevOps technologies, databases, caching, third-party libraries, and APIs. Additionally, you are proficient in writing test cases, creating documentation, and programmatically solving given problem statements (PS).
-          """)
-    # - Ensure that every code and command execution output is always written in a log file using packages like "tee" and execute in background using "nohup". For example: nohup command | tee <<log file name which can be used to check the output>> &
-    def responsibilities(self):
-        return textwrap.dedent(f"""
-            - Ensure you write a user story for the problem statement and get it finalized with the {AgentEnum.USER.name}:
-                - First understand the given problem statement, write a user story by enhancing the requirements and features in problem statement.
-                - Make sure that key points, information and data is always present in the user story.
-                - Have the features listed as points in the user story.
-                - Then send this user story as a {ActionEnum.QUESTION.name} to get a confirmation on. The message details should look like: "\nHere's the user story based on your problem statement:\n\n <<user story>> \n\nDoes everything look good, or would you like any changes?"
-            - Once the user story is finalized, then ensure to prepare a list of architecture components needed (by considering the problem statement and the finalized user story) and get it finalized with the {AgentEnum.USER.name}:
-                - Prepare list of architecture components including things like:
-                    - Programming language (example: Python, Node.js),
-                    - Framework (example: Express, Flask),
-                    - Database (example: PostgreSQL, MySQL),
-                    - Cache (example: Memcache, Redis), etc.
-                - Do not include Hosting component.
-                - Show the architecture components listed as points. Also specify intent of each component.
-                - Send the architecture components as a {ActionEnum.QUESTION.name} to get a confirmation on. The message details should look like: "\nHere are the main parts of the architecture::\n\n <<architecture components>> \n\nDoes everything look good to you, or do you need any adjustments?"
-            - Once architecture components are finalized, then {ActionEnum.GENERATE_STEPS.name} to solve the problem statement:
-                - Share the problem statement, finalized user story and finalized architecture compoents with {AgentEnum.PLANNER.name} to get the list of steps on how to solve the problem statement (PS).
-                - The message details shared with the planner should look like "\n\nProblem Statement (PS):\n<<problem statement>>\n\nUser Story:\n<<finalized user story>>\n\nArchitecture Components:\n<<finalized architecture components>>"
-            - Once steps are generated, ensure to solve the problem statement programatically by following the generated steps (one step at a time sequentially):
-                - Always write end-to-end working code in accordance with the problem statement, user story, and architectural components.
-                - Write concrete code and not just conceptualize or outline or simulate it.
-                - Identify URLs (Excluding GitHub) present in the PS, on which you have no knowledge and want to be trained on or researched. After training, infer from the trained content/knowledge. If the response of the inference has new URLs (Excluding GitHub), on which you have no knowledge, you can get trained on them too.
-                - Follow secure software development practices while generating code.
-                - Ensure that you don't create any file/folder outside of workspace root folder, i.e. './'
-                - Read the GitHub files by first cloning the repository and then reading the files at once.
-            - Ensure while responding with {ActionEnum.EXECUTE_COMMAND.name} action or {ActionEnum.INSTALL_PACKAGE.name} action:
-                - Command must be compatible with {os.name}.
-                - Command must be sufficiently chained. For example: 'source venv/bin/activate && pip install openai', 'cd server && npm run start'
-            - Always make sure:
-                - To respond with the {ActionEnum.RUN_SERVER.name} action to run a server like continuous process.
-                - Ensure if the step is to verify whether a command is installed or not, you check them one at a time.
-                - Pose explicit questions only when you have no other option but to reach out to the user. An ideal question format is direct, such as "Should I ...?" Additionally, it is crucial to ask such questions only when absolutely necessary.
-                - Regarding step status change messages ({ActionEnum.STEP_STARTED.name} action, {ActionEnum.STEP_COMPLETED.name} action):
-                    - Always implement / work on one step at a time, let's call it the current step.
-                    - If the work for the current step was already done as a part of some previous step, respond with {ActionEnum.STEP_COMPLETED.name} action for the current step.
-                    - Before starting work for the current step, respond with {ActionEnum.STEP_STARTED.name} action for the current step.
-                    - Before moving to the next step, respond with {ActionEnum.STEP_COMPLETED.name} action for the current step.
-                - Only interact with the agents listed below using the allowed responses, also mentioned below.
-                - Ensure the response is also enclosed inside 3 backticks (```).
-                - If error is encountered in execution of a command, then find the root cause and resolve the issue by solving the root cause.
-                - End the conversation if your solution is complete as per the problem statement, finalized user story and finalized architecture components.
-            """)
-
-    def capabilities(self):
-        return ""  # This should not be called.
-
-    def ending_prompt(self):
-        return ""
diff --git a/messages/sirji_messages/system_prompts/agents/executor.py b/messages/sirji_messages/system_prompts/agents/executor.py
deleted file mode 100644
index 4799de9e..00000000
--- a/messages/sirji_messages/system_prompts/agents/executor.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import textwrap
-import os
-
-from sirji_messages import AgentEnum, ActionEnum
-
-from .planner import PlannerSystemPrompt
-
-from .base import AgentSystemPromptBase
-
-
-class ExecutorSystemPrompt(AgentSystemPromptBase):
-
-    def name(self):
-        return AgentEnum.EXECUTOR.full_name
-
-    def short_name(self):
-        return AgentEnum.EXECUTOR.name
-
-    def intro(self):
-        return ""  # This will never be called.
-
-    def responsibilities(self):
-        return ""  # This will never be called.
-
-    def capabilities(self):
-        return textwrap.dedent(f"""
-          - Interact with {os.name} terminal.
-          - Run server like continuous process using {ActionEnum.RUN_SERVER.name} action.
-          - Create or update files using {ActionEnum.CREATE_FILE.name} action.
-          - Read content from a single file using {ActionEnum.READ_FILE.name} action.
-          - Read the content from all files in a directory and all its subdirectories at once (separated by a divider) using {ActionEnum.READ_DIR.name} action.
-          - Install required dependencies/packages/libraries using {ActionEnum.INSTALL_PACKAGE.name} action.
-          - Execute code and command using {ActionEnum.EXECUTE_COMMAND.name} action. Chained commands (using &&) are not supported.
-          """)
-
-    def ending_prompt(self):
-        return ""  # This will never be called.
diff --git a/messages/sirji_messages/system_prompts/agents/planner.py b/messages/sirji_messages/system_prompts/agents/planner.py
deleted file mode 100644
index ec146bcd..00000000
--- a/messages/sirji_messages/system_prompts/agents/planner.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum
-
-from .base import AgentSystemPromptBase
-
-
-class PlannerSystemPrompt(AgentSystemPromptBase):
-
-    def name(self):
-        return AgentEnum.PLANNER.full_name
-
-    def short_name(self):
-        return AgentEnum.PLANNER.name
-
-    def intro(self):
-        return textwrap.dedent(f"""
-          You are a {self.name()} ({self.short_name()}), an expert software architect skilled in devising steps to solve the given problem statement (PS). These steps will be utilized by an expert software developer whose expertise includes multiple backend programming languages, frontend technologies, DevOps technologies, databases, caching, third-party libraries, and APIs, and who is proficient in writing test cases and creating documentation.
-          """)
-    # - Ensure that all the steps are about either create file or install package or execute command or execute code to debug or git clone or read single file or read all files in a directory (including those in its subdirectories).
-    # - Don't explain the steps further using sub-steps.
-    # - Focus on particular data points given in the PS and not solve the problem in an over-generalized manner.
-    def responsibilities(self):
-        return textwrap.dedent(f"""
-          - Pay close attention to problem statement, user story and architecture components while generating steps to solve the problem programmatically.
-          - Ensure that each step in the list of steps should start with 'Step #: ....'
-          - Explain, in each step, what exact task needs to be done. For example: In Javascript file, implement xyz methods having abc capabilities.
-          - Directing the installation of programming language-specific packages or libraries in the project folder, ensuring there is no interference with machine-level/global installations. For instance, utilize venv for installing Python dependencies and package.json for Node.js dependencies.
-          - Ensuring that you first verify whether a system-level command is already installed. If it is not installed, you must inquire whether you have permission to install it.
-          - Ensure not to ask to create a new folder for the project. Treat '.' as the project root.
-          - Always add a step to execute the code and evaluate the response output. If the response has errors, solve them before moving ahead.
-          """)
-
-    def capabilities(self):
-        return textwrap.dedent("""
-          - Generate steps to solve the problem programmatically.
-          """)
-
-    def ending_prompt(self):
-        return ""
diff --git a/messages/sirji_messages/system_prompts/agents/researcher.py b/messages/sirji_messages/system_prompts/agents/researcher.py
deleted file mode 100644
index ff7886f8..00000000
--- a/messages/sirji_messages/system_prompts/agents/researcher.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum
-
-from .base import AgentSystemPromptBase
-
-
-class ResearcherSystemPrompt(AgentSystemPromptBase):
-
-    def name(self):
-        return AgentEnum.RESEARCHER.full_name
-
-    def short_name(self):
-        return AgentEnum.RESEARCHER.name
-
-    def intro(self):
-        return ""  # This will never be called.
-
-    def responsibilities(self):
-        return ""  # This will never be called.
-
-    def capabilities(self):
-        return textwrap.dedent("""
-            - Crawl the given URL and get trained on its content.
-            - Infer from the trained content/knowledge and try to respond to questions asked.
-            """)
-
-    def ending_prompt(self):
-        return ""  # This will never be called.
diff --git a/messages/sirji_messages/system_prompts/agents/user.py b/messages/sirji_messages/system_prompts/agents/user.py
deleted file mode 100644
index 4361ad00..00000000
--- a/messages/sirji_messages/system_prompts/agents/user.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import textwrap
-
-from sirji_messages import AgentEnum
-
-from .planner import PlannerSystemPrompt
-
-from .base import AgentSystemPromptBase
-
-
-class UserSystemPrompt(AgentSystemPromptBase):
-
-    def name(self):
-        return AgentEnum.USER.full_name
-
-    def short_name(self):
-        return AgentEnum.USER.name
-
-    def intro(self):
-        return ""  # This will never be called.
-
-    def responsibilities(self):
-        return ""  # This will never be called.
-
-    def capabilities(self):
-        return textwrap.dedent("""
-          - Provide the problem statement (PS).   
-          - Provide the answer to the question asked.             
-          - Acknowledge started or completed steps.
-          - Acknowledge the final solution.
-          """)
-
-    def ending_prompt(self):
-        return ""  # This will never be called.
diff --git a/messages/sirji_messages/system_prompts/factory.py b/messages/sirji_messages/system_prompts/factory.py
deleted file mode 100644
index 3c53938f..00000000
--- a/messages/sirji_messages/system_prompts/factory.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from sirji_messages import AgentEnum
-
-# Import all the agent system prompt classes
-from .agents.coder import CoderSystemPrompt
-from .agents.planner import PlannerSystemPrompt
-from .agents.researcher import ResearcherSystemPrompt
-from .agents.executor import ExecutorSystemPrompt
-from .agents.user import UserSystemPrompt
-
-
-class MetaAgentSystemPromptFactory(type):
-    def __getitem__(cls, agent):
-        try:
-            agent_enum = AgentEnum[agent]
-            return cls._agent_system_prompt_map[agent_enum]
-        except KeyError as e:
-            raise AttributeError(
-                f"{agent} not found in AgentSystemPromptFactory or Agent Enum.") from e
-
-# Use the metaclass for our factory
-
-
-class AgentSystemPromptFactory(metaclass=MetaAgentSystemPromptFactory):
-
-    # Map ActionTypes to their respective message classes
-    _agent_system_prompt_map = {
-        AgentEnum.CODER: CoderSystemPrompt,
-        AgentEnum.PLANNER: PlannerSystemPrompt,
-        AgentEnum.RESEARCHER: ResearcherSystemPrompt,
-        AgentEnum.EXECUTOR: ExecutorSystemPrompt,
-        AgentEnum.USER: UserSystemPrompt
-    }
diff --git a/sirji/vscode-extension/README.md b/sirji/vscode-extension/README.md
index f49dbafb..93977d96 100644
--- a/sirji/vscode-extension/README.md
+++ b/sirji/vscode-extension/README.md
@@ -3,7 +3,7 @@
 </p>
 
 <p align="center">
-  <em>Sirji is an Open Source AI Software Development Agent.</em>
+  <em>Sirji is an agentic AI framework for software development.</em>
 </p>
 
 <p align="center">
@@ -24,33 +24,20 @@
 
 ## Sirji
 
-Sirji is a Visual Studio Code extension that works as an AI software development agent.
+Sirji as an open-source framework where various AI agents collaborate via a messaging protocol to solve a given software problem. Problems range from building greenfield web apps to solving GitHub issues, writing test cases, and generating documentation.
 
-It is a virtual software developer that includes individual agents for planning, coding, researching, and executing projects.
+Sirji uses either the standard or user-generated recipe, that lists prescribed tasks and tips for solving a particular problem. Recipe also indicates which agent should perform each task.
 
-Sirji solves users’ problem statements ranging from a new greenfield project to an existing brownfield project where it enhances existing code, fixes bugs, and writes test cases.
+An Agent in the Sirji framework is a modular AI component that performs a specific task based on a custom pseudo code. The community can create a custom agent either by modifying an already existing agent or write entirely new agent with entirely different pseudo code.
 
-The extension leverages the capabilities of VS Code, including the Editor, Terminal, and Project Explorer.
-
-It provides an interactive chat interface through which users submit their problem statements, answer questions, and provide feedback to Sirji.
-
-Additionally and most importantly, Sirji sets up your local development environment by installing system-level packages as well as programming language-specific dependencies. It later executes the generated code in your local development environment.
-
-## Demo Video
-
-```
-Create a fully interactive website for playing the Tic-Tac-Toe game.
-```
-
-Watch on YouTube: <a href="https://www.youtube.com/watch?v=DC_gmz04Ovs" target="_blank">https://www.youtube.com/watch?v=DC_gmz04Ovs</a>
+Sirji is currently implemented as a Visual Studio Code extension. This extension provides an interactive chat interface right within your IDE through which you can submit your problem statement and give feedback to Sirji.
 
-<a href="https://www.youtube.com/watch?v=DC_gmz04Ovs" target="_blank"><img src="https://github.com/sirji-ai/sirji/assets/7627517/fff071a6-f019-4797-ad44-55d7670e819f" alt="Tic Tac Toe game by Sirji"></a>
+The extension leverages the capabilities of VS Code, including the Editor, Terminal, and Project Explorer.
 
+Additionally, Sirji sets up your local or remote development environment by installing system-level packages and programming language-specific dependencies. It executes the generated code in your local or remote development environment.
 
 ## Prerequisites
 
-Sirji has been tested on **macOS** only for now. We know there are certain OS-specific functionalities that we will soon generalize.
-
 Make sure you have installed all of the following prerequisites on your machine:
 
 - Visual Studio Code (>= 1.80.2)
@@ -58,7 +45,15 @@ Make sure you have installed all of the following prerequisites on your machine:
 - Python (>= 3.10) - Make sure `python --version` runs without error.
 - tee command - Make sure `which tee` runs without error.
 
-Also, you will need an OpenAI API key to access the GPT-4 Turbo model.
+Also, you will need an OpenAI API key to access the GPT-4o model.
+
+## Demo Video
+
+Here's a three-minute demo showing the five-second Sirji installation, followed by a quick walkthrough of Sirji's attempt to solve a given problem statement (building an interactive Tic-Tac-Toe game website).
+
+Watch on YouTube: <a href="https://www.youtube.com/watch?v=r1wJHLUDVTo" target="_blank">https://www.youtube.com/watch?v=r1wJHLUDVTo</a>
+
+<a href="https://www.youtube.com/watch?v=r1wJHLUDVTo" target="_blank"><img src="https://github.com/sirji-ai/sirji/assets/7627517/a21804a7-06d5-4974-ae94-bb72870b93fd" alt="Tic Tac Toe game by Sirji"></a>
 
 ## Installation
 
@@ -66,16 +61,33 @@ You can start using Sirji by installing this [extension](https://marketplace.vis
 
 ## Architecture
 
-Sirji gets the work done using it's following agents:
+Let's go step by step in understanding the architecture.
 
-- The **Planning Agent** takes a problem statement and breaks it down into steps.
-- The **Coding Agent** proceeds step by step through the generated steps to solve the problem programmatically.
-- The **Research Agent** utilizes RAG (Retrieval-Augmented Generation) and gets trained on URLs and search terms. It can later use this acquired knowledge to answer questions posed by the Coding Agent.
-- The **Executor Agent** is responsible for Filesystem CRUD, executing commands, and installing dependencies. The Executor Agent is implemented directly within the extension and is written in TypeScript.
+### Agent
 
-### Architecture Diagram
+An Agent in the Sirji framework is a modular AI component that performs a specific task based on a custom pseudo code.
+
+An agent defines its skills in an agent.yml file. This file lists the skills of the agent and the pseudo code to follow for each skill. It also specifies the LLM provider and model to be used for inference. Additionally, it lists the sub-agents that can be invoked from within the agent to complete certain parts of the task.
+
+### Recipe (recipe.json)
+
+A Recipe is a file that lists prescribed tasks and tips for solving a particular problem. It also indicates which agent should perform each task. The tips provide guidance for addressing issues that arise when tasks are performed out of the prescribed order. Each tip specifies the task and the agent responsible for it.
+
+### Orchestrator
+
+The Orchestrator is the central component in the Sirji framework, responsible for managing the flow and execution of tasks across different agents as per the recipe.
+
+### Agent Sessions
+An agent can be invoked in either a fresh session or asked to continue an existing session. When invoked in a new session, it starts with a new system prompt and does not retain the context from the previous session. Sessions help keep the context focused on specific tasks.
 
-<img width="100%" alt="VS Code Extension - Architecture" src="https://github.com/sirji-ai/sirji/assets/7627517/0cee6e34-a42a-4db0-81db-d2f930132465">
+### Project Folder
+The Project Folder is the primary directory for accessing all user-specific project files, including code files, documentation, and other relevant resources. When initializing Sirji, the user selects this folder as the primary workspace for the project.
+
+### Agent Output Folder
+The Agent Output Folder is designated for storing the results and data outputs generated by the agents. This folder is different from the project folder and this ensures that operational data is kept separate from project files.
+
+#### Agent Output Index
+The Agent Output Index is an index file for the Agent Output Folder that keeps track of all files written by agents in that folder along with the a brief description of the file contents.
 
 ### PyPI Packages
 
@@ -87,6 +99,19 @@ The tools for crawling URLs (converting them into markdowns), searching for term
 
 All these packages are invoked by Python Adapter Scripts, which are spawned by the extension.
 
+### Architecture Diagram
+![Sirji - Architecture Diagram](https://github.com/sirji-ai/sirji/assets/7627517/9068c6d1-a11b-4589-b09e-ad494334fd6b)
+
+## Roadmap
+We are calling our next release the ‘Core’ Release (ONGOING. ETA - May 20).
+
+Here is the link to the ‘Core’ release’s roadmap: https://github.com/orgs/sirji-ai/projects/5
+
+This is a significant release focused on the following key areas:
+- **User accounts**: Users will be required to create an account with Sirji. They can either bring their own LLM key or subscribe to a free but rate-limited Developer plan.
+- **Improve reliability**: The first version of the VS Code extension improved usability, but after using it ourselves for a while, we identified several issues and limitations ranging from incomplete solutions to a lack of web debugging capabilities. We are addressing these issues to make Sirji more reliable in solving software problems.
+- **Custom agents and recipes**: We are developing the framework to enable users to create and use custom agents and recipes (instructions on how the agents interact). This involves enhancing the orchestration functionality and refactoring existing base agents.
+
 ## Contributing
 
 We welcome contributions to Sirji! If you're interested in helping improve this VS Code extension, please take a look at our [Contributing Guidelines](./CONTRIBUTING.md) for more information on how to get started.
diff --git a/sirji/vscode-extension/package-lock.json b/sirji/vscode-extension/package-lock.json
index ac26f065..a8f7fff1 100644
--- a/sirji/vscode-extension/package-lock.json
+++ b/sirji/vscode-extension/package-lock.json
@@ -1,51 +1,243 @@
 {
   "name": "sirji",
-  "version": "0.0.1",
-  "lockfileVersion": 1,
+  "version": "0.0.11",
+  "lockfileVersion": 3,
   "requires": true,
-  "dependencies": {
-    "@aashutoshrathi/word-wrap": {
-      "version": "1.2.6",
-      "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
-      "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
-      "dev": true
+  "packages": {
+    "": {
+      "name": "sirji",
+      "version": "0.0.11",
+      "license": "MIT",
+      "dependencies": {
+        "@babel/parser": "^7.24.5",
+        "@babel/traverse": "^7.24.5",
+        "mime-types": "^2.1.35",
+        "uuid": "^9.0.1"
+      },
+      "devDependencies": {
+        "@types/babel__traverse": "^7.20.5",
+        "@types/esprima": "^4.0.6",
+        "@types/mime-types": "^2.1.4",
+        "@types/mocha": "^10.0.6",
+        "@types/node": "18.x",
+        "@types/uuid": "^9.0.8",
+        "@types/vscode": "^1.80.2",
+        "@typescript-eslint/eslint-plugin": "^7.0.2",
+        "@typescript-eslint/parser": "^7.0.2",
+        "@vscode/test-cli": "^0.0.6",
+        "@vscode/test-electron": "^2.3.9",
+        "concurrently": "^8.2.2",
+        "eslint": "^8.56.0",
+        "nodemon": "^3.1.0",
+        "typescript": "^5.3.3"
+      },
+      "engines": {
+        "vscode": "^1.80.2"
+      }
+    },
+    "node_modules/@babel/code-frame": {
+      "version": "7.24.2",
+      "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.2.tgz",
+      "integrity": "sha512-y5+tLQyV8pg3fsiln67BVLD1P13Eg4lh5RW9mF0zUuvLrv9uIQ4MCL+CRT+FTsBlBjcIan6PGsLcBN0m3ClUyQ==",
+      "dependencies": {
+        "@babel/highlight": "^7.24.2",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/generator": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.5.tgz",
+      "integrity": "sha512-x32i4hEXvr+iI0NEoEfDKzlemF8AmtOP8CcrRaEcpzysWuoEb1KknpcvMsHKPONoKZiDuItklgWhB18xEhr9PA==",
+      "dependencies": {
+        "@babel/types": "^7.24.5",
+        "@jridgewell/gen-mapping": "^0.3.5",
+        "@jridgewell/trace-mapping": "^0.3.25",
+        "jsesc": "^2.5.1"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-environment-visitor": {
+      "version": "7.22.20",
+      "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
+      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-function-name": {
+      "version": "7.23.0",
+      "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
+      "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+      "dependencies": {
+        "@babel/template": "^7.22.15",
+        "@babel/types": "^7.23.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-hoist-variables": {
+      "version": "7.22.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
+      "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+      "dependencies": {
+        "@babel/types": "^7.22.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-split-export-declaration": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.5.tgz",
+      "integrity": "sha512-5CHncttXohrHk8GWOFCcCl4oRD9fKosWlIRgWm4ql9VYioKm52Mk2xsmoohvm7f3JoiLSM5ZgJuRaf5QZZYd3Q==",
+      "dependencies": {
+        "@babel/types": "^7.24.5"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
     },
-    "@babel/runtime": {
+    "node_modules/@babel/helper-string-parser": {
       "version": "7.24.1",
-      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.1.tgz",
-      "integrity": "sha512-+BIznRzyqBf+2wCTxcKE3wDjfGeCoVE61KSHGpkzqrLi8qxqFwBeUFyId2cxkTmm55fzDGnm0+yCxaxygrLUnQ==",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.1.tgz",
+      "integrity": "sha512-2ofRCjnnA9y+wk8b9IAREroeUP02KHp431N2mhKniy2yKIDKpbrHv9eXwm8cBeWQYcJmzv5qKCu65P47eCF7CQ==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/helper-validator-identifier": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.5.tgz",
+      "integrity": "sha512-3q93SSKX2TWCG30M2G2kwaKeTYgEUp5Snjuj8qm729SObL6nbtUldAi37qbxkD5gg3xnBio+f9nqpSepGZMvxA==",
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/highlight": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.5.tgz",
+      "integrity": "sha512-8lLmua6AVh/8SLJRRVD6V8p73Hir9w5mJrhE+IPpILG31KKlI9iz5zmBYKcWPS59qSfgP9RaSBQSHHE81WKuEw==",
+      "dependencies": {
+        "@babel/helper-validator-identifier": "^7.24.5",
+        "chalk": "^2.4.2",
+        "js-tokens": "^4.0.0",
+        "picocolors": "^1.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/parser": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.5.tgz",
+      "integrity": "sha512-EOv5IK8arwh3LI47dz1b0tKUb/1uhHAnHJOrjgtQMIpu1uXd9mlFrJg9IUgGUgZ41Ch0K8REPTYpO7B76b4vJg==",
+      "bin": {
+        "parser": "bin/babel-parser.js"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@babel/runtime": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.24.5.tgz",
+      "integrity": "sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "regenerator-runtime": "^0.14.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/template": {
+      "version": "7.24.0",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.0.tgz",
+      "integrity": "sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==",
+      "dependencies": {
+        "@babel/code-frame": "^7.23.5",
+        "@babel/parser": "^7.24.0",
+        "@babel/types": "^7.24.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/traverse": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.5.tgz",
+      "integrity": "sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==",
+      "dependencies": {
+        "@babel/code-frame": "^7.24.2",
+        "@babel/generator": "^7.24.5",
+        "@babel/helper-environment-visitor": "^7.22.20",
+        "@babel/helper-function-name": "^7.23.0",
+        "@babel/helper-hoist-variables": "^7.22.5",
+        "@babel/helper-split-export-declaration": "^7.24.5",
+        "@babel/parser": "^7.24.5",
+        "@babel/types": "^7.24.5",
+        "debug": "^4.3.1",
+        "globals": "^11.1.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
+    "node_modules/@babel/types": {
+      "version": "7.24.5",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.5.tgz",
+      "integrity": "sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==",
+      "dependencies": {
+        "@babel/helper-string-parser": "^7.24.1",
+        "@babel/helper-validator-identifier": "^7.24.5",
+        "to-fast-properties": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=6.9.0"
       }
     },
-    "@bcoe/v8-coverage": {
+    "node_modules/@bcoe/v8-coverage": {
       "version": "0.2.3",
       "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
       "dev": true
     },
-    "@eslint-community/eslint-utils": {
+    "node_modules/@eslint-community/eslint-utils": {
       "version": "4.4.0",
       "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
       "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "eslint-visitor-keys": "^3.3.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "peerDependencies": {
+        "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
       }
     },
-    "@eslint-community/regexpp": {
+    "node_modules/@eslint-community/regexpp": {
       "version": "4.10.0",
       "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz",
       "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+      }
     },
-    "@eslint/eslintrc": {
+    "node_modules/@eslint/eslintrc": {
       "version": "2.1.4",
       "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz",
       "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ajv": "^6.12.4",
         "debug": "^4.3.2",
         "espree": "^9.6.0",
@@ -56,84 +248,120 @@
         "minimatch": "^3.1.2",
         "strip-json-comments": "^3.1.1"
       },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
       "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "@eslint/js": {
+    "node_modules/@eslint/js": {
       "version": "8.57.0",
       "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz",
       "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      }
     },
-    "@humanwhocodes/config-array": {
+    "node_modules/@humanwhocodes/config-array": {
       "version": "0.11.14",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz",
       "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@humanwhocodes/object-schema": "^2.0.2",
         "debug": "^4.3.1",
         "minimatch": "^3.0.5"
       },
+      "engines": {
+        "node": ">=10.10.0"
+      }
+    },
+    "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
       "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/@humanwhocodes/config-array/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "@humanwhocodes/module-importer": {
+    "node_modules/@humanwhocodes/module-importer": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
       "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=12.22"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
     },
-    "@humanwhocodes/object-schema": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz",
-      "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==",
+    "node_modules/@humanwhocodes/object-schema": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz",
+      "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==",
       "dev": true
     },
-    "@isaacs/cliui": {
+    "node_modules/@isaacs/cliui": {
       "version": "8.0.2",
       "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
       "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "string-width": "^5.1.2",
         "string-width-cjs": "npm:string-width@^4.2.0",
         "strip-ansi": "^7.0.1",
@@ -141,277 +369,403 @@
         "wrap-ansi": "^8.1.0",
         "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
       },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+      "dev": true,
       "dependencies": {
-        "ansi-regex": {
-          "version": "6.0.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
-          "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "6.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
-          "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
-          "dev": true
-        },
-        "emoji-regex": {
-          "version": "9.2.2",
-          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
-          "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
-          "dev": true
-        },
-        "string-width": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
-          "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
-          "dev": true,
-          "requires": {
-            "eastasianwidth": "^0.2.0",
-            "emoji-regex": "^9.2.2",
-            "strip-ansi": "^7.0.1"
-          }
-        },
-        "strip-ansi": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
-          "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^6.0.1"
-          }
-        },
-        "wrap-ansi": {
-          "version": "8.1.0",
-          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
-          "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "^6.1.0",
-            "string-width": "^5.0.1",
-            "strip-ansi": "^7.0.1"
-          }
-        }
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
-    "@istanbuljs/schema": {
+    "node_modules/@istanbuljs/schema": {
       "version": "0.1.3",
       "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
       "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/@jridgewell/gen-mapping": {
+      "version": "0.3.5",
+      "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz",
+      "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
+      "dependencies": {
+        "@jridgewell/set-array": "^1.2.1",
+        "@jridgewell/sourcemap-codec": "^1.4.10",
+        "@jridgewell/trace-mapping": "^0.3.24"
+      },
+      "engines": {
+        "node": ">=6.0.0"
+      }
     },
-    "@jridgewell/resolve-uri": {
+    "node_modules/@jridgewell/resolve-uri": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
       "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
-      "dev": true
+      "engines": {
+        "node": ">=6.0.0"
+      }
+    },
+    "node_modules/@jridgewell/set-array": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
+      "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
+      "engines": {
+        "node": ">=6.0.0"
+      }
     },
-    "@jridgewell/sourcemap-codec": {
+    "node_modules/@jridgewell/sourcemap-codec": {
       "version": "1.4.15",
       "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
-      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
-      "dev": true
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
     },
-    "@jridgewell/trace-mapping": {
+    "node_modules/@jridgewell/trace-mapping": {
       "version": "0.3.25",
       "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
       "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
-      "dev": true,
-      "requires": {
+      "dependencies": {
         "@jridgewell/resolve-uri": "^3.1.0",
         "@jridgewell/sourcemap-codec": "^1.4.14"
       }
     },
-    "@nodelib/fs.scandir": {
+    "node_modules/@nodelib/fs.scandir": {
       "version": "2.1.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
       "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@nodelib/fs.stat": "2.0.5",
         "run-parallel": "^1.1.9"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "@nodelib/fs.stat": {
+    "node_modules/@nodelib/fs.stat": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
       "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
     },
-    "@nodelib/fs.walk": {
+    "node_modules/@nodelib/fs.walk": {
       "version": "1.2.8",
       "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
       "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@nodelib/fs.scandir": "2.1.5",
         "fastq": "^1.6.0"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "@pkgjs/parseargs": {
+    "node_modules/@pkgjs/parseargs": {
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
       "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
       "dev": true,
-      "optional": true
+      "optional": true,
+      "engines": {
+        "node": ">=14"
+      }
     },
-    "@tootallnate/once": {
+    "node_modules/@tootallnate/once": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
       "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+      "dev": true,
+      "engines": {
+        "node": ">= 6"
+      }
+    },
+    "node_modules/@types/babel__traverse": {
+      "version": "7.20.5",
+      "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.5.tgz",
+      "integrity": "sha512-WXCyOcRtH37HAUkpXhUduaxdm82b4GSlyTqajXviN4EfiuPgNYR109xMCKvpl6zPIpua0DGlMEDCq+g8EdoheQ==",
+      "dev": true,
+      "dependencies": {
+        "@babel/types": "^7.20.7"
+      }
+    },
+    "node_modules/@types/esprima": {
+      "version": "4.0.6",
+      "resolved": "https://registry.npmjs.org/@types/esprima/-/esprima-4.0.6.tgz",
+      "integrity": "sha512-lIk+kSt9lGv5hxK6aZNjiUEGZqKmOTpmg0tKiJQI+Ow98fLillxsiZNik5+RcP7mXL929KiTH/D9jGtpDlMbVw==",
+      "dev": true,
+      "dependencies": {
+        "@types/estree": "*"
+      }
+    },
+    "node_modules/@types/estree": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz",
+      "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
       "dev": true
     },
-    "@types/istanbul-lib-coverage": {
+    "node_modules/@types/istanbul-lib-coverage": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
       "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
       "dev": true
     },
-    "@types/json-schema": {
-      "version": "7.0.15",
-      "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
-      "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+    "node_modules/@types/mime-types": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz",
+      "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==",
       "dev": true
     },
-    "@types/mocha": {
+    "node_modules/@types/mocha": {
       "version": "10.0.6",
       "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.6.tgz",
       "integrity": "sha512-dJvrYWxP/UcXm36Qn36fxhUKu8A/xMRXVT2cliFF1Z7UA9liG5Psj3ezNSZw+5puH2czDXRLcXQxf8JbJt0ejg==",
       "dev": true
     },
-    "@types/node": {
-      "version": "18.19.28",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.28.tgz",
-      "integrity": "sha512-J5cOGD9n4x3YGgVuaND6khm5x07MMdAKkRyXnjVR6KFhLMNh2yONGiP7Z+4+tBOt5mK+GvDTiacTOVGGpqiecw==",
+    "node_modules/@types/node": {
+      "version": "18.19.33",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.33.tgz",
+      "integrity": "sha512-NR9+KrpSajr2qBVp/Yt5TU/rp+b5Mayi3+OlMlcg2cVCfRmcG5PWZ7S4+MG9PZ5gWBoc9Pd0BKSRViuBCRPu0A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "undici-types": "~5.26.4"
       }
     },
-    "@types/semver": {
-      "version": "7.5.8",
-      "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz",
-      "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==",
+    "node_modules/@types/uuid": {
+      "version": "9.0.8",
+      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
+      "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
       "dev": true
     },
-    "@types/vscode": {
-      "version": "1.87.0",
-      "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.87.0.tgz",
-      "integrity": "sha512-y3yYJV2esWr8LNjp3VNbSMWG7Y43jC8pCldG8YwiHGAQbsymkkMMt0aDT1xZIOFM2eFcNiUc+dJMx1+Z0UT8fg==",
+    "node_modules/@types/vscode": {
+      "version": "1.89.0",
+      "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.89.0.tgz",
+      "integrity": "sha512-TMfGKLSVxfGfoO8JfIE/neZqv7QLwS4nwPwL/NwMvxtAY2230H2I4Z5xx6836pmJvMAzqooRQ4pmLm7RUicP3A==",
       "dev": true
     },
-    "@typescript-eslint/eslint-plugin": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.4.0.tgz",
-      "integrity": "sha512-yHMQ/oFaM7HZdVrVm/M2WHaNPgyuJH4WelkSVEWSSsir34kxW2kDJCxlXRhhGWEsMN0WAW/vLpKfKVcm8k+MPw==",
-      "dev": true,
-      "requires": {
-        "@eslint-community/regexpp": "^4.5.1",
-        "@typescript-eslint/scope-manager": "7.4.0",
-        "@typescript-eslint/type-utils": "7.4.0",
-        "@typescript-eslint/utils": "7.4.0",
-        "@typescript-eslint/visitor-keys": "7.4.0",
-        "debug": "^4.3.4",
+    "node_modules/@typescript-eslint/eslint-plugin": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.9.0.tgz",
+      "integrity": "sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==",
+      "dev": true,
+      "dependencies": {
+        "@eslint-community/regexpp": "^4.10.0",
+        "@typescript-eslint/scope-manager": "7.9.0",
+        "@typescript-eslint/type-utils": "7.9.0",
+        "@typescript-eslint/utils": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0",
         "graphemer": "^1.4.0",
-        "ignore": "^5.2.4",
+        "ignore": "^5.3.1",
         "natural-compare": "^1.4.0",
-        "semver": "^7.5.4",
-        "ts-api-utils": "^1.0.1"
+        "ts-api-utils": "^1.3.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "@typescript-eslint/parser": "^7.0.0",
+        "eslint": "^8.56.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
       }
     },
-    "@typescript-eslint/parser": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.4.0.tgz",
-      "integrity": "sha512-ZvKHxHLusweEUVwrGRXXUVzFgnWhigo4JurEj0dGF1tbcGh6buL+ejDdjxOQxv6ytcY1uhun1p2sm8iWStlgLQ==",
+    "node_modules/@typescript-eslint/parser": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz",
+      "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==",
       "dev": true,
-      "requires": {
-        "@typescript-eslint/scope-manager": "7.4.0",
-        "@typescript-eslint/types": "7.4.0",
-        "@typescript-eslint/typescript-estree": "7.4.0",
-        "@typescript-eslint/visitor-keys": "7.4.0",
+      "dependencies": {
+        "@typescript-eslint/scope-manager": "7.9.0",
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/typescript-estree": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0",
         "debug": "^4.3.4"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.56.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
       }
     },
-    "@typescript-eslint/scope-manager": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.4.0.tgz",
-      "integrity": "sha512-68VqENG5HK27ypafqLVs8qO+RkNc7TezCduYrx8YJpXq2QGZ30vmNZGJJJC48+MVn4G2dCV8m5ZTVnzRexTVtw==",
+    "node_modules/@typescript-eslint/scope-manager": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz",
+      "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==",
       "dev": true,
-      "requires": {
-        "@typescript-eslint/types": "7.4.0",
-        "@typescript-eslint/visitor-keys": "7.4.0"
+      "dependencies": {
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
       }
     },
-    "@typescript-eslint/type-utils": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.4.0.tgz",
-      "integrity": "sha512-247ETeHgr9WTRMqHbbQdzwzhuyaJ8dPTuyuUEMANqzMRB1rj/9qFIuIXK7l0FX9i9FXbHeBQl/4uz6mYuCE7Aw==",
+    "node_modules/@typescript-eslint/type-utils": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.9.0.tgz",
+      "integrity": "sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==",
       "dev": true,
-      "requires": {
-        "@typescript-eslint/typescript-estree": "7.4.0",
-        "@typescript-eslint/utils": "7.4.0",
+      "dependencies": {
+        "@typescript-eslint/typescript-estree": "7.9.0",
+        "@typescript-eslint/utils": "7.9.0",
         "debug": "^4.3.4",
-        "ts-api-utils": "^1.0.1"
+        "ts-api-utils": "^1.3.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.56.0"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
       }
     },
-    "@typescript-eslint/types": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.4.0.tgz",
-      "integrity": "sha512-mjQopsbffzJskos5B4HmbsadSJQWaRK0UxqQ7GuNA9Ga4bEKeiO6b2DnB6cM6bpc8lemaPseh0H9B/wyg+J7rw==",
-      "dev": true
+    "node_modules/@typescript-eslint/types": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz",
+      "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==",
+      "dev": true,
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      }
     },
-    "@typescript-eslint/typescript-estree": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.4.0.tgz",
-      "integrity": "sha512-A99j5AYoME/UBQ1ucEbbMEmGkN7SE0BvZFreSnTd1luq7yulcHdyGamZKizU7canpGDWGJ+Q6ZA9SyQobipePg==",
+    "node_modules/@typescript-eslint/typescript-estree": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz",
+      "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==",
       "dev": true,
-      "requires": {
-        "@typescript-eslint/types": "7.4.0",
-        "@typescript-eslint/visitor-keys": "7.4.0",
+      "dependencies": {
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/visitor-keys": "7.9.0",
         "debug": "^4.3.4",
         "globby": "^11.1.0",
         "is-glob": "^4.0.3",
-        "minimatch": "9.0.3",
-        "semver": "^7.5.4",
-        "ts-api-utils": "^1.0.1"
+        "minimatch": "^9.0.4",
+        "semver": "^7.6.0",
+        "ts-api-utils": "^1.3.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependenciesMeta": {
+        "typescript": {
+          "optional": true
+        }
       }
     },
-    "@typescript-eslint/utils": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.4.0.tgz",
-      "integrity": "sha512-NQt9QLM4Tt8qrlBVY9lkMYzfYtNz8/6qwZg8pI3cMGlPnj6mOpRxxAm7BMJN9K0AiY+1BwJ5lVC650YJqYOuNg==",
+    "node_modules/@typescript-eslint/utils": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.9.0.tgz",
+      "integrity": "sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@eslint-community/eslint-utils": "^4.4.0",
-        "@types/json-schema": "^7.0.12",
-        "@types/semver": "^7.5.0",
-        "@typescript-eslint/scope-manager": "7.4.0",
-        "@typescript-eslint/types": "7.4.0",
-        "@typescript-eslint/typescript-estree": "7.4.0",
-        "semver": "^7.5.4"
+        "@typescript-eslint/scope-manager": "7.9.0",
+        "@typescript-eslint/types": "7.9.0",
+        "@typescript-eslint/typescript-estree": "7.9.0"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
+      },
+      "peerDependencies": {
+        "eslint": "^8.56.0"
       }
     },
-    "@typescript-eslint/visitor-keys": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.4.0.tgz",
-      "integrity": "sha512-0zkC7YM0iX5Y41homUUeW1CHtZR01K3ybjM1l6QczoMuay0XKtrb93kv95AxUGwdjGr64nNqnOCwmEl616N8CA==",
+    "node_modules/@typescript-eslint/visitor-keys": {
+      "version": "7.9.0",
+      "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz",
+      "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==",
       "dev": true,
-      "requires": {
-        "@typescript-eslint/types": "7.4.0",
-        "eslint-visitor-keys": "^3.4.1"
+      "dependencies": {
+        "@typescript-eslint/types": "7.9.0",
+        "eslint-visitor-keys": "^3.4.3"
+      },
+      "engines": {
+        "node": "^18.18.0 || >=20.0.0"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/typescript-eslint"
       }
     },
-    "@ungap/structured-clone": {
+    "node_modules/@ungap/structured-clone": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz",
       "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==",
       "dev": true
     },
-    "@vscode/test-cli": {
+    "node_modules/@vscode/test-cli": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.6.tgz",
       "integrity": "sha512-4i61OUv5PQr3GxhHOuUgHdgBDfIO/kXTPCsEyFiMaY4SOqQTgkTmyZLagHehjOgCfsXdcrJa3zgQ7zoc+Dh6hQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@types/mocha": "^10.0.2",
         "c8": "^9.1.0",
         "chokidar": "^3.5.3",
@@ -421,144 +775,183 @@
         "mocha": "^10.2.0",
         "supports-color": "^9.4.0",
         "yargs": "^17.7.2"
+      },
+      "bin": {
+        "vscode-test": "out/bin.mjs"
       }
     },
-    "@vscode/test-electron": {
-      "version": "2.3.9",
-      "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.9.tgz",
-      "integrity": "sha512-z3eiChaCQXMqBnk2aHHSEkobmC2VRalFQN0ApOAtydL172zXGxTwGrRtviT5HnUB+Q+G3vtEYFtuQkYqBzYgMA==",
+    "node_modules/@vscode/test-electron": {
+      "version": "2.3.10",
+      "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.10.tgz",
+      "integrity": "sha512-FxMqrvUm6a8S5tP4CymNJ40e6kD+wUTWTc6K32U629yrCCa+kl/rmpkC2gKpN4F4zjg1r+0Hnk9sl0+N2atsYA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "http-proxy-agent": "^4.0.1",
         "https-proxy-agent": "^5.0.0",
         "jszip": "^3.10.1",
         "semver": "^7.5.2"
+      },
+      "engines": {
+        "node": ">=16"
       }
     },
-    "abbrev": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
-      "dev": true
-    },
-    "acorn": {
+    "node_modules/acorn": {
       "version": "8.11.3",
       "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz",
       "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==",
-      "dev": true
+      "dev": true,
+      "bin": {
+        "acorn": "bin/acorn"
+      },
+      "engines": {
+        "node": ">=0.4.0"
+      }
     },
-    "acorn-jsx": {
+    "node_modules/acorn-jsx": {
       "version": "5.3.2",
       "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
       "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true
+      "dev": true,
+      "peerDependencies": {
+        "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+      }
     },
-    "agent-base": {
+    "node_modules/agent-base": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
       "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6.0.0"
       }
     },
-    "ajv": {
+    "node_modules/ajv": {
       "version": "6.12.6",
       "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
       "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "fast-deep-equal": "^3.1.1",
         "fast-json-stable-stringify": "^2.0.0",
         "json-schema-traverse": "^0.4.1",
         "uri-js": "^4.2.2"
+      },
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/epoberezkin"
       }
     },
-    "ansi-colors": {
+    "node_modules/ansi-colors": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz",
       "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "ansi-regex": {
+    "node_modules/ansi-regex": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
       "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "dev": true
-    },
-    "ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
-      "requires": {
-        "color-convert": "^2.0.1"
+      "engines": {
+        "node": ">=8"
       }
     },
-    "anymatch": {
+    "node_modules/ansi-styles": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+      "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+      "dependencies": {
+        "color-convert": "^1.9.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/anymatch": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
       "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "normalize-path": "^3.0.0",
         "picomatch": "^2.0.4"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "argparse": {
+    "node_modules/argparse": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
       "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
       "dev": true
     },
-    "array-union": {
+    "node_modules/array-union": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
       "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "balanced-match": {
+    "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
       "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
       "dev": true
     },
-    "binary-extensions": {
+    "node_modules/binary-extensions": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
       "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "brace-expansion": {
+    "node_modules/brace-expansion": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
       "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "balanced-match": "^1.0.0"
       }
     },
-    "braces": {
+    "node_modules/braces": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
       "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "fill-range": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "browser-stdout": {
+    "node_modules/browser-stdout": {
       "version": "1.3.1",
       "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
       "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
       "dev": true
     },
-    "c8": {
+    "node_modules/c8": {
       "version": "9.1.0",
       "resolved": "https://registry.npmjs.org/c8/-/c8-9.1.0.tgz",
       "integrity": "sha512-mBWcT5iqNir1zIkzSPyI3NCR9EZCVI3WUD+AVO17MVWTSFNyUueXE82qTeampNtTr+ilN/5Ua3j24LgbCKjDVg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@bcoe/v8-coverage": "^0.2.3",
         "@istanbuljs/schema": "^0.1.3",
         "find-up": "^5.0.0",
@@ -570,95 +963,192 @@
         "v8-to-istanbul": "^9.0.0",
         "yargs": "^17.7.2",
         "yargs-parser": "^21.1.1"
+      },
+      "bin": {
+        "c8": "bin/c8.js"
+      },
+      "engines": {
+        "node": ">=14.14.0"
       }
     },
-    "callsites": {
+    "node_modules/callsites": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
       "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "camelcase": {
+    "node_modules/camelcase": {
       "version": "6.3.0",
       "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
       "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
-      "dev": true
-    },
-    "chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
-      "requires": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
+      "engines": {
+        "node": ">=10"
       },
-      "dependencies": {
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "chokidar": {
+    "node_modules/chalk": {
+      "version": "2.4.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+      "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+      "dependencies": {
+        "ansi-styles": "^3.2.1",
+        "escape-string-regexp": "^1.0.5",
+        "supports-color": "^5.3.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/chalk/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/chokidar": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
       "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "anymatch": "~3.1.2",
         "braces": "~3.0.2",
-        "fsevents": "~2.3.2",
         "glob-parent": "~5.1.2",
         "is-binary-path": "~2.1.0",
         "is-glob": "~4.0.1",
         "normalize-path": "~3.0.0",
         "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "funding": {
+        "url": "https://paulmillr.com/funding/"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
       }
     },
-    "cliui": {
+    "node_modules/cliui": {
       "version": "8.0.1",
       "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
       "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "string-width": "^4.2.0",
         "strip-ansi": "^6.0.1",
         "wrap-ansi": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=12"
+      }
+    },
+    "node_modules/cliui/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
       }
     },
-    "color-convert": {
+    "node_modules/cliui/node_modules/color-convert": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
       "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
       }
     },
-    "color-name": {
+    "node_modules/cliui/node_modules/color-name": {
       "version": "1.1.4",
       "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
       "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
-    "concat-map": {
+    "node_modules/cliui/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "node_modules/cliui/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/cliui/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dependencies": {
+        "color-name": "1.1.3"
+      }
+    },
+    "node_modules/color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="
+    },
+    "node_modules/concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
       "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
       "dev": true
     },
-    "concurrently": {
+    "node_modules/concurrently": {
       "version": "8.2.2",
       "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-8.2.2.tgz",
       "integrity": "sha512-1dP4gpXFhei8IOtlXRE/T/4H88ElHgTiUzh71YUmtjTEHMSRS2Z/fgOxHSxxusGHogsRfxNq1vyAwxSC+EVyDg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "chalk": "^4.1.2",
         "date-fns": "^2.30.0",
         "lodash": "^4.17.21",
@@ -669,135 +1159,259 @@
         "tree-kill": "^1.2.2",
         "yargs": "^17.7.2"
       },
+      "bin": {
+        "conc": "dist/bin/concurrently.js",
+        "concurrently": "dist/bin/concurrently.js"
+      },
+      "engines": {
+        "node": "^14.13.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://github.com/open-cli-tools/concurrently?sponsor=1"
+      }
+    },
+    "node_modules/concurrently/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/concurrently/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
       "dependencies": {
-        "supports-color": {
-          "version": "8.1.1",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
-          "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/concurrently/node_modules/chalk/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/concurrently/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/concurrently/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/concurrently/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/concurrently/node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
       }
     },
-    "convert-source-map": {
+    "node_modules/convert-source-map": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
       "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
       "dev": true
     },
-    "core-util-is": {
+    "node_modules/core-util-is": {
       "version": "1.0.3",
       "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
       "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
       "dev": true
     },
-    "cross-spawn": {
+    "node_modules/cross-spawn": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
       "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "path-key": "^3.1.0",
         "shebang-command": "^2.0.0",
         "which": "^2.0.1"
+      },
+      "engines": {
+        "node": ">= 8"
       }
     },
-    "date-fns": {
+    "node_modules/date-fns": {
       "version": "2.30.0",
       "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz",
       "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@babel/runtime": "^7.21.0"
+      },
+      "engines": {
+        "node": ">=0.11"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/date-fns"
       }
     },
-    "debug": {
+    "node_modules/debug": {
       "version": "4.3.4",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
       "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
-      "dev": true,
-      "requires": {
+      "dependencies": {
         "ms": "2.1.2"
+      },
+      "engines": {
+        "node": ">=6.0"
+      },
+      "peerDependenciesMeta": {
+        "supports-color": {
+          "optional": true
+        }
       }
     },
-    "decamelize": {
+    "node_modules/decamelize": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz",
       "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "deep-is": {
+    "node_modules/deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
       "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
       "dev": true
     },
-    "diff": {
+    "node_modules/diff": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
       "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.3.1"
+      }
     },
-    "dir-glob": {
+    "node_modules/dir-glob": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
       "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "path-type": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "doctrine": {
+    "node_modules/doctrine": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
       "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "esutils": "^2.0.2"
+      },
+      "engines": {
+        "node": ">=6.0.0"
       }
     },
-    "eastasianwidth": {
+    "node_modules/eastasianwidth": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
       "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
       "dev": true
     },
-    "emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+    "node_modules/emoji-regex": {
+      "version": "9.2.2",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+      "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
       "dev": true
     },
-    "enhanced-resolve": {
-      "version": "5.16.0",
-      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.0.tgz",
-      "integrity": "sha512-O+QWCviPNSSLAD9Ucn8Awv+poAkqn3T1XY5/N7kR7rQO9yfSGWkYZDwpJ+iKF7B8rxaQKWngSqACpgzeapSyoA==",
+    "node_modules/enhanced-resolve": {
+      "version": "5.16.1",
+      "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.16.1.tgz",
+      "integrity": "sha512-4U5pNsuDl0EhuZpq46M5xPslstkviJuhrdobaRDBk2Jy2KO37FDAJl4lb2KlNabxT0m4MTK2UHNrsAcphE8nyw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "graceful-fs": "^4.2.4",
         "tapable": "^2.2.0"
+      },
+      "engines": {
+        "node": ">=10.13.0"
       }
     },
-    "escalade": {
+    "node_modules/escalade": {
       "version": "3.1.2",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
       "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "escape-string-regexp": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
-      "dev": true
+    "node_modules/escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+      "engines": {
+        "node": ">=0.8.0"
+      }
     },
-    "eslint": {
+    "node_modules/eslint": {
       "version": "8.57.0",
       "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
       "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@eslint-community/eslint-utils": "^4.2.0",
         "@eslint-community/regexpp": "^4.6.1",
         "@eslint/eslintrc": "^2.1.4",
@@ -837,627 +1451,1042 @@
         "strip-ansi": "^6.0.1",
         "text-table": "^0.2.0"
       },
-      "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "glob-parent": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
-          "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
-          "dev": true,
-          "requires": {
-            "is-glob": "^4.0.3"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
+      "bin": {
+        "eslint": "bin/eslint.js"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "eslint-scope": {
+    "node_modules/eslint-scope": {
       "version": "7.2.2",
       "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
       "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "esrecurse": "^4.3.0",
         "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "eslint-visitor-keys": {
+    "node_modules/eslint-visitor-keys": {
       "version": "3.4.3",
       "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
       "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+      "dev": true,
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
+      }
+    },
+    "node_modules/eslint/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/eslint/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/eslint/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/eslint/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/eslint/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
       "dev": true
     },
-    "espree": {
+    "node_modules/eslint/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/glob-parent": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+      "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+      "dev": true,
+      "dependencies": {
+        "is-glob": "^4.0.3"
+      },
+      "engines": {
+        "node": ">=10.13.0"
+      }
+    },
+    "node_modules/eslint/node_modules/globals": {
+      "version": "13.24.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
+      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
+      "dev": true,
+      "dependencies": {
+        "type-fest": "^0.20.2"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/eslint/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/eslint/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/espree": {
       "version": "9.6.1",
       "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
       "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "acorn": "^8.9.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.4.1"
+      },
+      "engines": {
+        "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
-    "esquery": {
+    "node_modules/esquery": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
       "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "estraverse": "^5.1.0"
+      },
+      "engines": {
+        "node": ">=0.10"
       }
     },
-    "esrecurse": {
+    "node_modules/esrecurse": {
       "version": "4.3.0",
       "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
       "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "estraverse": "^5.2.0"
+      },
+      "engines": {
+        "node": ">=4.0"
       }
     },
-    "estraverse": {
+    "node_modules/estraverse": {
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
       "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=4.0"
+      }
     },
-    "esutils": {
+    "node_modules/esutils": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
       "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "fast-deep-equal": {
+    "node_modules/fast-deep-equal": {
       "version": "3.1.3",
       "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
       "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
       "dev": true
     },
-    "fast-glob": {
+    "node_modules/fast-glob": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
       "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@nodelib/fs.stat": "^2.0.2",
         "@nodelib/fs.walk": "^1.2.3",
         "glob-parent": "^5.1.2",
         "merge2": "^1.3.0",
         "micromatch": "^4.0.4"
+      },
+      "engines": {
+        "node": ">=8.6.0"
       }
     },
-    "fast-json-stable-stringify": {
+    "node_modules/fast-json-stable-stringify": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
       "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
       "dev": true
     },
-    "fast-levenshtein": {
+    "node_modules/fast-levenshtein": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
       "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
       "dev": true
     },
-    "fastq": {
+    "node_modules/fastq": {
       "version": "1.17.1",
       "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
       "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "reusify": "^1.0.4"
       }
     },
-    "file-entry-cache": {
+    "node_modules/file-entry-cache": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
       "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "flat-cache": "^3.0.4"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.0"
       }
     },
-    "fill-range": {
+    "node_modules/fill-range": {
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
       "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "to-regex-range": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "find-up": {
+    "node_modules/find-up": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
       "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "locate-path": "^6.0.0",
         "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "flat": {
+    "node_modules/flat": {
       "version": "5.0.2",
       "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz",
       "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==",
-      "dev": true
+      "dev": true,
+      "bin": {
+        "flat": "cli.js"
+      }
     },
-    "flat-cache": {
+    "node_modules/flat-cache": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz",
       "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "flatted": "^3.2.9",
         "keyv": "^4.5.3",
         "rimraf": "^3.0.2"
+      },
+      "engines": {
+        "node": "^10.12.0 || >=12.0.0"
       }
     },
-    "flatted": {
+    "node_modules/flatted": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
       "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
       "dev": true
     },
-    "foreground-child": {
+    "node_modules/foreground-child": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz",
       "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "cross-spawn": "^7.0.0",
         "signal-exit": "^4.0.1"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "fs.realpath": {
+    "node_modules/fs.realpath": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
       "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
       "dev": true
     },
-    "fsevents": {
+    "node_modules/fsevents": {
       "version": "2.3.3",
       "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
       "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
       "dev": true,
-      "optional": true
+      "hasInstallScript": true,
+      "optional": true,
+      "os": [
+        "darwin"
+      ],
+      "engines": {
+        "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+      }
     },
-    "get-caller-file": {
+    "node_modules/get-caller-file": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
       "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": "6.* || 8.* || >= 10.*"
+      }
     },
-    "glob": {
-      "version": "10.3.12",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.12.tgz",
-      "integrity": "sha512-TCNv8vJ+xz4QiqTpfOJA7HvYv+tNIRHKfUWw/q+v2jdgN4ebz+KY9tGx5J4rHP0o84mNP+ApH66HRX8us3Khqg==",
+    "node_modules/glob": {
+      "version": "10.3.15",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.15.tgz",
+      "integrity": "sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "foreground-child": "^3.1.0",
         "jackspeak": "^2.3.6",
         "minimatch": "^9.0.1",
         "minipass": "^7.0.4",
-        "path-scurry": "^1.10.2"
+        "path-scurry": "^1.11.0"
+      },
+      "bin": {
+        "glob": "dist/esm/bin.mjs"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "glob-parent": {
+    "node_modules/glob-parent": {
       "version": "5.1.2",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
       "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-glob": "^4.0.1"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
-    "globals": {
-      "version": "13.24.0",
-      "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz",
-      "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==",
-      "dev": true,
-      "requires": {
-        "type-fest": "^0.20.2"
+    "node_modules/globals": {
+      "version": "11.12.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "engines": {
+        "node": ">=4"
       }
     },
-    "globby": {
+    "node_modules/globby": {
       "version": "11.1.0",
       "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
       "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "array-union": "^2.1.0",
         "dir-glob": "^3.0.1",
         "fast-glob": "^3.2.9",
         "ignore": "^5.2.0",
         "merge2": "^1.4.1",
         "slash": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "graceful-fs": {
+    "node_modules/graceful-fs": {
       "version": "4.2.11",
       "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
       "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
       "dev": true
     },
-    "graphemer": {
+    "node_modules/graphemer": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
       "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
       "dev": true
     },
-    "has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "dev": true
+    "node_modules/has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+      "engines": {
+        "node": ">=4"
+      }
     },
-    "he": {
+    "node_modules/he": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz",
       "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
-      "dev": true
+      "dev": true,
+      "bin": {
+        "he": "bin/he"
+      }
     },
-    "html-escaper": {
+    "node_modules/html-escaper": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
       "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
       "dev": true
     },
-    "http-proxy-agent": {
+    "node_modules/http-proxy-agent": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
       "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@tootallnate/once": "1",
         "agent-base": "6",
         "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
-    "https-proxy-agent": {
+    "node_modules/https-proxy-agent": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
       "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "agent-base": "6",
         "debug": "4"
+      },
+      "engines": {
+        "node": ">= 6"
       }
     },
-    "ignore": {
+    "node_modules/ignore": {
       "version": "5.3.1",
       "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
       "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">= 4"
+      }
     },
-    "ignore-by-default": {
+    "node_modules/ignore-by-default": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
       "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==",
       "dev": true
     },
-    "immediate": {
+    "node_modules/immediate": {
       "version": "3.0.6",
       "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
       "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
       "dev": true
     },
-    "import-fresh": {
+    "node_modules/import-fresh": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
       "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "parent-module": "^1.0.0",
         "resolve-from": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "imurmurhash": {
+    "node_modules/imurmurhash": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
       "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.8.19"
+      }
     },
-    "inflight": {
+    "node_modules/inflight": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
       "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "once": "^1.3.0",
         "wrappy": "1"
       }
     },
-    "inherits": {
+    "node_modules/inherits": {
       "version": "2.0.4",
       "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
       "dev": true
     },
-    "is-binary-path": {
+    "node_modules/is-binary-path": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
       "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "binary-extensions": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "is-extglob": {
+    "node_modules/is-extglob": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
       "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "is-fullwidth-code-point": {
+    "node_modules/is-fullwidth-code-point": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
       "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "is-glob": {
+    "node_modules/is-glob": {
       "version": "4.0.3",
       "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
       "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-extglob": "^2.1.1"
+      },
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "is-number": {
+    "node_modules/is-number": {
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
       "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.12.0"
+      }
     },
-    "is-path-inside": {
+    "node_modules/is-path-inside": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
       "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "is-plain-obj": {
+    "node_modules/is-plain-obj": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
       "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "is-unicode-supported": {
+    "node_modules/is-unicode-supported": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
       "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "isarray": {
+    "node_modules/isarray": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
       "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
       "dev": true
     },
-    "isexe": {
+    "node_modules/isexe": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
       "dev": true
     },
-    "istanbul-lib-coverage": {
+    "node_modules/istanbul-lib-coverage": {
       "version": "3.2.2",
       "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
       "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "istanbul-lib-report": {
+    "node_modules/istanbul-lib-report": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
       "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "istanbul-lib-coverage": "^3.0.0",
         "make-dir": "^4.0.0",
         "supports-color": "^7.1.0"
       },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-lib-report/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-lib-report/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
       "dependencies": {
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "istanbul-reports": {
+    "node_modules/istanbul-reports": {
       "version": "3.1.7",
       "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
       "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "html-escaper": "^2.0.0",
         "istanbul-lib-report": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "jackspeak": {
+    "node_modules/jackspeak": {
       "version": "2.3.6",
       "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
       "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==",
       "dev": true,
-      "requires": {
-        "@isaacs/cliui": "^8.0.2",
+      "dependencies": {
+        "@isaacs/cliui": "^8.0.2"
+      },
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      },
+      "optionalDependencies": {
         "@pkgjs/parseargs": "^0.11.0"
       }
     },
-    "js-yaml": {
+    "node_modules/js-tokens": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
+    },
+    "node_modules/js-yaml": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
       "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "argparse": "^2.0.1"
+      },
+      "bin": {
+        "js-yaml": "bin/js-yaml.js"
       }
     },
-    "json-buffer": {
+    "node_modules/jsesc": {
+      "version": "2.5.2",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "bin": {
+        "jsesc": "bin/jsesc"
+      },
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/json-buffer": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
       "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
       "dev": true
     },
-    "json-schema-traverse": {
+    "node_modules/json-schema-traverse": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
       "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
       "dev": true
     },
-    "json-stable-stringify-without-jsonify": {
+    "node_modules/json-stable-stringify-without-jsonify": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
       "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
       "dev": true
     },
-    "jszip": {
+    "node_modules/jszip": {
       "version": "3.10.1",
       "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
       "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "lie": "~3.3.0",
         "pako": "~1.0.2",
         "readable-stream": "~2.3.6",
         "setimmediate": "^1.0.5"
       }
     },
-    "keyv": {
+    "node_modules/keyv": {
       "version": "4.5.4",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
       "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "json-buffer": "3.0.1"
       }
     },
-    "levn": {
+    "node_modules/levn": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
       "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "prelude-ls": "^1.2.1",
         "type-check": "~0.4.0"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
       }
     },
-    "lie": {
+    "node_modules/lie": {
       "version": "3.3.0",
       "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
       "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "immediate": "~3.0.5"
       }
     },
-    "locate-path": {
+    "node_modules/locate-path": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
       "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "p-locate": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "lodash": {
+    "node_modules/lodash": {
       "version": "4.17.21",
       "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
       "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
       "dev": true
     },
-    "lodash.merge": {
+    "node_modules/lodash.merge": {
       "version": "4.6.2",
       "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
       "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
       "dev": true
     },
-    "log-symbols": {
+    "node_modules/log-symbols": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
       "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "chalk": "^4.1.0",
         "is-unicode-supported": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "lru-cache": {
-      "version": "6.0.0",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
-      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+    "node_modules/log-symbols/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/log-symbols/node_modules/chalk": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
       "dev": true,
-      "requires": {
-        "yallist": "^4.0.0"
+      "dependencies": {
+        "ansi-styles": "^4.1.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/chalk?sponsor=1"
+      }
+    },
+    "node_modules/log-symbols/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
       }
     },
-    "make-dir": {
+    "node_modules/log-symbols/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/log-symbols/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/log-symbols/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/lru-cache": {
+      "version": "10.2.2",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
+      "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
+      "dev": true,
+      "engines": {
+        "node": "14 || >=16.14"
+      }
+    },
+    "node_modules/make-dir": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
       "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "merge2": {
+    "node_modules/merge2": {
       "version": "1.4.1",
       "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
       "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">= 8"
+      }
     },
-    "micromatch": {
+    "node_modules/micromatch": {
       "version": "4.0.5",
       "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
       "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "braces": "^3.0.2",
         "picomatch": "^2.3.1"
+      },
+      "engines": {
+        "node": ">=8.6"
       }
     },
-    "minimatch": {
-      "version": "9.0.3",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
-      "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
+    "node_modules/mime-db": {
+      "version": "1.52.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+      "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/mime-types": {
+      "version": "2.1.35",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+      "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+      "dependencies": {
+        "mime-db": "1.52.0"
+      },
+      "engines": {
+        "node": ">= 0.6"
+      }
+    },
+    "node_modules/minimatch": {
+      "version": "9.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
+      "integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "minipass": {
-      "version": "7.0.4",
-      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz",
-      "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==",
-      "dev": true
+    "node_modules/minipass": {
+      "version": "7.1.1",
+      "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.1.tgz",
+      "integrity": "sha512-UZ7eQ+h8ywIRAW1hIEl2AqdwzJucU/Kp59+8kkZeSvafXhZjul247BvIJjEVFVeON6d7lM46XX1HXCduKAS8VA==",
+      "dev": true,
+      "engines": {
+        "node": ">=16 || 14 >=14.17"
+      }
     },
-    "mocha": {
+    "node_modules/mocha": {
       "version": "10.4.0",
       "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.4.0.tgz",
       "integrity": "sha512-eqhGB8JKapEYcC4ytX/xrzKforgEc3j1pGlAXVy3eRwrtAy5/nIfT1SvgGzfN0XZZxeLq0aQWkOUAmqIJiv+bA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ansi-colors": "4.1.1",
         "browser-stdout": "1.3.1",
         "chokidar": "3.5.3",
@@ -1479,112 +2508,239 @@
         "yargs-parser": "20.2.4",
         "yargs-unparser": "2.0.0"
       },
+      "bin": {
+        "_mocha": "bin/_mocha",
+        "mocha": "bin/mocha.js"
+      },
+      "engines": {
+        "node": ">= 14.0.0"
+      }
+    },
+    "node_modules/mocha/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+      "dev": true,
       "dependencies": {
-        "chokidar": {
-          "version": "3.5.3",
-          "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
-          "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
-          "dev": true,
-          "requires": {
-            "anymatch": "~3.1.2",
-            "braces": "~3.0.2",
-            "fsevents": "~2.3.2",
-            "glob-parent": "~5.1.2",
-            "is-binary-path": "~2.1.0",
-            "is-glob": "~4.0.1",
-            "normalize-path": "~3.0.0",
-            "readdirp": "~3.6.0"
-          }
-        },
-        "cliui": {
-          "version": "7.0.4",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
-          "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
-          "dev": true,
-          "requires": {
-            "string-width": "^4.2.0",
-            "strip-ansi": "^6.0.0",
-            "wrap-ansi": "^7.0.0"
-          }
-        },
-        "glob": {
-          "version": "8.1.0",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
-          "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^5.0.1",
-            "once": "^1.3.0"
-          }
-        },
-        "minimatch": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
-          "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^2.0.1"
-          }
-        },
-        "ms": {
-          "version": "2.1.3",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "8.1.1",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
-          "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "yargs": {
-          "version": "16.2.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
-          "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
-          "dev": true,
-          "requires": {
-            "cliui": "^7.0.2",
-            "escalade": "^3.1.1",
-            "get-caller-file": "^2.0.5",
-            "require-directory": "^2.1.1",
-            "string-width": "^4.2.0",
-            "y18n": "^5.0.5",
-            "yargs-parser": "^20.2.2"
-          }
-        },
-        "yargs-parser": {
-          "version": "20.2.4",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
-          "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
-          "dev": true
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/mocha/node_modules/chokidar": {
+      "version": "3.5.3",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
+      "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "individual",
+          "url": "https://paulmillr.com/funding/"
         }
+      ],
+      "dependencies": {
+        "anymatch": "~3.1.2",
+        "braces": "~3.0.2",
+        "glob-parent": "~5.1.2",
+        "is-binary-path": "~2.1.0",
+        "is-glob": "~4.0.1",
+        "normalize-path": "~3.0.0",
+        "readdirp": "~3.6.0"
+      },
+      "engines": {
+        "node": ">= 8.10.0"
+      },
+      "optionalDependencies": {
+        "fsevents": "~2.3.2"
+      }
+    },
+    "node_modules/mocha/node_modules/cliui": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+      "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+      "dev": true,
+      "dependencies": {
+        "string-width": "^4.2.0",
+        "strip-ansi": "^6.0.0",
+        "wrap-ansi": "^7.0.0"
+      }
+    },
+    "node_modules/mocha/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/mocha/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/mocha/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "node_modules/mocha/node_modules/escape-string-regexp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+      "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/mocha/node_modules/glob": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz",
+      "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^5.0.1",
+        "once": "^1.3.0"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/mocha/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/mocha/node_modules/minimatch": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.0.1.tgz",
+      "integrity": "sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/mocha/node_modules/ms": {
+      "version": "2.1.3",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+      "dev": true
+    },
+    "node_modules/mocha/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/mocha/node_modules/supports-color": {
+      "version": "8.1.1",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
+      "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
+    },
+    "node_modules/mocha/node_modules/wrap-ansi": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^4.0.0",
+        "string-width": "^4.1.0",
+        "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
-    "ms": {
+    "node_modules/mocha/node_modules/yargs": {
+      "version": "16.2.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+      "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+      "dev": true,
+      "dependencies": {
+        "cliui": "^7.0.2",
+        "escalade": "^3.1.1",
+        "get-caller-file": "^2.0.5",
+        "require-directory": "^2.1.1",
+        "string-width": "^4.2.0",
+        "y18n": "^5.0.5",
+        "yargs-parser": "^20.2.2"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/mocha/node_modules/yargs-parser": {
+      "version": "20.2.4",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz",
+      "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-      "dev": true
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
     },
-    "natural-compare": {
+    "node_modules/natural-compare": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
       "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
       "dev": true
     },
-    "nodemon": {
+    "node_modules/nodemon": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz",
       "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "chokidar": "^3.5.2",
         "debug": "^4",
         "ignore-by-default": "^1.0.1",
@@ -1596,207 +2752,268 @@
         "touch": "^3.1.0",
         "undefsafe": "^2.0.5"
       },
+      "bin": {
+        "nodemon": "bin/nodemon.js"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "type": "opencollective",
+        "url": "https://opencollective.com/nodemon"
+      }
+    },
+    "node_modules/nodemon/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
       "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "has-flag": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
-          "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-          "dev": true
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        },
-        "supports-color": {
-          "version": "5.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
-          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-          "dev": true,
-          "requires": {
-            "has-flag": "^3.0.0"
-          }
-        }
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
       }
     },
-    "nopt": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
-      "integrity": "sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg==",
+    "node_modules/nodemon/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
       "dev": true,
-      "requires": {
-        "abbrev": "1"
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
+    "node_modules/nodemon/node_modules/supports-color": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+      "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=4"
       }
     },
-    "normalize-path": {
+    "node_modules/normalize-path": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
       "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "once": {
+    "node_modules/once": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
       "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "wrappy": "1"
       }
     },
-    "optionator": {
-      "version": "0.9.3",
-      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz",
-      "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+    "node_modules/optionator": {
+      "version": "0.9.4",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+      "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
       "dev": true,
-      "requires": {
-        "@aashutoshrathi/word-wrap": "^1.2.3",
+      "dependencies": {
         "deep-is": "^0.1.3",
         "fast-levenshtein": "^2.0.6",
         "levn": "^0.4.1",
         "prelude-ls": "^1.2.1",
-        "type-check": "^0.4.0"
+        "type-check": "^0.4.0",
+        "word-wrap": "^1.2.5"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
       }
     },
-    "p-limit": {
+    "node_modules/p-limit": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
       "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "p-locate": {
+    "node_modules/p-locate": {
       "version": "5.0.0",
       "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
       "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "pako": {
+    "node_modules/pako": {
       "version": "1.0.11",
       "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
       "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
       "dev": true
     },
-    "parent-module": {
+    "node_modules/parent-module": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
       "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "callsites": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=6"
       }
     },
-    "path-exists": {
+    "node_modules/path-exists": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
       "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "path-is-absolute": {
+    "node_modules/path-is-absolute": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
       "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "path-key": {
+    "node_modules/path-key": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
       "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "path-scurry": {
-      "version": "1.10.2",
-      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.2.tgz",
-      "integrity": "sha512-7xTavNy5RQXnsjANvVvMkEjvloOinkAjv/Z6Ildz9v2RinZ4SBKTWFOVRbaF8p0vpHnyjV/UwNDdKuUv6M5qcA==",
+    "node_modules/path-scurry": {
+      "version": "1.11.1",
+      "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+      "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "lru-cache": "^10.2.0",
         "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
       },
-      "dependencies": {
-        "lru-cache": {
-          "version": "10.2.0",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
-          "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
-          "dev": true
-        }
+      "engines": {
+        "node": ">=16 || 14 >=14.18"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
       }
     },
-    "path-type": {
+    "node_modules/path-type": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
       "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/picocolors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
+      "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew=="
     },
-    "picomatch": {
+    "node_modules/picomatch": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
       "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8.6"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/jonschlinkert"
+      }
     },
-    "prelude-ls": {
+    "node_modules/prelude-ls": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
       "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">= 0.8.0"
+      }
     },
-    "process-nextick-args": {
+    "node_modules/process-nextick-args": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
       "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
       "dev": true
     },
-    "pstree.remy": {
+    "node_modules/pstree.remy": {
       "version": "1.1.8",
       "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.8.tgz",
       "integrity": "sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==",
       "dev": true
     },
-    "punycode": {
+    "node_modules/punycode": {
       "version": "2.3.1",
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
       "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "queue-microtask": {
+    "node_modules/queue-microtask": {
       "version": "1.2.3",
       "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
       "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
-      "dev": true
+      "dev": true,
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ]
     },
-    "randombytes": {
+    "node_modules/randombytes": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
       "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "safe-buffer": "^5.1.0"
       }
     },
-    "readable-stream": {
+    "node_modules/readable-stream": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
       "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "core-util-is": "~1.0.0",
         "inherits": "~2.0.3",
         "isarray": "~1.0.0",
@@ -1804,472 +3021,763 @@
         "safe-buffer": "~5.1.1",
         "string_decoder": "~1.1.1",
         "util-deprecate": "~1.0.1"
-      },
-      "dependencies": {
-        "safe-buffer": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-          "dev": true
-        }
       }
     },
-    "readdirp": {
+    "node_modules/readdirp": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
       "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "picomatch": "^2.2.1"
+      },
+      "engines": {
+        "node": ">=8.10.0"
       }
     },
-    "regenerator-runtime": {
+    "node_modules/regenerator-runtime": {
       "version": "0.14.1",
       "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
       "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
       "dev": true
     },
-    "require-directory": {
+    "node_modules/require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
       "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
+      }
     },
-    "resolve-from": {
+    "node_modules/resolve-from": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
       "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=4"
+      }
     },
-    "reusify": {
+    "node_modules/reusify": {
       "version": "1.0.4",
       "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
       "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "iojs": ">=1.0.0",
+        "node": ">=0.10.0"
+      }
     },
-    "rimraf": {
+    "node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
       "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "glob": "^7.1.3"
       },
+      "bin": {
+        "rimraf": "bin.js"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
       "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "glob": {
-          "version": "7.2.3",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-          "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.1.1",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/rimraf/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/rimraf/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "run-parallel": {
+    "node_modules/run-parallel": {
       "version": "1.2.0",
       "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
       "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
       "dev": true,
-      "requires": {
+      "funding": [
+        {
+          "type": "github",
+          "url": "https://github.com/sponsors/feross"
+        },
+        {
+          "type": "patreon",
+          "url": "https://www.patreon.com/feross"
+        },
+        {
+          "type": "consulting",
+          "url": "https://feross.org/support"
+        }
+      ],
+      "dependencies": {
         "queue-microtask": "^1.2.2"
       }
     },
-    "rxjs": {
+    "node_modules/rxjs": {
       "version": "7.8.1",
       "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
       "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "tslib": "^2.1.0"
       }
     },
-    "safe-buffer": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+    "node_modules/safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
       "dev": true
     },
-    "semver": {
-      "version": "7.6.0",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
-      "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+    "node_modules/semver": {
+      "version": "7.6.2",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
+      "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
       "dev": true,
-      "requires": {
-        "lru-cache": "^6.0.0"
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "serialize-javascript": {
+    "node_modules/serialize-javascript": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz",
       "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "randombytes": "^2.1.0"
       }
     },
-    "setimmediate": {
+    "node_modules/setimmediate": {
       "version": "1.0.5",
       "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
       "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
       "dev": true
     },
-    "shebang-command": {
+    "node_modules/shebang-command": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
       "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "shebang-regex": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "shebang-regex": {
+    "node_modules/shebang-regex": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
       "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "shell-quote": {
+    "node_modules/shell-quote": {
       "version": "1.8.1",
       "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz",
       "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
-      "dev": true
+      "dev": true,
+      "funding": {
+        "url": "https://github.com/sponsors/ljharb"
+      }
     },
-    "signal-exit": {
+    "node_modules/signal-exit": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
       "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=14"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
     },
-    "simple-update-notifier": {
+    "node_modules/simple-update-notifier": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz",
       "integrity": "sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
       }
     },
-    "slash": {
+    "node_modules/slash": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
       "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
     },
-    "spawn-command": {
+    "node_modules/spawn-command": {
       "version": "0.0.2",
       "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2.tgz",
       "integrity": "sha512-zC8zGoGkmc8J9ndvml8Xksr1Amk9qBujgbF0JAIWO7kXr43w0h/0GJNM/Vustixu+YE8N/MTrQ7N31FvHUACxQ==",
       "dev": true
     },
-    "string-width": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
-      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+    "node_modules/string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
       "dev": true,
-      "requires": {
-        "emoji-regex": "^8.0.0",
-        "is-fullwidth-code-point": "^3.0.0",
-        "strip-ansi": "^6.0.1"
+      "dependencies": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "node_modules/string-width": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+      "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+      "dev": true,
+      "dependencies": {
+        "eastasianwidth": "^0.2.0",
+        "emoji-regex": "^9.2.2",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "string-width-cjs": {
-      "version": "npm:string-width@4.2.3",
+    "node_modules/string-width-cjs": {
+      "name": "string-width",
+      "version": "4.2.3",
       "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
       "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "emoji-regex": "^8.0.0",
         "is-fullwidth-code-point": "^3.0.0",
         "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+    "node_modules/string-width-cjs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "node_modules/string-width/node_modules/ansi-regex": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
       "dev": true,
-      "requires": {
-        "safe-buffer": "~5.1.0"
+      "engines": {
+        "node": ">=12"
       },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/string-width/node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+      "dev": true,
       "dependencies": {
-        "safe-buffer": {
-          "version": "5.1.2",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-          "dev": true
-        }
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
-    "strip-ansi": {
+    "node_modules/strip-ansi": {
       "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "strip-ansi-cjs": {
-      "version": "npm:strip-ansi@6.0.1",
+    "node_modules/strip-ansi-cjs": {
+      "name": "strip-ansi",
+      "version": "6.0.1",
       "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
       "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ansi-regex": "^5.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "strip-json-comments": {
+    "node_modules/strip-json-comments": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
       "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "supports-color": {
+    "node_modules/supports-color": {
       "version": "9.4.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz",
       "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/supports-color?sponsor=1"
+      }
     },
-    "tapable": {
+    "node_modules/tapable": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
       "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=6"
+      }
     },
-    "test-exclude": {
+    "node_modules/test-exclude": {
       "version": "6.0.0",
       "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
       "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@istanbuljs/schema": "^0.1.2",
         "glob": "^7.1.4",
         "minimatch": "^3.0.4"
       },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/test-exclude/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
       "dependencies": {
-        "brace-expansion": {
-          "version": "1.1.11",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-          "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-          "dev": true,
-          "requires": {
-            "balanced-match": "^1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "glob": {
-          "version": "7.2.3",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-          "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "^1.0.0",
-            "inflight": "^1.0.4",
-            "inherits": "2",
-            "minimatch": "^3.1.1",
-            "once": "^1.3.0",
-            "path-is-absolute": "^1.0.0"
-          }
-        },
-        "minimatch": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-          "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "^1.1.7"
-          }
-        }
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/test-exclude/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/test-exclude/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
       }
     },
-    "text-table": {
+    "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
       "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
       "dev": true
     },
-    "to-regex-range": {
+    "node_modules/to-fast-properties": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+      "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==",
+      "engines": {
+        "node": ">=4"
+      }
+    },
+    "node_modules/to-regex-range": {
       "version": "5.0.1",
       "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
       "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "is-number": "^7.0.0"
+      },
+      "engines": {
+        "node": ">=8.0"
       }
     },
-    "touch": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
-      "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+    "node_modules/touch": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.1.tgz",
+      "integrity": "sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==",
       "dev": true,
-      "requires": {
-        "nopt": "~1.0.10"
+      "bin": {
+        "nodetouch": "bin/nodetouch.js"
       }
     },
-    "tree-kill": {
+    "node_modules/tree-kill": {
       "version": "1.2.2",
       "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz",
       "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==",
-      "dev": true
+      "dev": true,
+      "bin": {
+        "tree-kill": "cli.js"
+      }
     },
-    "ts-api-utils": {
+    "node_modules/ts-api-utils": {
       "version": "1.3.0",
       "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz",
       "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=16"
+      },
+      "peerDependencies": {
+        "typescript": ">=4.2.0"
+      }
     },
-    "tslib": {
+    "node_modules/tslib": {
       "version": "2.6.2",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
       "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
       "dev": true
     },
-    "type-check": {
+    "node_modules/type-check": {
       "version": "0.4.0",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
       "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "prelude-ls": "^1.2.1"
+      },
+      "engines": {
+        "node": ">= 0.8.0"
       }
     },
-    "type-fest": {
+    "node_modules/type-fest": {
       "version": "0.20.2",
       "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
       "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     },
-    "typescript": {
-      "version": "5.4.3",
-      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.3.tgz",
-      "integrity": "sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==",
-      "dev": true
+    "node_modules/typescript": {
+      "version": "5.4.5",
+      "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz",
+      "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==",
+      "dev": true,
+      "bin": {
+        "tsc": "bin/tsc",
+        "tsserver": "bin/tsserver"
+      },
+      "engines": {
+        "node": ">=14.17"
+      }
     },
-    "undefsafe": {
+    "node_modules/undefsafe": {
       "version": "2.0.5",
       "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.5.tgz",
       "integrity": "sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==",
       "dev": true
     },
-    "undici-types": {
+    "node_modules/undici-types": {
       "version": "5.26.5",
       "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
       "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
       "dev": true
     },
-    "uri-js": {
+    "node_modules/uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
       "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "punycode": "^2.1.0"
       }
     },
-    "util-deprecate": {
+    "node_modules/util-deprecate": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
       "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
       "dev": true
     },
-    "v8-to-istanbul": {
+    "node_modules/uuid": {
+      "version": "9.0.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+      "funding": [
+        "https://github.com/sponsors/broofa",
+        "https://github.com/sponsors/ctavan"
+      ],
+      "bin": {
+        "uuid": "dist/bin/uuid"
+      }
+    },
+    "node_modules/v8-to-istanbul": {
       "version": "9.2.0",
       "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz",
       "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "@jridgewell/trace-mapping": "^0.3.12",
         "@types/istanbul-lib-coverage": "^2.0.1",
         "convert-source-map": "^2.0.0"
+      },
+      "engines": {
+        "node": ">=10.12.0"
       }
     },
-    "which": {
+    "node_modules/which": {
       "version": "2.0.2",
       "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
       "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "isexe": "^2.0.0"
+      },
+      "bin": {
+        "node-which": "bin/node-which"
+      },
+      "engines": {
+        "node": ">= 8"
+      }
+    },
+    "node_modules/word-wrap": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+      "dev": true,
+      "engines": {
+        "node": ">=0.10.0"
       }
     },
-    "workerpool": {
+    "node_modules/workerpool": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz",
       "integrity": "sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==",
       "dev": true
     },
-    "wrap-ansi": {
+    "node_modules/wrap-ansi": {
+      "version": "8.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+      "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-styles": "^6.1.0",
+        "string-width": "^5.0.1",
+        "strip-ansi": "^7.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi-cjs": {
+      "name": "wrap-ansi",
       "version": "7.0.0",
       "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
       "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "ansi-styles": "^4.0.0",
         "string-width": "^4.1.0",
         "strip-ansi": "^6.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
       }
     },
-    "wrap-ansi-cjs": {
-      "version": "npm:wrap-ansi@7.0.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
-      "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+    "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
       "dev": true,
-      "requires": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
+      "dependencies": {
+        "color-convert": "^2.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+      "dev": true,
+      "dependencies": {
+        "color-name": "~1.1.4"
+      },
+      "engines": {
+        "node": ">=7.0.0"
+      }
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/color-name": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+      "dev": true
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "node_modules/wrap-ansi-cjs/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/ansi-regex": {
+      "version": "6.0.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz",
+      "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/ansi-styles": {
+      "version": "6.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
+      "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+      }
+    },
+    "node_modules/wrap-ansi/node_modules/strip-ansi": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
+      "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
+      "dev": true,
+      "dependencies": {
+        "ansi-regex": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=12"
+      },
+      "funding": {
+        "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
-    "wrappy": {
+    "node_modules/wrappy": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
       "dev": true
     },
-    "y18n": {
+    "node_modules/y18n": {
       "version": "5.0.8",
       "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
       "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "dev": true
-    },
-    "yallist": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      }
     },
-    "yargs": {
+    "node_modules/yargs": {
       "version": "17.7.2",
       "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
       "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "cliui": "^8.0.1",
         "escalade": "^3.1.1",
         "get-caller-file": "^2.0.5",
@@ -2277,31 +3785,66 @@
         "string-width": "^4.2.3",
         "y18n": "^5.0.5",
         "yargs-parser": "^21.1.1"
+      },
+      "engines": {
+        "node": ">=12"
       }
     },
-    "yargs-parser": {
+    "node_modules/yargs-parser": {
       "version": "21.1.1",
       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
       "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=12"
+      }
     },
-    "yargs-unparser": {
+    "node_modules/yargs-unparser": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz",
       "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==",
       "dev": true,
-      "requires": {
+      "dependencies": {
         "camelcase": "^6.0.0",
         "decamelize": "^4.0.0",
         "flat": "^5.0.2",
         "is-plain-obj": "^2.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/yargs/node_modules/emoji-regex": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+      "dev": true
+    },
+    "node_modules/yargs/node_modules/string-width": {
+      "version": "4.2.3",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+      "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+      "dev": true,
+      "dependencies": {
+        "emoji-regex": "^8.0.0",
+        "is-fullwidth-code-point": "^3.0.0",
+        "strip-ansi": "^6.0.1"
+      },
+      "engines": {
+        "node": ">=8"
       }
     },
-    "yocto-queue": {
+    "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
       "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
-      "dev": true
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     }
   }
 }
diff --git a/sirji/vscode-extension/package.json b/sirji/vscode-extension/package.json
index 02652acb..631c4108 100644
--- a/sirji/vscode-extension/package.json
+++ b/sirji/vscode-extension/package.json
@@ -2,7 +2,7 @@
   "name": "sirji",
   "displayName": "Sirji",
   "description": "Sirji is an AI Software Development Agent.",
-  "version": "0.0.7",
+  "version": "0.0.12",
   "publisher": "TrueSparrow",
   "icon": "out/assets/sirji.png",
   "repository": {
@@ -55,9 +55,9 @@
   },
   "scripts": {
     "vscode:prepublish": "npm run compile",
-    "compile": "tsc -p ./ && cp -r src/views src/py_scripts src/assets out/",
+    "compile": "tsc -p ./ && cp -r src/views src/py_scripts src/assets src/defaults out/",
     "watch-ts": "tsc -watch -p ./",
-    "watch-other": "nodemon --watch src --ext html,css,js,py --exec 'mkdir -p out/ && cp -r src/views src/py_scripts src/assets out/'",
+    "watch-other": "nodemon --watch src --ext html,css,js,py --exec 'mkdir -p out/ && cp -r src/views src/py_scripts src/assets src/defaults out/'",
     "watch": "concurrently npm:watch-*",
     "pretest": "npm run compile && npm run lint",
     "lint": "eslint src --ext ts",
@@ -67,8 +67,12 @@
     "publish": "vsce publish"
   },
   "devDependencies": {
+    "@types/babel__traverse": "^7.20.5",
+    "@types/esprima": "^4.0.6",
+    "@types/mime-types": "^2.1.4",
     "@types/mocha": "^10.0.6",
     "@types/node": "18.x",
+    "@types/uuid": "^9.0.8",
     "@types/vscode": "^1.80.2",
     "@typescript-eslint/eslint-plugin": "^7.0.2",
     "@typescript-eslint/parser": "^7.0.2",
@@ -78,5 +82,11 @@
     "eslint": "^8.56.0",
     "nodemon": "^3.1.0",
     "typescript": "^5.3.3"
+  },
+  "dependencies": {
+    "@babel/parser": "^7.24.5",
+    "@babel/traverse": "^7.24.5",
+    "mime-types": "^2.1.35",
+    "uuid": "^9.0.1"
   }
 }
diff --git a/sirji/vscode-extension/src/defaults/agents/ARCHITECT.yml b/sirji/vscode-extension/src/defaults/agents/ARCHITECT.yml
new file mode 100644
index 00000000..d421099d
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/ARCHITECT.yml
@@ -0,0 +1,20 @@
+id: ARCHITECT
+name: Architect Agent
+llm:
+  provider: openai
+  model: gpt-3.5-turbo
+skills:
+  - skill: Generation of architecture components.
+    sub_tasks:
+      - "Read problem statement and epics & user stories from Agent Output Folder."
+      - "Elaborate architecture components and then finalize with USER. Elaboration must include coming up with concrete choices for programming language, framework, database, cache, and any other applicable components required for implementing the epics & user stories and the problem statement. Finalization involves discussion with USER, getting feedback, adjusting according to the feedback and again asking question by showing the updated architecture components."
+      - >
+        Respond with QUESTION ACTION to the USER to get a finalization on. The message details should look like:
+        
+        "Here are the architecture components:
+        
+         <<detailed architecture components>> 
+        
+        <<confirmation question for the user>>". Keep asking QUESTION until finalized, showing the updated architecture components.
+      - "Write the finalized architecture components by saving it to Agent Output Folder."
+      
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/defaults/agents/CODER.yml b/sirji/vscode-extension/src/defaults/agents/CODER.yml
new file mode 100644
index 00000000..1aeec586
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/CODER.yml
@@ -0,0 +1,19 @@
+id: CODER
+name: Coding Agent
+llm:
+  provider: openai
+  model: gpt-4o
+definitions: {}
+rules:
+  - "Ensure that you don't create any file/folder outside of project root folder, i.e. './'"
+  - "Follow secure software development practices while generating code."
+  - "Run commands which are compatible with SIRJI_OS."
+  - "Once the code is written, if the requires a server make sure to start/restart the server."
+skills:
+  - skill: "Developing end-to-end working code for the epic & user stories, making use of the finalized architecture components."
+    sub_tasks:
+      - "Read problem statement, epics & user stories and architecture components from Agent Output Folder."
+      - "Write concrete code implementing the epics & user stories and the problem statement. Do not just conceptualize or outline or simulate it."
+      - "Install programming language-specific packages or libraries in local folders, utilizing tools such as venv for installing Python dependencies and package.json for managing Node.js dependencies."
+      - "Verify whether a system-level command is already installed to avoid triggering the installation of packages that are already in place."
+      - "Always execute the code and evaluate the response output. If the response has errors, solve them before moving ahead."
diff --git a/sirji/vscode-extension/src/defaults/agents/CODE_PLANNER.yml b/sirji/vscode-extension/src/defaults/agents/CODE_PLANNER.yml
new file mode 100644
index 00000000..d658bce4
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/CODE_PLANNER.yml
@@ -0,0 +1,50 @@
+id: CODE_PLANNER
+name: Code Planner
+llm:
+  provider: openai
+  model: gpt-4o
+
+skills:
+  - skill: Analyze problem statements, identify relevant files, thoroughly review their contents, identify relevant dependencies, thoroughly review their contents too, and create a detailed implementation guide.
+    pseudo_code: |
+        1. Initialize:
+            - Read the problem statement from the AGENT OUTPUT FOLDER.
+            - Access the project folder structure and concise file summaries.
+
+        2. Identify and Note Relevant Files:
+            - Create a list to hold file paths and their relevance scores.
+            - For each file path in the file summaries:
+                - Score each file based on the necessity to review its content in relation to the problem statement. This can involve criteria such as:
+                    a) Direct references to features, modules, or components mentioned in the problem statement.
+                    b) Relevance of the file's functionality to the problem being solved.
+                    c) Frequency of key terms from the problem statement appearing in the file summary.
+                    d) Historical modification patterns that suggest the file has been central to similar issues.
+                - Add the file path and its relevance score to the list.
+            - Sort the list by relevance scores in descending order.
+            - Keep only the top 20 most relevant file paths.
+            - Send these top 20 file paths to the ongoing conversation notes in the AGENT OUTPUT FOLDER (Note: These notes are ongoing and not to be indexed in the AGENT OUTPUT INDEX).
+
+        3. Deep Dive into Identified Files:
+            - Repeat until all necessary changes are fully understood:
+                - For each file listed in the ongoing conversation notes:
+                    - Read the file content thoroughly.
+                    - Identify specific parts of the content that directly relate to solving the problem statement.
+                    - Send these identified parts to the ongoing conversation notes in the AGENT OUTPUT FOLDER (Note: Continually update these notes, and they are not to be indexed).
+                    - Determine if further reading of other files is needed based on references or dependencies found.
+                    - Update the ongoing conversation notes with any additional files that need detailed review.
+
+        4. Create and Finalize Implementation Guide:
+            - Construct and review a detailed, standalone implementation guide:
+                - List all the technical instructions for necessary changes, specifying exact file paths and descriptions of changes.
+                - Provide specifics on coding requirements, such as function signatures, data structures, and algorithms to be used or modified.
+                - Outline the creation of new files, including their paths, the specific logic to be implemented, and detailed function signatures and class definitions.
+                - Explain how these new functionalities will interact with existing components, including dependency and integration points.
+                - Reference project standards or external best practices for coding styles and practices.
+                - Ensure that the guide follows a bottom-up approach in implementation order, starting from the most foundational changes to the higher-level ones.
+                - Review the guide for completeness, clarity, and technical accuracy.
+                - Ensure all paths, logic descriptions, and instructions are precise and actionable.
+            - Store the implementation guide in the AGENT OUTPUT FOLDER.
+            - Register the implementation guide to the AGENT OUTPUT INDEX.
+
+
+
diff --git a/sirji/vscode-extension/src/defaults/agents/CODE_WRITER.yml b/sirji/vscode-extension/src/defaults/agents/CODE_WRITER.yml
new file mode 100644
index 00000000..a7a55b91
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/CODE_WRITER.yml
@@ -0,0 +1,27 @@
+id: CODE_WRITER
+
+name: Code writer
+
+llm:
+  provider: openai
+  model: gpt-4o
+
+skills:
+  - skill: "Read implementation guide, extract necessary file changes, and apply these modifications to the project files."
+    pseudo_code: |
+      1. Initialize:
+          - Read the implementation guide from the AGENT OUTPUT FOLDER.
+
+      2. Process Implementation Guide:
+          - Extract a list of project files and the specific changes detailed in the implementation guide.
+          - Write the extracted list to the ongoing conversation notes in the AGENT OUTPUT FOLDER (Note: These notes are ongoing and not to be indexed in the AGENT OUTPUT INDEX).
+
+      3. Implement Changes:
+          - For each entry in the extracted list of project files from the ongoing conversation notes:
+              - If changes are needed in an existing file:
+                  - Read the existing file content.
+                  - Apply the necessary changes using FIND_AND_REPLACE and INSERT_TEXT actions.
+              - Use CREATE_PROJECT_FILE action when a new file is indicated.
+
+      4. Finalize:
+          - Respond back to the agent who invoked you, detailing your actions in the BODY.
diff --git a/sirji/vscode-extension/src/defaults/agents/FILE_SHORTLISTER.yml b/sirji/vscode-extension/src/defaults/agents/FILE_SHORTLISTER.yml
new file mode 100644
index 00000000..3467b61a
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/FILE_SHORTLISTER.yml
@@ -0,0 +1,22 @@
+id: FILE_SHORTLISTER
+name: File Shortlister
+llm:
+  provider: openai
+  model: gpt-4o
+skills:
+  - skill: "Shortlist Essential Files, identifying primary files based on provided summaries and extracting dependencies, creating a comprehensive set of files that may require modifications or can serve as references to address the problem statement."
+    pseudo_code: |
+      - Read the problem statement from Agent Output Folder to understand the requirements.
+      - Utilize the following definitions and subroutine to confirm the list of file paths:
+        DEFINITIONS:
+        - "Target for Modification" file paths are those that might require modifications to meet the requirements.
+        - "Reference for New Development" file paths are those that might contain well-written source code that will serve as a template or guide for the coding style, patterns, and practices expected in new files.
+        SUBROUTINE:
+          REPEAT
+              i. EXTRACT_DEPENDENCIES by sending the "Target for Modification" and "Reference for New Development" file paths to the EXECUTOR.
+              ii. Sanitize the dependency file paths by adding file extensions, for the files without the extension, referencing the project folder structure. Failure to do so will cause errors in further steps. Use these sanitized file paths henceforth. 
+              iii. QUESTION SIRJI_USER requesting confirmation or feedback on the combined list of "Target for Modification", "Reference for New Development" files, and fetched dependencies of those files, presented without individual category headings.
+              iv. IF SIRJI_USER provides feedback for changes THEN MODIFY the appropriate list of file categories based on feedback, referencing the project folder structure. Continue to the next iteration, as feedback was given in the current iteration.
+          UNTIL SIRJI_USER confirms the list of file paths or does not want to do any further chnages in the list
+      - Store the confirmed list of essential file paths in Agent Output Folder, clearly grouped under the categories: "Target for Modification", "Reference for New Development", and "Dependency".
+      - Respond back to the agent who invoked you, detailing your actions in the BODY.
diff --git a/sirji/vscode-extension/src/defaults/agents/NODE_JS_API_CODER.yml b/sirji/vscode-extension/src/defaults/agents/NODE_JS_API_CODER.yml
new file mode 100644
index 00000000..5d281652
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/NODE_JS_API_CODER.yml
@@ -0,0 +1,18 @@
+id: NODE_JS_API_CODER
+
+name: Node JS API Coder
+
+llm:
+  provider: openai
+  model: gpt-4o
+
+sub_agents:
+    - id: CODE_PLANNER
+    - id: CODE_WRITER
+
+skills:
+  - skill: "Developing robust backend REST APIs using Node.js and Express, integrating Sequelize ORM with PostgreSQL databases, and implementing Redis for efficient caching solutions."
+    pseudo_code: |
+      1. INVOKE_AGENT CODE_PLANNER to analyze problem statements, identify relevant files, thoroughly review their contents, identify relevant dependencies, thoroughly review their contents too, and create a detailed implementation guide.
+      2. INVOKE_AGENT CODE_WRITER to read the implementation guide, extract necessary file changes, apply these modifications to the project files.
+      3. Respond back to the agent who invoked you, detailing your actions in the BODY.
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/defaults/agents/ORCHESTRATOR.yml b/sirji/vscode-extension/src/defaults/agents/ORCHESTRATOR.yml
new file mode 100644
index 00000000..9de74d9a
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/ORCHESTRATOR.yml
@@ -0,0 +1,5 @@
+id: ORCHESTRATOR
+name: Orchestrator
+llm:
+  provider: openai
+  model: gpt-3.5-turbo
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/defaults/agents/PRODUCT_MANAGER.yml b/sirji/vscode-extension/src/defaults/agents/PRODUCT_MANAGER.yml
new file mode 100644
index 00000000..ad72b933
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/agents/PRODUCT_MANAGER.yml
@@ -0,0 +1,18 @@
+id: PRODUCT_MANAGER
+name: Product Manager Agent
+llm:
+  provider: openai
+  model: gpt-3.5-turbo
+definitions:
+  Proposal: "The QUESTION asked to SIRJI_USER showing the initial or revised Epics and User Stories. Typical Question Asked: \"Here are the detailed epics and user stories based on your problem statement:\n\n <<detailed epics and user stories>> \n\n<<confirmation question for the SIRJI_USER>>\""
+  Finalization: "Finalization involves discussion with SIRJI_USER by sending 'Proposal', getting feedback, adjusting according to the feedback and again sending the revised 'Proposal'. Keep on doing it till SIRJI_USER agrees."
+  Finalized epics and user stories: "The 'Proposal' on which the SIRJI_USER agrees."
+rules:
+  - "Elaboration must include detailed screen elements and interactions, without leaving anything abstract."
+  - "UI created for any user story must me modern and neat."
+skills:
+  - skill: "Finalize Epics and User Story"
+    sub_tasks:
+      - "Read problem statement from Agent Output Folder."
+      - "Elaborate the problem statement into epics & then send the 'Proposal' to SIRJI_USER to get 'Finalization'."
+      - "Write the finalized epics and user stories by saving it to Agent Output Folder."
diff --git a/sirji/vscode-extension/src/defaults/recipe.json b/sirji/vscode-extension/src/defaults/recipe.json
new file mode 100644
index 00000000..1b3bbff9
--- /dev/null
+++ b/sirji/vscode-extension/src/defaults/recipe.json
@@ -0,0 +1,13 @@
+{
+  "llm": {
+    "provider": "openai",
+    "model": "gpt-3.5-turbo"
+  },
+  "prescribed_tasks": [
+    {
+      "task": "Develop robust backend REST APIs using Node.js and Express, integrating Sequelize ORM with PostgreSQL databases, and implementing Redis for efficient caching solutions.",
+      "agent": "NODE_JS_API_CODER"
+    }
+  ],
+  "tips": []
+}
diff --git a/sirji/vscode-extension/src/py_scripts/agents/coding_agent.py b/sirji/vscode-extension/src/py_scripts/agents/coding_agent.py
deleted file mode 100644
index 4da0a2ce..00000000
--- a/sirji/vscode-extension/src/py_scripts/agents/coding_agent.py
+++ /dev/null
@@ -1,99 +0,0 @@
-import argparse
-import os
-import json
-from sirji_messages import MessageFactory, ActionEnum, AgentEnum
-from sirji_agents import CodingAgent
-
-class CodingAgentRunner:
-    def get_workplace_file_path(self, filename):
-        return os.path.join(self._get_workspace_folder(), '.sirji', self._get_run_id_folder(), filename)
-    
-    def _get_workspace_folder(self):
-        workspace = os.environ.get("SIRJI_WORKSPACE")
-        if workspace is None:
-            raise ValueError(
-                "SIRJI_WORKSPACE is not set as an environment variable")
-        return workspace
-    
-    def _get_run_id_folder(self):
-        run_id = os.environ.get("SIRJI_RUN_ID")
-        if run_id is None:
-            raise ValueError(
-                "SIRJI_RUN_ID is not set as an environment variable")
-        return run_id
-
-    def read_or_initialize_conversation_file(self, file_path):
-        if not os.path.exists(file_path) or os.path.getsize(file_path) == 0:
-            with open(file_path, 'w') as file:
-                json.dump({"conversations": [], "prompt_tokens": 0, "completion_tokens": 0}, file, indent=4)
-                return [], 0, 0
-        else:
-            with open(file_path, 'r') as file:
-                contents = json.load(file)
-                return contents["conversations"], contents["prompt_tokens"], contents["completion_tokens"]
-
-    def write_conversations_to_file(self, file_path, conversations, prompt_tokens, completion_tokens):
-        with open(file_path, 'w') as file:
-            json.dump({"conversations": conversations, "prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens}, file, indent=4)
-  
-
-    def process_input_file(self, input_file_path, conversations):
-        with open(input_file_path, 'r') as file:
-            contents = file.read()
-
-        if not conversations:
-            message_class = MessageFactory[ActionEnum.PROBLEM_STATEMENT.name]
-            message_str = message_class().generate({"details": contents})
-        elif conversations[-1]['parsed_content']['TO'] == AgentEnum.USER.name:
-            last_action = conversations[-1]['parsed_content']['ACTION']
-
-            if last_action in [ActionEnum.INFORM.name, ActionEnum.QUESTION.name]:
-                message_class = MessageFactory[ActionEnum.ANSWER.name]
-                message_str = message_class().generate({"details": contents})
-            elif last_action == ActionEnum.SOLUTION_COMPLETE.name:
-                message_class = MessageFactory[ActionEnum.FEEDBACK.name]
-                message_str = message_class().generate({"details": contents})
-            elif last_action in [ActionEnum.STEP_STARTED.name, ActionEnum.STEP_COMPLETED.name]:
-                message_class = MessageFactory[ActionEnum.ACKNOWLEDGE.name]
-                message_str = message_class().generate({"details": contents})
-                print(f"Message: {message_str}")
-            else:
-                raise ValueError(f"Invalid action: {last_action}")
-        elif conversations[-1]['parsed_content']['TO'] == AgentEnum.EXECUTOR.name:
-            last_action = conversations[-1]['parsed_content']['ACTION']
-
-            if last_action in [ActionEnum.EXECUTE_COMMAND.name, ActionEnum.RUN_SERVER.name, ActionEnum.CREATE_FILE.name, ActionEnum.INSTALL_PACKAGE.name, ActionEnum.READ_FILE.name, ActionEnum.READ_DIR.name]:
-                message_class = MessageFactory[ActionEnum.OUTPUT.name]
-                message_str = message_class().generate({"details": contents})
-            else:
-                raise ValueError(f"Invalid action: {last_action}")
-        else:
-            message_str = contents
-
-        return message_str
-
-    def process_message(self, message_str, conversations):
-        coder = CodingAgent()
-        return coder.message(message_str, conversations)
-        
-    def main(self, input_file, conversation_file):
-        input_file_path = self.get_workplace_file_path(input_file)
-        conversation_file_path = self.get_workplace_file_path(conversation_file)
-
-        conversations, prompt_tokens, completion_tokens = self.read_or_initialize_conversation_file(conversation_file_path)
-        message_str = self.process_input_file(input_file_path, conversations)
-
-        response, conversations, prompt_tokens_consumed, completion_tokens_consumed = self.process_message(message_str, conversations)
-        
-        prompt_tokens += prompt_tokens_consumed
-        completion_tokens += completion_tokens_consumed
-        self.write_conversations_to_file(conversation_file_path, conversations, prompt_tokens, completion_tokens)
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description="Process interactions.")
-    parser.add_argument("--input", required=True, help="Input file name")
-    parser.add_argument("--conversation", required=True, help="Conversation file name")
-    
-    args = parser.parse_args()
-    agent_runner = CodingAgentRunner()
-    agent_runner.main(args.input, args.conversation)
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/py_scripts/agents/invoke_agent.py b/sirji/vscode-extension/src/py_scripts/agents/invoke_agent.py
new file mode 100644
index 00000000..eb3af450
--- /dev/null
+++ b/sirji/vscode-extension/src/py_scripts/agents/invoke_agent.py
@@ -0,0 +1,118 @@
+import argparse
+import os
+import json
+import yaml
+import textwrap
+from sirji_messages import MessageFactory, ActionEnum, AgentEnum
+from sirji_agents import GenericAgent
+
+class AgentRunner:    
+    def _get_project_folder(self):
+        project_folder = os.environ.get("SIRJI_PROJECT")
+        if project_folder is None:
+            raise ValueError(
+                "SIRJI_PROJECT is not set as an environment variable")
+        return project_folder
+
+    def read_or_initialize_conversation_file(self, file_path):
+        if not os.path.exists(file_path) or os.path.getsize(file_path) == 0:
+            with open(file_path, 'w') as file:
+                json.dump({"conversations": [], "prompt_tokens": 0, "completion_tokens": 0}, file, indent=4)
+                return [], 0, 0
+        else:
+            with open(file_path, 'r') as file:
+                contents = json.load(file)
+                return contents["conversations"], contents["prompt_tokens"], contents["completion_tokens"]
+
+    def write_conversations_to_file(self, file_path, conversations, prompt_tokens, completion_tokens):
+        with open(file_path, 'w') as file:
+            json.dump({"conversations": conversations, "prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens}, file, indent=4)
+
+    def read_file(self, file_path):
+        print('---------')
+        print(file_path)
+        with open(file_path, 'r') as file:
+            contents = file.read()
+        return contents 
+  
+
+    def process_input_file(self, input_file_path, conversations):
+        with open(input_file_path, 'r') as file:
+            contents = file.read()
+
+        if len(conversations) > 1 and conversations[-1]['parsed_content']['TO'] in [AgentEnum.SIRJI_USER.name, AgentEnum.ORCHESTRATOR.name]:
+            last_message = conversations[-1]['parsed_content']
+            
+            message_class = MessageFactory[ActionEnum.RESPONSE.name]
+            message_str = message_class().generate({
+            "from_agent_id": f"{last_message['TO']}",
+            "to_agent_id": f"{last_message['FROM']}",
+            "summary": "EMPTY",
+            "body": textwrap.dedent(f"""
+            {contents}
+            """)})
+        else:
+            message_str = contents
+
+        return message_str
+
+    def process_message(self, message_str, conversations, config, agent_output_index, file_summaries):
+        agent = GenericAgent(config, agent_output_index, file_summaries)
+        return agent.message(message_str, conversations)
+        
+    def main(self, agent_id, agent_session_id, agent_callstack):
+        sirji_installation_dir = os.environ.get("SIRJI_INSTALLATION_DIR")
+        sirji_run_path = os.environ.get("SIRJI_RUN_PATH")
+        sirji_project_folder = os.environ.get("SIRJI_PROJECT")
+        
+        input_file_path = os.path.join(sirji_run_path, 'input.txt')
+        conversation_file_path = os.path.join(sirji_run_path, 'conversations', f'{agent_callstack}.{agent_session_id}.json')
+        agent_output_index_path = os.path.join(sirji_run_path, 'agent_output', 'index.json')
+        
+        agent_config_path = os.path.join(sirji_installation_dir, 'active_recipe', 'agents', f'{agent_id}.yml')
+
+        file_summaries_folder_path = os.path.join(sirji_installation_dir, 'file_summaries')
+        file_summaries_file_path = os.path.join(file_summaries_folder_path, 'index.json')
+
+        with open(file_summaries_file_path, 'r') as file:
+            file_summaries_index = json.load(file)
+            relative_path = file_summaries_index.get(sirji_project_folder, '')
+            file_summaries_path = os.path.join(file_summaries_folder_path, relative_path)
+
+        with open(file_summaries_path, 'r') as file:
+            file_summaries = file.read()
+
+
+        conversations, prompt_tokens, completion_tokens = self.read_or_initialize_conversation_file(conversation_file_path)
+        message_str = self.process_input_file(input_file_path, conversations)
+
+        config_file_contents = self.read_file(agent_config_path)
+        # config = json.loads(config_file_contents)
+        config = yaml.safe_load(config_file_contents)
+
+        agent_output_index_contents = self.read_file(agent_output_index_path)
+        agent_output_index = json.loads(agent_output_index_contents)
+
+        llm = config['llm']
+        
+        # Set SIRJI_MODEL_PROVIDER env var to llm.provider
+        os.environ['SIRJI_MODEL_PROVIDER'] = llm['provider']
+        # Set SIRJI_MODEL env var to llm.model
+        os.environ['SIRJI_MODEL'] = llm['model']
+
+        response, conversations, prompt_tokens_consumed, completion_tokens_consumed = self.process_message(message_str, conversations, config, agent_output_index, file_summaries)
+        
+        prompt_tokens += prompt_tokens_consumed
+        completion_tokens += completion_tokens_consumed
+        self.write_conversations_to_file(conversation_file_path, conversations, prompt_tokens, completion_tokens)
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description="Process interactions.")
+    parser.add_argument("--agent_id", required=True, help="Agent Id")
+    parser.add_argument("--agent_session_id", required=True, help="Agent Session Id")
+    parser.add_argument("--agent_callstack", required=True, help="Agent Call Stack")
+ 
+    
+    args = parser.parse_args()
+    agent_runner = AgentRunner()
+    agent_runner.main(args.agent_id, args.agent_session_id, args.agent_callstack)
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/py_scripts/agents/invoke_orchestator.py b/sirji/vscode-extension/src/py_scripts/agents/invoke_orchestator.py
new file mode 100644
index 00000000..f583388a
--- /dev/null
+++ b/sirji/vscode-extension/src/py_scripts/agents/invoke_orchestator.py
@@ -0,0 +1,110 @@
+import argparse
+import os
+import json
+from sirji_agents import Orchestrator
+
+class AgentRunner:
+    def _get_project_folder(self):
+        project_folder = os.environ.get("SIRJI_PROJECT")
+        if project_folder is None:
+            raise ValueError(
+                "SIRJI_PROJECT is not set as an environment variable")
+        return project_folder
+
+    def read_or_initialize_conversation_file(self, file_path):
+        if not os.path.exists(file_path) or os.path.getsize(file_path) == 0:
+            with open(file_path, 'w') as file:
+                json.dump({"conversations": [], "prompt_tokens": 0, "completion_tokens": 0}, file, indent=4)
+                return [], 0, 0
+        else:
+            with open(file_path, 'r') as file:
+                contents = json.load(file)
+                return contents["conversations"], contents["prompt_tokens"], contents["completion_tokens"]
+
+    def write_conversations_to_file(self, file_path, conversations, prompt_tokens, completion_tokens):
+        with open(file_path, 'w') as file:
+            json.dump({"conversations": conversations, "prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens}, file, indent=4)
+            file.flush()
+            os.fsync(file.fileno())  # Ensure all internal buffers associated with the file are written to disk
+
+    def read_input_file(self, input_file_path):
+        with open(input_file_path, 'r') as file:
+            contents = file.read()
+        return contents
+  
+
+    def process_input_file(self, input_file_path, conversations):
+        if not os.path.exists(input_file_path):
+            with open(input_file_path, 'w') as file:
+                json.dump({}, file, indent=4)
+        
+        with open(input_file_path, 'r') as file:
+            contents = file.read()
+            message_str = contents
+
+        return message_str
+
+    def process_message(self, message_str, conversations, recipe, installed_agents): 
+        agent = Orchestrator(recipe)
+        return agent.message(message_str, conversations)
+    
+    def read_agents_from_files(self, directory):
+        installed_agents = []
+        
+        # Loop through each file in the directory
+        for filename in os.listdir(directory):
+            if filename.endswith('.json'):
+                file_path = os.path.join(directory, filename)
+                
+                # Read and parse the JSON file
+                with open(file_path, 'r') as file:
+                    data = json.load(file)
+                    
+                    # Extract the required information
+                    agent = {
+                        "id": data["id"],
+                        "name": data["name"],
+                        "skills": [skill["skill"] for skill in data["skills"]]
+                    }
+                    
+                    # Append the agent object to the list
+                    installed_agents.append(agent)
+        
+        return installed_agents
+        
+    def main(self, agent_id):
+        ## move to a function   
+        sirji_installation_dir = os.environ.get("SIRJI_INSTALLATION_DIR")
+        sirji_run_path = os.environ.get("SIRJI_RUN_PATH")
+
+        input_file_path = os.path.join(sirji_run_path, 'input.txt')
+        conversation_file_path = os.path.join(sirji_run_path, 'conversations', f'{agent_id}.json')
+        agent_output_index_path = os.path.join(sirji_run_path, 'agent_output', 'index.json')
+
+        recipe_file_path = os.path.join(sirji_installation_dir, 'active_recipe', 'recipe.json')
+        installed_agent_folder = os.path.join(sirji_installation_dir, 'active_recipe', 'agents')
+
+        installed_agents = self.read_agents_from_files(installed_agent_folder)
+
+        conversations, prompt_tokens, completion_tokens = self.read_or_initialize_conversation_file(conversation_file_path)
+        message_str = self.process_input_file(input_file_path, conversations)
+
+        recipe_file_contents = self.read_input_file(recipe_file_path)
+        recipe = json.loads(recipe_file_contents)
+
+        llm = recipe['llm']
+        
+        # Set SIRJI_MODEL_PROVIDER env var to llm.provider
+        os.environ['SIRJI_MODEL_PROVIDER'] = llm['provider']
+        # Set SIRJI_MODEL env var to llm.model
+        os.environ['SIRJI_MODEL'] = llm['model']
+        
+        response, conversations, prompt_tokens_consumed, completion_tokens_consumed = self.process_message(message_str, conversations, recipe, installed_agents)
+        
+        prompt_tokens += prompt_tokens_consumed
+        completion_tokens += completion_tokens_consumed
+        self.write_conversations_to_file(conversation_file_path, conversations, prompt_tokens, completion_tokens)
+
+if __name__ == "__main__":
+    agent_runner = AgentRunner()
+    agent_runner.main('ORCHESTRATOR')
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/py_scripts/agents/planning_agent.py b/sirji/vscode-extension/src/py_scripts/agents/planning_agent.py
deleted file mode 100644
index 6843ac60..00000000
--- a/sirji/vscode-extension/src/py_scripts/agents/planning_agent.py
+++ /dev/null
@@ -1,68 +0,0 @@
-import argparse
-import os
-import json
-from sirji_agents import PlanningAgent
-
-class PlanningAgentRunner:
-    def get_workplace_file_path(self, filename):
-        return os.path.join(self._get_workspace_folder(), '.sirji', self._get_run_id_folder(), filename)
-    
-    def _get_workspace_folder(self):
-        workspace = os.environ.get("SIRJI_WORKSPACE")
-        if workspace is None:
-            raise ValueError(
-                "SIRJI_WORKSPACE is not set as an environment variable")
-        return workspace
-    
-    def _get_run_id_folder(self):
-        run_id = os.environ.get("SIRJI_RUN_ID")
-        if run_id is None:
-            raise ValueError(
-                "SIRJI_RUN_ID is not set as an environment variable")
-        return run_id
-
-    def read_or_initialize_conversation_file(self, file_path):
-            if not os.path.exists(file_path) or os.path.getsize(file_path) == 0:
-                with open(file_path, 'w') as file:
-                    json.dump({"conversations": [], "prompt_tokens": 0, "completion_tokens": 0}, file, indent=4)
-                    return [], 0, 0
-            else:
-                with open(file_path, 'r') as file:
-                    contents = json.load(file)
-                    return contents["conversations"], contents["prompt_tokens"], contents["completion_tokens"]
-
-    def write_conversations_to_file(self, file_path, conversations, prompt_tokens, completion_tokens):
-        with open(file_path, 'w') as file:
-            json.dump({"conversations": conversations, "prompt_tokens": prompt_tokens, "completion_tokens": completion_tokens}, file, indent=4)
-    
-    def process_input_file(self, input_file_path, conversations):
-        with open(input_file_path, 'r') as file:
-            contents = file.read()
-        return contents
-
-    def process_message(self, message_str, conversations):
-        planner = PlanningAgent()
-        return planner.message(message_str, conversations)
-        
-    def main(self, input_file, conversation_file):
-        input_file_path = self.get_workplace_file_path(input_file)
-        conversation_file_path = self.get_workplace_file_path(conversation_file)
-
-        conversations, prompt_tokens, completion_tokens = self.read_or_initialize_conversation_file(conversation_file_path)
-
-        message_str = self.process_input_file(input_file_path, conversations)
-
-        response, conversations, prompt_tokens_consumed, completion_tokens_consumed = self.process_message(message_str, conversations)
-        
-        prompt_tokens += prompt_tokens_consumed
-        completion_tokens += completion_tokens_consumed
-        self.write_conversations_to_file(conversation_file_path, conversations, prompt_tokens, completion_tokens)
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(description="Process interactions.")
-    parser.add_argument("--input", required=True, help="Input file name")
-    parser.add_argument("--conversation", required=True, help="Conversation file name")
-    
-    args = parser.parse_args()
-    agent_runner = PlanningAgentRunner()
-    agent_runner.main(args.input, args.conversation)
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/py_scripts/agents/research_agent.py b/sirji/vscode-extension/src/py_scripts/agents/research_agent.py
index e14192b7..817b8107 100644
--- a/sirji/vscode-extension/src/py_scripts/agents/research_agent.py
+++ b/sirji/vscode-extension/src/py_scripts/agents/research_agent.py
@@ -6,20 +6,20 @@
 
 class ResearchAgentRunner:
     def get_workplace_file_path(self, filename):
-        return os.path.join(self._get_workspace_folder(), '.sirji', self._get_run_id_folder(), filename)
+        return os.path.join(self._get_run_path(), filename)
     
-    def _get_workspace_folder(self):
-        workspace = os.environ.get("SIRJI_WORKSPACE")
-        if workspace is None:
+    def _get_project_folder(self):
+        project_folder = os.environ.get("SIRJI_PROJECT")
+        if project_folder is None:
             raise ValueError(
-                "SIRJI_WORKSPACE is not set as an environment variable")
-        return workspace
+                "SIRJI_PROJECT is not set as an environment variable")
+        return project_folder
     
-    def _get_run_id_folder(self):
-        run_id = os.environ.get("SIRJI_RUN_ID")
+    def _get_run_path(self):
+        run_id = os.environ.get("SIRJI_RUN_PATH")
         if run_id is None:
             raise ValueError(
-                "SIRJI_RUN_ID is not set as an environment variable")
+                "SIRJI_RUN_PATH is not set as an environment variable")
         return run_id 
     
     def read_or_initialize_conversation_file(self, file_path):
diff --git a/sirji/vscode-extension/src/py_scripts/requirements-windows.txt b/sirji/vscode-extension/src/py_scripts/requirements-windows.txt
index 1a15bd7d..7fde7fd9 100644
--- a/sirji/vscode-extension/src/py_scripts/requirements-windows.txt
+++ b/sirji/vscode-extension/src/py_scripts/requirements-windows.txt
@@ -1,3 +1,4 @@
 urllib3==2.2.1
-sirji-messages==0.0.14
-sirji-agents==0.0.21
\ No newline at end of file
+pyyaml==6.0.1
+sirji-messages==0.0.18
+sirji-agents==0.0.26
diff --git a/sirji/vscode-extension/src/py_scripts/requirements.txt b/sirji/vscode-extension/src/py_scripts/requirements.txt
index 26c0946a..4094bcfa 100644
--- a/sirji/vscode-extension/src/py_scripts/requirements.txt
+++ b/sirji/vscode-extension/src/py_scripts/requirements.txt
@@ -1,3 +1,4 @@
 urllib3==1.25.11
-sirji-messages==0.0.14
-sirji-agents==0.0.21
+pyyaml==6.0.1
+sirji-messages==0.0.18
+sirji-agents==0.0.26
diff --git a/sirji/vscode-extension/src/utils/invoke_agent.ts b/sirji/vscode-extension/src/utils/adapter_wrapper.ts
similarity index 65%
rename from sirji/vscode-extension/src/utils/invoke_agent.ts
rename to sirji/vscode-extension/src/utils/adapter_wrapper.ts
index 825086d5..73daf178 100644
--- a/sirji/vscode-extension/src/utils/invoke_agent.ts
+++ b/sirji/vscode-extension/src/utils/adapter_wrapper.ts
@@ -5,41 +5,23 @@ import os from 'os';
 import { SecretStorage } from './secret_storage';
 import { Constants } from './constants';
 import fs from 'fs';
+import { readDirectoryStructure } from './executor/read_directory_structure';
 
-export async function invokeAgent(context: vscode.ExtensionContext | undefined, workspaceRootPath: string, sirjiRunId: string, scriptPath: string, args: string[] = []): Promise<any> {
+export async function spawnAdapter(
+  context: vscode.ExtensionContext | undefined,
+  sirjiInstallationPath: string,
+  sirjiRunPath: string,
+  projectRootPath: string,
+  scriptPath: string,
+  args: string[] = []
+): Promise<any> {
   console.log('Executing command:', 'python3', [scriptPath, ...args].join(' '));
-  const response = await executePythonScript(context, workspaceRootPath, sirjiRunId, scriptPath, args);
-  console.log(response);
-  return response;
-}
-
-function getPythonPath(workspaceRootPath: string, venvPath: string): string {
-  let pythonPath = 'python3';
-
-  if (fs.existsSync(venvPath)) {
-    // Determine the correct path for the Python executable based on the OS
-    const pythonExecutable = os.platform() === 'win32' ? 'scripts/python.exe' : 'bin/python3';
 
-    // Generate the full path to the Python executable inside the virtual environment
-    pythonPath = path.join(venvPath, pythonExecutable);
-  }
-
-  return pythonPath;
-}
-
-async function getEnvVars(context: vscode.ExtensionContext | undefined, workspaceRootPath: string): Promise<any> {
-  const secretManager = new SecretStorage(context);
-  const envVars = JSON.parse((await secretManager.retrieveSecret(Constants.ENV_VARS_KEY)) || '{}');
-  envVars.SIRJI_WORKSPACE = workspaceRootPath;
-
-  return envVars;
-}
+  const venvPath = path.join(sirjiInstallationPath, 'venv');
+  const pythonPath = getPythonPath(venvPath);
+  const envVars = await getEnvVars(context, sirjiInstallationPath, projectRootPath, sirjiRunPath);
 
-async function executePythonScript(context: vscode.ExtensionContext | undefined, workspaceRootPath: string, sirjiRunId: string, scriptPath: string, args: string[] = []): Promise<any> {
-  const venvPath = path.join(workspaceRootPath, Constants.PYHTON_VENV_FOLDER);
-  const pythonPath = getPythonPath(workspaceRootPath, venvPath);
-  const envVars = await getEnvVars(context, workspaceRootPath);
-  envVars.SIRJI_RUN_ID = sirjiRunId;
+  console.log('---------env vars', envVars);
 
   return new Promise((resolve, reject) => {
     const process = childProcess.spawn(pythonPath, [scriptPath, ...args], {
@@ -74,3 +56,27 @@ async function executePythonScript(context: vscode.ExtensionContext | undefined,
     });
   });
 }
+
+function getPythonPath(venvPath: string): string {
+  let pythonPath = 'python3';
+
+  if (fs.existsSync(venvPath)) {
+    // Determine the correct path for the Python executable based on the OS
+    const pythonExecutable = os.platform() === 'win32' ? 'scripts/python.exe' : 'bin/python3';
+
+    // Generate the full path to the Python executable inside the virtual environment
+    pythonPath = path.join(venvPath, pythonExecutable);
+  }
+
+  return pythonPath;
+}
+
+async function getEnvVars(context: vscode.ExtensionContext | undefined, sirjiInstallationPath: string, projectRootPath: string, sirjiRunPath: string): Promise<any> {
+  const secretManager = new SecretStorage(context);
+  const envVars = JSON.parse((await secretManager.retrieveSecret(Constants.ENV_VARS_KEY)) || '{}');
+  envVars.SIRJI_INSTALLATION_DIR = sirjiInstallationPath;
+  envVars.SIRJI_PROJECT = projectRootPath;
+  envVars.SIRJI_RUN_PATH = sirjiRunPath;
+  envVars.SIRJI_PROJECT_STRUCTURE = await readDirectoryStructure(projectRootPath, 'Directory: /');
+  return envVars;
+}
diff --git a/sirji/vscode-extension/src/utils/agent_stack_manager.ts b/sirji/vscode-extension/src/utils/agent_stack_manager.ts
new file mode 100644
index 00000000..2c065b37
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/agent_stack_manager.ts
@@ -0,0 +1,28 @@
+export class AgentStackManager {
+    private agentCallStack: string;
+  
+    constructor(initialStack: string = "") {
+        this.agentCallStack = initialStack;
+    }
+  
+    // Function to add an agent ID to the call stack
+    public addAgentId(agentId: string): void {
+        if (this.agentCallStack.length > 0) {
+            this.agentCallStack += `.${agentId}`;
+        } else {
+            this.agentCallStack = agentId;
+        }
+    }
+  
+    // Function to remove the last agent ID from the call stack
+    public removeLastAgentId(): void {
+        const ids = this.agentCallStack.split('.');
+        ids.pop(); // Remove the last element
+        this.agentCallStack = ids.join('.');
+    }
+  
+    // Utility method to view the current stack
+    public getStack(): string {
+        return this.agentCallStack;
+    }
+  }
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/utils/constants.ts b/sirji/vscode-extension/src/utils/constants.ts
index 164fe8d2..bb90428b 100644
--- a/sirji/vscode-extension/src/utils/constants.ts
+++ b/sirji/vscode-extension/src/utils/constants.ts
@@ -2,29 +2,21 @@ import path from 'path';
 
 export const Constants = {
   ENV_VARS_KEY: 'sirjiSecrets',
-  HISTORY_FOLDER: '.sirji',
-  PYHTON_VENV_FOLDER: getPythonVenvPath(),
   CODER_JSON_FILE: 'coder.json',
   PLANNER_JSON_FILE: 'planner.json',
   RESEARCHER_JSON_FILE: 'researcher.json',
   PYTHON_INPUT_FILE: 'input.txt',
   PROMPT_TOKEN_PRICE_PER_MILLION_TOKENS: 10,
-  COMPLETION_TOKEN_PRICE_PER_MILLION_TOKENS: 30
+  COMPLETION_TOKEN_PRICE_PER_MILLION_TOKENS: 30,
+  SESSIONS: 'sessions'
 };
 
-function getPythonVenvPath(): string {
-  return path.join('.sirji', 'venv');
-}
-
 export const ACTION_ENUM = {
   //user and coder conversations
   PROBLEM_STATEMENT: 'PROBLEM_STATEMENT',
   QUESTION: 'QUESTION',
   ANSWER: 'ANSWER',
   INFORM: 'INFORM',
-  STEP_STARTED: 'STEP_STARTED',
-  STEP_COMPLETED: 'STEP_COMPLETED',
-  ACKNOWLEDGE: 'ACKNOWLEDGE',
   SOLUTION_COMPLETE: 'SOLUTION_COMPLETE',
   FEEDBACK: 'FEEDBACK',
 
@@ -42,18 +34,26 @@ export const ACTION_ENUM = {
   //coder and executor conversations
   EXECUTE_COMMAND: 'EXECUTE_COMMAND',
   RUN_SERVER: 'RUN_SERVER',
-  CREATE_FILE: 'CREATE_FILE',
-  READ_FILE: 'READ_FILE',
-  READ_DIR: 'READ_DIR',
-  INSTALL_PACKAGE: 'INSTALL_PACKAGE',
+  CREATE_PROJECT_FILE: 'CREATE_PROJECT_FILE',
+  READ_PROJECT_FILES: 'READ_PROJECT_FILES',
   OUTPUT: 'OUTPUT',
-  OPEN_BROWSER: 'OPEN_BROWSER'
+  OPEN_BROWSER: 'OPEN_BROWSER',
+  CREATE_AGENT_OUTPUT_FILE: 'CREATE_AGENT_OUTPUT_FILE',
+  READ_AGENT_OUTPUT_FILES: 'READ_AGENT_OUTPUT_FILES',
+  APPEND_TO_AGENT_OUTPUT_INDEX: 'APPEND_TO_AGENT_OUTPUT_INDEX',
+  READ_AGENT_OUTPUT_INDEX: 'READ_AGENT_OUTPUT_INDEX',
+  SEARCH_FILE_IN_PROJECT: 'SEARCH_FILE_IN_PROJECT',
+  FIND_AND_REPLACE: 'FIND_AND_REPLACE',
+  INSERT_TEXT: 'INSERT_TEXT',
+  EXTRACT_DEPENDENCIES: 'EXTRACT_DEPENDENCIES'
 };
 
 export const ACTOR_ENUM = {
-  USER: 'USER',
+  USER: 'SIRJI_USER',
   CODER: 'CODER',
   PLANNER: 'PLANNER',
   RESEARCHER: 'RESEARCHER',
-  EXECUTOR: 'EXECUTOR'
+  EXECUTOR: 'EXECUTOR',
+  ORCHESTRATOR: 'ORCHESTRATOR',
+  SHORTLISTER: 'SHORTLISTER'
 };
diff --git a/sirji/vscode-extension/src/utils/create_file.ts b/sirji/vscode-extension/src/utils/create_file.ts
deleted file mode 100644
index cac63152..00000000
--- a/sirji/vscode-extension/src/utils/create_file.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as fs from 'fs';
-
-export async function createFile(workspaceRootPath: string, fileName: string, fileContent: string): Promise<string> {
-  try {
-    const uri = vscode.Uri.file(path.join(workspaceRootPath, fileName));
-
-    const directoryPath = path.dirname(uri.fsPath);
-    if (!fs.existsSync(directoryPath)) {
-      await vscode.workspace.fs.createDirectory(vscode.Uri.file(directoryPath));
-    }
-
-    const content = Buffer.from(fileContent, 'utf8');
-    await vscode.workspace.fs.writeFile(uri, content);
-
-    console.log(`File created successfully: ${uri.fsPath}`);
-
-    return 'Done';
-  } catch (e) {
-    const errorMessage = `Failed to create or write to the file. Error: ${e}`;
-    return errorMessage;
-  }
-}
diff --git a/sirji/vscode-extension/src/utils/execute_command.ts b/sirji/vscode-extension/src/utils/execute_command.ts
deleted file mode 100644
index 6f7acb55..00000000
--- a/sirji/vscode-extension/src/utils/execute_command.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import * as vscode from 'vscode';
-import * as fs from 'fs';
-import * as path from 'path';
-
-const fsPromises = fs.promises;
-let sirjiTerminal: vscode.Terminal | undefined;
-
-async function checkForChanges(filePath: string, previousContent: string): Promise<{ hasChanges: boolean; currentContent: string }> {
-  const currentContent = await fsPromises.readFile(filePath, 'utf-8');
-  const hasChanges = currentContent !== previousContent;
-  return {
-    hasChanges,
-    currentContent
-  };
-}
-
-function constructResponse(isRunning: boolean, tempFilePath: string, tempFileContent: string): string {
-  let response = isRunning ? 'Execute Command still running.' : 'Execute command complete.';
-  response += ` Command execution output from ${tempFilePath}:\n`;
-  response += tempFileContent;
-  return response;
-}
-
-export async function executeCommand(command: string, workspaceRootPath: string): Promise<string> {
-  if (!sirjiTerminal) {
-    sirjiTerminal = vscode.window.createTerminal(`Sirji Terminal`);
-    vscode.window.onDidCloseTerminal((terminal) => {
-      if (terminal === sirjiTerminal) {
-        sirjiTerminal = undefined;
-      }
-    });
-  }
-
-  sirjiTerminal.show(true);
-
-  const fileName = `output.txt`;
-  const filePath = path.join(workspaceRootPath, fileName);
-  if (command.startsWith('source ')) {
-    command = `${command} 2> "${filePath}"`;
-  } else {
-    command = `${command} 2>&1 | tee "${filePath}"`;
-  }
-
-  sirjiTerminal.sendText(command);
-
-  await new Promise((resolve) => setTimeout(resolve, 1000));
-
-  let previousContent = '';
-
-  const checkForChangesAndConstructResponse = (): Promise<string> => {
-    return new Promise((resolve, reject) => {
-      const intervalId = setInterval(async () => {
-        const { hasChanges, currentContent } = await checkForChanges(filePath, previousContent);
-
-        if (!hasChanges) {
-          clearInterval(intervalId);
-          resolve(constructResponse(false, filePath, currentContent));
-        } else {
-          previousContent = currentContent;
-        }
-      }, 10000);
-    });
-  };
-
-  return await checkForChangesAndConstructResponse();
-}
diff --git a/sirji/vscode-extension/src/utils/executor/append_to_agent_output_index.ts b/sirji/vscode-extension/src/utils/executor/append_to_agent_output_index.ts
new file mode 100644
index 00000000..2d7d9e64
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/append_to_agent_output_index.ts
@@ -0,0 +1,50 @@
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as fs from 'fs';
+
+export async function appendToAgentOutputsIndex(agentOutputFolderPath: string, messageBody: string, agentId: string): Promise<string> {
+  try {
+    const [filePathString, filePathContentDescription] = messageBody.split('---');
+    const filePath = filePathString.replace('File path:', '').trim();
+
+    let fileDescription = '';
+    if (filePathContentDescription) {
+      fileDescription = filePathContentDescription.trim();
+    }
+
+    const fileContent = {
+      [filePath]: {
+        description: fileDescription,
+        created_by: agentId
+      }
+    };
+
+    const uri = vscode.Uri.file(path.join(agentOutputFolderPath, 'index.json'));
+
+    const directoryPath = path.dirname(uri.fsPath);
+    if (!fs.existsSync(directoryPath)) {
+      await vscode.workspace.fs.createDirectory(vscode.Uri.file(directoryPath));
+    }
+
+    let content: Buffer;
+
+    if (fs.existsSync(uri.fsPath)) {
+      const existingContent = await vscode.workspace.fs.readFile(uri);
+      const existingContentString = Buffer.from(existingContent).toString('utf-8');
+      const existingContentJson = JSON.parse(existingContentString);
+      existingContentJson[filePath] = fileContent[filePath];
+      content = Buffer.from(JSON.stringify(existingContentJson, null, 2), 'utf8');
+    } else {
+      content = Buffer.from(JSON.stringify(fileContent, null, 2), 'utf8');
+    }
+
+    await vscode.workspace.fs.writeFile(uri, content);
+
+    console.log(`Agent Output Index updated successfully: ${uri.fsPath}`);
+
+    return 'Updated agent output index file.';
+  } catch (e) {
+    const errorMessage = `Failed to create or write to the file. Error: ${e}`;
+    return errorMessage;
+  }
+}
diff --git a/sirji/vscode-extension/src/utils/executor/create_file.ts b/sirji/vscode-extension/src/utils/executor/create_file.ts
new file mode 100644
index 00000000..ac665b09
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/create_file.ts
@@ -0,0 +1,43 @@
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as fs from 'fs';
+
+export async function createFile(rootPath: string, isProjectRoot: boolean, body: string): Promise<string> {
+  try {
+    const [filePathPart, fileContent] = body.split('---');
+    const filePath = filePathPart.replace('File path:', '').trim();
+
+    const fullPath = path.isAbsolute(filePath) ? filePath : path.join(rootPath, filePath);
+    const uri = vscode.Uri.file(fullPath);
+
+    if (isProjectRoot) {
+      if (!isInsideProject(uri.fsPath, rootPath)) {
+        throw new Error('File path is outside of the project folder tree. Write operation denied.');
+      }
+    } else {
+      if (path.isAbsolute(filePath)) {
+        throw new Error('Absolute file path is not allowed while creating file in Agent Output Folder. Write operation denied.');
+      }
+    }
+
+    const directoryPath = path.dirname(uri.fsPath);
+    if (!fs.existsSync(directoryPath)) {
+      await vscode.workspace.fs.createDirectory(vscode.Uri.file(directoryPath));
+    }
+
+    const content = Buffer.from(fileContent, 'utf8');
+    await vscode.workspace.fs.writeFile(uri, content);
+
+    console.log(`File created successfully: ${uri.fsPath}`);
+
+    return 'Done';
+  } catch (e) {
+    const errorMessage = `Failed to create or write to the file. Error: ${e}`;
+    return errorMessage;
+  }
+}
+
+function isInsideProject(filePath: string, projectRootPath: string): boolean {
+  const relativePath = path.relative(projectRootPath, filePath);
+  return !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
+}
diff --git a/sirji/vscode-extension/src/utils/execute_spawn.ts b/sirji/vscode-extension/src/utils/executor/execute_spawn.ts
similarity index 90%
rename from sirji/vscode-extension/src/utils/execute_spawn.ts
rename to sirji/vscode-extension/src/utils/executor/execute_spawn.ts
index cd5c9443..2032b783 100644
--- a/sirji/vscode-extension/src/utils/execute_spawn.ts
+++ b/sirji/vscode-extension/src/utils/executor/execute_spawn.ts
@@ -12,14 +12,14 @@ function constructResponse(success: boolean, output: string): string {
 }
 
 // let sirjiTerminal: vscode.Terminal | undefined;
-export async function executeSpawn(command: string, workspaceRootPath: string): Promise<string> {
+export async function executeSpawn(command: string, projectRootPath: string): Promise<string> {
   let successResp = '';
   let errorResp = '';
   const [cmd, ...args] = command.split(/\s+/);
 
   return new Promise(async (resolve, reject) => {
     const child = spawn(cmd, args, {
-      cwd: workspaceRootPath,
+      cwd: projectRootPath,
       shell: true
     });
 
diff --git a/sirji/vscode-extension/src/utils/execute_task.ts b/sirji/vscode-extension/src/utils/executor/execute_task.ts
similarity index 90%
rename from sirji/vscode-extension/src/utils/execute_task.ts
rename to sirji/vscode-extension/src/utils/executor/execute_task.ts
index c93d4a03..3b6cfc9e 100644
--- a/sirji/vscode-extension/src/utils/execute_task.ts
+++ b/sirji/vscode-extension/src/utils/executor/execute_task.ts
@@ -1,7 +1,6 @@
 import * as vscode from 'vscode';
 import * as fs from 'fs';
 import * as path from 'path';
-import { Constants } from './constants';
 import * as os from 'os';
 
 let currentTaskExecution: any = null;
@@ -24,12 +23,12 @@ function constructResponse(isRunning: Boolean, tempFileRelativePath: string, tem
   return response;
 }
 
-export async function executeTask(command: string, workspaceRootPath: string, sirjiRunId: string): Promise<string> {
+export async function executeTask(command: string, projectRootPath: string): Promise<string> {
   return new Promise(async (resolve, reject) => {
-    const tempFileName = `output.txt`;
+    const tempFileName = `output_${Date.now()}.txt`;
 
-    const tempFileRelativePath = path.join(Constants.HISTORY_FOLDER, sirjiRunId, tempFileName);
-    const tempFilePath = path.join(workspaceRootPath, tempFileRelativePath);
+    const tempFileRelativePath = path.join(projectRootPath, tempFileName);
+    const tempFilePath = path.join(projectRootPath, tempFileRelativePath);
 
     let tempFileContent = '';
 
diff --git a/sirji/vscode-extension/src/utils/executor/executor.ts b/sirji/vscode-extension/src/utils/executor/executor.ts
new file mode 100644
index 00000000..b9b77c18
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/executor.ts
@@ -0,0 +1,94 @@
+import { createFile } from './create_file';
+import { executeSpawn } from './execute_spawn';
+import { executeTask } from './execute_task';
+import { openBrowser } from './open_browser';
+import { readContent } from './read_content';
+import { appendToAgentOutputsIndex } from './append_to_agent_output_index';
+import { readAgentOutputsIndex } from './read_agent_output_index';
+
+import { ACTION_ENUM } from '../constants';
+import { searchFileInProject } from './search_file_in_project';
+import { findAndReplaceInProjectFile } from './find_and_replace_in_project_file';
+import { insertText } from './insert_text';
+import { readDependencies } from './extract_file_dependencies';
+
+export class Executor {
+  private parsedMessage: any;
+  private projectRootPath: any;
+  private agentOutputFolderPath: any;
+  private sirjiRunFolderPath: any;
+
+  public constructor(parsedMessage: any, projectRootPath: any, agentOutputFolderPath: any, sirjiRunFolderPath: any) {
+    const oThis = this;
+
+    oThis.parsedMessage = parsedMessage;
+    oThis.projectRootPath = projectRootPath;
+    oThis.agentOutputFolderPath = agentOutputFolderPath;
+    oThis.sirjiRunFolderPath = sirjiRunFolderPath;
+  }
+
+  public async perform() {
+    const oThis = this;
+
+    let rawOutput = await oThis.handleAction(oThis.parsedMessage.ACTION);
+    return oThis.formatMessage(rawOutput);
+  }
+
+  private async handleAction(action: string) {
+    const oThis = this;
+
+    switch (action) {
+      case ACTION_ENUM.CREATE_PROJECT_FILE:
+        return await createFile(oThis.projectRootPath, true, oThis.parsedMessage.BODY);
+      case ACTION_ENUM.CREATE_AGENT_OUTPUT_FILE:
+        return await createFile(oThis.agentOutputFolderPath, false, oThis.parsedMessage.BODY);
+      case ACTION_ENUM.EXECUTE_COMMAND:
+        return await executeSpawn(oThis.parsedMessage.BODY, oThis.projectRootPath);
+      case ACTION_ENUM.RUN_SERVER:
+        return await executeTask(oThis.parsedMessage.BODY, oThis.sirjiRunFolderPath);
+      case ACTION_ENUM.OPEN_BROWSER:
+        openBrowser(oThis.parsedMessage.URL);
+        return 'Done';
+      case ACTION_ENUM.READ_PROJECT_FILES:
+        return await readContent(oThis.projectRootPath, oThis.parsedMessage.BODY, false);
+      case ACTION_ENUM.READ_AGENT_OUTPUT_FILES:
+        return await readContent(oThis.agentOutputFolderPath, oThis.parsedMessage.BODY, false);
+      case ACTION_ENUM.APPEND_TO_AGENT_OUTPUT_INDEX:
+        return await appendToAgentOutputsIndex(oThis.agentOutputFolderPath, oThis.parsedMessage.BODY, oThis.parsedMessage.FROM);
+      case ACTION_ENUM.READ_AGENT_OUTPUT_INDEX:
+        return await readAgentOutputsIndex(oThis.agentOutputFolderPath);
+      case ACTION_ENUM.SEARCH_FILE_IN_PROJECT:
+        return await searchFileInProject(oThis.parsedMessage.BODY);
+      case ACTION_ENUM.FIND_AND_REPLACE:
+        return await findAndReplaceInProjectFile(oThis.parsedMessage.BODY, oThis.projectRootPath);
+      case ACTION_ENUM.INSERT_TEXT:
+        return await insertText(oThis.parsedMessage.BODY, oThis.projectRootPath);
+      case ACTION_ENUM.EXTRACT_DEPENDENCIES:
+        return await readDependencies(oThis.parsedMessage.BODY, oThis.projectRootPath);
+      default:
+        throw `Invalid message ACTION: ${action} sent to executor.`;
+    }
+  }
+
+  private formatMessage(rawOutput: any) {
+    const oThis = this;
+
+    const newParsedMessage = {
+      FROM: oThis.parsedMessage.TO,
+      TO: oThis.parsedMessage.FROM,
+      ACTION: ACTION_ENUM.RESPONSE,
+      SUMMARY: 'Empty',
+      BODY: '\n' + rawOutput
+    };
+
+    const rawMessage = `***
+FROM: ${newParsedMessage.FROM}
+TO: ${newParsedMessage.TO}
+ACTION: ${newParsedMessage.ACTION}
+SUMMARY: ${newParsedMessage.SUMMARY}
+BODY: \n${newParsedMessage.BODY}
+***`;
+
+    return { rawMessage, parsedMessage: newParsedMessage };
+  }
+}
diff --git a/sirji/vscode-extension/src/utils/executor/extract_file_dependencies.ts b/sirji/vscode-extension/src/utils/executor/extract_file_dependencies.ts
new file mode 100644
index 00000000..24b34400
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/extract_file_dependencies.ts
@@ -0,0 +1,144 @@
+import fs from 'fs';
+import path from 'path';
+import * as parser from '@babel/parser';
+import traverse from '@babel/traverse';
+import { Node, Identifier, StringLiteral, BinaryExpression } from '@babel/types';
+
+interface DependencyMap {
+  [file: string]: string[];
+}
+
+const variableValues = new Map<string, string>();
+
+const readCode = async (filePath: string): Promise<string> => {
+  return fs.promises.readFile(filePath, 'utf8');
+};
+
+const resolvePath = (node: Node): string | null => {
+  if (node.type === 'BinaryExpression' && node.operator === '+') {
+    const left = resolvePath(node.left as any);
+    const right = resolvePath(node.right as any);
+    return left && right ? path.join(left, right) : null;
+  } else if (node.type === 'StringLiteral') {
+    return node.value;
+  } else if (node.type === 'Identifier') {
+    return variableValues.get(node.name) || null;
+  } else if (node.type === 'TemplateLiteral') {
+    let resolvedPath = '';
+    for (const part of node.quasis) {
+      resolvedPath += part.value.raw;
+    }
+    if (resolvedPath.startsWith('/')) {
+      resolvedPath = resolvedPath.slice(1);
+    }
+    return resolvedPath;
+  }
+  return null;
+};
+
+const safePathResolve = (baseDir: string, relativePath: string): string => {
+  const normalizedBaseDir = path.normalize(baseDir + '/');
+
+  let resolvedPath = normalizedBaseDir;
+  const pathParts = relativePath.split('/');
+
+  for (const part of pathParts) {
+    if (part === '..') {
+      let parentDir = path.dirname(resolvedPath);
+      if (parentDir.startsWith(normalizedBaseDir)) {
+        resolvedPath = parentDir;
+      }
+    } else if (part !== '.') {
+      resolvedPath = path.join(resolvedPath, part);
+    }
+  }
+
+  return resolvedPath;
+};
+
+const getFileWithExtension = (filePath: string, baseDir: string): string => {
+  if (!filePath.startsWith('.')) {
+    return filePath;
+  }
+
+  const absolutePath = safePathResolve(baseDir, filePath);
+  const possibleExtensions = ['.js', '.ts'];
+
+  let finalPath = absolutePath;
+
+  for (let ext of possibleExtensions) {
+    let testedPath = absolutePath + ext;
+    if (fs.existsSync(testedPath)) {
+      finalPath = testedPath;
+      break;
+    }
+  }
+
+  return path.relative(baseDir, finalPath);
+};
+
+const extractDependencies = async (filePath: string, baseDir: string): Promise<string[]> => {
+  if (!fs.existsSync(filePath) || !filePath.endsWith('.js')) {
+    console.log(`Skipping non-existent or non-JS/TS file: ${filePath}`);
+    return [];
+  }
+
+  const code = await readCode(filePath);
+  const ast = parser.parse(code, {
+    sourceType: 'module',
+    plugins: ['dynamicImport']
+  });
+
+  let dependencies = new Set<string>();
+
+  traverse(ast, {
+    VariableDeclarator(path) {
+      const { node } = path;
+      if (node.id.type === 'Identifier' && node.init && node.init.type === 'StringLiteral') {
+        variableValues.set(node.id.name, node.init.value);
+      }
+    },
+    CallExpression({ node }) {
+      if (node.callee.type === 'Identifier' && node.callee.name === 'require' && node.arguments.length === 1 && node.arguments[0].type !== 'SpreadElement') {
+        const arg = node.arguments[0];
+        if (arg.type === 'StringLiteral') {
+          dependencies.add(getFileWithExtension(arg.value, baseDir));
+        } else if (arg.type === 'BinaryExpression' && arg.operator === '+') {
+          const resolvedPath = resolvePath(arg);
+          if (resolvedPath) {
+            dependencies.add(getFileWithExtension(resolvedPath, baseDir));
+          }
+        } else if (arg.type === 'TemplateLiteral') {
+          const resolvedPath = resolvePath(arg);
+          if (resolvedPath) {
+            dependencies.add(getFileWithExtension(resolvedPath, baseDir));
+          }
+        }
+      }
+    }
+  });
+
+  return Array.from(dependencies);
+};
+
+export const readDependencies = async (body: string, projectRootPath: string): Promise<string[]> => {
+  const filePaths = body
+    .split('[')[1]
+    .split(']')[0]
+    .split(',')
+    .map((filePath) => filePath.trim().slice(1, -1));
+
+  const allDependencies = new Set<string>();
+
+  for (const filePath of filePaths) {
+    try {
+      const fullPath = path.resolve(projectRootPath, filePath);
+      const dependencies = await extractDependencies(fullPath, projectRootPath);
+      dependencies.forEach((dep) => allDependencies.add(dep));
+    } catch (error) {
+      console.log(`Error processing ${filePath}: ${error}`);
+    }
+  }
+
+  return Array.from(allDependencies);
+};
diff --git a/sirji/vscode-extension/src/utils/executor/find_and_replace_in_project.ts b/sirji/vscode-extension/src/utils/executor/find_and_replace_in_project.ts
new file mode 100644
index 00000000..edda4adf
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/find_and_replace_in_project.ts
@@ -0,0 +1,52 @@
+import * as vscode from 'vscode';
+import * as fs from 'fs';
+
+export const findAndReplaceInProject = async (body: string, globPattern?: string, exclude: string = '**/node_modules/**'): Promise<string> => {
+  const searchText = body.split('Find:')[1].split('---')[0].trim();
+  const replacement = body.split('Replace:')[1].split('---')[0].trim();
+  const folderPath = body.split('Directory:')[1].trim();
+
+  console.log(`Searching for files with pattern: ${searchText} in folder: ${folderPath} and replacing with: ${replacement}`);
+
+  const basePath = folderPath ? `${folderPath}/` : '**/';
+  const namePattern = '**/*.*';
+  const pattern = `${basePath}${namePattern}`;
+
+  try {
+    const files = await vscode.workspace.findFiles(pattern, exclude);
+    const foundFiles: vscode.Uri[] = [];
+
+    for (const file of files) {
+      console.log(`Found file: ${file.fsPath}`);
+      const content = fs.readFileSync(file.fsPath, 'utf-8');
+      if (content.includes(searchText)) {
+        foundFiles.push(file);
+      }
+    }
+
+    console.log(`Found ${files.length} files with pattern: ${pattern}` + ` and ${foundFiles.length} files with search text: ${searchText}`);
+
+    for (const file of foundFiles) {
+      console.log(`Replacing in file: ${file.fsPath}`);
+      const document = await vscode.workspace.openTextDocument(file);
+      const editor = await vscode.window.showTextDocument(document);
+
+      const allText = new vscode.Range(document.positionAt(0), document.positionAt(document.getText().length));
+
+      await editor.edit((editBuilder) => {
+        let text = document.getText(allText);
+        const regex = new RegExp(searchText, 'g');
+        text = text.replace(regex, replacement);
+        editBuilder.replace(allText, text);
+      });
+      await document.save();
+      //close the file
+      await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
+    }
+
+    return 'Done';
+  } catch (error) {
+    console.error(`Error replacing text in files: ${error}`);
+    return 'Error while replacing text in files. error: ' + error;
+  }
+};
diff --git a/sirji/vscode-extension/src/utils/executor/find_and_replace_in_project_file.ts b/sirji/vscode-extension/src/utils/executor/find_and_replace_in_project_file.ts
new file mode 100644
index 00000000..196cf177
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/find_and_replace_in_project_file.ts
@@ -0,0 +1,55 @@
+import * as vscode from 'vscode';
+import * as fs from 'fs';
+import path from 'path';
+
+export const findAndReplaceInProjectFile = async (body: string, projectRootPath: string, globPattern?: string, exclude: string = '**/node_modules/**'): Promise<string> => {
+  let searchText, replacement, filePath;
+
+  try {
+    searchText = body.split('FIND:')[1].split('---')[0].trim();
+    replacement = body.split('REPLACE:')[1].split('---')[0].trim();
+    filePath = body.split('FILE_PATH:')[1].split('---')[0].trim();
+  } catch (error) {
+    console.error('Error parsing body:', error);
+    return 'Error: Your response must conform strictly to one of the allowed Response Templates, as it will be processed programmatically and only these templates are recognized. Your response for the FIND_AND_REPLACE_IN_PROJECT_FILE action must conform this response template: FILE_PATH: {{File path}} --- FIND: {{Find this text}} --- REPLACE: {{Replace with this text}}---';
+  }
+
+  filePath = path.join(projectRootPath, filePath);
+
+  console.log(`Searching for files with pattern: ${searchText} in folder: ${filePath} and replacing with: ${replacement}`);
+
+  const basePath = filePath ? `${filePath}/` : '**/';
+  const namePattern = '**/*.*';
+  const pattern = `${basePath}${namePattern}`;
+
+  console.log(`Searching for files with pattern: ${pattern} and excluding: ${exclude} in folder: ${filePath}`);
+  try {
+    if (fs.existsSync(filePath)) {
+      const document = await vscode.workspace.openTextDocument(filePath);
+      const editor = await vscode.window.showTextDocument(document);
+      const allText = new vscode.Range(document.positionAt(0), document.positionAt(document.getText().length));
+
+      let text = document.getText(allText);
+      if (!text.includes(searchText)) {
+        return 'ERROR: The specified string to find was not found in the document. Please re-read the content of the file and ensure you have provided the correct string to search for, then try again.';
+      }
+
+      await editor.edit((editBuilder) => {
+        const regex = new RegExp(searchText, 'g');
+        text = text.replace(regex, replacement);
+        editBuilder.replace(allText, text);
+      });
+
+      await document.save();
+      await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
+      console.log('Replacement done in file:', filePath);
+      return 'Done';
+    } else {
+      console.error('File does not exist:', filePath);
+      return 'Error: File does not exist';
+    }
+  } catch (error) {
+    console.error(`Error replacing text in files: ${error}`);
+    return 'Error while replacing text in files. error: ' + error;
+  }
+};
diff --git a/sirji/vscode-extension/src/utils/executor/insert_text.ts b/sirji/vscode-extension/src/utils/executor/insert_text.ts
new file mode 100644
index 00000000..4a08d325
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/insert_text.ts
@@ -0,0 +1,58 @@
+import * as vscode from 'vscode';
+import * as fs from 'fs';
+import path from 'path';
+
+export const insertText = async (body: string, projectRootPath: string, globPattern?: string, exclude: string = '**/node_modules/**'): Promise<string> => {
+  let searchText, textToInsert, filePath, insertPosition;
+
+  try {
+    searchText = body.split('FIND:')[1].split('---')[0].trim();
+    textToInsert = body.split('TEXT_TO_INSERT:')[1].split('---')[0].trim();
+    filePath = body.split('FILE_PATH:')[1].split('---')[0].trim();
+    insertPosition = body.split('INSERT_POSITION:')[1].split('---')[0].trim();
+  } catch (error) {
+    console.error('Error parsing body:', error);
+    return 'Error in processing your last response. Your response must conform strictly to one of the allowed Response Templates, as it will be processed programmatically and only these templates are recognized. Your response for the INSERT_TEXT action must conform this response template: FILE_PATH: {{File path}} ---FIND: {{Text to find}} ---INSERT_POSITION: {{above or below}}---TEXT_TO_INSERT: {{Text to insert}}--- ';
+  }
+  filePath = path.join(projectRootPath, filePath);
+
+  console.log(`Inserting text in file: ${filePath} based on search text: '${searchText}' with replacement: '${textToInsert}' and insert position: '${insertPosition}'`);
+
+  try {
+    if (!fs.existsSync(filePath)) {
+      console.error('File does not exist:', filePath);
+      return 'Error: File does not exist';
+    }
+
+    const document = await vscode.workspace.openTextDocument(filePath);
+    const editor = await vscode.window.showTextDocument(document);
+
+    const range = new vscode.Range(document.positionAt(0), document.positionAt(document.getText().length));
+    const text = document.getText(range);
+
+    const index = text.indexOf(searchText);
+    if (index === -1) {
+      console.error('Search text not found in the document.');
+      return 'ERROR: The specified string to find was not found in the document. Please re-read the content of the file and ensure you have provided the correct string to search for, then try again';
+    }
+
+    const position = document.positionAt(index);
+    const line = position.line;
+
+    await editor.edit((editBuilder) => {
+      if (insertPosition.toLowerCase() === 'above') {
+        editBuilder.insert(new vscode.Position(line, 0), textToInsert + '\n');
+      } else if (insertPosition.toLowerCase() === 'below') {
+        editBuilder.insert(new vscode.Position(line + 1, 0), textToInsert + '\n');
+      }
+    });
+
+    await document.save();
+    await vscode.commands.executeCommand('workbench.action.closeActiveEditor');
+    console.log('Text insertion completed in file:', filePath);
+    return 'Done';
+  } catch (error) {
+    console.error(`Error processing file: ${error}`);
+    return `Failed to process file: ${error}`;
+  }
+};
diff --git a/sirji/vscode-extension/src/utils/open_browser.ts b/sirji/vscode-extension/src/utils/executor/open_browser.ts
similarity index 100%
rename from sirji/vscode-extension/src/utils/open_browser.ts
rename to sirji/vscode-extension/src/utils/executor/open_browser.ts
diff --git a/sirji/vscode-extension/src/utils/executor/read_agent_output_index.ts b/sirji/vscode-extension/src/utils/executor/read_agent_output_index.ts
new file mode 100644
index 00000000..349676ac
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/read_agent_output_index.ts
@@ -0,0 +1,28 @@
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as fs from 'fs';
+
+export async function readAgentOutputsIndex(agentOutputFolderPath: string): Promise<string> {
+  try {
+    const fileName = 'index.json';
+
+    const uri = vscode.Uri.file(path.join(agentOutputFolderPath, fileName));
+
+    const directoryPath = path.dirname(uri.fsPath);
+
+    if (!fs.existsSync(directoryPath)) {
+      await vscode.workspace.fs.createDirectory(vscode.Uri.file(directoryPath));
+    }
+
+    if (!fs.existsSync(uri.fsPath)) {
+      return 'Agent Output Index not found';
+    }
+
+    const content = await vscode.workspace.fs.readFile(uri);
+
+    return `Content of Agent Output Index\n---\n${Buffer.from(content).toString('utf-8')}`;
+  } catch (e) {
+    const errorMessage = `Failed to create or write to the file. Error: ${e}`;
+    return errorMessage;
+  }
+}
diff --git a/sirji/vscode-extension/src/utils/executor/read_content.ts b/sirji/vscode-extension/src/utils/executor/read_content.ts
new file mode 100644
index 00000000..ade2ee9c
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/read_content.ts
@@ -0,0 +1,124 @@
+import * as path from 'path';
+import * as fs from 'fs/promises';
+import * as mimetype from 'mime-types';
+
+const SKIP_LIST = ['__pycache__', '.git', '.github', '.gitlab', '.vscode', '.idea', 'node_modules', '.DS_Store', 'venv', '.venv', '.sass-cache', 'dist', 'out', 'build', 'logs', '.npm', 'temp', 'tmp'];
+
+// Define media MIME types to skip
+const MEDIA_MIME_TYPES = [
+  'image',
+  'video',
+  'audio'
+  // 'application/pdf', // PDF files
+  // 'application/zip', // ZIP archives
+  // 'application/x-tar', // TAR archives
+  // 'application/x-gzip', // GZIP archives
+  // 'application/x-rar-compressed', // RAR archives
+  // 'application/vnd.ms-excel', // Excel files
+  // 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // Excel files (xlsx)
+  // 'application/msword', // Word documents
+  // 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // Word documents (docx)
+  // 'application/vnd.ms-powerpoint', // PowerPoint presentations
+  // 'application/vnd.openxmlformats-officedocument.presentationml.presentation', // PowerPoint presentations (pptx)
+  // 'application/vnd.oasis.opendocument.text', // OpenDocument Text
+  // 'application/vnd.oasis.opendocument.spreadsheet', // OpenDocument Spreadsheet
+  // 'application/vnd.oasis.opendocument.presentation' // OpenDocument Presentation
+];
+
+function isPathInsideRoot(rootPath: string, targetPath: string): boolean {
+  const resolvedRoot = path.resolve(rootPath);
+  const resolvedTarget = path.resolve(targetPath);
+  return resolvedTarget.startsWith(resolvedRoot);
+}
+
+export async function readContent(projectRootPath: string, body: string, isDirectory: boolean): Promise<string> {
+  async function shouldSkip(name: string): Promise<boolean> {
+    return SKIP_LIST.includes(name);
+  }
+
+  async function readFile(filePath: string): Promise<string> {
+    try {
+      const fileMimetype = mimetype.lookup(filePath);
+      let content = null;
+      const relativePath = path.relative(projectRootPath, filePath);
+
+      const stats = await fs.stat(filePath);
+      if (stats.size > 102400) {
+        content = `Skipping file of size greater than 100 KB: ${filePath}`;
+      } else if (fileMimetype && MEDIA_MIME_TYPES.some((type) => fileMimetype.startsWith(type))) {
+        content = `Skipping file of media type: ${filePath}`;
+      } else if (fileMimetype && fileMimetype.startsWith('application/octet-stream')) {
+        content = `Skipping binary file: ${filePath}`;
+      } else {
+        content = await fs.readFile(filePath, 'utf8');
+      }
+
+      return `File: ${relativePath}\n\n${content}\n\n---\n\n`;
+    } catch (err) {
+      console.error(`Failed to read file ${filePath}:`, err);
+      throw err;
+    }
+  }
+
+  async function readDirectory(directoryPath: string): Promise<string> {
+    try {
+      let files = await fs.readdir(directoryPath, { withFileTypes: true });
+      let results = [];
+
+      for (const file of files) {
+        if (await shouldSkip(file.name)) {
+          continue; // Skips current iteration if name matches any in SKIP_LIST
+        }
+
+        const currentPath = path.join(directoryPath, file.name);
+        if (file.isDirectory()) {
+          results.push(await readDirectory(currentPath));
+        } else {
+          results.push(await readFile(currentPath));
+        }
+      }
+
+      return results.join('');
+    } catch (err) {
+      console.error(`Failed to read directory ${directoryPath}:`, err);
+      throw err;
+    }
+  }
+
+  let result = '';
+  let inputPaths = [];
+
+  if (isDirectory) {
+    const directoryPath = body.split('Directory:')[1].trim();
+    inputPaths.push(directoryPath);
+  } else {
+    const filePaths = body.split('File paths:')[1];
+    inputPaths = JSON.parse(filePaths);
+  }
+
+  console.log('-------inputPaths', inputPaths);
+
+  for (const inputPath of inputPaths) {
+    try {
+      const fullPath = path.isAbsolute(inputPath) ? inputPath : path.join(projectRootPath, inputPath);
+
+      if (!isPathInsideRoot(projectRootPath, fullPath)) {
+        throw new Error(`Path '${inputPath}' is not within the project root.`);
+      }
+
+      console.log('-------fullPath', fullPath);
+      const stats = await fs.stat(fullPath);
+
+      if (stats.isDirectory()) {
+        result += await readDirectory(fullPath);
+      } else {
+        result += await readFile(fullPath);
+      }
+    } catch (e) {
+      const errorMessage = `Failed to read the path ${inputPath}. Error: ${e}`;
+      console.error(errorMessage);
+      result += errorMessage;
+    }
+  }
+  return result;
+}
diff --git a/sirji/vscode-extension/src/utils/executor/read_directory_structure.ts b/sirji/vscode-extension/src/utils/executor/read_directory_structure.ts
new file mode 100644
index 00000000..71a3820b
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/read_directory_structure.ts
@@ -0,0 +1,59 @@
+import * as path from 'path';
+import * as fs from 'fs/promises';
+
+const SKIP_LIST = new Set<string>([
+  '__pycache__', '.git', '.github', '.gitlab', '.vscode', '.idea', 
+  'node_modules', '.DS_Store', 'venv', '.venv', '.sass-cache', 
+  'dist', 'out', 'build', 'logs', '.npm', 'temp', 'tmp'
+]);
+
+export async function readDirectoryStructure(projectRootPath: string, body: string): Promise<string> {
+  const inputPath = body.split('Directory:')[1].trim();
+  const fullPath = path.join(projectRootPath, inputPath);
+
+  async function readGitignore(): Promise<void> {
+    try {
+      const gitignorePath = path.join(projectRootPath, '.gitignore');
+      const data = await fs.readFile(gitignorePath, 'utf8');
+      const gitignoreEntries = data.split('\n')
+                                   .map(entry => entry.trim())
+                                   .filter(entry => entry && !entry.startsWith('#'));
+      gitignoreEntries.forEach(entry => SKIP_LIST.add(entry));
+    } catch (err: any) {
+      if (err.code !== 'ENOENT') {
+        console.warn(`Failed to read .gitignore:`, err);
+        throw err;
+      }
+    }
+  }
+
+  function shouldSkip(name: string): boolean {
+    return SKIP_LIST.has(name);
+  }
+
+  async function readDirectory(directoryPath: string): Promise<string> {
+    try {
+      const files = await fs.readdir(directoryPath);
+      const promises = files.map(async (file) => {
+        const filePath = path.join(directoryPath, file);
+        const stats = await fs.stat(filePath);
+        if (stats.isDirectory()) {
+          if (shouldSkip(file)) {
+            return '';
+          }
+          return readDirectory(filePath);
+        } else {
+          return path.relative(projectRootPath, filePath) + '\n';
+        }
+      });
+      const contents = await Promise.all(promises);
+      return contents.join('');
+    } catch (err) {
+      console.error(`Failed to read directory ${directoryPath}:`, err);
+      throw err;
+    }
+  }
+
+  await readGitignore();
+  return readDirectory(fullPath);
+}
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/utils/executor/search_file_in_project.ts b/sirji/vscode-extension/src/utils/executor/search_file_in_project.ts
new file mode 100644
index 00000000..c8ff2b55
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/executor/search_file_in_project.ts
@@ -0,0 +1,32 @@
+import * as vscode from 'vscode';
+import * as fs from 'fs';
+
+export async function searchFileInProject(body: string, fileType: string = '*', maxResults: number = 10, exclude: string = '**/node_modules/**'): Promise<vscode.Uri[]> {
+  const searchText = body.split('Search:')[1].split('---')[0].trim();
+  const folderPath = body.split('Directory:')[1].trim();
+
+  console.log(`Searching for files with pattern: ${searchText} in folder: ${folderPath}`);
+
+  const basePath = folderPath ? `${folderPath}/` : '**/';
+  const namePattern = searchText.includes('*') ? searchText : `*${searchText}*`;
+  const pattern = `${basePath}${namePattern}.${fileType}`;
+
+  try {
+    const files = await vscode.workspace.findFiles(pattern, exclude, maxResults);
+
+    const result: vscode.Uri[] = [];
+
+    for (const file of files) {
+      console.log(`Found file: ${file.fsPath}`);
+      const content = fs.readFileSync(file.fsPath, 'utf-8');
+      if (content.includes(searchText)) {
+        result.push(file);
+      }
+    }
+
+    console.log(`Found ${result.length} files`);
+    return result;
+  } catch (error) {
+    return [];
+  }
+}
diff --git a/sirji/vscode-extension/src/utils/facilitator.ts b/sirji/vscode-extension/src/utils/facilitator.ts
index d6192d02..3724b272 100644
--- a/sirji/vscode-extension/src/utils/facilitator.ts
+++ b/sirji/vscode-extension/src/utils/facilitator.ts
@@ -1,23 +1,25 @@
 import * as vscode from 'vscode';
 import { randomBytes } from 'crypto';
 import path from 'path';
+import os from 'os';
+import * as fs from 'fs';
 
 import { renderView } from './render_view';
 import { MaintainHistory } from './maintain_history';
-import { invokeAgent } from './invoke_agent';
+import { spawnAdapter } from './adapter_wrapper';
 import { SecretStorage } from './secret_storage';
 import { Constants, ACTOR_ENUM, ACTION_ENUM } from './constants';
-import { openBrowser } from './open_browser';
-import { executeCommand } from './execute_command';
-import { createFile } from './create_file';
-import { readContent } from './read_content';
-import { executeTask } from './execute_task';
-import { executeSpawn } from './execute_spawn';
+
+import { Executor } from './executor/executor';
+import { readDependencies } from './executor/extract_file_dependencies';
+
+import { AgentStackManager } from './agent_stack_manager';
+import { SessionManager } from './session_manager';
 
 export class Facilitator {
   private context: vscode.ExtensionContext | undefined;
-  private workspaceRootUri: any;
-  private workspaceRootPath: any;
+  private projectRootUri: any;
+  private projectRootPath: any;
   private sirjiRunId: string = '';
   private chatPanel: vscode.WebviewPanel | undefined;
   private secretManager: SecretStorage | undefined;
@@ -26,6 +28,14 @@ export class Facilitator {
   private isPlannerTabShown: Boolean = false;
   private isResearcherTabShown: Boolean = false;
   private isCoderTabShown: Boolean = false;
+  private isFirstUserMessage: Boolean = true;
+  private stackManager: AgentStackManager = new AgentStackManager();
+  private sessionManager: SessionManager | null = null;
+  private agentOutputFolderPath: string = '';
+  private lastMessageFrom: string = '';
+  private sirjiInstallationFolderPath: string = '';
+  private sirjiRunFolderPath: string = '';
+  private inputFilePath: string = '';
 
   public constructor(context: vscode.ExtensionContext) {
     const oThis = this;
@@ -36,38 +46,30 @@ export class Facilitator {
   public async init() {
     const oThis = this;
 
-    // Setup workspace
-    await oThis.selectWorkspace();
+    // Setup Project Folder
+    await oThis.selectProjectFolder();
 
-    // Setup Environment
-    await oThis.setupEnvironment();
+    // Setup folders for run, installed_agents, etc.
+    await oThis.initializeFolders();
 
     // Setup secret manager
     await oThis.setupSecretManager();
 
-    // Setup History Manager
-    // oThis.setupHistoryManager();
-
     // Open Chat Panel
     oThis.openChatViewPanel();
 
     return oThis.chatPanel;
   }
 
-  private async setupEnvironment() {
-    const oThis = this;
-    oThis.sirjiRunId = randomBytes(16).toString('hex');
-  }
-
-  private async selectWorkspace(): Promise<void> {
+  private async selectProjectFolder(): Promise<void> {
     const oThis = this;
 
-    oThis.workspaceRootUri = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri : null;
-    oThis.workspaceRootPath = oThis.workspaceRootUri ? oThis.workspaceRootUri.fsPath : null;
+    oThis.projectRootUri = vscode.workspace.workspaceFolders ? vscode.workspace.workspaceFolders[0].uri : null;
+    oThis.projectRootPath = oThis.projectRootUri ? oThis.projectRootUri.fsPath : null;
 
-    if (!oThis.workspaceRootUri) {
+    if (!oThis.projectRootUri) {
       // Prompt user to open a folder
-      const openFolderMsg = 'No workspace/folder is open. Please open a folder to proceed.';
+      const openFolderMsg = 'No project folder is open. Please open a folder to proceed.';
       await vscode.window.showErrorMessage(openFolderMsg, 'Open Folder').then(async (selection) => {
         if (selection === 'Open Folder') {
           await vscode.commands.executeCommand('workbench.action.files.openFolder');
@@ -77,11 +79,62 @@ export class Facilitator {
     }
   }
 
-  private setupHistoryManager() {
+  private async initializeFolders() {
     const oThis = this;
-    oThis.historyManager = new MaintainHistory();
 
-    oThis.historyManager.createHistoryFolder(oThis.workspaceRootPath, oThis.sirjiRunId);
+    oThis.sirjiRunId = Date.now().toString() + '_' + randomBytes(16).toString('hex');
+
+    let rootPath = oThis.context?.globalStorageUri.path || '';
+
+    console.log('-----rootPath------', rootPath);
+
+    let sirjiInstallationFolderPath = path.join(rootPath, 'Sirji');
+    oThis.sirjiInstallationFolderPath = sirjiInstallationFolderPath;
+
+    let sessionFolderPath = path.join(sirjiInstallationFolderPath, Constants.SESSIONS);
+    let runFolderPath = path.join(sessionFolderPath, oThis.sirjiRunId);
+    oThis.sirjiRunFolderPath = runFolderPath;
+
+    let conversationFolderPath = path.join(runFolderPath, 'conversations');
+    oThis.agentOutputFolderPath = path.join(runFolderPath, 'agent_output');
+    let activeRecipeFolderPath = path.join(sirjiInstallationFolderPath, 'active_recipe');
+
+    let agentSessionsFilePath = path.join(runFolderPath, 'agent_sessions.json');
+    let constantsFilePath = path.join(runFolderPath, 'constants.json');
+    let recipeFilePath = path.join(activeRecipeFolderPath, 'recipe.json');
+    let installedAgentsFolderPath = path.join(activeRecipeFolderPath, 'agents');
+    let fileSummariesFolderPath = path.join(sirjiInstallationFolderPath, 'file_summaries');
+
+    fs.mkdirSync(runFolderPath, { recursive: true });
+    fs.mkdirSync(conversationFolderPath, { recursive: true });
+    fs.mkdirSync(oThis.agentOutputFolderPath, { recursive: true });
+    fs.mkdirSync(activeRecipeFolderPath, { recursive: true });
+    fs.mkdirSync(fileSummariesFolderPath, { recursive: true });
+
+    fs.writeFileSync(constantsFilePath, JSON.stringify({ project_folder: oThis.projectRootPath }, null, 4), 'utf-8');
+
+    fs.writeFileSync(agentSessionsFilePath, JSON.stringify({ sessions: [] }, null, 4), 'utf-8');
+    oThis.sessionManager = new SessionManager(agentSessionsFilePath);
+
+    if (!fs.existsSync(recipeFilePath)) {
+      fs.copyFileSync(path.join(__dirname, '..', 'defaults', 'recipe.json'), recipeFilePath);
+      await oThis.copyDirectory(path.join(__dirname, '..', 'defaults', 'agents'), installedAgentsFolderPath);
+      fs.writeFileSync(path.join(sirjiInstallationFolderPath, 'active_recipe', 'config.json'), '{}', 'utf-8');
+    }
+  }
+
+  private async copyDirectory(source: string, destination: string) {
+    if (!fs.existsSync(destination)) {
+      fs.mkdirSync(destination, { recursive: true });
+    }
+
+    let items = fs.readdirSync(source);
+
+    items.forEach((item) => {
+      let srcPath = path.join(source, item);
+      let destPath = path.join(destination, item);
+      fs.copyFileSync(srcPath, destPath);
+    });
   }
 
   private async setupSecretManager() {
@@ -91,6 +144,20 @@ export class Facilitator {
     await oThis.retrieveSecret();
   }
 
+  private openChatViewPanel() {
+    const oThis = this;
+
+    oThis.chatPanel = renderView(oThis.context, 'chat', oThis.projectRootUri, oThis.projectRootPath, oThis.sirjiRunId);
+
+    oThis.chatPanel.webview.onDidReceiveMessage(
+      async (message: any) => {
+        await oThis.handleMessagesFromChatPanel(message);
+      },
+      undefined,
+      (oThis.context || {}).subscriptions
+    );
+  }
+
   private async retrieveSecret() {
     const oThis = this;
 
@@ -124,27 +191,14 @@ export class Facilitator {
     });
   }
 
-  private openChatViewPanel() {
-    const oThis = this;
-
-    oThis.chatPanel = renderView(oThis.context, 'chat', oThis.workspaceRootUri, oThis.workspaceRootPath, oThis.sirjiRunId);
-
-    oThis.chatPanel.webview.onDidReceiveMessage(
-      async (message: any) => {
-        await oThis.handleMessagesFromChatPanel(message);
-      },
-      undefined,
-      (oThis.context || {}).subscriptions
-    );
-  }
-
   private async readCoderLogs() {
     const oThis = this;
 
-    const coderConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, 'logs', 'coder.log');
+    const coderConversationFilePath = path.join(oThis.sirjiRunFolderPath, 'logs', 'coder.log');
 
     let coderLogFileContent = '';
 
+    // TODO P1: remove history manager.
     if (oThis.historyManager?.checkIfFileExists(coderConversationFilePath)) {
       coderLogFileContent = oThis.historyManager?.readFile(coderConversationFilePath);
       // return coderLogFileContent;
@@ -159,7 +213,7 @@ export class Facilitator {
   private async readPlannerLogs() {
     const oThis = this;
 
-    const plannerConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, 'logs', 'planner.log');
+    const plannerConversationFilePath = path.join(oThis.sirjiRunFolderPath, 'logs', 'planner.log');
 
     let plannerLogFileContent = '';
     if (oThis.historyManager?.checkIfFileExists(plannerConversationFilePath)) {
@@ -176,7 +230,7 @@ export class Facilitator {
   private async readResearcherLogs() {
     const oThis = this;
 
-    const researcherConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, 'logs', 'researcher.log');
+    const researcherConversationFilePath = path.join(oThis.sirjiRunFolderPath, 'logs', 'researcher.log');
 
     let researcherLogFileContent = '';
     if (oThis.historyManager?.checkIfFileExists(researcherConversationFilePath)) {
@@ -196,14 +250,12 @@ export class Facilitator {
     oThis.chatPanel?.webview.postMessage({
       type: 'botMessage',
       content: {
-        message: 'Hello, I am Sirji. Please wait while i am setting up the workspace...',
+        message: 'Hello, I am Sirji. Please wait while I am getting initialized...',
         allowUserMessage: false,
-        messageInputText: 'Sirji> is setting up the workspace... Please wait...'
+        messageInputText: 'Sirji> is getting initialized... Please wait...'
       }
     });
 
-    // Setup Python virtual env and Install dependencies
-
     try {
       await oThis.setupVirtualEnv();
     } catch (error) {
@@ -234,15 +286,19 @@ export class Facilitator {
     const oThis = this;
 
     try {
-      await invokeAgent(oThis.context, oThis.workspaceRootPath, oThis.sirjiRunId, path.join(__dirname, '..', 'py_scripts', 'setup_virtual_env.py'), [
+      await spawnAdapter(oThis.context, oThis.sirjiInstallationFolderPath, oThis.sirjiRunFolderPath, oThis.projectRootPath, path.join(__dirname, '..', 'py_scripts', 'setup_virtual_env.py'), [
         '--venv',
-        path.join(oThis.workspaceRootPath, Constants.PYHTON_VENV_FOLDER)
+        path.join(oThis.sirjiInstallationFolderPath, 'venv')
       ]);
     } catch (error) {
       oThis.sendErrorToChatPanel(error);
     }
   }
 
+  private writeToFile(filePath: string, content: string, options: any = 'utf-8'): void {
+    fs.writeFileSync(filePath, content, options);
+  }
+
   private async handleMessagesFromChatPanel(message: any) {
     const oThis = this;
 
@@ -268,13 +324,48 @@ export class Facilitator {
         break;
 
       case 'userMessage':
-        if (!oThis.historyManager) {
-          oThis.setupHistoryManager();
+        if (oThis.isFirstUserMessage) {
+          const agentOutputIndexFilePath = path.join(oThis.agentOutputFolderPath, 'index.json');
+
+          let creatorAgent = 'SIRJI';
+          let creatorForlderPath = path.join(oThis.agentOutputFolderPath, creatorAgent);
+          let problemStatementFilePath = path.join(creatorForlderPath, 'problem.txt');
+
+          let problemStatementFilePathKey = path.join(creatorAgent, 'problem.txt');
+
+          fs.mkdirSync(creatorForlderPath, { recursive: true });
+          fs.writeFileSync(problemStatementFilePath, message.content, 'utf-8');
+
+          oThis.writeToFile(problemStatementFilePath, message.content);
+
+          fs.writeFileSync(
+            agentOutputIndexFilePath,
+            JSON.stringify({
+              [problemStatementFilePathKey]: {
+                description: 'Problem statement from the SIRJI_USER.',
+                created_by: creatorAgent
+              }
+            }),
+            'utf-8'
+          );
+
+          oThis.isFirstUserMessage = false;
+
+          await oThis.initFacilitation(message.content, {
+            TO: ACTOR_ENUM.ORCHESTRATOR
+          });
+        } else {
+          console.log('message.content--------', message.content);
+
+          oThis.inputFilePath = path.join(oThis.sirjiRunFolderPath, 'input.txt');
+          fs.writeFileSync(oThis.inputFilePath, message.content, 'utf-8');
+
+          await oThis.initFacilitation(message.content, {
+            TO: oThis.lastMessageFrom,
+            FROM: ACTOR_ENUM.USER
+          });
         }
 
-        await oThis.initFacilitation(message.content, {
-          TO: ACTOR_ENUM.CODER
-        });
         break;
 
       default:
@@ -282,253 +373,165 @@ export class Facilitator {
     }
   }
 
-  private async initFacilitation(rawMessage: string, parsedMessage: any) {
+  async initFacilitation(rawMessage: string, parsedMessage: any) {
     const oThis = this;
 
     let keepFacilitating: Boolean = true;
     while (keepFacilitating) {
-      console.log('inside while loop', parsedMessage);
-      const inputFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, Constants.PYTHON_INPUT_FILE);
-      switch (parsedMessage.TO) {
-        case ACTOR_ENUM.CODER:
-          if (parsedMessage.ACTION === ACTION_ENUM.STEPS) {
-            oThis.chatPanel?.webview.postMessage({
-              type: 'plannedSteps',
-              content: parsedMessage.PARSED_STEPS
-            });
-          }
-
-          if (!oThis.isCoderTabShown) {
-            oThis.isCoderTabShown = true;
-            oThis.chatPanel?.webview.postMessage({
-              type: 'showCoderTab',
-              content: {
-                sirjiRunId: oThis.sirjiRunId,
-                logs: oThis.readCoderLogs()
-              }
-            });
-          }
-
-          oThis.historyManager?.writeFile(inputFilePath, rawMessage);
-
-          oThis.toCoderRelayToChatPanel(parsedMessage);
-
-          const coderConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, Constants.CODER_JSON_FILE);
-
-          const codingAgentPath = path.join(__dirname, '..', 'py_scripts', 'agents', 'coding_agent.py');
-
-          try {
-            await invokeAgent(oThis.context, oThis.workspaceRootPath, oThis.sirjiRunId, codingAgentPath, ['--input', inputFilePath, '--conversation', coderConversationFilePath]);
-          } catch (error) {
-            oThis.sendErrorToChatPanel(error);
-          }
-
-          const coderConversationContent = JSON.parse(oThis.historyManager?.readFile(coderConversationFilePath));
-
-          const lastCoderMessage: any = coderConversationContent.conversations[coderConversationContent.conversations.length - 1];
+      oThis.displayParsedMessageSummaryToChatPanel(parsedMessage);
+      oThis.lastMessageFrom = parsedMessage?.FROM;
+      console.log('rawMessage-------', rawMessage);
+      console.log('parsedMessage------', parsedMessage);
+      console.log('lastMessageFrom------', oThis.lastMessageFrom);
+
+      const inputFilePath = path.join(oThis.sirjiRunFolderPath, 'input.txt');
+
+      if (parsedMessage.ACTION === 'INVOKE_AGENT' || parsedMessage.ACTION === 'INVOKE_AGENT_EXISTING_SESSION') {
+        let agent_id = parsedMessage.TO;
+
+        oThis.stackManager.addAgentId(agent_id);
+        let agentCallstack = oThis.stackManager.getStack();
+
+        let sessionId = parsedMessage.ACTION === 'INVOKE_AGENT' ? oThis.sessionManager?.startNewSession(agentCallstack) : oThis.sessionManager?.reuseSession(agentCallstack);
+
+        try {
+          await spawnAdapter(oThis.context, oThis.sirjiInstallationFolderPath, oThis.sirjiRunFolderPath, oThis.projectRootPath, path.join(__dirname, '..', 'py_scripts', 'agents', 'invoke_agent.py'), [
+            '--agent_id',
+            agent_id,
+            '--agent_callstack',
+            agentCallstack,
+            '--agent_session_id',
+            sessionId
+          ]);
+        } catch (error) {
+          oThis.sendErrorToChatPanel(error);
+          keepFacilitating = false;
+        }
 
-          console.log('lastCoderMessage', lastCoderMessage);
+        const agentConversationFilePath = path.join(oThis.sirjiRunFolderPath, 'conversations', `${agentCallstack}.${sessionId}.json`);
+        console.log('agentConversationFilePath------', agentConversationFilePath);
 
-          rawMessage = lastCoderMessage?.content;
+        const conversationContent = JSON.parse(fs.readFileSync(agentConversationFilePath, 'utf-8'));
+        const lastAgentMessage: any = conversationContent.conversations[conversationContent.conversations.length - 1];
 
-          parsedMessage = lastCoderMessage?.parsed_content;
+        console.log('------lastAgentMessage------', lastAgentMessage);
 
-          oThis.fromCoderRelayToChatPanel(parsedMessage);
+        rawMessage = lastAgentMessage?.content;
 
-          break;
+        parsedMessage = lastAgentMessage?.parsed_content;
 
-        case ACTOR_ENUM.RESEARCHER:
-          if (!oThis.isResearcherTabShown) {
-            oThis.isResearcherTabShown = true;
-            oThis.chatPanel?.webview.postMessage({
-              type: 'showResearcherTab',
-              content: {
-                sirjiRunId: oThis.sirjiRunId
-              }
-            });
-          }
-          oThis.historyManager?.writeFile(inputFilePath, rawMessage);
+        fs.writeFileSync(inputFilePath, rawMessage, 'utf-8');
 
-          const researcherConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, Constants.RESEARCHER_JSON_FILE);
+        if (parsedMessage.ACTION == ACTION_ENUM.RESPONSE) {
+          oThis.stackManager.removeLastAgentId();
+        }
+      } else {
+        switch (parsedMessage.TO) {
+          case ACTOR_ENUM.ORCHESTRATOR:
+            try {
+              await spawnAdapter(
+                oThis.context,
+                oThis.sirjiInstallationFolderPath,
+                oThis.sirjiRunFolderPath,
+                oThis.projectRootPath,
+                path.join(__dirname, '..', 'py_scripts', 'agents', 'invoke_orchestator.py')
+              );
+            } catch (error) {
+              oThis.sendErrorToChatPanel(error);
+              keepFacilitating = false;
+            }
 
-          const researcherAgentPath = path.join(__dirname, '..', 'py_scripts', 'agents', 'research_agent.py');
+            const orchestratorConversationFilePath = path.join(oThis.sirjiRunFolderPath, 'conversations', 'ORCHESTRATOR.json');
+            console.log('orchestratorConversationFilePath-----', orchestratorConversationFilePath);
 
-          try {
-            await invokeAgent(oThis.context, oThis.workspaceRootPath, oThis.sirjiRunId, researcherAgentPath, ['--input', inputFilePath, '--conversation', researcherConversationFilePath]);
-          } catch (error) {
-            oThis.sendErrorToChatPanel(error);
-          }
+            let conversationContent = JSON.parse(fs.readFileSync(orchestratorConversationFilePath, 'utf-8'));
 
-          const researcherConversationContent = JSON.parse(oThis.historyManager?.readFile(researcherConversationFilePath));
+            const lastOrchestratorMessage: any = conversationContent.conversations[conversationContent.conversations.length - 1];
 
-          const lastResearcherMessage: any = researcherConversationContent.conversations[researcherConversationContent.conversations.length - 1];
+            console.log('lastCoderMessage', lastOrchestratorMessage);
 
-          console.log('lastResearcherMessage', lastResearcherMessage);
+            rawMessage = lastOrchestratorMessage?.content;
 
-          rawMessage = lastResearcherMessage?.content;
+            parsedMessage = lastOrchestratorMessage?.parsed_content;
 
-          parsedMessage = lastResearcherMessage?.parsed_content;
+            oThis.writeToFile(inputFilePath, rawMessage);
+            break;
 
-          break;
+          case ACTOR_ENUM.USER:
+            if (parsedMessage.ACTION === ACTION_ENUM.SOLUTION_COMPLETE) {
+              keepFacilitating = false;
+              oThis.chatPanel?.webview.postMessage({
+                type: 'solutionCompleted',
+                content: { message: parsedMessage.BODY, allowUserMessage: true }
+              });
+            }
 
-        case ACTOR_ENUM.PLANNER:
-          if (!oThis.isPlannerTabShown) {
-            oThis.isPlannerTabShown = true;
-            oThis.chatPanel?.webview.postMessage({
-              type: 'showPlannerTab',
-              content: {
-                sirjiRunId: oThis.sirjiRunId
-              }
-            });
-          }
-          oThis.historyManager?.writeFile(inputFilePath, rawMessage);
-
-          const plannerConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, Constants.PLANNER_JSON_FILE);
-
-          const plannerAgentPath = path.join(__dirname, '..', 'py_scripts', 'agents', 'planning_agent.py');
-
-          try {
-            await invokeAgent(oThis.context, oThis.workspaceRootPath, oThis.sirjiRunId, plannerAgentPath, ['--input', inputFilePath, '--conversation', plannerConversationFilePath]);
-          } catch (error) {
-            oThis.sendErrorToChatPanel(error);
-          }
-
-          const plannerConversationContent = JSON.parse(oThis.historyManager?.readFile(plannerConversationFilePath));
-
-          const lastPlannerMessage: any = plannerConversationContent.conversations[plannerConversationContent.conversations.length - 1];
-
-          console.log('lastPlannerMessage', lastPlannerMessage);
-
-          rawMessage = lastPlannerMessage?.content;
-
-          parsedMessage = lastPlannerMessage?.parsed_content;
-
-          break;
-
-        case ACTOR_ENUM.USER:
-          if (parsedMessage.ACTION === ACTION_ENUM.STEP_STARTED) {
-            oThis.chatPanel?.webview.postMessage({
-              type: 'plannedStepStart',
-              content: parsedMessage.DETAILS
-            });
-
-            rawMessage = 'sure';
-            parsedMessage = {
-              TO: ACTOR_ENUM.CODER
-            };
-          }
-
-          if (parsedMessage.ACTION === ACTION_ENUM.STEP_COMPLETED) {
-            oThis.chatPanel?.webview.postMessage({
-              type: 'plannedStepComplete',
-              content: parsedMessage.DETAILS
-            });
-
-            rawMessage = 'sure';
-            parsedMessage = {
-              TO: ACTOR_ENUM.CODER
-            };
-          }
-
-          if (parsedMessage.ACTION === ACTION_ENUM.SOLUTION_COMPLETE) {
-            keepFacilitating = false;
-            oThis.chatPanel?.webview.postMessage({
-              type: 'solutionCompleted',
-              content: { message: parsedMessage.DETAILS, allowUserMessage: true }
-            });
-          }
-
-          if (parsedMessage.ACTION === ACTION_ENUM.QUESTION || parsedMessage.ACTION === ACTION_ENUM.INFORM) {
-            keepFacilitating = false;
-            oThis.chatPanel?.webview.postMessage({
-              type: 'botMessage',
-              content: { message: parsedMessage.DETAILS, allowUserMessage: true }
-            });
-          }
-          break;
-
-        case ACTOR_ENUM.EXECUTOR:
-          switch (parsedMessage.ACTION) {
-            case ACTION_ENUM.OPEN_BROWSER:
-              //TODO:Implement this
-              openBrowser(parsedMessage.URL);
-              console.log('Browse', parsedMessage);
-              break;
-
-            case ACTION_ENUM.INSTALL_PACKAGE:
-              const installPackageCommandRes = await executeSpawn(parsedMessage.COMMAND, oThis.workspaceRootPath);
-              rawMessage = installPackageCommandRes;
-              parsedMessage = {
-                TO: ACTOR_ENUM.CODER
-              };
-              console.log('installPackageCommandRes', installPackageCommandRes);
-              break;
-
-            case ACTION_ENUM.EXECUTE_COMMAND:
-              const executedCommandRes = await executeSpawn(parsedMessage.COMMAND, oThis.workspaceRootPath);
-
-              rawMessage = executedCommandRes;
-              parsedMessage = {
-                TO: ACTOR_ENUM.CODER
-              };
-              console.log('executedCommandRes', executedCommandRes);
-              break;
-
-            case ACTION_ENUM.RUN_SERVER:
-              const runServerRes = await executeTask(parsedMessage.COMMAND, oThis.workspaceRootPath, oThis.sirjiRunId);
-
-              rawMessage = runServerRes;
-              parsedMessage = {
-                TO: ACTOR_ENUM.CODER
-              };
-              console.log('runServerRes', runServerRes);
-              break;
-
-            case ACTION_ENUM.CREATE_FILE:
-              const createFileRes = await createFile(oThis.workspaceRootPath, parsedMessage.FILENAME, parsedMessage.CONTENT);
-              rawMessage = createFileRes;
-              parsedMessage = {
-                TO: ACTOR_ENUM.CODER
-              };
-              console.log('Create', createFileRes);
-              break;
-
-            case ACTION_ENUM.READ_DIR:
-              const readDirContentRes = await readContent(oThis.workspaceRootPath, parsedMessage.DIRPATH);
-              rawMessage = readDirContentRes;
-              parsedMessage = {
-                TO: ACTOR_ENUM.CODER
-              };
-              break;
-
-            case ACTION_ENUM.READ_FILE:
-              const readFileContentRes = await readContent(oThis.workspaceRootPath, parsedMessage.FILENAME);
-              rawMessage = readFileContentRes;
-              parsedMessage = {
-                TO: ACTOR_ENUM.CODER
-              };
-              break;
-
-            default:
+            if (parsedMessage.ACTION === ACTION_ENUM.QUESTION) {
+              keepFacilitating = false;
+              oThis.chatPanel?.webview.postMessage({
+                type: 'botMessage',
+                content: { message: parsedMessage.BODY, allowUserMessage: true }
+              });
+            }
+            oThis.writeToFile(inputFilePath, rawMessage);
+            break;
+
+          case ACTOR_ENUM.EXECUTOR:
+            try {
+              const executor = new Executor(parsedMessage, oThis.projectRootPath, oThis.agentOutputFolderPath, oThis.sirjiRunFolderPath);
+              const executorResp = await executor.perform();
+
+              rawMessage = executorResp.rawMessage;
+              parsedMessage = executorResp.parsedMessage;
+              oThis.writeToFile(inputFilePath, rawMessage);
+            } catch (error) {
+              console.log('error------', error);
               console.log('Execution default', parsedMessage);
               oThis.chatPanel?.webview.postMessage({
                 type: 'botMessage',
-                content: { message: `Executor called with unknown action: ${parsedMessage.ACTION}. Raw message: ${rawMessage}`, allowUserMessage: true }
+                content: { message: `An error occurred during the execution of the Python script: ${error}`, allowUserMessage: true }
               });
               keepFacilitating = false;
-              break;
-          }
+            }
+            break;
+
+          default:
+            let agent_id = parsedMessage.TO;
+
+            let agentCallstack = oThis.stackManager.getStack();
+            let sessionId = oThis.sessionManager?.reuseSession(agentCallstack);
+
+            try {
+              await spawnAdapter(
+                oThis.context,
+                oThis.sirjiInstallationFolderPath,
+                oThis.sirjiRunFolderPath,
+                oThis.projectRootPath,
+                path.join(__dirname, '..', 'py_scripts', 'agents', 'invoke_agent.py'),
+                ['--agent_id', parsedMessage.TO, '--agent_callstack', agentCallstack, '--agent_session_id', sessionId]
+              );
+            } catch (error) {
+              oThis.sendErrorToChatPanel(error);
+              keepFacilitating = false;
+            }
 
-          break;
+            const agentConversationFilePath = path.join(oThis.sirjiRunFolderPath, 'conversations', `${agentCallstack}.${sessionId}.json`);
 
-        default:
-          console.log('Actor default', parsedMessage);
-          oThis.chatPanel?.webview.postMessage({
-            type: 'botMessage',
-            content: { message: `Received message with unknown TO: ${parsedMessage.TO}. Raw message: ${rawMessage}`, allowUserMessage: true }
-          });
-          keepFacilitating = false;
-          break;
+            let genericAgentConversationContent = JSON.parse(fs.readFileSync(agentConversationFilePath, 'utf-8'));
+            const lastAgentMessage: any = genericAgentConversationContent.conversations[genericAgentConversationContent.conversations.length - 1];
+
+            console.log('------lastAgentMessage------', lastAgentMessage);
+
+            rawMessage = lastAgentMessage?.content;
+
+            parsedMessage = lastAgentMessage?.parsed_content;
+            oThis.writeToFile(inputFilePath, rawMessage);
+
+            if (parsedMessage.ACTION == ACTION_ENUM.RESPONSE) {
+              oThis.stackManager.removeLastAgentId();
+            }
+            break;
+        }
       }
 
       const totalTokensUsed = await oThis.calculateTotalTokensUsed();
@@ -543,64 +546,19 @@ export class Facilitator {
     }
   }
 
-  private fromCoderRelayToChatPanel(parsedMessage: any) {
+  private displayParsedMessageSummaryToChatPanel(parsedMessage: any) {
     const oThis = this;
 
     let contentMessage = null;
 
-    if (!parsedMessage || !parsedMessage.ACTION) {
-      return;
-    }
-
-    switch (parsedMessage.ACTION) {
-      case ACTION_ENUM.GENERATE_STEPS:
-        contentMessage = 'Generating steps to solve the given problem statement.';
-        break;
-
-      case ACTION_ENUM.CREATE_FILE:
-        contentMessage = `Creating File: ${parsedMessage.FILENAME}`;
-        break;
-
-      case ACTION_ENUM.EXECUTE_COMMAND:
-        contentMessage = `Executing Command: ${parsedMessage.COMMAND}`;
-        break;
-
-      case ACTION_ENUM.RUN_SERVER:
-        contentMessage = `Running Server: ${parsedMessage.COMMAND}`;
-        break;
-
-      case ACTION_ENUM.INSTALL_PACKAGE:
-        contentMessage = `Installing Package: ${parsedMessage.COMMAND}`;
-        break;
-
-      case ACTION_ENUM.READ_FILE:
-        contentMessage = `Reading File: ${parsedMessage.FILENAME}`;
-        break;
-
-      case ACTION_ENUM.READ_DIR:
-        contentMessage = `Reading Files in Folder (and its Sub-Folders): ${parsedMessage.DIRPATH}`;
-        break;
-
-      case ACTION_ENUM.TRAIN_USING_URL:
-        contentMessage = `Training Research Agent (RAG): Using contents from ${parsedMessage.URL}`;
-        break;
-
-      case ACTION_ENUM.INFER:
-        contentMessage = 'Inferring from the Research Agent based on trained knowledge';
-        break;
-
-      default:
-        break;
-    }
-
-    if (!contentMessage) {
+    if (!parsedMessage || !parsedMessage.ACTION || parsedMessage.TO == ACTOR_ENUM.USER || !parsedMessage.SUMMARY.trim() || parsedMessage.SUMMARY.trim().toLowerCase() === 'empty') {
       return;
     }
 
     oThis.chatPanel?.webview.postMessage({
       type: 'botMessage',
       content: {
-        message: contentMessage,
+        message: `${parsedMessage.FROM}: ${parsedMessage.SUMMARY.trim()}`,
         allowUserMessage: false
       }
     });
@@ -640,26 +598,35 @@ export class Facilitator {
   private async calculateTotalTokensUsed() {
     const oThis = this;
 
-    const coderConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, Constants.CODER_JSON_FILE);
-    const researcherConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, Constants.RESEARCHER_JSON_FILE);
-    const plannerConversationFilePath = path.join(oThis.workspaceRootPath, Constants.HISTORY_FOLDER, oThis.sirjiRunId, Constants.PLANNER_JSON_FILE);
+    // TODO - we need to read the conversation files of all the agents
+
+    // const coderConversationFilePath = path.join(oThis.sirjiRunId, Constants.CODER_JSON_FILE);
+    // const researcherConversationFilePath = path.join(oThis.sirjiRunId, Constants.RESEARCHER_JSON_FILE);
+    // const plannerConversationFilePath = path.join(oThis.sirjiRunId, Constants.PLANNER_JSON_FILE);
+
+    // const coderTokensUsed = await oThis.getTokensUsed(coderConversationFilePath);
+    // const researcherTokensUsed = await oThis.getTokensUsed(researcherConversationFilePath);
+    // const plannerTokensUsed = await oThis.getTokensUsed(plannerConversationFilePath);
 
-    const coderTokensUsed = await oThis.getTokensUsed(coderConversationFilePath);
-    const researcherTokensUsed = await oThis.getTokensUsed(researcherConversationFilePath);
-    const plannerTokensUsed = await oThis.getTokensUsed(plannerConversationFilePath);
+    // const totalPromptTokens = coderTokensUsed.prompt_tokens + researcherTokensUsed.prompt_tokens + plannerTokensUsed.prompt_tokens;
 
-    const totalPromptTokens = coderTokensUsed.prompt_tokens + researcherTokensUsed.prompt_tokens + plannerTokensUsed.prompt_tokens;
+    // const totalCompletionTokens = coderTokensUsed.completion_tokens + researcherTokensUsed.completion_tokens + plannerTokensUsed.completion_tokens;
 
-    const totalCompletionTokens = coderTokensUsed.completion_tokens + researcherTokensUsed.completion_tokens + plannerTokensUsed.completion_tokens;
+    // const totalPromptTokensValueInDollar = (totalPromptTokens * Constants.PROMPT_TOKEN_PRICE_PER_MILLION_TOKENS) / 1000000.0;
+    // const totalCompletionTokensValueInDollar = (totalCompletionTokens * Constants.COMPLETION_TOKEN_PRICE_PER_MILLION_TOKENS) / 1000000.0;
 
-    const totalPromptTokensValueInDollar = (totalPromptTokens * Constants.PROMPT_TOKEN_PRICE_PER_MILLION_TOKENS) / 1000000.0;
-    const totalCompletionTokensValueInDollar = (totalCompletionTokens * Constants.COMPLETION_TOKEN_PRICE_PER_MILLION_TOKENS) / 1000000.0;
+    // return {
+    //   total_prompt_tokens: totalPromptTokens,
+    //   total_completion_tokens: totalCompletionTokens,
+    //   total_prompt_tokens_value: totalPromptTokensValueInDollar,
+    //   total_completion_tokens_value: totalCompletionTokensValueInDollar
+    // };
 
     return {
-      total_prompt_tokens: totalPromptTokens,
-      total_completion_tokens: totalCompletionTokens,
-      total_prompt_tokens_value: totalPromptTokensValueInDollar,
-      total_completion_tokens_value: totalCompletionTokensValueInDollar
+      total_prompt_tokens: 0,
+      total_completion_tokens: 0,
+      total_prompt_tokens_value: 0,
+      total_completion_tokens_value: 0
     };
   }
 
@@ -691,3 +658,4 @@ export class Facilitator {
     });
   }
 }
+async function getResponseFromExecutor(parsedMessage: any, oThis: any, rawMessage: string, keepFacilitating: Boolean) {}
diff --git a/sirji/vscode-extension/src/utils/maintain_history.ts b/sirji/vscode-extension/src/utils/maintain_history.ts
index 54720c78..916817c3 100644
--- a/sirji/vscode-extension/src/utils/maintain_history.ts
+++ b/sirji/vscode-extension/src/utils/maintain_history.ts
@@ -3,8 +3,8 @@ import * as path from 'path';
 import { Constants } from './constants';
 
 export class MaintainHistory {
-  public createHistoryFolder(workspaceRootPath: any, sirjiRunId: string): void {
-    const dirPath = path.join(workspaceRootPath, Constants.HISTORY_FOLDER, sirjiRunId);
+  public createHistoryFolder(projectRootPath: any, sirjiRunId: string): void {
+    const dirPath = path.join(projectRootPath, sirjiRunId);
     fs.mkdirSync(dirPath, { recursive: true });
   }
 
diff --git a/sirji/vscode-extension/src/utils/read_content.ts b/sirji/vscode-extension/src/utils/read_content.ts
deleted file mode 100644
index 2727b6ad..00000000
--- a/sirji/vscode-extension/src/utils/read_content.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import * as vscode from 'vscode';
-import * as path from 'path';
-import * as fs from 'fs/promises';
-
-const SKIP_LIST = ['__pycache__', '.git', '.github', '.gitlab', '.vscode', '.idea', 'node_modules', '.DS_Store', 'venv', '.venv', '.sass-cache', 'dist', 'out', 'build', 'logs', '.npm', 'temp', 'tmp'];
-
-export async function readContent(workspaceRootPath: string, inputPath: string): Promise<string> {
-  let fullPath = path.join(workspaceRootPath, inputPath);
-
-  function shouldSkip(name: string): boolean {
-    return SKIP_LIST.includes(name);
-  }
-
-  async function readFile(filePath: string): Promise<string> {
-    try {
-      const content = await fs.readFile(filePath, 'utf8');
-      const relativePath = path.relative(workspaceRootPath, filePath);
-      return `File: ${relativePath}\n\n${content}\n\n---\n\n`;
-    } catch (err) {
-      console.error(`Failed to read file ${filePath}:`, err);
-      throw err;
-    }
-  }
-
-  async function readDirectory(directoryPath: string): Promise<string> {
-    try {
-      let files = await fs.readdir(directoryPath, { withFileTypes: true });
-      let results = [];
-
-      for (const file of files) {
-        // Skip logic implementation
-        if (shouldSkip(file.name)) {
-          continue; // Skips current iteration if name matches any in SKIP_LIST
-        }
-
-        const currentPath = path.join(directoryPath, file.name);
-        if (file.isDirectory()) {
-          results.push(await readDirectory(currentPath));
-        } else {
-          results.push(await readFile(currentPath));
-        }
-      }
-
-      return results.join('');
-    } catch (err) {
-      console.error(`Failed to read directory ${directoryPath}:`, err);
-      throw err;
-    }
-  }
-
-  try {
-    const stats = await fs.stat(fullPath);
-
-    if (stats.isDirectory()) {
-      return readDirectory(fullPath);
-    } else {
-      return readFile(fullPath);
-    }
-  } catch (e) {
-    const errorMessage = `Failed to read the path. Error: ${e}`;
-    return errorMessage;
-  }
-}
diff --git a/sirji/vscode-extension/src/utils/render_view.ts b/sirji/vscode-extension/src/utils/render_view.ts
index e6b4faae..1d9592b1 100644
--- a/sirji/vscode-extension/src/utils/render_view.ts
+++ b/sirji/vscode-extension/src/utils/render_view.ts
@@ -2,7 +2,7 @@ import * as vscode from 'vscode';
 import path from 'path';
 import * as fs from 'fs';
 
-export function renderView(context: vscode.ExtensionContext | undefined, view: string, workspaceRootUri: any, workspaceRootPath: any, sirjiRunId: string): vscode.WebviewPanel {
+export function renderView(context: vscode.ExtensionContext | undefined, view: string, projectRootUri: any, projectRootPath: any, sirjiRunId: string): vscode.WebviewPanel {
   let viewDetails: any;
 
   if (view === 'chat') {
diff --git a/sirji/vscode-extension/src/utils/session_manager.ts b/sirji/vscode-extension/src/utils/session_manager.ts
new file mode 100644
index 00000000..da66d67f
--- /dev/null
+++ b/sirji/vscode-extension/src/utils/session_manager.ts
@@ -0,0 +1,67 @@
+import { v4 as uuidv4 } from 'uuid';
+import fs from 'fs';
+
+interface Session {
+    sessionId: string;
+    callStack: string;
+    timestamp: string;
+}
+
+export class SessionManager {
+    private filePath: string;
+
+    constructor(filePath: string) {
+        this.filePath = filePath;
+    }
+
+    public startNewSession(callStack: string): string {
+        const newSession: Session = {
+            sessionId: uuidv4(),
+            callStack: callStack,
+            timestamp: new Date().toISOString()
+        };
+        const data = this.readSessionsFile();
+        data.sessions.push(newSession);
+        this.writeSessionsFile(data);
+
+        return newSession.sessionId;
+    }
+
+    public reuseSession(callStack: string): string | null {
+        const data = this.readSessionsFile();
+        const filteredSessions: Session[] = data.sessions.filter((session: Session) => session.callStack === callStack);
+        if (filteredSessions.length > 0) {
+            filteredSessions.sort((a: Session, b: Session) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
+            return filteredSessions[0].sessionId;
+        }
+        
+        return null;
+    }
+
+    public getSessionTimestampMillis(sessionId: string): number | null {
+        const data = this.readSessionsFile();
+        const session = data.sessions.find((session: Session) => session.sessionId === sessionId);
+        if (session) {
+            return new Date(session.timestamp).getTime();
+        }
+        return null;
+    }
+
+    private readSessionsFile(): { sessions: Session[] } {
+        try {
+            const fileContents = fs.readFileSync(this.filePath, 'utf8');
+            return JSON.parse(fileContents) as { sessions: Session[] };
+        } catch (error) {
+            console.error("Error reading the sessions file:", error);
+            return { sessions: [] };
+        }
+    }
+
+    private writeSessionsFile(data: { sessions: Session[] }): void {
+        try {
+            fs.writeFileSync(this.filePath, JSON.stringify(data, null, 4));
+        } catch (error) {
+            console.error("Error writing to the sessions file:", error);
+        }
+    }
+}
\ No newline at end of file
diff --git a/sirji/vscode-extension/src/views/chat/chat.css b/sirji/vscode-extension/src/views/chat/chat.css
index 8c1fb6ff..797d3348 100644
--- a/sirji/vscode-extension/src/views/chat/chat.css
+++ b/sirji/vscode-extension/src/views/chat/chat.css
@@ -606,22 +606,22 @@ label {
 }
 
 .tab-button {
-  color: #9d9d9d;
+  color: var(--vscode-titleBar-inactiveForeground);
   cursor: pointer;
   padding: 5px 3px;
 }
 
 .tab-button:hover {
-  color: var(--vscode-list-hoverForeground);
+  color: var(--vscode-titleBar-activeForeground);
 }
 
 .tab-button.active {
-  color: var(--vscode-list-hoverForeground);
+  color: var(--vscode-titleBar-activeForeground);
   border-bottom: 1px solid var(--vscode-statusBarItem-remoteBackground);
 }
 
 .chat-tab-button{
-  color: var(--vscode-list-hoverForeground);
+  color: var(--vscode-titleBar-activeForeground);
   padding: 5px 3px;
   border-bottom: 1px solid var(--vscode-statusBarItem-remoteBackground);
 }
@@ -650,13 +650,13 @@ label {
 
 .toolbar-icon{
   svg > path {
-    fill: var(--vscode-activityBar-inactiveForeground)
+    fill: var(--vscode-titleBar-inactiveForeground)
   }
 }
 
 .toolbar-icon:hover {
   svg > path {
-    fill: var(--vscode-activityBar-foreground);
+    fill: var(--vscode-titleBar-activeForeground);
   }
 }
 
@@ -776,17 +776,17 @@ label {
 }
 
 .log-tab-button {
-  color: #9d9d9d;
+  color: var(--vscode-titleBar-inactiveForeground);
   cursor: pointer;
   padding: 5px 3px;
 }
 
 .log-tab-button:hover {
-  color: var(--vscode-list-hoverForeground);
+  color: var(--vscode-titleBar-activeForeground);
 }
 
 .log-tab-button.active {
-  color: var(--vscode-list-hoverForeground);
+  color: var(--vscode-titleBar-activeForeground);
   border-bottom: 1px solid var(--vscode-statusBarItem-remoteBackground);
 }
 
diff --git a/sirji/vscode-extension/tsconfig.json b/sirji/vscode-extension/tsconfig.json
index 6954702e..9559ed14 100644
--- a/sirji/vscode-extension/tsconfig.json
+++ b/sirji/vscode-extension/tsconfig.json
@@ -8,10 +8,6 @@
 		],
 		"sourceMap": true,
 		"rootDir": "src",
-		"strict": true   /* enable all strict type-checking options */
-		/* Additional Checks */
-		// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
-		// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
-		// "noUnusedParameters": true,  /* Report errors on unused parameters. */
+		"strict": true
 	}
 }
diff --git a/tools/README.md b/tools/README.md
index c2e04573..f66e6b91 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -3,7 +3,7 @@
 </p>
 
 <p align="center">
-  <em>Sirji is an Open Source AI Software Development Agent.</em>
+  <em>Sirji is an agentic AI framework for software development.</em>
 </p>
 
 <p align="center">
@@ -60,23 +60,23 @@ playwright install
 
 ### Environment Variables
 
-Ensure that following environment variables are set:
+Ensure that the following environment variables are set:
 
 ```zsh
-export SIRJI_WORKSPACE="Absolute folder path for Sirji to use as it's workspace. Note that a .sirji folder will be created inside it."
-export SIRJI_RUN_ID='Unique alphanumeric ID for each run. Note that a sub folder named by this ID will be created inside of .sirji folder to store logs, etc.'
+export SIRJI_PROJECT="Absolute folder path for Sirji to use as its project folder."
+export SIRJI_RUN_PATH='Folder having run specific logs, etc.'
 ```
 
 ### Crawl URLs
 
-Crawl URLs tool will be used to crawl the web pages and extract the information from the web pages. And store the information for the further processing by researcher.
+Crawl URLs tool will be used to crawl the web pages and extract the information from the web pages. And store the information for further processing by the researcher.
 
 ```python
 from sirji_tools import crawl_urls
 
 urls = ['https://www.google.com', 'https://www.yahoo.com']
 
-crawl_urls(urls, 'workspace/researcher')
+crawl_urls(urls, 'project/researcher')
 ```
 
 ### Search
@@ -107,7 +107,7 @@ p_logger.info("Log line here")
 1. Fork and clone the repository.
 2. Create and activate the virtual environment as described above.
 3. Set the environment variables as described above.
-4. Install the package in editable mode by running the following command from repository root:
+4. Install the package in editable mode by running the following command from the repository root:
 
 ```zsh
 pip install -e .
@@ -121,7 +121,7 @@ playwright install
 
 ## Running Tests and Coverage Analysis
 
-Follow the above mentioned steps for "contributors", before running the test cases.
+Follow the above-mentioned steps for "contributors", before running the test cases.
 
 ```zsh
 # Install testing dependencies
diff --git a/tools/setup.py b/tools/setup.py
index e1bc413f..c1a39c12 100644
--- a/tools/setup.py
+++ b/tools/setup.py
@@ -2,7 +2,7 @@
 
 setup(
     name='sirji-tools',
-    version='0.0.9',
+    version='0.0.12',
     author='Sirji',
     description='Crawler and search tools used by Sirji.',
     license='MIT',
diff --git a/tools/sirji_tools/logger/logger.py b/tools/sirji_tools/logger/logger.py
index b14af0ef..71ad05fb 100644
--- a/tools/sirji_tools/logger/logger.py
+++ b/tools/sirji_tools/logger/logger.py
@@ -25,20 +25,20 @@ def __init__(self, file_name, log_level):
         self.logger = self._setup_logger(file_name, log_level)
     
     def _log_folder(self):
-        return os.path.join(self._get_workspace_folder(), '.sirji', self._get_run_id_folder(), "logs")
+        return os.path.join(self._get_run_path(), "logs")
     
-    def _get_workspace_folder(self):
-        workspace = os.environ.get("SIRJI_WORKSPACE")
-        if workspace is None:
+    def _get_project_folder(self):
+        project_folder = os.environ.get("SIRJI_PROJECT")
+        if project_folder is None:
             raise ValueError(
-                "SIRJI_WORKSPACE is not set as an environment variable")
-        return workspace
+                "SIRJI_PROJECT is not set as an environment variable")
+        return project_folder
 
-    def _get_run_id_folder(self):
-        run_id = os.environ.get("SIRJI_RUN_ID")
+    def _get_run_path(self):
+        run_id = os.environ.get("SIRJI_RUN_PATH")
         if run_id is None:
             raise ValueError(
-                "SIRJI_RUN_ID is not set as an environment variable")
+                "SIRJI_RUN_PATH is not set as an environment variable")
         return run_id 
     
     def _log_file_path(self, file_name):


Test patch:
diff --git a/.github/workflows/pytest_on_pr.yml b/.github/workflows/pytest_on_pr.yml
index d3b2b003..70e790fc 100644
--- a/.github/workflows/pytest_on_pr.yml
+++ b/.github/workflows/pytest_on_pr.yml
@@ -50,8 +50,8 @@ jobs:
 
       - name: Run tests and coverage (tools)
         env:
-          SIRJI_WORKSPACE: '.'
-          SIRJI_RUN_ID: 'abcd1234'
+          SIRJI_PROJECT: '.'
+          SIRJI_RUN_PATH: './abcd1234'
         run: |
           cd tools
           source venv/bin/activate
diff --git a/messages/tests/integration/__init__.py b/messages/tests/integration/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/messages/tests/integration/test_message_factory.py b/messages/tests/integration/test_message_factory.py
deleted file mode 100644
index dac3ce59..00000000
--- a/messages/tests/integration/test_message_factory.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import pytest
-from sirji_messages import ActionEnum
-from sirji_messages.messages.factory import MessageFactory
-
-# Here we're importing specific message classes for comparison
-from sirji_messages.messages.actions.acknowledge import AcknowledgeMessage
-from sirji_messages.messages.actions.question import QuestionMessage
-from sirji_messages.messages.actions.inform import InformMessage
-from sirji_messages.messages.actions.problem_statement import ProblemStatementMessage
-
-# Test Cases for MessageFactory
-
-
-def test_message_factory_acknowledge():
-    assert isinstance(MessageFactory[ActionEnum.ACKNOWLEDGE.name](
-    ), AcknowledgeMessage), "Incorrect message class for ACKNOWLEDGE action"
-
-
-def test_message_factory_question():
-    assert isinstance(MessageFactory[ActionEnum.QUESTION.name](
-    ), QuestionMessage), "Incorrect message class for QUESTION action"
-
-
-def test_message_factory_inform():
-    assert isinstance(MessageFactory[ActionEnum.INFORM.name](
-    ), InformMessage), "Incorrect message class for INFORM action"
-
-
-def test_message_factory_problem_statement():
-    assert isinstance(MessageFactory[ActionEnum.PROBLEM_STATEMENT.name](
-    ), ProblemStatementMessage), "Incorrect message class for PROBLEM_STATEMENT action"
-
-# Optionally, you could add tests to verify the correct behavior or outputs of these messages or their methods.
-# For example, you could test the generation of sample messages, ensuring it matches expected formats.
diff --git a/messages/tests/integration/test_system_prompts.py b/messages/tests/integration/test_system_prompts.py
deleted file mode 100644
index e4e61eee..00000000
--- a/messages/tests/integration/test_system_prompts.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import pytest
-from sirji_messages import AgentEnum
-from sirji_messages.system_prompts.factory import AgentSystemPromptFactory
-
-# Here we're importing the specific system prompt classes for comparison
-from sirji_messages.system_prompts.agents.coder import CoderSystemPrompt
-from sirji_messages.system_prompts.agents.planner import PlannerSystemPrompt
-from sirji_messages.system_prompts.agents.user import UserSystemPrompt
-from sirji_messages.system_prompts.agents.executor import ExecutorSystemPrompt
-from sirji_messages.system_prompts.agents.researcher import ResearcherSystemPrompt
-
-# Test Cases for AgentSystemPromptFactory
-
-
-def test_system_prompt_factory_coder():
-    assert isinstance(AgentSystemPromptFactory[AgentEnum.CODER.name](
-    ), CoderSystemPrompt), "Incorrect system prompt for CODER"
-
-
-def test_system_prompt_factory_planner():
-    assert isinstance(AgentSystemPromptFactory[AgentEnum.PLANNER.name](
-    ), PlannerSystemPrompt), "Incorrect system prompt for PLANNER"
-
-
-def test_system_prompt_factory_user():
-    # Noting here that User might not invoke prompts, but testing for completeness
-    assert isinstance(AgentSystemPromptFactory[AgentEnum.USER.name](
-    ), UserSystemPrompt), "Incorrect system prompt for USER"
-
-
-def test_system_prompt_factory_executor():
-    assert isinstance(AgentSystemPromptFactory[AgentEnum.EXECUTOR.name](
-    ), ExecutorSystemPrompt), "Incorrect system prompt for EXECUTOR"
-
-
-def test_system_prompt_factory_researcher():
-    assert isinstance(AgentSystemPromptFactory[AgentEnum.RESEARCHER.name](
-    ), ResearcherSystemPrompt), "Incorrect system prompt for RESEARCHER"
-
-# Optionally, you could test for the expected outputs or properties of each class, ensuring integration
-# between the system prompts and their respective agent roles perform correctly.
diff --git a/messages/tests/integration/test_system_prompts_base.py b/messages/tests/integration/test_system_prompts_base.py
deleted file mode 100644
index 9b2becef..00000000
--- a/messages/tests/integration/test_system_prompts_base.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import pytest
-from sirji_messages.system_prompts.agents.base import AgentSystemPromptBase
-from sirji_messages.system_prompts.factory import AgentSystemPromptFactory
-from sirji_messages import AgentEnum
-
-
-@pytest.mark.parametrize("agent_class", [
-    AgentSystemPromptFactory[AgentEnum.CODER.name],
-    AgentSystemPromptFactory[AgentEnum.PLANNER.name],
-    # Add all agent classes
-])
-def test_agent_system_prompt_base_integration(agent_class):
-    agent_instance = agent_class()
-    prompt_text = agent_instance.system_prompt()
-
-    assert isinstance(prompt_text, str), "System prompt text must be a string"
-    assert len(prompt_text) > 0, "System prompt text should not be empty"
-    # This can be expanded with specific checks for each agent type
-
-# Additionally, test other methods and properties if applicable
diff --git a/messages/tests/test_action_enum.py b/messages/tests/test_action_enum.py
new file mode 100644
index 00000000..a74872e9
--- /dev/null
+++ b/messages/tests/test_action_enum.py
@@ -0,0 +1,30 @@
+import pytest
+from sirji_messages import ActionEnum
+def test_action_enum_membership():
+    assert ActionEnum['ANSWER'] == ActionEnum.ANSWER
+    assert ActionEnum['INVOKE_AGENT'] == ActionEnum.INVOKE_AGENT
+    assert ActionEnum['INVOKE_AGENT_EXISTING_SESSION'] == ActionEnum.INVOKE_AGENT_EXISTING_SESSION
+    assert ActionEnum['EXECUTE_COMMAND'] == ActionEnum.EXECUTE_COMMAND
+    assert ActionEnum['APPEND_TO_AGENT_OUTPUT_INDEX'] == ActionEnum.APPEND_TO_AGENT_OUTPUT_INDEX
+    assert ActionEnum['READ_AGENT_OUTPUT_INDEX'] == ActionEnum.READ_AGENT_OUTPUT_INDEX
+    assert ActionEnum['RUN_SERVER'] == ActionEnum.RUN_SERVER
+    assert ActionEnum['CREATE_PROJECT_FILE'] == ActionEnum.CREATE_PROJECT_FILE
+    assert ActionEnum['CREATE_AGENT_OUTPUT_FILE'] == ActionEnum.CREATE_AGENT_OUTPUT_FILE
+    assert ActionEnum['GENERATE_STEPS'] == ActionEnum.GENERATE_STEPS
+    assert ActionEnum['PROBLEM_STATEMENT'] == ActionEnum.PROBLEM_STATEMENT
+    assert ActionEnum['INFER'] == ActionEnum.INFER
+    assert ActionEnum['INFORM'] == ActionEnum.INFORM
+    assert ActionEnum['OUTPUT'] == ActionEnum.OUTPUT
+    assert ActionEnum['QUESTION'] == ActionEnum.QUESTION
+    assert ActionEnum['RESPONSE'] == ActionEnum.RESPONSE
+    assert ActionEnum['SOLUTION_COMPLETE'] == ActionEnum.SOLUTION_COMPLETE
+    assert ActionEnum['STEPS'] == ActionEnum.STEPS
+    assert ActionEnum['TRAIN_USING_SEARCH_TERM'] == ActionEnum.TRAIN_USING_SEARCH_TERM
+    assert ActionEnum['TRAIN_USING_URL'] == ActionEnum.TRAIN_USING_URL
+    assert ActionEnum['FEEDBACK'] == ActionEnum.FEEDBACK
+    assert ActionEnum['TRAINING_OUTPUT'] == ActionEnum.TRAINING_OUTPUT
+    assert ActionEnum['READ_PROJECT_FILES'] == ActionEnum.READ_PROJECT_FILES
+    assert ActionEnum['READ_AGENT_OUTPUT_FILES'] == ActionEnum.READ_AGENT_OUTPUT_FILES
+    assert ActionEnum['FIND_AND_REPLACE'] == ActionEnum.FIND_AND_REPLACE
+    assert ActionEnum['INSERT_TEXT'] == ActionEnum.INSERT_TEXT
+    assert ActionEnum['EXTRACT_DEPENDENCIES'] == ActionEnum.EXTRACT_DEPENDENCIES
\ No newline at end of file
diff --git a/messages/tests/test_agent_enum.py b/messages/tests/test_agent_enum.py
new file mode 100644
index 00000000..0355732e
--- /dev/null
+++ b/messages/tests/test_agent_enum.py
@@ -0,0 +1,33 @@
+
+import pytest
+from sirji_messages.agent_enum import AgentEnum
+
+def test_agent_enum_values():
+    assert AgentEnum.ORCHESTRATOR.value == 0
+    assert AgentEnum.CODER.value == 1
+    assert AgentEnum.PLANNER.value == 2
+    assert AgentEnum.EXECUTOR.value == 3
+    assert AgentEnum.RESEARCHER.value == 4
+    assert AgentEnum.SIRJI_USER.value == 5
+    assert AgentEnum.ANY.value == 6
+    assert AgentEnum.CALLER.value == 7
+
+def test_agent_enum_full_names():
+    assert AgentEnum.ORCHESTRATOR.full_name == "Orchestrator"
+    assert AgentEnum.CODER.full_name == "Coding Agent"
+    assert AgentEnum.PLANNER.full_name == "Planning Agent"
+    assert AgentEnum.EXECUTOR.full_name == "Execution Agent"
+    assert AgentEnum.RESEARCHER.full_name == "Research Agent"
+    assert AgentEnum.SIRJI_USER.full_name == "End User"
+    assert AgentEnum.ANY.full_name == "Any Agent"
+    assert AgentEnum.CALLER.full_name == "Caller Agent"
+
+def test_agent_enum_membership():
+    assert AgentEnum['ORCHESTRATOR'] == AgentEnum.ORCHESTRATOR
+    assert AgentEnum['CODER'] == AgentEnum.CODER
+    assert AgentEnum['PLANNER'] == AgentEnum.PLANNER
+    assert AgentEnum['EXECUTOR'] == AgentEnum.EXECUTOR
+    assert AgentEnum['RESEARCHER'] == AgentEnum.RESEARCHER
+    assert AgentEnum['SIRJI_USER'] == AgentEnum.SIRJI_USER
+    assert AgentEnum['ANY'] == AgentEnum.ANY
+    assert AgentEnum['CALLER'] == AgentEnum.CALLER
diff --git a/messages/tests/test_append_to_agent_output_index.py b/messages/tests/test_append_to_agent_output_index.py
new file mode 100644
index 00000000..0cdbb9ca
--- /dev/null
+++ b/messages/tests/test_append_to_agent_output_index.py
@@ -0,0 +1,34 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.append_to_agent_output_index import AppendToAgentOutputIndexMessage
+
+def test_append_to_agent_output_index_message_sample():
+    message = AppendToAgentOutputIndexMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: APPEND_TO_AGENT_OUTPUT_INDEX
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    File path: {{file path of the agent output file relative to the Agent Output Folder}}
+    ---
+    {{Description of the agent output file, to be used by other agents to know what it is about}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_append_to_agent_output_index_message_description():
+    message = AppendToAgentOutputIndexMessage()
+    assert message.description() == "Register to the Agent Output Index"
+
+def test_append_to_agent_output_index_message_instructions():
+    message = AppendToAgentOutputIndexMessage()
+    instructions = message.instructions()
+    
+    assert instructions == [
+        "Ensure to register new agent output files to the Agent Output Index.",
+        "The file path must be in the following format: '{{Your Agent ID}}/{{file name}}'."
+    ]
\ No newline at end of file
diff --git a/messages/tests/test_base.py b/messages/tests/test_base.py
new file mode 100644
index 00000000..cf5284a5
--- /dev/null
+++ b/messages/tests/test_base.py
@@ -0,0 +1,54 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.base import BaseMessages
+
+class TestMessage(BaseMessages):
+    def __init__(self):
+        self.action = "TEST_ACTION"
+
+    def sample(self):
+        return "Sample message"
+
+    def description(self):
+        return "Test message description"
+
+    def instructions(self):
+        return ["Instruction 1", "Instruction 2"]
+
+def test_base_message_abstract_methods():
+    test_message = TestMessage()
+    
+    assert test_message.sample() == "Sample message"
+    assert test_message.description() == "Test message description"
+    assert test_message.instructions() == ["Instruction 1", "Instruction 2"]
+
+def test_base_message_generate():
+    test_message = TestMessage()
+    obj = {
+        "from_agent_id": "AGENT_1",
+        "to_agent_id": "AGENT_2",
+        "summary": "Test summary",
+        "body": "Test body"
+    }
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: AGENT_1
+    TO: AGENT_2
+    ACTION: TEST_ACTION
+    SUMMARY: Test summary
+    BODY: Test body
+    ***""")
+    
+    generated_message = test_message.generate(obj)
+    assert generated_message.strip() == expected_output.strip()
+
+def test_base_message_generate_with_missing_keys():
+    test_message = TestMessage()
+    obj = {
+        "from_agent_id": "AGENT_1",
+        "summary": "Test summary",
+        "body": "Test body"
+    }
+    with pytest.raises(KeyError):
+        test_message.generate(obj)
\ No newline at end of file
diff --git a/messages/tests/test_create_agent_output_file.py b/messages/tests/test_create_agent_output_file.py
new file mode 100644
index 00000000..ffcc3e17
--- /dev/null
+++ b/messages/tests/test_create_agent_output_file.py
@@ -0,0 +1,34 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.create_agent_output_file import CreateAgentOutputFileMessage
+
+def test_create_agent_output_file_message_sample():
+    message = CreateAgentOutputFileMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: CREATE_AGENT_OUTPUT_FILE
+    SUMMARY: {{{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    File path: {{file path}}
+    ---
+    {{file contents}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_create_agent_output_file_message_description():
+    message = CreateAgentOutputFileMessage()
+    assert message.description() == "Create a File Inside Agent Output Folder"
+
+def test_create_agent_output_file_message_instructions():
+    message = CreateAgentOutputFileMessage()
+    instructions = message.instructions()
+    
+    assert instructions == [
+        "The file path must be in the following format: '{{Your Agent ID}}/{{file name}}'."
+    ]
\ No newline at end of file
diff --git a/messages/tests/test_create_project_file.py b/messages/tests/test_create_project_file.py
new file mode 100644
index 00000000..d9daf3c1
--- /dev/null
+++ b/messages/tests/test_create_project_file.py
@@ -0,0 +1,34 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.create_project_file import CreateProjectFileMessage
+
+def test_create_project_file_message_sample():
+    message = CreateProjectFileMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: CREATE_PROJECT_FILE
+    SUMMARY: {{{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    File path: {{file path}}
+    ---
+    {{file contents}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_create_project_file_message_description():
+    message = CreateProjectFileMessage()
+    assert message.description() == "Create a File Inside Project Folder Only"
+
+def test_create_project_file_message_instructions():
+    message = CreateProjectFileMessage()
+    instructions = message.instructions()
+    
+    assert instructions == [
+        "The file path must be relative to the project root.",
+        "The file contents should never be enclosed within ``` starting and ending markers."
+    ]
\ No newline at end of file
diff --git a/messages/tests/test_custom_exceptions.py b/messages/tests/test_custom_exceptions.py
new file mode 100644
index 00000000..da4d8707
--- /dev/null
+++ b/messages/tests/test_custom_exceptions.py
@@ -0,0 +1,26 @@
+import pytest
+from sirji_messages.custom_exceptions import MessageValidationError, MessageParsingError
+
+def test_message_validation_error():
+    with pytest.raises(MessageValidationError) as exc_info:
+        raise MessageValidationError("Test validation error")
+    assert str(exc_info.value) == "Test validation error"
+    assert exc_info.value.message == "Test validation error"
+
+def test_message_validation_error_default_message():
+    with pytest.raises(MessageValidationError) as exc_info:
+        raise MessageValidationError()
+    assert str(exc_info.value) == "Invalid message format"
+    assert exc_info.value.message == "Invalid message format"
+
+def test_message_parsing_error():
+    with pytest.raises(MessageParsingError) as exc_info:
+        raise MessageParsingError("Test parsing error")
+    assert str(exc_info.value) == "Test parsing error"
+    assert exc_info.value.message == "Test parsing error"
+
+def test_message_parsing_error_default_message():
+    with pytest.raises(MessageParsingError) as exc_info:
+        raise MessageParsingError()
+    assert str(exc_info.value) == "Error parsing message"
+    assert exc_info.value.message == "Error parsing message"
\ No newline at end of file
diff --git a/messages/tests/test_execute_command.py b/messages/tests/test_execute_command.py
new file mode 100644
index 00000000..38d4e955
--- /dev/null
+++ b/messages/tests/test_execute_command.py
@@ -0,0 +1,32 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.execute_command import ExecuteCommandMessage
+
+def test_execute_command_message_sample():
+    message = ExecuteCommandMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: EXECUTE_COMMAND
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    {{command}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_execute_command_message_description():
+    message = ExecuteCommandMessage()
+    assert message.description() == "Execute a Command, Install Packages, or Install Dependencies"
+
+def test_execute_command_message_instructions():
+    message = ExecuteCommandMessage()
+    instructions = message.instructions()
+    
+    assert instructions == [
+        "The command must use the project root as the current working directory.",
+        "The command must be sufficiently chained. For example, 'source venv/bin/activate && pip install openai', 'cd server && npm run start'."
+    ]
\ No newline at end of file
diff --git a/messages/tests/test_extract_dependencies.py b/messages/tests/test_extract_dependencies.py
new file mode 100644
index 00000000..80bee301
--- /dev/null
+++ b/messages/tests/test_extract_dependencies.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.extract_dependencies import ExtractDependenciesMessage
+
+def test_extract_dependencies_message_sample():
+    message = ExtractDependenciesMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: EXTRACT_DEPENDENCIES
+    SUMMARY: {{{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    {{Array of file paths}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_extract_dependencies_message_description():
+    message = ExtractDependenciesMessage()
+    assert message.description() == "Extract Dependencies of The Specified Files"
+
+def test_extract_dependencies_message_instructions():
+    message = ExtractDependenciesMessage()
+    instructions = message.instructions()
+    
+    assert instructions == ["The file path must be relative to the project root."]
\ No newline at end of file
diff --git a/messages/tests/test_factory.py b/messages/tests/test_factory.py
new file mode 100644
index 00000000..3a19e603
--- /dev/null
+++ b/messages/tests/test_factory.py
@@ -0,0 +1,18 @@
+from sirji_messages.messages.factory import MessageFactory
+from sirji_messages.action_enum import ActionEnum
+from sirji_messages.messages.actions.execute_command import ExecuteCommandMessage
+from sirji_messages.messages.actions.run_server import RunServerMessage
+from sirji_messages.messages.actions.create_project_file import CreateProjectFileMessage
+from sirji_messages.messages.actions.create_agent_output_file import CreateAgentOutputFileMessage
+import pytest
+
+def test_message_factory_getitem():
+    assert MessageFactory[ActionEnum.EXECUTE_COMMAND.name] == ExecuteCommandMessage
+    assert MessageFactory[ActionEnum.RUN_SERVER.name] == RunServerMessage
+    assert MessageFactory[ActionEnum.CREATE_PROJECT_FILE.name] == CreateProjectFileMessage
+    assert MessageFactory[ActionEnum.CREATE_AGENT_OUTPUT_FILE.name] == CreateAgentOutputFileMessage
+
+def test_message_factory_invalid_action():
+    with pytest.raises(AttributeError) as exc_info:
+        MessageFactory["INVALID_ACTION"]
+    assert str(exc_info.value) == "INVALID_ACTION not found in MessageFactory or ActionType Enum."
\ No newline at end of file
diff --git a/messages/tests/test_helper.py b/messages/tests/test_helper.py
new file mode 100644
index 00000000..dab0d074
--- /dev/null
+++ b/messages/tests/test_helper.py
@@ -0,0 +1,37 @@
+import pytest
+from sirji_messages.helper import allowed_response_templates
+from sirji_messages.agent_enum import AgentEnum
+from sirji_messages.permissions import permissions_dict
+
+def test_allowed_response_templates():
+    from_agent = AgentEnum.ANY
+    to_agent = AgentEnum.EXECUTOR
+    response_template = allowed_response_templates(from_agent, to_agent)
+    
+    assert "Allowed Response Templates TO EXECUTOR:" in response_template
+    assert "Function 1. " in response_template
+    assert "Response template:" in response_template
+
+def test_allowed_response_templates_orchestrator_to_any():
+    from_agent = AgentEnum.ORCHESTRATOR
+    to_agent = AgentEnum.ANY
+    response_template = allowed_response_templates(from_agent, to_agent)
+    
+    assert "To invoke an agent, please respond with the text below" in response_template
+    assert "Function 1. " in response_template
+    assert "Response template:" in response_template
+
+def test_allowed_response_templates_any_to_caller():
+    from_agent = AgentEnum.ANY
+    to_agent = AgentEnum.CALLER
+    response_template = allowed_response_templates(from_agent, to_agent)
+    
+    assert "Respond to the agent which invoked you" in response_template
+    assert "Function 1. " in response_template
+    assert "Response template:" in response_template
+
+def test_allowed_response_templates_invalid_agents():
+    from_agent = 'INVALID_AGENT'
+    to_agent = AgentEnum.EXECUTOR
+    with pytest.raises(KeyError):
+        allowed_response_templates(from_agent, to_agent)
\ No newline at end of file
diff --git a/messages/tests/test_infer.py b/messages/tests/test_infer.py
new file mode 100644
index 00000000..4152a310
--- /dev/null
+++ b/messages/tests/test_infer.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.infer import InferMessage
+
+def test_infer_message_sample():
+    message = InferMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: RESEARCHER
+    ACTION: INFER
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    {{Infer query}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_infer_message_description():
+    message = InferMessage()
+    assert message.description() == "Ask questions on the trained content"
+
+def test_infer_message_instructions():
+    message = InferMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_init.py b/messages/tests/test_init.py
new file mode 100644
index 00000000..7d5b6595
--- /dev/null
+++ b/messages/tests/test_init.py
@@ -0,0 +1,51 @@
+
+import pytest
+from sirji_messages import (
+    message_parse,
+    MessageFactory,
+    ActionEnum,
+    AgentEnum,
+    MessageParsingError,
+    MessageValidationError,
+    validate_permission,
+    permissions_dict,
+    allowed_response_templates
+)
+
+def test_imports():
+    # Test if all imports are available
+    assert message_parse is not None
+    assert MessageFactory is not None
+    assert ActionEnum is not None
+    assert AgentEnum is not None
+    assert MessageParsingError is not None
+    assert MessageValidationError is not None
+    assert validate_permission is not None
+    assert permissions_dict is not None
+    assert allowed_response_templates is not None
+
+def test_enum_members():
+    # Test if enums have expected members
+    assert ActionEnum.ANSWER.name == "ANSWER"
+    assert AgentEnum.CODER.name == "CODER"
+
+def test_exceptions():
+    # Test if exceptions can be raised and caught
+    with pytest.raises(MessageParsingError):
+        raise MessageParsingError("Test parsing error")
+    
+    with pytest.raises(MessageValidationError):
+        raise MessageValidationError("Test validation error")
+
+def test_validate_permission():
+    # Test if validate_permission function works as expected
+    assert validate_permission("ANY", "EXECUTOR", "CREATE_PROJECT_FILE") == True
+    assert validate_permission("ANY", "EXECUTOR", "INVALID_ACTION") == False
+
+def test_allowed_response_templates():
+    # Test if allowed_response_templates function works as expected
+    from_agent = AgentEnum.ANY
+    to_agent = AgentEnum.EXECUTOR
+    response_template = allowed_response_templates(from_agent, to_agent)
+    
+    assert "Allowed Response Templates TO EXECUTOR:" in response_template
\ No newline at end of file
diff --git a/messages/tests/test_invoke_agent.py b/messages/tests/test_invoke_agent.py
new file mode 100644
index 00000000..89fb4eed
--- /dev/null
+++ b/messages/tests/test_invoke_agent.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.invoke_agent import InvokeAgentMessage
+
+def test_invoke_agent_message_sample():
+    message = InvokeAgentMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: ORCHESTRATOR
+    TO: {{To Agent ID}}
+    ACTION: INVOKE_AGENT
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    {{Purpose of invocation}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_invoke_agent_message_description():
+    message = InvokeAgentMessage()
+    assert message.description() == "Invoke an agent in a fresh session"
+
+def test_invoke_agent_message_instructions():
+    message = InvokeAgentMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_invoke_agent_existing_session.py b/messages/tests/test_invoke_agent_existing_session.py
new file mode 100644
index 00000000..0003c2a1
--- /dev/null
+++ b/messages/tests/test_invoke_agent_existing_session.py
@@ -0,0 +1,29 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.invoke_agent_existing_session import InvokeAgentExistingSessionMessage
+
+def test_invoke_agent_existing_session_message_sample():
+    message = InvokeAgentExistingSessionMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: ORCHESTRATOR
+    TO: {{To Agent ID}}
+    ACTION: INVOKE_AGENT_EXISTING_SESSION
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    {{Purpose of invocation}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_invoke_agent_existing_session_message_description():
+    message = InvokeAgentExistingSessionMessage()
+    assert message.description() == "Invoke an agent continuing on the existing session"
+
+def test_invoke_agent_existing_session_message_instructions():
+    message = InvokeAgentExistingSessionMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_parser.py b/messages/tests/test_parser.py
new file mode 100644
index 00000000..de88dbc0
--- /dev/null
+++ b/messages/tests/test_parser.py
@@ -0,0 +1,72 @@
+
+import pytest
+from sirji_messages.parser import parse, MessageParsingError, MessageValidationError
+
+def test_parse_valid_message():
+    message_str = """***
+    FROM: CODER
+    TO: USER
+    ACTION: INFORM
+    SUMMARY: Welcome
+    BODY: Welcome to sirji-messages. Here's how you can start.
+    ***"""
+    
+    expected_output = {
+        'FROM': 'CODER',
+        'TO': 'USER',
+        'ACTION': 'INFORM',
+        'SUMMARY': 'Welcome',
+        'BODY': "Welcome to sirji-messages. Here's how you can start."
+    }
+    
+    parsed_message = parse(message_str)
+    assert parsed_message == expected_output
+
+def test_parse_missing_property():
+    message_str = """***
+    FROM: CODER
+    TO: USER
+    ACTION: INFORM
+    SUMMARY: Welcome
+    ***"""
+    
+    with pytest.raises(MessageValidationError) as exc_info:
+        parse(message_str)
+    assert str(exc_info.value) == "Message does not meet the minimum length requirement"
+
+def test_parse_invalid_action():
+    message_str = """***
+    FROM: CODER
+    TO: USER
+    ACTION: INVALID_ACTION
+    SUMMARY: Welcome
+    BODY: Welcome to sirji-messages. Here's how you can start.
+    ***"""
+    
+    with pytest.raises(MessageValidationError) as exc_info:
+        parse(message_str)
+    assert str(exc_info.value) == "Action INVALID_ACTION is not recognized"
+
+def test_parse_invalid_format():
+    message_str = """**
+    FROM: CODER
+    TO: USER
+    ACTION: INFORM
+    SUMMARY: Welcome
+    BODY: Welcome to sirji-messages. Here's how you can start.
+    **"""
+    
+    with pytest.raises(MessageValidationError) as exc_info:
+        parse(message_str)
+    assert str(exc_info.value) == "Message must start and end with ***"
+
+def test_parse_short_message():
+    message_str = """***
+    FROM: CODER
+    TO: USER
+    ACTION: INFORM
+    ***"""
+    
+    with pytest.raises(MessageValidationError) as exc_info:
+        parse(message_str)
+    assert str(exc_info.value) == "Message does not meet the minimum length requirement"
\ No newline at end of file
diff --git a/messages/tests/test_permissions.py b/messages/tests/test_permissions.py
new file mode 100644
index 00000000..f31dac8c
--- /dev/null
+++ b/messages/tests/test_permissions.py
@@ -0,0 +1,30 @@
+import pytest
+from sirji_messages.permissions import validate_permission, permissions_dict
+from sirji_messages.agent_enum import AgentEnum
+from sirji_messages.action_enum import ActionEnum
+
+def test_validate_permission_valid():
+    assert validate_permission("ANY", "EXECUTOR", "CREATE_PROJECT_FILE") == True
+    assert validate_permission("ANY", "SIRJI_USER", "QUESTION") == True
+    assert validate_permission("ORCHESTRATOR", "SIRJI_USER", "SOLUTION_COMPLETE") == True
+    assert validate_permission("ORCHESTRATOR", "ANY", "INVOKE_AGENT") == True
+
+def test_validate_permission_invalid():
+    assert validate_permission("ANY", "EXECUTOR", "INVALID_ACTION") == False
+    assert validate_permission("ANY", "INVALID_AGENT", "QUESTION") == False
+    assert validate_permission("INVALID_AGENT", "SIRJI_USER", "QUESTION") == False
+    assert validate_permission("ORCHESTRATOR", "SIRJI_USER", "INVALID_ACTION") == False
+
+def test_permissions_dict():
+    assert (AgentEnum.ANY, AgentEnum.EXECUTOR) in permissions_dict
+    assert ActionEnum.CREATE_PROJECT_FILE in permissions_dict[(AgentEnum.ANY, AgentEnum.EXECUTOR)]
+    assert ActionEnum.QUESTION in permissions_dict[(AgentEnum.ANY, AgentEnum.SIRJI_USER)]
+    assert ActionEnum.SOLUTION_COMPLETE in permissions_dict[(AgentEnum.ORCHESTRATOR, AgentEnum.SIRJI_USER)]
+    assert ActionEnum.INVOKE_AGENT in permissions_dict[(AgentEnum.ORCHESTRATOR, AgentEnum.ANY)]
+
+def test_permissions_dict_invalid():
+    assert ('INVALID_AGENT', AgentEnum.EXECUTOR) not in permissions_dict
+    assert 'INVALID_ACTION' not in permissions_dict[(AgentEnum.ANY, AgentEnum.EXECUTOR)]
+    assert 'INVALID_ACTION' not in permissions_dict[(AgentEnum.ANY, AgentEnum.SIRJI_USER)]
+    assert 'INVALID_ACTION' not in permissions_dict[(AgentEnum.ORCHESTRATOR, AgentEnum.SIRJI_USER)]
+    assert 'INVALID_ACTION' not in permissions_dict[(AgentEnum.ORCHESTRATOR, AgentEnum.ANY)]
\ No newline at end of file
diff --git a/messages/tests/test_question.py b/messages/tests/test_question.py
new file mode 100644
index 00000000..96c1f942
--- /dev/null
+++ b/messages/tests/test_question.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.question import QuestionMessage
+
+def test_question_message_sample():
+    message = QuestionMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: SIRJI_USER
+    ACTION: QUESTION
+    SUMMARY: Empty
+    BODY: 
+    {{Question}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_question_message_description():
+    message = QuestionMessage()
+    assert message.description() == "Ask a question"
+
+def test_question_message_instructions():
+    message = QuestionMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_read_agent_output_files.py b/messages/tests/test_read_agent_output_files.py
new file mode 100644
index 00000000..edde7bf0
--- /dev/null
+++ b/messages/tests/test_read_agent_output_files.py
@@ -0,0 +1,29 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.read_agent_output_files import ReadAgentOutputFilesMessage
+
+def test_read_agent_output_files_message_sample():
+    message = ReadAgentOutputFilesMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: READ_AGENT_OUTPUT_FILES
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    File paths: {{Array of file paths}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_read_agent_output_files_message_description():
+    message = ReadAgentOutputFilesMessage()
+    assert message.description() == "Read Multiple Files From Agent Output Folder"
+
+def test_read_agent_output_files_message_instructions():
+    message = ReadAgentOutputFilesMessage()
+    instructions = message.instructions()
+    
+    assert instructions == ["The file paths must be in the following format: '{{Your Agent ID}}/{{file name}}'."]
\ No newline at end of file
diff --git a/messages/tests/test_read_agent_output_index.py b/messages/tests/test_read_agent_output_index.py
new file mode 100644
index 00000000..0b5b03e4
--- /dev/null
+++ b/messages/tests/test_read_agent_output_index.py
@@ -0,0 +1,29 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.read_agent_output_index import ReadAgentOutputIndexMessage
+
+def test_read_agent_output_index_message_sample():
+    message = ReadAgentOutputIndexMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: READ_AGENT_OUTPUT_INDEX
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    Empty
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_read_agent_output_index_message_description():
+    message = ReadAgentOutputIndexMessage()
+    assert message.description() == "Read Agent Output Index"
+
+def test_read_agent_output_index_message_instructions():
+    message = ReadAgentOutputIndexMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_read_project_files.py b/messages/tests/test_read_project_files.py
new file mode 100644
index 00000000..b78ef382
--- /dev/null
+++ b/messages/tests/test_read_project_files.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.read_project_files import ReadProjectFilesMessage
+
+def test_read_project_files_message_sample():
+    message = ReadProjectFilesMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: READ_PROJECT_FILES
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    File paths: {{Array of file paths}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_read_project_files_message_description():
+    message = ReadProjectFilesMessage()
+    assert message.description() == "Read Multiple Files From Project Folder Only"
+
+def test_read_project_files_message_instructions():
+    message = ReadProjectFilesMessage()
+    instructions = message.instructions()
+    
+    assert instructions == ["The file paths must be relative to the project root."]
\ No newline at end of file
diff --git a/messages/tests/test_response.py b/messages/tests/test_response.py
new file mode 100644
index 00000000..1c0f1a17
--- /dev/null
+++ b/messages/tests/test_response.py
@@ -0,0 +1,29 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.response import ResponseMessage
+
+def test_response_message_sample():
+    message = ResponseMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Agent Id of the agent sending the response}}
+    TO: {{Your Agent ID}}
+    ACTION: RESPONSE
+    SUMMARY: Empty
+    BODY: 
+    {{Response}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_response_message_description():
+    message = ResponseMessage()
+    assert message.description() == "The response output"
+
+def test_response_message_instructions():
+    message = ResponseMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_run_server.py b/messages/tests/test_run_server.py
new file mode 100644
index 00000000..1f3d666a
--- /dev/null
+++ b/messages/tests/test_run_server.py
@@ -0,0 +1,32 @@
+import pytest
+import textwrap
+from sirji_messages.messages.actions.run_server import RunServerMessage
+
+def test_run_server_message_sample():
+    message = RunServerMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: RUN_SERVER
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    {{command}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_run_server_message_description():
+    message = RunServerMessage()
+    assert message.description() == "Run a Server or a Continuous Running Process"
+
+def test_run_server_message_instructions():
+    message = RunServerMessage()
+    instructions = message.instructions()
+    
+    assert instructions == [
+        "The command must use the project root as the current working directory.",
+        "The command must be sufficiently chained. For example, 'source my_env.sh && npm start'."
+    ]
\ No newline at end of file
diff --git a/messages/tests/test_search_file_in_project.py b/messages/tests/test_search_file_in_project.py
new file mode 100644
index 00000000..e0c1d96a
--- /dev/null
+++ b/messages/tests/test_search_file_in_project.py
@@ -0,0 +1,32 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.search_file_in_project import SearchFileInProject
+
+def test_search_file_in_project_message_sample():
+    message = SearchFileInProject()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: EXECUTOR
+    ACTION: SEARCH_FILE_IN_PROJECT
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    Search: {{Search term}}
+    ---
+    Directory: {{Directory path}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_search_file_in_project_message_description():
+    message = SearchFileInProject()
+    assert message.description() == "Search for a file in a directory and all its subdirectories"
+
+def test_search_file_in_project_message_instructions():
+    message = SearchFileInProject()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_solution_complete.py b/messages/tests/test_solution_complete.py
new file mode 100644
index 00000000..9b3c1820
--- /dev/null
+++ b/messages/tests/test_solution_complete.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.solution_complete import SolutionCompleteMessage
+
+def test_solution_complete_message_sample():
+    message = SolutionCompleteMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: SIRJI_USER
+    ACTION: SOLUTION_COMPLETE
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    {{Summarize what all was done for getting the solution.}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_solution_complete_message_description():
+    message = SolutionCompleteMessage()
+    assert message.description() == "Inform About Solution Completed"
+
+def test_solution_complete_message_instructions():
+    message = SolutionCompleteMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_train_using_search_term.py b/messages/tests/test_train_using_search_term.py
new file mode 100644
index 00000000..c49fc0b8
--- /dev/null
+++ b/messages/tests/test_train_using_search_term.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.train_using_search_term import TrainUsingSearchTermMessage
+
+def test_train_using_search_term_message_sample():
+    message = TrainUsingSearchTermMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: RESEARCHER
+    ACTION: TRAIN_USING_SEARCH_TERM
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    Term: {{search term}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_train_using_search_term_message_description():
+    message = TrainUsingSearchTermMessage()
+    assert message.description() == "Train using a search term"
+
+def test_train_using_search_term_message_instructions():
+    message = TrainUsingSearchTermMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/test_train_using_url.py b/messages/tests/test_train_using_url.py
new file mode 100644
index 00000000..64bdc0a5
--- /dev/null
+++ b/messages/tests/test_train_using_url.py
@@ -0,0 +1,30 @@
+
+import pytest
+import textwrap
+from sirji_messages.messages.actions.train_using_url import TrainUsingUrlMessage
+
+def test_train_using_url_message_sample():
+    message = TrainUsingUrlMessage()
+    sample_message = message.sample()
+    
+    expected_output = textwrap.dedent("""
+    ***
+    FROM: {{Your Agent ID}}
+    TO: RESEARCHER
+    ACTION: TRAIN_USING_URL
+    SUMMARY: {{Display a concise summary to the user, describing the action using the present continuous tense.}}
+    BODY: 
+    URL: {{url}}
+    ***""")
+    
+    assert sample_message.strip() == expected_output.strip()
+
+def test_train_using_url_message_description():
+    message = TrainUsingUrlMessage()
+    assert message.description() == "Train using a URL"
+
+def test_train_using_url_message_instructions():
+    message = TrainUsingUrlMessage()
+    instructions = message.instructions()
+    
+    assert instructions == []
\ No newline at end of file
diff --git a/messages/tests/unit/__init__.py b/messages/tests/unit/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/messages/tests/unit/test_actions_base.py b/messages/tests/unit/test_actions_base.py
deleted file mode 100644
index 894badf3..00000000
--- a/messages/tests/unit/test_actions_base.py
+++ /dev/null
@@ -1,31 +0,0 @@
-import pytest
-from sirji_messages.messages.actions.base import BaseMessages
-
-# Creating a concrete class by inheriting from BaseMessages for testing purposes
-
-
-class ConcreteMessage(BaseMessages):
-    def template_payload_part(self):
-        return "Payload part"
-
-    def sample(self):
-        return "Sample message"
-
-    def description(self):
-        return "Description"
-
-    def custom_properties(self):
-        return ['DETAILS']
-
-
-def test_base_messages_instantiation():
-    concrete_message = ConcreteMessage()
-    assert isinstance(concrete_message, BaseMessages)
-
-
-def test_base_messages_methods():
-    concrete_message = ConcreteMessage()
-    assert concrete_message.template_payload_part() == "Payload part"
-    assert concrete_message.sample() == "Sample message"
-    assert concrete_message.description() == "Description"
-    assert concrete_message.custom_properties() == ['DETAILS']
diff --git a/messages/tests/unit/test_custom_exceptions.py b/messages/tests/unit/test_custom_exceptions.py
deleted file mode 100644
index 0a3c16e4..00000000
--- a/messages/tests/unit/test_custom_exceptions.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import pytest
-from sirji_messages import MessageValidationError, MessageParsingError
-
-
-def test_message_validation_error():
-    with pytest.raises(MessageValidationError) as exc_info:
-        raise MessageValidationError("Custom error message")
-    assert str(
-        exc_info.value) == "Custom error message", "MessageValidationError does not show the correct message"
-
-
-def test_message_parsing_error():
-    with pytest.raises(MessageParsingError) as exc_info:
-        raise MessageParsingError("Parsing failed")
-    assert str(
-        exc_info.value) == "Parsing failed", "MessageParsingError does not show the correct message"
diff --git a/messages/tests/unit/test_enums.py b/messages/tests/unit/test_enums.py
deleted file mode 100644
index 2d9addb5..00000000
--- a/messages/tests/unit/test_enums.py
+++ /dev/null
@@ -1,30 +0,0 @@
-import pytest
-from sirji_messages import AgentEnum, ActionEnum
-
-# Test Cases for AgentEnum
-
-
-def test_agent_enum_values_and_full_names():
-    assert AgentEnum.CODER.value == 1, "CODER value mismatch"
-    assert AgentEnum.CODER.full_name == "Coding Agent", "CODER full name mismatch"
-    assert AgentEnum.USER.value == 5, "USER value mismatch"
-    assert AgentEnum.USER.full_name == "End User", "USER full name mismatch"
-
-
-def test_agent_enum_names():
-    assert AgentEnum.CODER.name == "CODER", "Incorrect name for CODER"
-    assert AgentEnum.USER.name == "USER", "Incorrect name for USER"
-
-# Test Cases for ActionEnum
-
-
-def test_action_enum_auto_values():
-    # Test specific actions to ensure their auto-generated values are distinct
-    assert ActionEnum.ACKNOWLEDGE.value != ActionEnum.ANSWER.value, "ACKNOWLEDGE and ANSWER values should not be equal"
-    assert ActionEnum.EXECUTE_COMMAND.value != ActionEnum.CREATE_FILE.value, "EXECUTE_COMMAND and CREATE_FILE values should not be equal"
-
-
-def test_action_enum_membership():
-    # Check if certain actions are in the ActionEnum
-    assert "INFORM" in ActionEnum.__members__, "INFORM should be a member of ActionEnum"
-    assert "QUESTION" in ActionEnum.__members__, "QUESTION should be a member of ActionEnum"
diff --git a/messages/tests/unit/test_parser.py b/messages/tests/unit/test_parser.py
deleted file mode 100644
index a26ba004..00000000
--- a/messages/tests/unit/test_parser.py
+++ /dev/null
@@ -1,101 +0,0 @@
-import pytest
-from sirji_messages import message_parse, MessageParsingError, MessageValidationError
-
-# Test Cases for message_parse function
-
-
-def test_message_parse_valid_input():
-    input_message = """
-    ```
-    FROM: CODER
-    TO: USER
-    ACTION: QUESTION
-    DETAILS: Some information.
-    ```
-    """
-    expected_output = {
-        'FROM': 'CODER',
-        'TO': 'USER',
-        'ACTION': 'QUESTION',
-        'DETAILS': 'Some information.'
-    }
-    assert message_parse(
-        input_message) == expected_output, "Valid message parsing failed"
-
-
-def test_message_parse_invalid_format_raises_error():
-    input_message = "FROM: CODER\nTO: USER\nACTION: QUESTION\nDETAILS: Some information."
-    with pytest.raises(MessageValidationError):
-        message_parse(input_message)
-
-
-def test_message_parse_missing_action_raises_error():
-    input_message = """
-    ```
-    FROM: CODER
-    TO: USER
-    DETAILS: Missing action field.
-    ```
-    """
-    with pytest.raises(MessageValidationError):
-        message_parse(input_message)
-
-
-def test_message_parse_incorrect_message_raises_error():
-    input_message = """
-    ```
-    This is not a correctly formatted message.
-    ```
-    """
-    with pytest.raises(MessageValidationError):
-        message_parse(input_message)
-
-
-def test_message_parse_permission_denied_error():
-    input_message = """
-    ```
-    FROM: USER
-    TO: CODER
-    ACTION: CREATE_FILE
-    DETAILS: Attempting an unauthorized action.
-    ```
-    """
-    with pytest.raises(MessageValidationError):
-        message_parse(input_message)
-
-# Testing with extra spaces around the key elements
-
-
-def test_message_parse_with_extra_spaces():
-    input_message = """
-    ```
-    FROM :  CODER
-    TO : USER
-    ACTION : QUESTION
-    DETAILS : Extra spaces around colons.
-    ```
-    """
-    expected_output = {
-        'FROM': 'CODER',
-        'TO': 'USER',
-        'ACTION': 'QUESTION',
-        'DETAILS': 'Extra spaces around colons.'
-    }
-    assert message_parse(
-        input_message) == expected_output, "Message parsing failed with extra spaces"
-
-# Adjusting the test to align with the current implementation's case sensitivity
-
-
-def test_message_parse_case_sensitivity():
-    input_message = """
-    ```
-    from: CODER
-    to: USER
-    action: QUESTION
-    details: Checking case sensitivity.
-    ```
-    """
-    # Expecting a MessageValidationError due to case sensitivity
-    with pytest.raises(MessageValidationError):
-        message_parse(input_message)
diff --git a/messages/tests/unit/test_permissions.py b/messages/tests/unit/test_permissions.py
deleted file mode 100644
index d133e9cc..00000000
--- a/messages/tests/unit/test_permissions.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import pytest
-from sirji_messages import validate_permission, AgentEnum, ActionEnum
-
-# Test cases for validate_permission function
-
-
-def test_permission_valid():
-    # Assuming Coder has permission to inform a User
-    assert validate_permission(
-        "CODER", "USER", "QUESTION"), "Valid permission was denied"
-
-
-def test_permission_invalid_action():
-    # Assuming Coder does not have permission to execute a command directly to a User
-    assert not validate_permission(
-        "CODER", "USER", "EXECUTE_COMMAND"), "Invalid action was erroneously permitted"
-
-
-def test_permission_invalid_agent_pair():
-    # Assuming no direct interaction is allowed from Executor to User
-    assert not validate_permission(
-        "EXECUTOR", "USER", "QUESTION"), "Invalid agent pair was erroneously permitted"
-
-
-def test_permission_nonexistent_from_agent():
-    assert not validate_permission(
-        "FAKE_AGENT", "USER", "QUESTION"), "Permission check with nonexistent 'from' agent should be denied"
-
-
-def test_permission_nonexistent_to_agent():
-    assert not validate_permission(
-        "CODER", "FAKE_AGENT", "QUESTION"), "Permission check with nonexistent 'to' agent should be denied"
-
-
-def test_permission_nonexistent_action():
-    assert not validate_permission(
-        "CODER", "USER", "FAKE_ACTION"), "Permission check with nonexistent action should be denied"
-
-# Testing with invalid agent enums
-
-
-def test_permission_with_invalid_agent_enum():
-    assert not validate_permission(
-        "INVALID_AGENT", "USER", "QUESTION"), "Permission check with invalid enum should return False instead of raising KeyError"