<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Phú</title>
    <description>The latest articles on DEV Community by Phú (@lkp).</description>
    <link>https://dev.to/lkp</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F807538%2Fe1954dbe-0152-47f7-9369-2d858f3812fc.jpg</url>
      <title>DEV Community: Phú</title>
      <link>https://dev.to/lkp</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lkp"/>
    <language>en</language>
    <item>
      <title>I Used Gemma 4 as a Local Coding Agent With OpenCode. Here’s What Happened</title>
      <dc:creator>Phú</dc:creator>
      <pubDate>Wed, 13 May 2026 14:18:31 +0000</pubDate>
      <link>https://dev.to/lkp/i-used-gemma-4-as-a-local-coding-agent-with-opencode-heres-what-happened-19mh</link>
      <guid>https://dev.to/lkp/i-used-gemma-4-as-a-local-coding-agent-with-opencode-heres-what-happened-19mh</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Write About Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;Cloud coding assistants are useful. I use them to explain unfamiliar code, generate tests, review changes, and sometimes help me debug weird problems faster than I could alone. But I have always had one question: What if I can use coding assistants locally? Is it possible?&lt;/p&gt;

&lt;p&gt;That question led me to try a setup with latest open weight model of Google which is Gemma 4. This is my setup:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gemma 4 26B A4B MXFP4 of Unsloth as the model&lt;/li&gt;
&lt;li&gt;OpenCode as the coding agent&lt;/li&gt;
&lt;li&gt;My own codebase as the test environment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was simple: I wanted to see whether Gemma 4 could behave like a useful local coding agent inside my real development workflow. Not a benchmark. Not a perfect lab test. Just a practical experiment: give the model real coding tasks, let it inspect files, ask it to make changes, and see what actually happens.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is OpenCode?
&lt;/h1&gt;

&lt;p&gt;OpenCode is an open-source AI coding agent. It can connect to many different model providers, and its model documentation says it supports local models as well.&lt;/p&gt;

&lt;p&gt;That made it a good fit for this experiment.&lt;/p&gt;

&lt;p&gt;I was not looking for simple autocomplete. I wanted to test agent-style behavior:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can it inspect my project?&lt;/li&gt;
&lt;li&gt;Can it find the right files?&lt;/li&gt;
&lt;li&gt;Can it implement new feature?&lt;/li&gt;
&lt;li&gt;Can it understand a bug?&lt;/li&gt;
&lt;li&gt;Can it suggest a safe fix?&lt;/li&gt;
&lt;li&gt;Can it review a diff before I commit?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, that is the difference between a chatbot and a coding agent.&lt;/p&gt;

&lt;p&gt;A chatbot answers questions.&lt;/p&gt;

&lt;p&gt;A coding agent works inside the codebase.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why I chose Gemma 4
&lt;/h1&gt;

&lt;p&gt;Gemma 4 was interesting for this experiment because Google describes the family as supporting reasoning, multimodal input, larger context windows, enhanced coding capability, and agentic workflows. Google’s Gemma 4 documentation lists four model sizes: E2B, E4B, 31B, and 26B A4B. It also says the small models support a 128K context window, while the medium models support 256K.&lt;/p&gt;

&lt;p&gt;That matters for coding.&lt;/p&gt;

&lt;p&gt;A coding assistant needs more than short answers. It needs enough context to understand files, dependencies, naming conventions, and the relationship between different parts of a project.&lt;/p&gt;

&lt;p&gt;Google DeepMind also describes the 26B and 31B Gemma 4 models as aimed at advanced reasoning for IDEs, coding assistants, and agentic workflows.&lt;/p&gt;

&lt;p&gt;So Gemma 4 felt like the right model family to test with OpenCode.&lt;/p&gt;

&lt;h1&gt;
  
  
  My configuration
&lt;/h1&gt;

&lt;p&gt;I use llama.cpp with KV Cache is 8bit. I try with maximum context window of this model. This is my configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./build/bin/llama-server &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-m&lt;/span&gt; /home/Downloads/gemma-4-26B-A4B-it-MXFP4_MOE.gguf &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-ngl&lt;/span&gt; all &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-c&lt;/span&gt; 262144 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-fa&lt;/span&gt; on &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-ctk&lt;/span&gt; q8_0 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-ctv&lt;/span&gt; q8_0 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--host&lt;/span&gt; 127.0.0.1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--port&lt;/span&gt; 8080

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my opencode configuration, I setup it like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://opencode.ai/config.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"provider"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"llama.cpp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"npm"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@ai-sdk/openai-compatible"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"llama-server (local)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"baseURL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://127.0.0.1:8080/v1"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"models"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"gemma-4-26B-A4B-it-MXFP4_MOE"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Gemma 4 26B A4B MXFP4"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then now, I run command to create Laravel project with React to try to test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;laravel new gemma4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After run this command, choose React as stack. Do not need to use built authentication. &lt;/p&gt;

&lt;h1&gt;
  
  
  Can it inspect my project?
&lt;/h1&gt;

&lt;p&gt;I check it with this prompt &lt;code&gt;Explain to me tech stack of this project.&lt;/code&gt;, see how it will answer.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thinking: The user wants to know the tech stack of the current project. I should start by exploring the codebase to identify the main technologies used. I'll look for key files like composer.json, package.json, vite.config.js, etc.
⚙ laravel-boost_application-info 
Thinking: The laravel-boost_application-info tool provided a comprehensive list of the tech stack.
Summary:
- Backend: PHP 8.5, Laravel 13.8.0
- Frontend: React 19.2.6, Inertia.js 3.1.0 (inertiajs/inertia-laravel and @inertiajs/react)
- Styling: Tailwind CSS 4.3.0
- Database: SQLite
- Testing: Pest 4.7.0, PHPUnit 12.5.24
- Build Tools/Environment: Vite, Laravel Sail 1.58.0, Laravel Pint 1.29.1 (formatting), ESLint 9.39.4, Prettier 3.8.3
- Other Laravel Ecosystem: Laravel Wayfinder, Laravel Boost, Laravel Prompts, Laravel MCP, Laravel Pail
I can now answer the user's request.
This project uses the following tech stack:
*   Backend: PHP 8.5 with Laravel 13.8.0
*   Frontend: React 19.2.6 and Inertia.js 3.1.0
*   Styling: Tailwind CSS 4.3.0
*   Database: SQLite
*   Testing: Pest 4.7.0 and PHPUnit 12.5.24
*   Tooling: Vite, Laravel Sail, Laravel Pint (formatting), ESLint, and Prettier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is correct. Now, try to ask more detail &lt;code&gt;Where can I add my controller?&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thinking: The user wants to know where to add a controller in this Laravel project.
I should look for the standard Laravel directory structure to confirm where controllers are typically placed.
Standard Laravel controllers are located in app/Http/Controllers.
I will use ls or glob to check the existence of this directory.
✱ Glob "app/Http/Controllers/**/*" (1 match)
You can add your controllers in app/Http/Controllers.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and &lt;code&gt;Where can I add my test?&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thinking: The user is asking where they can add their tests.
I should look for existing tests in the project to identify the testing directory and pattern.
I'll start by using glob to find directories that look like test directories (e.g., tests/).
✱ Glob "tests/**/*" (4 matches)
Thinking: The user wants to know where to add tests.
The glob results show:
- tests/TestCase.php
- tests/Feature/ExampleTest.php
- tests/Pest.php
- tests/Unit/ExampleTest.php
This indicates that tests are located in the tests/ directory, specifically divided into tests/Feature and tests/Unit.
The project uses Pest, as indicated by tests/Pest.php and the pestphp/pest package in the application info.
I will inform the user that they can add tests in the tests/ directory, specifically in tests/Feature for feature tests and tests/Unit for unit tests.
You can add your tests in the tests/ directory, specifically in:
*   tests/Feature for feature tests.
*   tests/Unit for unit tests.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty nice. Now ask what does this project current have. My question is &lt;code&gt;What is this project about? Explain in detail.&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thinking: The user wants a detailed explanation of what the project is about.
I need to explore the codebase to understand its purpose.
I'll start by listing the files in the root directory and looking at README.md if it exists.
# List files in the root directory
$ ls -F
AGENTS.md
CLAUDE.md
app/
artisan*
boost.json
bootstrap/
composer.json
composer.lock
config/
database/
eslint.config.js
node_modules/
opencode.json
package-lock.json
package.json
phpunit.xml
pint.json
pnpm-workspace.yaml
public/
resources/
routes/
storage/
tests/
tsconfig.json
vendor/
vite.config.ts
Click to collapse
Thinking: There's no README.md. I'll check CLAUDE.md and AGENTS.md as they might contain information about the project. I'll also look at composer.json to see the package dependencies and potentially a description.
→ Read CLAUDE.md 
Thinking: CLAUDE.md seems to be a set of guidelines for the assistant (me) rather than a description of the project's business logic. It contains rules for using the Laravel ecosystem tools.
I'll check AGENTS.md.
→ Read AGENTS.md 
Thinking: Both CLAUDE.md and AGENTS.md are just the Laravel Boost guidelines. They don't describe the project's actual functionality.
I'll look at the routes/web.php and routes/api.php to see what endpoints exist, and then inspect the controllers and models to understand the business logic.
→ Read routes/web.php 
Thinking: The routes/web.php only has a single route pointing to a welcome Inertia page. This suggests the project might be a very minimal boilerplate or a template.
Let's check resources/js/pages/ to see what the welcome component looks like.
✱ Glob "resources/js/pages/**/*" (1 match)
Thinking: Okay, let's read resources/js/pages/welcome.tsx.
→ Read resources/js/pages/welcome.tsx 
Thinking: The welcome.tsx is just the standard Laravel welcome page.
This project appears to be a fresh installation of Laravel with Inertia and React, likely used as a development environment or a template for building applications. There is no specific business logic currently implemented.
I'll summarize based on the tech stack I found earlier and the fact that it's a minimal/boilerplate setup.
Based on the current codebase, this project appears to be a minimal boilerplate or template for a web application. It does not yet contain specific business logic or a defined purpose beyond being a starting point.
It is configured with a modern, full-stack architecture:
*   Backend Framework: Laravel 13 (PHP 8.5)
*   Frontend Framework: React 19 with Inertia.js 3 (providing a Single Page Application experience)
*   Styling: Tailwind CSS 4
*   Database: SQLite
*   Testing Suite: Pest 4 and PHPUnit 12
The current application only contains a standard "Welcome" page, which serves as a placeholder for developers to begin building their own features.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In response, you can see that it list correct file. Read content of welcome page, then answer correctly. So for me, it is good for understand my project.&lt;/p&gt;

&lt;h1&gt;
  
  
  Plan and implementation
&lt;/h1&gt;

&lt;p&gt;I will try to implement fitness project. I will need landing page with contact us form. Sign in and sign up page for my customer and dashboard for them. I will ask it to plan first to see how it does.&lt;br&gt;
This is my prompt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Implement fitness project. I need a landing page to introduce about fitness, have contact us form page for user to send question. Sign in and sign up page. When login successfully, user can see their dashboard. 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since output is too long now, so I only put a final result here. This is what it plan for me:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have analyzed your requirements and the project environment. Based on your request, I have developed a comprehensive implementation plan.
Proposed Implementation Plan
Phase 1: Authentication Setup
I recommend installing Laravel Breeze (Inertia/React stack). This is the industry standard for Laravel applications and will automatically provide secure, pre-built:
- Sign-in and Sign-up pages.
- Password reset functionality.
- Session management and protected routes.
- A functional Dashboard page.
Phase 2: Core Features
1.  Landing Page: A visually appealing introduction to your fitness project using Tailwind CSS.
2.  Contact Us Page:
    - A dedicated ContactMessage model and database table to store inquiries.
    - A ContactController to handle form submissions.
    - A React-based form page with validation.
3.  Dashboard: A personalized area for logged-in users to view their fitness-related information.
Phase 3: UI/UX &amp;amp; Refinement
- Theme: Implement a cohesive fitness-themed design using Tailwind CSS.
- Layouts: Create shared layouts for the Landing page (public) and the Dashboard (authenticated).
- Components: Build reusable UI elements like buttons, inputs, and navigation bars.
---
Clarifying Questions
Before I begin, please clarify the following:
1.  Authentication: Are you okay with me using Laravel Breeze to set up the authentication system? It is the fastest and most secure method.
2.  Dashboard Content: Do you have specific fitness data you'd like displayed on the dashboard (e.g., step counter, calorie tracker, workout logs), or should I use placeholder data for now?
3.  Contact Form: Should contact messages simply be saved to the database, or would you like them to be emailed to an administrator as well?
Once you confirm these details, I will start the implementation.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As usual, I ask it to put this into plan.md. Just an old day habit, I put into plan.md then I start new session to implement. With this way, I avoid to pollute context window of implementation. Now, I ask it to implement phase by phase. &lt;code&gt;Implement phase 1 in plan.md&lt;/code&gt;, &lt;code&gt;Implement phase 2 in plan.md&lt;/code&gt; and so on.&lt;/p&gt;

&lt;p&gt;Now I have sign in and sign up page. Note that UI is actually from Breeze package. So mainly in this phase, it install and configure Breeze package correctly. Now move to implement landing page and dashboard. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wr5lgcfi8p064lcvrgv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wr5lgcfi8p064lcvrgv.png" alt=" " width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgqepq55ikv9hp0g7npbv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgqepq55ikv9hp0g7npbv.png" alt=" " width="800" height="714"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, it finish to implement landing page, but when go to localhost:8000 which is domain of my app, it still show welcome page of laravel. I see that error is because of mismatch &lt;code&gt;Pages&lt;/code&gt; to &lt;code&gt;pages&lt;/code&gt;. However, I want to let it check and see if it can figure out this issue or not. I use playwright mcp and ask it to visit localhost:8000 to check and report to me. My prompt &lt;code&gt;Even after finish to implement @resources/js/pages/Welcome.tsx , in localhost:8000 shows nothing. Use playwright to check that and let me know what is an issue.&lt;/code&gt;. And wow, it actually can figure out. This is its response.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;issue&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;mismatch&lt;/span&gt; &lt;span class="nx"&gt;between&lt;/span&gt; &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;located&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;where&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;Inertia&lt;/span&gt; &lt;span class="nx"&gt;resolver&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;looking&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;configured&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="nx"&gt;components&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt; &lt;span class="nx"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nf"&gt;resolvePageComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="s2"&gt;`./Pages/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.jsx`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;glob&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Pages/**/*.jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="nx"&gt;However&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;implementation&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;located&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tsx &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;lowercase&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tsx&lt;/span&gt; &lt;span class="nx"&gt;extension&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt; &lt;span class="nx"&gt;As&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Inertia&lt;/span&gt; &lt;span class="nx"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;still&lt;/span&gt; &lt;span class="nx"&gt;loading&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;old&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="nx"&gt;at&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nx"&gt;To&lt;/span&gt; &lt;span class="nx"&gt;fix&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;either&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Move&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;rename&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Pages&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;Welcome&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;tsx &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;resolver&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;support&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tsx&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Update&lt;/span&gt; &lt;span class="nx"&gt;resources&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;js&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;jsx&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;support&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;pages&lt;/span&gt; &lt;span class="nx"&gt;directory&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tsx&lt;/span&gt; &lt;span class="nx"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I ask it to fix this issue. This is response after it fixes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have fixed the issue by:
1. Moving Welcome.tsx, Dashboard.tsx, and Contact.tsx from resources/js/pages/ to the standard resources/js/Pages/ directory and renaming them to .tsx.
2. Removing the old .jsx versions of these components.
3. Updating resources/js/app.jsx with a flexible resolver that supports both .jsx and .tsx extensions.
The application now correctly renders the new components at localhost:8000.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But well, style is not good. Seems like it miss style.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8edg8a4s0k51hll26ua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk8edg8a4s0k51hll26ua.png" alt=" " width="800" height="551"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No worries, ask it to check and fix again. Yay, it figured out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgl8byzw0lxyf0sr3piqu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgl8byzw0lxyf0sr3piqu.png" alt=" " width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, it looks beautiful. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwv7m6calm198lqqw5mq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwv7m6calm198lqqw5mq.png" alt=" " width="800" height="808"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Actually, I expect it show contact us form there as well. But when click to a button, it redirects to another page. However, it is ok. Then I test contact us form. At least it works. However, it does not show any notification to let user know that they send successfully.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fueazc3664hdnmbbu8itc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fueazc3664hdnmbbu8itc.png" alt=" " width="615" height="872"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now, I move on to check dashboard in login page. I run command to seed user. Then I login. And wow, it is nice. This is awesome I can say.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sv0h4luy517bepoxlv1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5sv0h4luy517bepoxlv1.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, if want to understand codebase, find and fix bug, this model is great. However, for implementation, it is a little bit inconsistent for UI and have many bugs to fix after finish.&lt;/p&gt;
&lt;h1&gt;
  
  
  Test
&lt;/h1&gt;

&lt;p&gt;Now I want to try to let it test page. Do manual testing with playwright and report to me. See if it test properly or not. I expect it test landing page, responsive. Test contact us form works or not. Then login, sign up and dashboard. This is my prompt &lt;code&gt;go to localhost:8000 with playwright. Test and report to me which feature work and which one is not. Check credential of user in seed and use that to login to test dashboard.&lt;/code&gt;. In the meantime, I take some coffee :D. This is result.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have completed the testing. Here is the report:
Credentials used (from DatabaseSeeder.php):
- Email: test@example.com
- Password: password
Test Results:
- Login: ✅ Works (successfully logged in with seed credentials).
- Dashboard: ✅ Works (all metrics and recent workouts loaded correctly).
- Profile: ✅ Works (profile information and password update sections are accessible).
- Contact Us: ✅ Works (form loads and submits without errors).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It did not test landing page at all. So I need to ask it to check. Simple prompt &lt;code&gt;Test landing page and responsive&lt;/code&gt;. Result is good. Then I am confident about my application after testing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I have tested the landing page responsiveness:
Landing Page Test Results:
- Desktop View: ✅ Works (all headings, paragraphs, and links are present).
- Mobile View (375x667): ✅ Works (content structure is preserved).
- Tablet View (768x1024): ✅ Works (content structure is preserved).
- Responsiveness: ✅ Responsive (the page layout and elements adapt correctly to different viewport sizes without errors).
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I will commit this changes. Another simple prompts "commit all changes". Since I have not init git before. So it only show commit "init". I think I have another chance to challenge it. So I will ask it that if no changes relate to plan.md. Put that to first commit call "init". Then check all changes and commit second time. Let's see how it goes. My prompt &lt;code&gt;check changes, if changes not in @plan.md , add that with commit "init". Then check all changes left, generate commit message and then commit it&lt;/code&gt;. This is a result I get:&lt;br&gt;
&lt;code&gt;Laravel Breeze, Contact Us feature, and Dashboard&lt;/code&gt;. Not very detail but it is ok. &lt;/p&gt;
&lt;h1&gt;
  
  
  Bonus
&lt;/h1&gt;

&lt;p&gt;After test it with understand project, implement new feature, testing and commit. It is good for around 30B model. I am quite interested about understanding project, codebase and testing. So I want to do further testing with random open source repo. I choose rtk repo here &lt;a href="https://github.com/rtk-ai/rtk" rel="noopener noreferrer"&gt;RTK AI&lt;/a&gt;. So I clone that to my local. Then I ask it a question &lt;code&gt;Check this repo and explain to me how does it work.&lt;/code&gt; It respond to me.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="err"&gt;RTK&lt;/span&gt; &lt;span class="err"&gt;(Rust&lt;/span&gt; &lt;span class="err"&gt;Token&lt;/span&gt; &lt;span class="err"&gt;Killer)&lt;/span&gt; &lt;span class="err"&gt;is&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;high-performance&lt;/span&gt; &lt;span class="err"&gt;CLI&lt;/span&gt; &lt;span class="err"&gt;proxy&lt;/span&gt; &lt;span class="err"&gt;designed&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;minimize&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;number&lt;/span&gt; &lt;span class="err"&gt;of&lt;/span&gt; &lt;span class="err"&gt;tokens&lt;/span&gt; &lt;span class="err"&gt;an&lt;/span&gt; &lt;span class="err"&gt;LLM&lt;/span&gt; &lt;span class="err"&gt;(like&lt;/span&gt; &lt;span class="err"&gt;Claude&lt;/span&gt; &lt;span class="err"&gt;Code,&lt;/span&gt; &lt;span class="err"&gt;GitHub&lt;/span&gt; &lt;span class="err"&gt;Copilot,&lt;/span&gt; &lt;span class="err"&gt;or&lt;/span&gt; &lt;span class="err"&gt;Cursor)&lt;/span&gt; &lt;span class="err"&gt;has&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;consume&lt;/span&gt; &lt;span class="err"&gt;when&lt;/span&gt; &lt;span class="err"&gt;running&lt;/span&gt; &lt;span class="err"&gt;shell&lt;/span&gt; &lt;span class="err"&gt;commands.&lt;/span&gt;
&lt;span class="err"&gt;How&lt;/span&gt; &lt;span class="err"&gt;It&lt;/span&gt; &lt;span class="err"&gt;Works&lt;/span&gt;
&lt;span class="err"&gt;RTK&lt;/span&gt; &lt;span class="err"&gt;operates&lt;/span&gt; &lt;span class="err"&gt;using&lt;/span&gt; &lt;span class="err"&gt;three&lt;/span&gt; &lt;span class="err"&gt;main&lt;/span&gt; &lt;span class="err"&gt;mechanisms:&lt;/span&gt;
&lt;span class="err"&gt;1.&lt;/span&gt;  &lt;span class="err"&gt;Explicit&lt;/span&gt; &lt;span class="err"&gt;Command&lt;/span&gt; &lt;span class="err"&gt;Modules:&lt;/span&gt;
    &lt;span class="err"&gt;RTK&lt;/span&gt; &lt;span class="err"&gt;has&lt;/span&gt; &lt;span class="err"&gt;built-in,&lt;/span&gt; &lt;span class="err"&gt;highly&lt;/span&gt; &lt;span class="err"&gt;optimized&lt;/span&gt; &lt;span class="err"&gt;filters&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;common&lt;/span&gt; &lt;span class="err"&gt;commands&lt;/span&gt; &lt;span class="err"&gt;(e.g.,&lt;/span&gt; &lt;span class="err"&gt;git,&lt;/span&gt; &lt;span class="err"&gt;cargo,&lt;/span&gt; &lt;span class="err"&gt;npm,&lt;/span&gt; &lt;span class="err"&gt;pytest,&lt;/span&gt; &lt;span class="err"&gt;docker).&lt;/span&gt; &lt;span class="err"&gt;When&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;run&lt;/span&gt; &lt;span class="err"&gt;rtk&lt;/span&gt; &lt;span class="err"&gt;git&lt;/span&gt; &lt;span class="err"&gt;status,&lt;/span&gt; &lt;span class="err"&gt;instead&lt;/span&gt; &lt;span class="err"&gt;of&lt;/span&gt; &lt;span class="err"&gt;getting&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;full&lt;/span&gt; &lt;span class="err"&gt;raw&lt;/span&gt; &lt;span class="err"&gt;output,&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;get&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;condensed,&lt;/span&gt; &lt;span class="err"&gt;token-optimized&lt;/span&gt; &lt;span class="err"&gt;version&lt;/span&gt; &lt;span class="err"&gt;that&lt;/span&gt; &lt;span class="err"&gt;retains&lt;/span&gt; &lt;span class="err"&gt;only&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;essential&lt;/span&gt; &lt;span class="err"&gt;information.&lt;/span&gt;
&lt;span class="err"&gt;2.&lt;/span&gt;  &lt;span class="err"&gt;Automatic&lt;/span&gt; &lt;span class="err"&gt;Command&lt;/span&gt; &lt;span class="err"&gt;Rewriting&lt;/span&gt; &lt;span class="err"&gt;(Hooks):&lt;/span&gt;
    &lt;span class="err"&gt;The&lt;/span&gt; &lt;span class="err"&gt;most&lt;/span&gt; &lt;span class="err"&gt;powerful&lt;/span&gt; &lt;span class="err"&gt;feature&lt;/span&gt; &lt;span class="err"&gt;is&lt;/span&gt; &lt;span class="err"&gt;its&lt;/span&gt; &lt;span class="err"&gt;integration&lt;/span&gt; &lt;span class="err"&gt;with&lt;/span&gt; &lt;span class="err"&gt;AI&lt;/span&gt; &lt;span class="err"&gt;agents.&lt;/span&gt; &lt;span class="err"&gt;When&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;run&lt;/span&gt; &lt;span class="err"&gt;rtk&lt;/span&gt; &lt;span class="err"&gt;init&lt;/span&gt; &lt;span class="err"&gt;-g,&lt;/span&gt; &lt;span class="err"&gt;it&lt;/span&gt; &lt;span class="err"&gt;installs&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;"hook"&lt;/span&gt; &lt;span class="err"&gt;into&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;AI&lt;/span&gt; &lt;span class="err"&gt;tool&lt;/span&gt; &lt;span class="err"&gt;(like&lt;/span&gt; &lt;span class="err"&gt;Claude&lt;/span&gt; &lt;span class="err"&gt;Code).&lt;/span&gt; &lt;span class="err"&gt;This&lt;/span&gt; &lt;span class="err"&gt;hook&lt;/span&gt; &lt;span class="err"&gt;intercepts&lt;/span&gt; &lt;span class="err"&gt;Bash&lt;/span&gt; &lt;span class="err"&gt;commands&lt;/span&gt; &lt;span class="err"&gt;before&lt;/span&gt; &lt;span class="err"&gt;they&lt;/span&gt; &lt;span class="err"&gt;are&lt;/span&gt; &lt;span class="err"&gt;executed&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;shell&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;transparently&lt;/span&gt; &lt;span class="err"&gt;rewrites&lt;/span&gt; &lt;span class="err"&gt;them.&lt;/span&gt;
    &lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;User&lt;/span&gt; &lt;span class="err"&gt;runs:&lt;/span&gt; &lt;span class="err"&gt;git&lt;/span&gt; &lt;span class="err"&gt;status&lt;/span&gt;
    &lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;Hook&lt;/span&gt; &lt;span class="err"&gt;intercepts&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;rewrites&lt;/span&gt; &lt;span class="err"&gt;to:&lt;/span&gt; &lt;span class="err"&gt;rtk&lt;/span&gt; &lt;span class="err"&gt;git&lt;/span&gt; &lt;span class="err"&gt;status&lt;/span&gt;
    &lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;Result:&lt;/span&gt; &lt;span class="err"&gt;The&lt;/span&gt; &lt;span class="err"&gt;AI&lt;/span&gt; &lt;span class="err"&gt;receives&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;compact&lt;/span&gt; &lt;span class="err"&gt;output&lt;/span&gt; &lt;span class="err"&gt;without&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;ever&lt;/span&gt; &lt;span class="err"&gt;having&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;manually&lt;/span&gt; &lt;span class="err"&gt;type&lt;/span&gt; &lt;span class="err"&gt;rtk.&lt;/span&gt;
&lt;span class="err"&gt;3.&lt;/span&gt;  &lt;span class="err"&gt;TOML-based&lt;/span&gt; &lt;span class="err"&gt;Fallback&lt;/span&gt; &lt;span class="err"&gt;Filters:&lt;/span&gt;
    &lt;span class="err"&gt;For&lt;/span&gt; &lt;span class="err"&gt;commands&lt;/span&gt; &lt;span class="err"&gt;that&lt;/span&gt; &lt;span class="err"&gt;RTK&lt;/span&gt; &lt;span class="err"&gt;doesn't&lt;/span&gt; &lt;span class="err"&gt;have&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;built-in&lt;/span&gt; &lt;span class="err"&gt;module&lt;/span&gt; &lt;span class="err"&gt;for,&lt;/span&gt; &lt;span class="err"&gt;it&lt;/span&gt; &lt;span class="err"&gt;uses&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;fallback&lt;/span&gt; &lt;span class="err"&gt;system.&lt;/span&gt; &lt;span class="err"&gt;If&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;command&lt;/span&gt; &lt;span class="err"&gt;is&lt;/span&gt; &lt;span class="err"&gt;intercepted&lt;/span&gt; &lt;span class="err"&gt;but&lt;/span&gt; &lt;span class="err"&gt;not&lt;/span&gt; &lt;span class="err"&gt;recognized,&lt;/span&gt; &lt;span class="err"&gt;RTK&lt;/span&gt; &lt;span class="err"&gt;looks&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;matching&lt;/span&gt; &lt;span class="err"&gt;configuration&lt;/span&gt; &lt;span class="err"&gt;in&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;local&lt;/span&gt; &lt;span class="err"&gt;.rtk.toml&lt;/span&gt; &lt;span class="err"&gt;file.&lt;/span&gt; &lt;span class="err"&gt;This&lt;/span&gt; &lt;span class="err"&gt;allows&lt;/span&gt; &lt;span class="err"&gt;you&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;define&lt;/span&gt; &lt;span class="err"&gt;custom&lt;/span&gt; &lt;span class="err"&gt;regex-based&lt;/span&gt; &lt;span class="err"&gt;filtering,&lt;/span&gt; &lt;span class="err"&gt;grouping,&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;truncation&lt;/span&gt; &lt;span class="err"&gt;rules&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;any&lt;/span&gt; &lt;span class="err"&gt;tool.&lt;/span&gt;
&lt;span class="err"&gt;Core&lt;/span&gt; &lt;span class="err"&gt;Strategies&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;Token&lt;/span&gt; &lt;span class="err"&gt;Savings&lt;/span&gt;
&lt;span class="err"&gt;To&lt;/span&gt; &lt;span class="err"&gt;reduce&lt;/span&gt; &lt;span class="err"&gt;token&lt;/span&gt; &lt;span class="err"&gt;counts&lt;/span&gt; &lt;span class="err"&gt;by&lt;/span&gt; &lt;span class="err"&gt;60-90%,&lt;/span&gt; &lt;span class="err"&gt;RTK&lt;/span&gt; &lt;span class="err"&gt;applies&lt;/span&gt; &lt;span class="err"&gt;four&lt;/span&gt; &lt;span class="err"&gt;strategies&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;command&lt;/span&gt; &lt;span class="err"&gt;outputs:&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;Smart&lt;/span&gt; &lt;span class="err"&gt;Filtering:&lt;/span&gt; &lt;span class="err"&gt;Removes&lt;/span&gt; &lt;span class="err"&gt;"noise"&lt;/span&gt; &lt;span class="err"&gt;like&lt;/span&gt; &lt;span class="err"&gt;boilerplate&lt;/span&gt; &lt;span class="err"&gt;text,&lt;/span&gt; &lt;span class="err"&gt;comments,&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;excessive&lt;/span&gt; &lt;span class="err"&gt;whitespace.&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;Grouping:&lt;/span&gt; &lt;span class="err"&gt;Aggregates&lt;/span&gt; &lt;span class="err"&gt;similar&lt;/span&gt; &lt;span class="err"&gt;items&lt;/span&gt; &lt;span class="err"&gt;(e.g.,&lt;/span&gt; &lt;span class="err"&gt;grouping&lt;/span&gt; &lt;span class="err"&gt;multiple&lt;/span&gt; &lt;span class="err"&gt;file&lt;/span&gt; &lt;span class="err"&gt;errors&lt;/span&gt; &lt;span class="err"&gt;by&lt;/span&gt; &lt;span class="err"&gt;their&lt;/span&gt; &lt;span class="err"&gt;error&lt;/span&gt; &lt;span class="err"&gt;type&lt;/span&gt; &lt;span class="err"&gt;or&lt;/span&gt; &lt;span class="err"&gt;directory).&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;Truncation:&lt;/span&gt; &lt;span class="err"&gt;Keeps&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;most&lt;/span&gt; &lt;span class="err"&gt;relevant&lt;/span&gt; &lt;span class="err"&gt;context&lt;/span&gt; &lt;span class="err"&gt;(like&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;last&lt;/span&gt; &lt;span class="err"&gt;few&lt;/span&gt; &lt;span class="err"&gt;lines&lt;/span&gt; &lt;span class="err"&gt;of&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;long&lt;/span&gt; &lt;span class="err"&gt;log)&lt;/span&gt; &lt;span class="err"&gt;while&lt;/span&gt; &lt;span class="err"&gt;cutting&lt;/span&gt; &lt;span class="err"&gt;redundant&lt;/span&gt; &lt;span class="err"&gt;data.&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;Deduplication:&lt;/span&gt; &lt;span class="err"&gt;Collapses&lt;/span&gt; &lt;span class="err"&gt;repeated&lt;/span&gt; &lt;span class="err"&gt;log&lt;/span&gt; &lt;span class="err"&gt;lines&lt;/span&gt; &lt;span class="err"&gt;into&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;single&lt;/span&gt; &lt;span class="err"&gt;line&lt;/span&gt; &lt;span class="err"&gt;with&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;count&lt;/span&gt; &lt;span class="err"&gt;(e.g.,&lt;/span&gt; &lt;span class="nn"&gt;[error]&lt;/span&gt; &lt;span class="err"&gt;...&lt;/span&gt; &lt;span class="err"&gt;(x42)).&lt;/span&gt;
&lt;span class="err"&gt;Key&lt;/span&gt; &lt;span class="err"&gt;Commands&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;rtk&lt;/span&gt; &lt;span class="err"&gt;init:&lt;/span&gt; &lt;span class="err"&gt;Sets&lt;/span&gt; &lt;span class="err"&gt;up&lt;/span&gt; &lt;span class="err"&gt;integration&lt;/span&gt; &lt;span class="err"&gt;for&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;specific&lt;/span&gt; &lt;span class="err"&gt;AI&lt;/span&gt; &lt;span class="err"&gt;agent.&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;rtk&lt;/span&gt; &lt;span class="err"&gt;gain:&lt;/span&gt; &lt;span class="err"&gt;Displays&lt;/span&gt; &lt;span class="err"&gt;your&lt;/span&gt; &lt;span class="err"&gt;token&lt;/span&gt; &lt;span class="err"&gt;savings&lt;/span&gt; &lt;span class="err"&gt;statistics&lt;/span&gt; &lt;span class="err"&gt;and&lt;/span&gt; &lt;span class="err"&gt;history.&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;rtk&lt;/span&gt; &lt;span class="err"&gt;proxy&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;cmd&amp;gt;:&lt;/span&gt; &lt;span class="err"&gt;Runs&lt;/span&gt; &lt;span class="err"&gt;a&lt;/span&gt; &lt;span class="err"&gt;command&lt;/span&gt; &lt;span class="err"&gt;exactly&lt;/span&gt; &lt;span class="err"&gt;as-is&lt;/span&gt; &lt;span class="err"&gt;but&lt;/span&gt; &lt;span class="err"&gt;still&lt;/span&gt; &lt;span class="err"&gt;tracks&lt;/span&gt; &lt;span class="err"&gt;the&lt;/span&gt; &lt;span class="err"&gt;usage&lt;/span&gt; &lt;span class="err"&gt;metrics.&lt;/span&gt;
&lt;span class="err"&gt;*&lt;/span&gt;   &lt;span class="err"&gt;rtk&lt;/span&gt; &lt;span class="err"&gt;read&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;file&amp;gt;:&lt;/span&gt; &lt;span class="err"&gt;A&lt;/span&gt; &lt;span class="err"&gt;smart&lt;/span&gt; &lt;span class="err"&gt;file&lt;/span&gt; &lt;span class="err"&gt;reader&lt;/span&gt; &lt;span class="err"&gt;that&lt;/span&gt; &lt;span class="err"&gt;can&lt;/span&gt; &lt;span class="err"&gt;provide&lt;/span&gt; &lt;span class="err"&gt;"aggressive"&lt;/span&gt; &lt;span class="err"&gt;summaries&lt;/span&gt; &lt;span class="err"&gt;(signatures&lt;/span&gt; &lt;span class="err"&gt;only)&lt;/span&gt; &lt;span class="err"&gt;to&lt;/span&gt; &lt;span class="err"&gt;save&lt;/span&gt; &lt;span class="err"&gt;tokens.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage, I understand a big picture how RTK can save token and it is written in Rust. But I still not have a clear understand how exactly does it help to save token. Then I want to add it to give me detail example so I can understand clearer. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;Give me detail example of output so I understand why rtk save tokens.&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="n"&gt;rtk&lt;/span&gt; &lt;span class="n"&gt;saves&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;removing&lt;/span&gt; &lt;span class="s"&gt;"noise"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boilerplate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;repetitive&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;large&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;preserving&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="s"&gt;"signal"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="n"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;structure&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;that&lt;/span&gt; &lt;span class="n"&gt;an&lt;/span&gt; &lt;span class="n"&gt;LLM&lt;/span&gt; &lt;span class="n"&gt;needs&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;solve&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="py"&gt;.
Here&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;detailed&lt;/span&gt; &lt;span class="n"&gt;examples&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;how&lt;/span&gt; &lt;span class="n"&gt;different&lt;/span&gt; &lt;span class="n"&gt;strategies&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="mf"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Smart&lt;/span&gt; &lt;span class="nf"&gt;Filtering&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Noise&lt;/span&gt; &lt;span class="n"&gt;Removal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Remove&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;repetitive&lt;/span&gt; &lt;span class="n"&gt;paths&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt; &lt;span class="n"&gt;listings&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;Raw&lt;/span&gt; &lt;span class="n"&gt;ls&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nf"&gt;la&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;800&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;drwxr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;xr&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;  &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;staff&lt;/span&gt; &lt;span class="mi"&gt;480&lt;/span&gt; &lt;span class="n"&gt;Jan&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;staff&lt;/span&gt; &lt;span class="mi"&gt;1234&lt;/span&gt; &lt;span class="n"&gt;Jan&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;staff&lt;/span&gt; &lt;span class="mi"&gt;567&lt;/span&gt; &lt;span class="n"&gt;Jan&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;--&lt;/span&gt;   &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;staff&lt;/span&gt; &lt;span class="mi"&gt;234&lt;/span&gt; &lt;span class="n"&gt;Jan&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;40&lt;/span&gt; &lt;span class="n"&gt;more&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;metadata&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;rtk&lt;/span&gt; &lt;span class="nf"&gt;ls&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;my&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;project&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
    &lt;span class="o"&gt;+--&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+--&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+--&lt;/span&gt; &lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="p"&gt;|&lt;/span&gt;   &lt;span class="o"&gt;+--&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="o"&gt;+--&lt;/span&gt; &lt;span class="n"&gt;Cargo&lt;/span&gt;&lt;span class="py"&gt;.toml&lt;/span&gt;
    &lt;span class="o"&gt;+--&lt;/span&gt; &lt;span class="n"&gt;README&lt;/span&gt;&lt;span class="py"&gt;.md&lt;/span&gt;

&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="mf"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Aggressive&lt;/span&gt; &lt;span class="n"&gt;Signature&lt;/span&gt; &lt;span class="n"&gt;Extraction&lt;/span&gt;
&lt;span class="n"&gt;Goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;When&lt;/span&gt; &lt;span class="n"&gt;reading&lt;/span&gt; &lt;span class="n"&gt;large&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;show&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="s"&gt;"skeleton"&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;function&lt;/span&gt; &lt;span class="n"&gt;signatures&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;instead&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;full&lt;/span&gt; &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;Raw&lt;/span&gt; &lt;span class="n"&gt;cat&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="nf"&gt;.rs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(())&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c1"&gt;// ... 190 lines of complex logic ...&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;rtk&lt;/span&gt; &lt;span class="n"&gt;read&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="nf"&gt;aggressive&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;process_data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u8&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;Config&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="mf"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Deduplication&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;Grouping&lt;/span&gt;
&lt;span class="n"&gt;Goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Merge&lt;/span&gt; &lt;span class="n"&gt;thousands&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;repetitive&lt;/span&gt; &lt;span class="n"&gt;logs&lt;/span&gt; &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt; &lt;span class="n"&gt;reports&lt;/span&gt; &lt;span class="n"&gt;into&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="n"&gt;summary&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;Raw&lt;/span&gt; &lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;running&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;
    &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;test_parse&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;
    &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;test_format&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt;
    &lt;span class="n"&gt;test&lt;/span&gt; &lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;test_edge_case&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="n"&gt;FAILED&lt;/span&gt;
    &lt;span class="n"&gt;thread&lt;/span&gt; &lt;span class="nv"&gt;'utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;test_edge_case&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt; &lt;span class="n"&gt;panicked&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="nv"&gt;'assertion&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;left&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;right&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;
      &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;huge&lt;/span&gt; &lt;span class="n"&gt;backtrace&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;environment&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;repetitive&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;rtk&lt;/span&gt; &lt;span class="n"&gt;cargo&lt;/span&gt; &lt;span class="nf"&gt;test&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;FAILED&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="n"&gt;tests&lt;/span&gt;
    &lt;span class="n"&gt;test_edge_case&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;assertion&lt;/span&gt; &lt;span class="n"&gt;failed&lt;/span&gt;
    &lt;span class="n"&gt;test_overflow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;panic&lt;/span&gt; &lt;span class="n"&gt;at&lt;/span&gt; &lt;span class="n"&gt;utils&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;18&lt;/span&gt;

&lt;span class="o"&gt;---&lt;/span&gt;
&lt;span class="mf"&gt;4.&lt;/span&gt; &lt;span class="nf"&gt;Truncation&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;Condensing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;Goal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Simplify&lt;/span&gt; &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="n"&gt;outputs&lt;/span&gt; &lt;span class="n"&gt;by&lt;/span&gt; &lt;span class="n"&gt;removing&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;focusing&lt;/span&gt; &lt;span class="n"&gt;only&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;changed&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;Raw&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="nf"&gt;diff&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;000&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;diff&lt;/span&gt; &lt;span class="o"&gt;--&lt;/span&gt;&lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="n"&gt;abc123&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;def456&lt;/span&gt; &lt;span class="mi"&gt;100644&lt;/span&gt;
    &lt;span class="o"&gt;---&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="o"&gt;+++&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="py"&gt;.rs&lt;/span&gt;
    &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt;
     &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt;    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.validate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
         &lt;span class="nd"&gt;println!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Starting..."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;*&lt;/span&gt;   &lt;span class="n"&gt;rtk&lt;/span&gt; &lt;span class="n"&gt;git&lt;/span&gt; &lt;span class="nf"&gt;diff&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;~&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt; &lt;span class="n"&gt;tokens&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="nf"&gt;.rs&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;/-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt;  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;load&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;+&lt;/span&gt;  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="nf"&gt;.validate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;-&lt;/span&gt;  &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice, now I understand how does it work. I can start to tweak that for my need, start to contribute if I want. Honestly speaking, it will save you a lot of money for spending to read project. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;After this experiment, my answer is: yes, Gemma 4 can be a useful local coding agent with OpenCode — but it works best when I treat it as a coding partner, not as a fully autonomous developer.&lt;/p&gt;

&lt;p&gt;The strongest part of Gemma 4 was codebase understanding. It correctly inspected my Laravel + React project, identified the stack, found where controllers and tests should live, and explained that the project was still a fresh boilerplate. That is already very useful. When I tried it on the RTK open source repository, it also gave me a clear high-level explanation of how the project works and then followed up with practical examples. For learning a new codebase, this is where Gemma 4 impressed me the most.&lt;/p&gt;

&lt;p&gt;For implementation, the result was more mixed. It successfully planned and built a fitness application with authentication, a landing page, contact form, and dashboard. It also installed and configured Laravel Breeze correctly. However, the first implementation was not perfect. There were issues with file naming, Inertia page resolution, styling, and missing user feedback after submitting the contact form. The good part is that when I asked Gemma 4 to debug those problems, it was able to inspect the project, understand the issue, and fix it.&lt;/p&gt;

&lt;p&gt;Testing was also useful, but not perfect. It could use Playwright to test login, dashboard, profile, and contact form flows. However, it missed the landing page until I explicitly asked it to test that page and responsiveness. This taught me an important lesson: local coding agents can test applications, but the quality of the result depends a lot on how specific the prompt is.&lt;/p&gt;

&lt;p&gt;My biggest takeaway is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Gemma 4 + OpenCode is very good at understanding, investigating, explaining, and fixing code. It is also capable of implementing real features, but the output still needs human review, UI polish, and follow-up debugging.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This experiment changed how I think about local AI coding. Before trying it, I thought local models were mainly interesting for privacy. After using Gemma 4 with OpenCode, I think local models are also interesting for developer productivity.&lt;/p&gt;

&lt;p&gt;A local coding agent does not need to replace cloud tools completely to be valuable. Even if it only helps me understand a codebase, debug an issue, test a page, or prepare a first implementation draft, that already saves time.&lt;/p&gt;

&lt;p&gt;So my final verdict is simple:&lt;/p&gt;

&lt;p&gt;Gemma 4 did not replace me as a developer. But with OpenCode, it became a practical local coding assistant that can understand projects, implement features, debug issues, test pages, and explain unfamiliar repositories. It still needs guidance, but for an open model running locally, the result is impressive.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>Hermes agent: Connect to Discord</title>
      <dc:creator>Phú</dc:creator>
      <pubDate>Tue, 12 May 2026 00:13:44 +0000</pubDate>
      <link>https://dev.to/lkp/hermes-agent-connect-to-discord-2p95</link>
      <guid>https://dev.to/lkp/hermes-agent-connect-to-discord-2p95</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In last post, we already find out how to setup and connect Hermes Agent to Telegram. Today, we find out how to connect that to discord. &lt;/p&gt;

&lt;h1&gt;
  
  
  Flow
&lt;/h1&gt;

&lt;p&gt;First of all, you need to create bot in Discord. After that, you setup gateway to use this Discord bot. Then you start gateway. After that, you can chat with your agent through Discord. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8xfjld09vc8qmueuf9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8xfjld09vc8qmueuf9i.png" alt="Discord gateway flow" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Create Discord Bot
&lt;/h1&gt;

&lt;p&gt;Go to this &lt;a href="https://discord.com/developers/home" rel="noopener noreferrer"&gt;Discord developer portal&lt;/a&gt; with your account. Then go to applications on the left menu side bar. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9d26h1fbxji5cvekhyt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw9d26h1fbxji5cvekhyt.png" alt="Create application" width="800" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then type your bot name. Click agree then click "Create" button. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95wy28ule43yvsz85g1i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95wy28ule43yvsz85g1i.png" alt="Create application form" width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, you see it like this &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw359ct2k0nxfa2u4p7em.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw359ct2k0nxfa2u4p7em.png" alt="Application Dashboard" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then go to Bot item on the left. It has section call "Reset Token", click to this button to get Reset Token. Then you go to hermes, run command &lt;code&gt;hermes gateway setup&lt;/code&gt;, then choose &lt;code&gt;Discord&lt;/code&gt;. Next, it will ask for bot token, paste your &lt;code&gt;Reset Token&lt;/code&gt; in here. Then go back to Discord Portal, we continue to setup bot. In left menu, choose OAuth2, scroll to bottom. Find and check Bot checkbox. Then it will show another section name "Bot Permissions", choose permission you want your bot to have. In here, I choose Send Message for Text Permission.Then choose copy Generated URL, then open new tab and paste it to url. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhiwlii1pira65ys9axu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhiwlii1pira65ys9axu3.png" alt=" " width="800" height="911"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15o7wm8sm55osbajs8ib.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F15o7wm8sm55osbajs8ib.png" alt=" " width="789" height="743"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click continue. Then go back to hermes to finish setup gateway. It show you like this &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16hwd8oevwg4wzr9996m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16hwd8oevwg4wzr9996m.png" alt=" " width="800" height="148"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you choose what you need. In this case, I just let it Enable open access. Then we can start to talk with agent on this channel. This is an example. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq6o46x1yjwpe6hgg9rp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkq6o46x1yjwpe6hgg9rp.png" alt=" " width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Playaround with Agent
&lt;/h1&gt;
&lt;h2&gt;
  
  
  Generate Image
&lt;/h2&gt;

&lt;p&gt;Since I use Minimax model so it can generate image as well. I ask it to create minimax gen image skill, then ask it to use that image to gen image for me. Quite nice. I notice that, even I do not ask it to create generate image skill, it will auto create if I ask it to generate image use Minimax. After many try, it start to automatically create skill for this repeated tasks. That's why it call that it is an agent that grow with you. Another part that it has memory so it can remember what you say. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0pt4dqdshoznvidlh84.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn0pt4dqdshoznvidlh84.png" alt=" " width="800" height="998"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Generate Music
&lt;/h2&gt;

&lt;p&gt;Another case that I want to generate music, then I ask my agent to do that. Just simple prompt like this. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3t1qnjv1zi83llhhw341.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3t1qnjv1zi83llhhw341.png" alt=" " width="800" height="752"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the end, it can figure out and produce me this one. Quite chill.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5eq4zrs6vy4nubj2ae9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5eq4zrs6vy4nubj2ae9.png" alt=" " width="800" height="546"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Speak
&lt;/h2&gt;

&lt;p&gt;Another use case is that, I ask my agent and it answer me by using TTS. So instead of show me text, it generate that to audio and play that to answer. So I do not to read, only need to hear. To have this, you only need to choose TTS. In Discord, use this command &lt;code&gt;/voice&lt;/code&gt; in channel you want it to answer you with audio. Then choose &lt;code&gt;tts&lt;/code&gt; option. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7y0o4353gyl66j9340i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff7y0o4353gyl66j9340i.png" alt=" " width="800" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my case, I choose to use Minimax TTS since I have subscription of it. However, I want to do this in another level that I can go to voice, then I can talk to it in realtime. &lt;/p&gt;

&lt;p&gt;First of all, you need to go back to OAuth2. Then check these item in Bot Permissions. Then copy &lt;code&gt;Generated URL&lt;/code&gt; and paste to new tab again. Choose your channel so bot can join that channel. Next, you join to voice channel on the left, in this case, I join general channel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0d6dyr5z6epjyn8psj19.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0d6dyr5z6epjyn8psj19.png" alt=" " width="800" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6rgwdddf5aycsjpn1y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6rgwdddf5aycsjpn1y8.png" alt=" " width="312" height="89"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you join, in channel, you type &lt;code&gt;voice&lt;/code&gt;. Then choose channel and type your Voice channel name. Bot will join your voice channel. And now you can start to talk with it. This is my demo. It is super slow. However, at least, now I can talk to my bot directly. If change to use another TTS like like Elevenlabs, surely it will be much faster and more natural. However, to really answer in realtime, we need to have streaming which Hermes agent does not have currently. Maybe, I will try to implement that someday and show you. I already can do that with GPT realtime voice 2.0. However, to make it work in Hermes agent, need to have extra step.  &lt;/p&gt;


&lt;div&gt;
    &lt;iframe src="https://www.youtube.com/embed/KRfkPh3xKqA"&gt;
    &lt;/iframe&gt;
  &lt;/div&gt;


&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That's all for today. Hope you guys enjoy this article. Any question, please comment below. See you next time.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>api</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Hermes agent: Introduction</title>
      <dc:creator>Phú</dc:creator>
      <pubDate>Sun, 26 Apr 2026 02:37:22 +0000</pubDate>
      <link>https://dev.to/lkp/hermes-agent-introduction-c38</link>
      <guid>https://dev.to/lkp/hermes-agent-introduction-c38</guid>
      <description>&lt;h1&gt;
  
  
  Concept
&lt;/h1&gt;

&lt;p&gt;"Hermes Agent" is an open-source AI agent developed by Nous Research. It is described as an agent that runs continuously on your server, has long-term memory, can learn over time, connects to many chat platforms/tools, and supports browser automation. The project is released under the MIT license.&lt;/p&gt;

&lt;p&gt;Typically, this AI agent is meant to work as a real assistant. It can do more than just answer messages or connect to third-party services for information. It can manage your machine and even help deploy a web app, for example. It also has long-term memory to remember your habits and notes. In parallel, it can self-learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you repeat the same kind of task, it can proactively create a reusable skill so you do not need to manually re-derive the same steps every time.&lt;/li&gt;
&lt;li&gt;This reduces token usage for similar or repetitive work.&lt;/li&gt;
&lt;li&gt;It supports multiple gateways to mobile-friendly chat apps like Telegram and Discord, so you can operate your AI agent and machine from your phone.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Installation
&lt;/h1&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scripts/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then refresh your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc    &lt;span class="c"&gt;# reload shell (or: source ~/.zshrc)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, &lt;code&gt;hermes&lt;/code&gt; command is available in your terminal. Next, you need to run &lt;code&gt;hermes setup&lt;/code&gt; to setup LLM for your hermes. You can choose quick setup or full setup up to you. In here, I choose quick setup to setup LLM only. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6e2k1ewwz19ndro71yk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6e2k1ewwz19ndro71yk.png" alt="Setup" width="729" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am using Minimax global, so I choose this option. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9c75rjjde8djfhmblrq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9c75rjjde8djfhmblrq.png" alt="Choose provider" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then it asks me to pass my api key:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6ivrc30ahqlvejoni6q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr6ivrc30ahqlvejoni6q.png" alt="Pass api key" width="800" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, you need to choose model. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgafsztkrdc6ng69v4pn5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgafsztkrdc6ng69v4pn5.png" alt="Choose models" width="532" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, it asks to setup messaging platform or not. In this case, we skip this step. I will guide you to setup gateway later in this post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzyf01gjqvhihuwpvaqg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqzyf01gjqvhihuwpvaqg.png" alt=" " width="618" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then test with &lt;code&gt;hermes&lt;/code&gt;. If you see the expected prompt, the agent is installed successfully.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmuc6p9fy2ouzp3nrud8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmuc6p9fy2ouzp3nrud8.png" alt="Hermes Agent installed" width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try asking what it is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvobpkm6dc9jgs0tvufvq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvobpkm6dc9jgs0tvufvq.png" alt="Prompt asking identity" width="800" height="214"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  SOUL.md
&lt;/h1&gt;

&lt;p&gt;When using AI, we usually define a &lt;strong&gt;system prompt&lt;/strong&gt; so the model knows who it is and what it should do. This helps it stay focused on a specific type of work. For example, without a system prompt, if you ask for a simple "Hello World" program, the model may choose a language it is most familiar with. If you want it to always respond in a specific language, it may not comply consistently.&lt;/p&gt;

&lt;p&gt;A system prompt is a way to standardize this behavior across sessions. If you want it to act as a PHP expert, you can include:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You are an expert in PHP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then every prompt will be interpreted in that context, and the model will try to answer with PHP-oriented decisions and knowledge.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcamfd010qrhmx6c78b2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcamfd010qrhmx6c78b2l.png" alt="System Prompt" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In Hermes Agent, there is &lt;strong&gt;&lt;code&gt;SOUL.md&lt;/code&gt;&lt;/strong&gt;, which plays a role similar to a system prompt. To optimize usage, set up &lt;code&gt;SOUL.md&lt;/code&gt; for the agent. By default it is located at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/.hermes/SOUL.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzz1thqtbhs7gwz5b1zmr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzz1thqtbhs7gwz5b1zmr.png" alt="Update SOUL.md" width="795" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I changed it to:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqj7sjbpqbtlcl2zv140u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqj7sjbpqbtlcl2zv140u.png" alt="Result" width="800" height="29"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After that, asking in that session, it now behaves as a PHP expert.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwz6exiobc4gq4rvnrxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwz6exiobc4gq4rvnrxk.png" alt="Workspace session behavior" width="800" height="207"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Session
&lt;/h1&gt;

&lt;p&gt;At this point, I asked myself: why make it this complex? If I keep one session and ask questions from start to finish, it remembers previous context. Why bother with system prompts? Also, nobody has time to create a new session all the time.&lt;/p&gt;

&lt;p&gt;That can work initially: if you define the role in the first prompt, by prompt 100 it may still remember. But over time, behavior can degrade. When you cover too many topics in one long session, the model may become confused.&lt;/p&gt;

&lt;p&gt;Example: you work in &lt;code&gt;workspace1&lt;/code&gt;, ask it to save output to &lt;code&gt;result&lt;/code&gt;, then later switch to &lt;code&gt;workspace2&lt;/code&gt;. If you later ask again to save to &lt;code&gt;result&lt;/code&gt;, it may default to &lt;code&gt;workspace2/result&lt;/code&gt; because it inferred the active context changed. If you use two separate sessions, session 1 for &lt;code&gt;workspace1&lt;/code&gt; and session 2 for &lt;code&gt;workspace2&lt;/code&gt;, the same command will correctly map to each workspace.&lt;/p&gt;

&lt;p&gt;When working longer, the model also has a finite context window:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0yd2eb00py3nkdh2nx9d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0yd2eb00py3nkdh2nx9d.png" alt="Context window" width="663" height="43"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That status bar shows the model is &lt;code&gt;minimax 2.7 highspeed&lt;/code&gt; with a context window of &lt;code&gt;204.8k&lt;/code&gt;. Every user prompt and model reply consumes part of that budget. The post shows one question-and-answer pair consuming about &lt;code&gt;11.7k&lt;/code&gt; tokens.&lt;/p&gt;

&lt;p&gt;As history grows beyond the window limit, the model compresses previous context. For example, when at around &lt;code&gt;200k&lt;/code&gt; tokens it may summarize context down to about &lt;code&gt;10k&lt;/code&gt; tokens. You can then continue with the summary, but the compressed memory loses detail. Some earlier details may no longer be present.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2om6ll1uuex5raxug1as.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2om6ll1uuex5raxug1as.png" alt="Context window compress" width="800" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That is why it is useful to keep a system prompt and open a fresh session for different tasks. You can start a new session using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/new
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folfibf2f9hkq0f16m95v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Folfibf2f9hkq0f16m95v.png" alt=" " width="641" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Prompt
&lt;/h1&gt;

&lt;p&gt;This is the prompt area used to communicate with the AI. This is where you issue commands or requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkph94o6x9o2xc0f74q2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frkph94o6x9o2xc0f74q2.png" alt=" " width="800" height="66"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example I asked it to summarize a YouTube video. Hermes Agent shows each step it performs, such as invoking a skill and opening the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53kz2umj5t3lduqgqh0g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53kz2umj5t3lduqgqh0g.png" alt=" " width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this is the result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fud24ucalf3h2606fj0s0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fud24ucalf3h2606fj0s0.png" alt=" " width="800" height="293"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Gateway
&lt;/h1&gt;

&lt;p&gt;If you want to use your AI agent through chat apps (for example Telegram or Discord), either for team use or for personal use, set up a gateway.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqamc4eyz9aczseqw50pe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqamc4eyz9aczseqw50pe.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I used Telegram as an example. First, use Telegram BotFather to create a bot. It gives you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a bot access handle (to open your bot)&lt;/li&gt;
&lt;li&gt;the bot token&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrt6u8al3s14eateg8y2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzrt6u8al3s14eateg8y2.png" alt=" " width="654" height="699"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hermes gateway setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then choose the Telegram gateway, paste the bot token into &lt;code&gt;bot token&lt;/code&gt;, and set &lt;code&gt;allow user id&lt;/code&gt; using &lt;code&gt;@userinfobot&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa145mlrgniqzf1ox2l4h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa145mlrgniqzf1ox2l4h.png" alt=" " width="772" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kxb8qjd65v0dq8m6u1r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0kxb8qjd65v0dq8m6u1r.png" alt=" " width="800" height="562"&gt;&lt;/a&gt;&lt;br&gt;
If your team should all be able to chat with the bot, enable &lt;strong&gt;open access&lt;/strong&gt;. If you want manual approval first, use &lt;strong&gt;Use DM pairing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrpj9deodn0srvd8u5ym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrpj9deodn0srvd8u5ym.png" alt=" " width="628" height="473"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this step, you can choose open access to allow any user in this channel can chat with hermes agent. Otherwise, you choose pairing dm. This one, you can approve which message bot will answer, which one it will not answer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53zhce359tgk13uaf4sc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53zhce359tgk13uaf4sc.png" alt=" " width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For gateway mode:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Option 1: manual mode. You run &lt;code&gt;hermes gateway start&lt;/code&gt; each time.&lt;/li&gt;
&lt;li&gt;Option 2: service mode. The gateway runs automatically as a background service.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr5jmpcx9e48u2hzwyhd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr5jmpcx9e48u2hzwyhd.png" alt=" " width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test it by running the same brief video task, this time via Telegram.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5mqqqh3xv2j9z6aqfwq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft5mqqqh3xv2j9z6aqfwq.png" alt=" " width="749" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flihnosoc28vvdahvd7qv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flihnosoc28vvdahvd7qv.png" alt=" " width="744" height="962"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;That’s a brief first look. The next post &lt;a href="https://dev.to/lkp/hermes-agent-connect-to-discord-2p95"&gt;Connect Hermes Agent to Discord&lt;/a&gt;, I will show you how to connect to Discord. If you need help, leave a comment.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>bot</category>
    </item>
    <item>
      <title>Nextjs: Introduction</title>
      <dc:creator>Phú</dc:creator>
      <pubDate>Thu, 02 Feb 2023 01:41:03 +0000</pubDate>
      <link>https://dev.to/lkp/nextjs-introduction-hej</link>
      <guid>https://dev.to/lkp/nextjs-introduction-hej</guid>
      <description>&lt;h2&gt;
  
  
  What is Nextjs?
&lt;/h2&gt;

&lt;p&gt;Acorrding to the official documentation, Next.js is a flexible React framework that gives you building blocks to create fast web applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Nextjs?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Difference rendering techniques
&lt;/h3&gt;

&lt;p&gt;Server Side Rendering is technique when you want to get new data from server, client will pass necessary params to server and get the whole html from server. With this approach, our app is not reactive. When you search something, filter something, click something, it will reload the whole html. It is not very friendly when you have a lot of data and user need to spend time to look at blank screen while your site is loading data. But it is good for SEO cause it always return html and google bot know what is your site about. &lt;/p&gt;

&lt;p&gt;Client Side Rendering is technique when you pass params to server from client, you will get data in json format from server. For that reason, you will save your bandwidth, your page will load faster and it will be more reactive. Nowadays, good frameworks like React, Vue, Angular do these things really well. It also handle or at least, give you a tool or a clear guide transpile to work with old browser, bundling, minifying, splitting. It will make your app faster and more compatible. However, big disadvantage in this approach is that it is hard to SEO. Why? When you load a page, in React case, you only have an html element with id is root, after that React will handle to render the rest. And google bot just see the html element before React render the rest so it only see your page have an html element with id is root. For that reason, it have no idea what is your site about and lower your page rank.&lt;/p&gt;

&lt;p&gt;Static Site Generation is technique to generate html file in build time. For example, you finish to implement your about page, you build your project, it will generate html file of about page and store in your project. So when user want to view your about page, the site will return that file instead of calling data from server. Then, it will much faster. It is very good if you don't have many changes for your page. Like about page, login page, landing page,... you won't often change or don't often have a new data so these pages is good to use SSG. &lt;/p&gt;

&lt;p&gt;Usually, you don't have all these technique in your application cause no framework support all these rendering technique yet until Nextjs. Before Nextjs, if you want SSR, you may go with pure PHP, Laravel + Blade or Symfony + Twig. If you want CSR, definitely go with React, Vue or Angular and SSG will a place where you want to use gatsby. In Nextjs, you can choose the rendering technique you want. Thus, you can have page A with SSR, page B with CSR, page C with SSG. How cool is that?&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;p&gt;To boost your site faster, you need to care about many things like code splitting, minifying files, image optimaztion, the way to get assets and many more. Thankfully, with Nextjs, you don't need to care much about this. If you use correct component which are provide by Nextjs, it will do all the heavy job for you. Small example is that when you have an image on your site, you need to take care very 2 basic things. First of all, you need to have difference size of that image for difference viewport. Secondly, you want your page only load that image when user near to it, so you will have very long page and of course, you don't want to load image at the end of that page where user don't see it when the page is loaded. When user scroll down near to the end, that image will be load. Therefore, to solve these two problems, you need add srcset and apply lazy load to your image. With simple component &lt;code&gt;Image&lt;/code&gt;, it handle these two things automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  Routing
&lt;/h3&gt;

&lt;p&gt;In Nextjs, it route base on file. In my opinion, it is more friendly for routing base on file. In case I want to find component for route &lt;code&gt;/posts/&lt;/code&gt;, I can easily know that I need to go to index file in posts folder. No need to go to see which component is used for that route.&lt;/p&gt;

&lt;h3&gt;
  
  
  SEO
&lt;/h3&gt;

&lt;p&gt;Nextjs provide a Head component. With this component, you can always add description, title, meta tag on header in Nextjs. For that reason, it will be better for SEO.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That's is a short introduction to nextjs. In recap, it provides us many ways to render page, help we improve performance, routing base on file, provide us a way to SEO and much more.&lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>web3</category>
      <category>blockchain</category>
    </item>
    <item>
      <title>Multiple authentication in Laravel 9</title>
      <dc:creator>Phú</dc:creator>
      <pubDate>Mon, 16 Jan 2023 01:46:52 +0000</pubDate>
      <link>https://dev.to/lkp/multiple-authentication-in-laravel-9-2mfk</link>
      <guid>https://dev.to/lkp/multiple-authentication-in-laravel-9-2mfk</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;In a basic web app, we usually have two parts, app and cms. App is for user to use and cms for staff to manage content in that system. So to design this web app, we need to have a role. User with role admin can access cms site and user without role admin cannot access cms. But what if you want to use 2 difference models for security, for performance? How can we authenticate with 2 difference models?&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduce app
&lt;/h2&gt;

&lt;p&gt;This is a web app have two parts, app and CMS. Model Staff can only access CMS part and model User can only access app part. Since Laravel have default guard authentication for User model, we will discuss more about Staff model&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure guard
&lt;/h2&gt;

&lt;p&gt;First of all, you need to add new guard to existing guard in &lt;code&gt;config/auth.php&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   'guards' =&amp;gt; [
        ...
        'staff' =&amp;gt; [
            'driver' =&amp;gt; 'session',
            'provider' =&amp;gt; 'staffs',
        ],
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this configuration, I add new guard name &lt;strong&gt;staff&lt;/strong&gt;, this guard use driver is session and provider name staffs. Currently, we do not have any provider name staffs, so let's define it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    'providers' =&amp;gt; [
        ...
        'staffs' =&amp;gt; [
            'driver' =&amp;gt; 'eloquent',
            'model' =&amp;gt; App\Models\Staff::class,
        ],
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this definition, we define provider name staffs using driver eloquent and model we want to use is &lt;code&gt;App\Models\Staff&lt;/code&gt;. Last but not least, we need to configure password part so we can reset password with Staff model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    'passwords' =&amp;gt; [
        ...
        'staffs' =&amp;gt; [
            'provider' =&amp;gt; 'staffs',
            'table' =&amp;gt; 'staff_password_resets',
            'expire' =&amp;gt; 60,
            'throttle' =&amp;gt; 60,
        ],
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is quite simple. We use provider name staffs, table is staff_password_resets, expire and throttle is 60 minutes. Since we use staff_password_resets to reset password then remember to migrate it. &lt;/p&gt;

&lt;h2&gt;
  
  
  Ensure
&lt;/h2&gt;

&lt;p&gt;After configuration, we need to ensure these things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Migrate table for reset password
It will look like this one:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public function up()
    {
        Schema::create('staff_password_resets', function (Blueprint $table) {
            $table-&amp;gt;string('email')-&amp;gt;index();
            $table-&amp;gt;string('token');
            $table-&amp;gt;timestamp('created_at')-&amp;gt;nullable();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('staff_password_resets');
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Have Staff model
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?php

namespace App\Models;

// use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;

class Staff extends Authenticatable
{
    use HasApiTo   'guards' =&amp;gt; [
        ...
        'staff' =&amp;gt; [
            'driver' =&amp;gt; 'session',
            'provider' =&amp;gt; 'staffs',
        ],
    ],kens, HasFactory, Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array&amp;lt;int, string&amp;gt;
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for serialization.
     *
     * @var array&amp;lt;int, string&amp;gt;
     */
    protected $hidden = [
        'password',
        'remember_token',
    ];

    /**
     * The attributes that should be cast.
     *
     * @var array&amp;lt;string, string&amp;gt;
     */
    protected $casts = [
        'email_verified_at' =&amp;gt; 'datetime',
    ];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Have data in table&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zjpgyqtmm1j017f0uda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zjpgyqtmm1j017f0uda.png" alt="Data in Staff table" width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Use new guard
&lt;/h2&gt;

&lt;p&gt;Let's try out new guard. In login logic, you will have code like this:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
Auth::attempt($this-&amp;gt;only('email', 'password'), $this-&amp;gt;boolean('remember'))&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
This one will not work because it will use default guard which is user guard. If we want to use new guard, we need to explicitly use it. Change it to this:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
Auth::guard('staff)-&amp;gt;attempt($this-&amp;gt;only('email', 'password'), $this-&amp;gt;boolean('remember'))&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
So this one tell Laravel to use guard name staff instead of default. Try to login and check the session, you will see that we login successfully and have a session. However, we cannot go to page which ask for authentication. Why? Cause in these pages, we still not use new guard yet. This is my route:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('/dashboard', function () {
    return view('dashboard');
})-&amp;gt;middleware(['auth', 'verified'])-&amp;gt;name('dashboard');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a look at &lt;code&gt;middleware(['auth', 'verified'])&lt;/code&gt;. It will go to auth and verified middlewar before run callback in Route::get. Verified middleware simply check verified_at colume in table is null or not and auth middleware check that user is authenticated or not. Cause we just use auth middleware then again, it use default guard which is user guard. We need to tell it to use staff guard by passing parameter to middleware. Change it to this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('/dashboard', function () {
    return view('dashboard');
})-&amp;gt;middleware(['auth:staff', 'verified'])-&amp;gt;name('dashboard');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we change to use auth middleware with staff guard instead of user guard. Then try to login again and you can access &lt;code&gt;/dashboard&lt;/code&gt; route:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxmii0wuj8moegbrpglv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpxmii0wuj8moegbrpglv.png" alt="Dashboard after login" width="800" height="176"&gt;&lt;/a&gt;&lt;br&gt;
Perfection. You rock.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing
&lt;/h2&gt;

&lt;p&gt;Lastly, we need to test to make sure that user in User table cannot use their data to login to &lt;code&gt;/dashboard&lt;/code&gt;. This is user in User table:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpb117vgndts953k93ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkpb117vgndts953k93ln.png" alt="User in User table" width="800" height="152"&gt;&lt;/a&gt;&lt;br&gt;
Try to login using this credential:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6gioim0buecb9gl3exe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fn6gioim0buecb9gl3exe.png" alt="Try to login with User table" width="800" height="625"&gt;&lt;/a&gt;&lt;br&gt;
Failed. Great, this is what we expect, it cannot find any records cause when using staff guard, it just only take a look in Staff table. That's why, it did not found any records. That's all. Thanks for reading.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>webcomponents</category>
      <category>frontend</category>
      <category>design</category>
    </item>
    <item>
      <title>VIM: Introduction</title>
      <dc:creator>Phú</dc:creator>
      <pubDate>Sat, 16 Jul 2022 16:02:36 +0000</pubDate>
      <link>https://dev.to/lkp/vim-introduction-2dgl</link>
      <guid>https://dev.to/lkp/vim-introduction-2dgl</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5iu1ag4xxvhd9vi8uou9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5iu1ag4xxvhd9vi8uou9.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Video for this tutorial here:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/BNx7tgDdTi0" rel="noopener noreferrer"&gt;https://youtu.be/BNx7tgDdTi0&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is VIM?
&lt;/h2&gt;

&lt;p&gt;First of all, let’s talk about vi (pronouce vee-eye). Vi editor is a super popular editor in linux because it help you to increase your productivity by just using your keyboard. For that reason, you don’t need to use mouse when you want to move around in your file, you want to copy paste character or word, etc.&lt;/p&gt;

&lt;p&gt;That’s it for vi and VIM is VI iMproved. So VIM is an improvement version of vi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open VIM
&lt;/h2&gt;

&lt;p&gt;So how can we enter the VIM world. Firstly, you need to have VIM in your computer. If you do not have VIM, then go to install it first. For Ubuntu, you can run this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo apt install vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In Arch based distro:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;sudo pacman -S vim&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After you have vim in your computer then open your terminal and type vim . The screen you are seeing is VIM welcome screen. It will explain to you what is VIM, version of VIM, VIM’s author, license and some helpful command, especially quit command. Why we need to pay attention to quit command? Because some people use VIM for many years just because they have no idea how to quit VIM. Don’t be that guy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quit VIM
&lt;/h2&gt;

&lt;p&gt;As I say, quit VIM is a very important thing. Thus, to quit VIM, type ESC , after that type :q! . It means quit VIM without saving anything. Another way, you can type ZZ and you can quit VIM, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write something, save and quit
&lt;/h2&gt;

&lt;p&gt;Now, open VIM again by typing vim . Type i , you will see INSERT message on the bottom left of your screen. In this mode, you can type anything you want. So let’s type some code: &amp;lt;?php echo 'Hello World'; . Save it by type ESC and type :w filename , it means save this file whose name is filename . In this case, I want it to be index.php then I will type :w index.php and type :q to exit. Next, check files, you will see your new file name index.php . Let’s run it if you have PHP in your computer, if not then skip it php index.php . Hooray, you can open VIM, type something and save it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Small tip and trick
&lt;/h2&gt;

&lt;p&gt;I have a quicker way to name your file. When you open vim, you can type your filename after vim command. For example, vim filename , it means you start to write on file whose name is filename. Then when you want to save it, you just need to run command :w . In addition, if you want to save and quit, you can type :wq , it means write this file and quit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we learnt how to open, write, save and quit VIM. See you next time. Until that, I hope you happy with VIM. See ya!&lt;/p&gt;

</description>
      <category>vim</category>
      <category>programming</category>
      <category>editor</category>
    </item>
  </channel>
</rss>
