<?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: Nuwan Karunarathna</title>
    <description>The latest articles on DEV Community by Nuwan Karunarathna (@nuwannnz).</description>
    <link>https://dev.to/nuwannnz</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F111849%2Ffd461fa4-aef3-4f5f-b78f-a8f0d7770d95.jpg</url>
      <title>DEV Community: Nuwan Karunarathna</title>
      <link>https://dev.to/nuwannnz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nuwannnz"/>
    <language>en</language>
    <item>
      <title>Understanding the Harness Behind AI Coding Agents</title>
      <dc:creator>Nuwan Karunarathna</dc:creator>
      <pubDate>Tue, 04 Aug 2026 15:13:40 +0000</pubDate>
      <link>https://dev.to/nuwannnz/understanding-the-harness-behind-ai-coding-agents-2co8</link>
      <guid>https://dev.to/nuwannnz/understanding-the-harness-behind-ai-coding-agents-2co8</guid>
      <description>&lt;p&gt;If you've used Claude Code, you've probably experienced something like this.&lt;/p&gt;

&lt;p&gt;You ask it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Refactor our authentication service to use JWT refresh tokens."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A few moments later it has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Searched your repository&lt;/li&gt;
&lt;li&gt;Read multiple files&lt;/li&gt;
&lt;li&gt;Updated your implementation&lt;/li&gt;
&lt;li&gt;Run the test suite&lt;/li&gt;
&lt;li&gt;Fixed a failing test&lt;/li&gt;
&lt;li&gt;Asked permission before executing another command&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It feels like the AI understands your entire project.&lt;/p&gt;

&lt;p&gt;But here's the interesting part:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The language model doesn't know how to do any of those things.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It doesn't know how to read files.&lt;/p&gt;

&lt;p&gt;It doesn't know how to execute terminal commands.&lt;/p&gt;

&lt;p&gt;It doesn't know how to run tests.&lt;/p&gt;

&lt;p&gt;It only reasons about &lt;strong&gt;what should happen next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The software around it makes everything else possible.&lt;/p&gt;

&lt;p&gt;That software is called &lt;strong&gt;the harness&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Think of an AI agent like a human
&lt;/h2&gt;

&lt;p&gt;Imagine a human brain without a body.&lt;/p&gt;

&lt;p&gt;It can think.&lt;/p&gt;

&lt;p&gt;It can reason.&lt;/p&gt;

&lt;p&gt;It can make plans.&lt;/p&gt;

&lt;p&gt;But it can't interact with the world.&lt;/p&gt;

&lt;p&gt;Now give it eyes to observe, hands to act, memory to remember, and muscles to execute.&lt;/p&gt;

&lt;p&gt;The brain hasn't changed.&lt;/p&gt;

&lt;p&gt;Its ability to interact with the world has.&lt;/p&gt;

&lt;p&gt;AI coding agents work the same way.&lt;/p&gt;

&lt;p&gt;The language model is the brain.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;harness&lt;/strong&gt; is the body.&lt;/p&gt;

&lt;p&gt;It gives the model access to tools, memory, context and the ability to perform actions.&lt;/p&gt;

&lt;p&gt;Without a harness, an LLM is just a reasoning engine.&lt;/p&gt;

&lt;p&gt;With a harness, it becomes an AI coding agent.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is the harness?
&lt;/h2&gt;

&lt;p&gt;The harness is the software layer surrounding the language model.&lt;/p&gt;

&lt;p&gt;Its job is simple:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connect the model to your development environment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A typical coding harness provides:&lt;/p&gt;

&lt;h3&gt;
  
  
  Context
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Read files&lt;/li&gt;
&lt;li&gt;Search the codebase&lt;/li&gt;
&lt;li&gt;Retrieve documentation&lt;/li&gt;
&lt;li&gt;Select relevant context&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Actions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Edit files&lt;/li&gt;
&lt;li&gt;Execute terminal commands&lt;/li&gt;
&lt;li&gt;Run tests&lt;/li&gt;
&lt;li&gt;Build projects&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  State
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Track task progress&lt;/li&gt;
&lt;li&gt;Remember previous steps&lt;/li&gt;
&lt;li&gt;Manage conversation history&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Safety
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ask for approval&lt;/li&gt;
&lt;li&gt;Restrict dangerous actions&lt;/li&gt;
&lt;li&gt;Sandbox execution&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Orchestration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Decide which tool to use&lt;/li&gt;
&lt;li&gt;Handle failures&lt;/li&gt;
&lt;li&gt;Retry when necessary&lt;/li&gt;
&lt;li&gt;Decide when the task is complete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Notice something important.&lt;/p&gt;

&lt;p&gt;None of these capabilities come from the language model itself.&lt;/p&gt;

&lt;p&gt;The model provides the reasoning.&lt;/p&gt;

&lt;p&gt;The harness provides the execution.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6pju07s50uj4i3avkx72.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6pju07s50uj4i3avkx72.png" alt=" " width="800" height="953"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The agent loop
&lt;/h2&gt;

&lt;p&gt;The biggest difference between ChatGPT and an AI coding agent isn't tool access.&lt;/p&gt;

&lt;p&gt;It's the &lt;strong&gt;execution loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A coding agent repeatedly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Think&lt;/li&gt;
&lt;li&gt;Use a tool&lt;/li&gt;
&lt;li&gt;Observe the result&lt;/li&gt;
&lt;li&gt;Think again&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search the repository&lt;/li&gt;
&lt;li&gt;Read a file&lt;/li&gt;
&lt;li&gt;Notice another dependency&lt;/li&gt;
&lt;li&gt;Read that file&lt;/li&gt;
&lt;li&gt;Edit both files&lt;/li&gt;
&lt;li&gt;Run the tests&lt;/li&gt;
&lt;li&gt;See a failure&lt;/li&gt;
&lt;li&gt;Fix the failure&lt;/li&gt;
&lt;li&gt;Run the tests again&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This loop can happen dozens of times before you receive the final response.&lt;/p&gt;

&lt;p&gt;Without a harness, the model only performs a single reasoning step.&lt;/p&gt;

&lt;p&gt;With a harness, it can iteratively work towards a solution.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why software engineers should care
&lt;/h2&gt;

&lt;p&gt;Understanding the harness changes the questions you ask.&lt;/p&gt;

&lt;p&gt;Instead of focusing only on prompts, you start thinking like a systems engineer.&lt;/p&gt;

&lt;p&gt;Questions such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How is context gathered?&lt;/li&gt;
&lt;li&gt;What tools should the agent have?&lt;/li&gt;
&lt;li&gt;When should it ask for approval?&lt;/li&gt;
&lt;li&gt;How should failures be handled?&lt;/li&gt;
&lt;li&gt;How does it know the task is complete?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are the questions that determine whether an AI coding agent feels like a chatbot or like a teammate.&lt;/p&gt;

&lt;p&gt;As frontier models become increasingly similar, the harness becomes the real differentiator. So, two products can use the same language model and still provide completely different developer experiences because one retrieves better context, executes tools more effectively, and orchestrates the entire workflow more intelligently.&lt;/p&gt;




&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Anthropic&lt;/strong&gt; – &lt;em&gt;Claude Code Documentation&lt;/em&gt; &lt;br&gt;
&lt;a href="https://docs.anthropic.com/en/docs/claude-code" rel="noopener noreferrer"&gt;https://docs.anthropic.com/en/docs/claude-code&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Anthropic&lt;/strong&gt; – &lt;em&gt;Building Effective AI Agents&lt;/em&gt; &lt;br&gt;
&lt;a href="https://www.anthropic.com/engineering/building-effective-agents" rel="noopener noreferrer"&gt;https://www.anthropic.com/engineering/building-effective-agents&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Addy Osmani&lt;/strong&gt; – Articles on AI-assisted software engineering&lt;br&gt;
&lt;a href="https://addyosmani.com/blog/" rel="noopener noreferrer"&gt;https://addyosmani.com/blog/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Overriding methods in JavaScript using prototypes</title>
      <dc:creator>Nuwan Karunarathna</dc:creator>
      <pubDate>Sun, 16 Feb 2020 18:08:09 +0000</pubDate>
      <link>https://dev.to/nuwannnz/overriding-methods-in-javascript-using-prototypes-16i9</link>
      <guid>https://dev.to/nuwannnz/overriding-methods-in-javascript-using-prototypes-16i9</guid>
      <description>&lt;p&gt;JavaScript is not considered as  a fully object oriented programming language instead it is known as a object based programming language or a prototype based language. That means JavaScript supports some of object oriented concepts to some extent but not fully supported. Confusing right? Some may even argue that JavaScript has classes. Yes it has the &lt;code&gt;class&lt;/code&gt; keyword introduced in ES2015 but it is considered as 'syntactical sugar'. Underneath it is still prototypes running the business. So in this article we are going to learn about how to override methods in JavaScript and what is happening underneath with prototypes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prototypes
&lt;/h3&gt;

&lt;p&gt;First of all, lets have a little look into prototypes in JavaScript. A prototype has the same meaning as a parent class in OOP languages but at the same time it is different. In JavaScript, each and every object or function has a linked prototype.  For example if we run the below snippet in a console we can see the prototype of a function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function someFunction(){}
console.log(someFunction.prototype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    constructor: ƒ someFunction(),
    __proto__: {
        constructor: ƒ Object(),
        hasOwnProperty: ƒ hasOwnProperty(),
        isPrototypeOf: ƒ isPrototypeOf(),
        propertyIsEnumerable: ƒ propertyIsEnumerable(),
        toLocaleString: ƒ toLocaleString(),
        toString: ƒ toString(),
        valueOf: ƒ valueOf()
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above output is the prototype of the function &lt;code&gt;someFunction&lt;/code&gt;. In here you may notice a property called &lt;code&gt;__proto__&lt;/code&gt;. This is the prototype of the &lt;code&gt;someFunction&lt;/code&gt;'s prototype. This is called as the chain of prototypes and it will go and go on until the &lt;code&gt;__proto__&lt;/code&gt; becomes null.&lt;br&gt;&lt;br&gt;
now let's create an instance of this &lt;code&gt;someFunction&lt;/code&gt; and add some new properties to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let someOtherFunction = new someFunction();
someOtherFunction.someOthervalue = 'new value';
console.log(someOtherFunction);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    someOtherValue: "new value",
    __proto__: {        
        constructor: ƒ doSomething(),
        __proto__: {
            constructor: ƒ Object(),
            hasOwnProperty: ƒ hasOwnProperty(),
            isPrototypeOf: ƒ isPrototypeOf(),
            propertyIsEnumerable: ƒ propertyIsEnumerable(),
            toLocaleString: ƒ toLocaleString(),
            toString: ƒ toString(),
            valueOf: ƒ valueOf()
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we can see that adding a new property to the &lt;code&gt;someOtherFunction&lt;/code&gt;  did not affected the prototype of it but added a new property on top of it. This is the point we are going to utilize to override methods. &lt;/p&gt;

&lt;h3&gt;
  
  
  Override methods
&lt;/h3&gt;

&lt;p&gt;Let's check the below snippet. In here lets use objects instead of functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
let person  = {
  fName:'John', 
  lName:'Pillip',
  age: 23,
  getName: function(){
      return `${this.fName} ${this.lName}`
  },
  getAge: function(){
      return `${this.age} years`
  }
}

console.log(person.getName());
console.log(person.getAge());


// create an instance from the person object
let newPerson = Object.create(person);

// instead of a new property, let's add a function with the same name 
newPerson.getName = function(){
  return `${this.lName} ${this.fName}` 
}

console.log('');
console.log(newPerson.getName());
console.log(newPerson.getAge());


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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"John Pillip"
"23 years"

"Pillip John"
"23 years"

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

&lt;/div&gt;



&lt;p&gt;So let's breakdown what's happening. First we created a &lt;code&gt;person&lt;/code&gt; object and the &lt;code&gt;getName()&lt;/code&gt; ran the way we expected. Then we created a new instance of the &lt;code&gt;person&lt;/code&gt; called &lt;code&gt;newPerson&lt;/code&gt;. Here comes the interesting part, we add a function called &lt;code&gt;getName()&lt;/code&gt; to the &lt;code&gt;newPerson&lt;/code&gt; . Now when we ran the snippet, &lt;code&gt;newPerson&lt;/code&gt; executed its own &lt;code&gt;getName()&lt;/code&gt; function and override the &lt;code&gt;getName()&lt;/code&gt; of &lt;code&gt;person&lt;/code&gt;. Yay method overriding!. Okay but why that happened. Let's take a look at the &lt;code&gt;newPerson&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;{
    getName: ƒ (),
    __proto__: {
        fName: "nuwan",
        lName: "karunarathna",
        getName: ƒ (),
        getAge: f (),
        __proto__: Object
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see the prototype of the &lt;code&gt;newPerson&lt;/code&gt; has the &lt;code&gt;getName()&lt;/code&gt; method which is the original method but now &lt;code&gt;newPerson&lt;/code&gt; also has its own method called &lt;code&gt;getName()&lt;/code&gt; . So at runtime, when we call the &lt;code&gt;getName()&lt;/code&gt;  of the &lt;code&gt;newPerson&lt;/code&gt; JavaScript will check whether the &lt;code&gt;newPerson&lt;/code&gt; has a own method called &lt;code&gt;getName()&lt;/code&gt; and in our case it has, so JavaScript executes that method  and ignores the &lt;code&gt;getName()&lt;/code&gt; of the prototype of the &lt;code&gt;newPerson&lt;/code&gt;. This is called shadowing methods. Now in contrast when executing the &lt;code&gt;getAge()&lt;/code&gt; JavaScript checks whether the &lt;code&gt;newPerson&lt;/code&gt; has a own method called &lt;code&gt;getAge()&lt;/code&gt; but it doesn't and now it will check the prototype of the &lt;code&gt;newPerson&lt;/code&gt;  to find a method with that name to execute it and luckily it does so it will be executed but if it did not had a matching method, JavaScript will perform this searching through the prototype chain until a method is matched.&lt;/p&gt;

&lt;p&gt;So this is how we can override methods in JavaScript and we learned how it is happening underneath with the prototypes. We can use the above technique for override properties too. &lt;/p&gt;

&lt;p&gt;So in summary we can easily override methods and properties in JavaScript and it is good to have an understanding about how it is actually happening too.&lt;/p&gt;

&lt;p&gt;Let's meet in another article. Until then, Happy coding! :) &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>coding</category>
    </item>
    <item>
      <title>grep command [ Linux tips ]</title>
      <dc:creator>Nuwan Karunarathna</dc:creator>
      <pubDate>Fri, 03 Jan 2020 16:24:39 +0000</pubDate>
      <link>https://dev.to/nuwannnz/grep-command-linux-tips-lef</link>
      <guid>https://dev.to/nuwannnz/grep-command-linux-tips-lef</guid>
      <description>&lt;p&gt;Grep command can be used to filter or search text from files or input streams.&lt;/p&gt;

&lt;p&gt;Basic usage,&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grep “text_to_search” fileToSearch&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In here the “text_to_search” can be a plain string or a regular expression. &lt;/p&gt;

&lt;h3&gt;
  
  
  Example 1
&lt;/h3&gt;

&lt;p&gt;Assume that we need to find whether the text “user login failed” has appeared in a log file. Then we can use the grep command like below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grep “user login failed” logFile.txt&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;After running the above line grep will print the lines of text which includes the text “user login failed”.&lt;/p&gt;

&lt;p&gt;Another very useful way we can use grep command is to filter out input streams like the output of another command (or another grep command). &lt;/p&gt;

&lt;h3&gt;
  
  
  Example 2
&lt;/h3&gt;

&lt;p&gt;Let’s say you want to find out whether a file is there in a folder which contains like 1000 other files. We can simply use the grep command to find out that like below.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls | grep “file_name_to_find”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In here the ‘|’ (pipe) will send the output of the &lt;code&gt;ls&lt;/code&gt; command as an input to the &lt;code&gt;grep&lt;/code&gt; command(but it’s not a &lt;code&gt;grep&lt;/code&gt; specific operator).&lt;/p&gt;

&lt;p&gt;So these are the most common ways we can use grep to make our lives easier and it has limitless usages but grep has many more options too. Below are some of the options we can use.&lt;/p&gt;

&lt;p&gt;-n : prints the line number&lt;br&gt;
-o : prints only the matching part of the text&lt;br&gt;
-c : prints the number of matches&lt;/p&gt;

&lt;h3&gt;
  
  
  Example 3
&lt;/h3&gt;

&lt;p&gt;If we want to know how many files have the name as the file name in the above example we can simply use the -c option.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls | grep -c “file_name_to_find”&lt;/code&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>beginners</category>
      <category>bash</category>
    </item>
  </channel>
</rss>
