<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://willmcgugan.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="http://willmcgugan.github.io/" rel="alternate" type="text/html" /><updated>2026-10-15T15:00:04+00:00</updated><id>http://willmcgugan.github.io/feed.xml</id><title type="html">Will McGugan</title><subtitle>Will McGugan&apos;s essays</subtitle><author><name>Will McGugan</name></author><entry><title type="html">The Living Mountain Chapter 2</title><link href="http://willmcgugan.github.io/living-mountain-chapter-2/" rel="alternate" type="text/html" title="The Living Mountain Chapter 2" /><published>2026-10-15T00:00:00+00:00</published><updated>2026-10-15T00:00:00+00:00</updated><id>http://willmcgugan.github.io/living-mountain-chapter-2</id><content type="html" xml:base="http://willmcgugan.github.io/living-mountain-chapter-2/"><![CDATA[<h1 id="2-sealg">2. Sealg</h1>

<p>Calum reached the Land Rover first, panting from the thrill of defying his parents. He climbed into the driver seat as a child might tackle a climbing frame. Alastair followed, carrying with him a bundle of something wrapped in a blanket, which he casually tossed onto the back seat. Only two years older than Calum, Alastair was as tall as a full-grown man and swung himself in without effort.</p>

<p>“You got it?” asked Calum.</p>

<p>“Of course I fucking got it. What do you think that is in the back seat?”</p>

<p>Calum looked at the bundle in the back. The blanket had slipped off, exposing gun-metal as dark as a shadow against the back-seat fabric.</p>

<p>“Fuck. Keys! Where does he keep them?” Alastair scanned the interior of the Rover. He pulled down the sun-visor. Nothing. He reached into the glove compartment, digging through the assortment of objects he found there. A spanner, a lighter, map, and finally car keys, which he held up and jingled playfully. “Fuck, aye,” Alastair said, grinning. He slid the keys into the ignition and stopped. Then he turned to Calum who recognized the wide-eyed look. Like a cat about to pounce.</p>

<p>As much as Calum had managed to avoid the extremes of their parent’s wrath his brother was adept at invoking, he suspected his reputation as the good brother would not be enough to protect him from the consequences of this night-time jaunt they had planned. Leaving the house and taking the Rover without permission would earn them both a hiding—but taking the Browning was beyond forbidden. There was no precedence for such a transgression.</p>

<p>It wasn’t too late to turn back. Dad was in the living room digesting dinner and drinking lager, oblivious to the whereabouts of his sons. They could restore the shotgun to its place on the top of the rack in the shed and return to their shared bedroom without their parents suspecting a thing.</p>

<p>“He loves that shotgun,” Calum noted. The Browning B-80 was Dad’s favorite amongst his guns and—Calum suspected—his favorite amongst his children. He had spent the previous evening polishing the walnut stock with hard wax oil until the mottled wood grain gleamed.</p>

<p>Experienced hunters by they time they reached their teens, the boys were no stranger to guns. Alastair in particular delighted in shooting rabbits and regularly re-stocked the freezer with venison. Taking one of the other half dozen shotguns or rifles in the shed without permission would have been considered a misdemeanor at most. But not the Browning. Dad would take that personally. A point Calum thought to raise with his brother before it occurred to him that offending their father was rather the point.</p>

<p>Alastair didn’t say a word as he turned the key in the ignition. The engine turned over and the cabin rumbled. This would surely rouse their father who could hear a car engine from half a mile down the mountain. Alastair put the vehicle into reverse and turned around in the driveway a little too fast, knocking over his mother’s plant pots which shattered and spread dirt over the driveway. Facing the gate, Alastair put the vehicle into first, stopping short of engaging the clutch. The gate to the farmhouse was closed. No lock, just a latch built from the same cast iron as the gate itself and as solidly constructed. There was no time to get out of the Rover, open the gate, and return to the Rover for a quick getaway. Not before his father was there to grab both of them by the scruff of the neck. Calum saw only two options. They could stop and face the music, perhaps using a last-minute change of heart as a bargaining chip to reduce their collective punishment. The second option would be more dramatic and almost too ridiculous to consider. Even before Calum had thought it through he knew that to Alastair, who invariably chose the path of greatest chaos, there was only one option.</p>

<p>“No”, Calum said, meekly.</p>

<p>“I’m doing it.”</p>

<p>Alastair engaged the clutch and floored the accelerator as the farmhouse door swung open to the silhouette of their father. Dirt and gravel kicked up from the back wheels. Alastair turned the vehicle away from the gate as they accelerated, aiming for the fence—much to Calum’s relief as the sturdy gate was cemented into the ground. Calum braced himself against the dash as the Rover’s grill collided with the fence, sending a starburst of sparks into the air. The Rover pulled away from the farmhouse, their father standing in the doorway, back-lit and casting a long shadow over the crushed fence and ruined flower beds.</p>

<p>Alastair, watching the rear view mirror, gestured a raised middle finger behind him just as soon as he felt they were far enough away for his father not to see it.</p>

<hr />

<p>“Did you see those sparks?” asked Alastair. Calum, barely able to assemble words into a sentence after all the excitement, agreed with a vigorous nod. “Just like the A-team,” Alastair continued, “No. Dukes of Hazard. Hey, do you think we could get some air-time in this thing?”</p>

<p>Calum giggled. The Land Rover felt as anchored to the ground as the granite boulders that littered the slopes of Ranoch. Implausible as it seemed, the imagery of them jumping a gulch while being pursued by a cavalcade of cop cars had them both in hysterics.</p>

<p>The Rover reached a fork in the gravel track. One branch turned into single lane tarmac and would take them into the village. The other carried on snaking upwards into the mountain. Alastair braked and put the Rover in neutral.</p>

<p>“Have we got any food?” asked Alastair. They had just eaten dinner, but it would be a long night ahead of them.</p>

<p>“Think so,” Calum said, “Dad always keeps biscuits in the Rover.” He fished around in the door bin and pulled out a long cylinder of Rich Tea biscuits, about half of which had been eaten.</p>

<p>“Is that all?”</p>

<p>“Afraid so,” Calum confirmed, mournfully.</p>

<p>“Let’s go into town and get a chippy for later,” Alastair said, putting the Rover into gear.</p>

<p>“We can’t do that. Somebody might see you.”</p>

<p>“See me doing what? Buying chips?”</p>

<p>“Driving without a license.”</p>

<p>Alastair cursed. On the mountainside, nobody cared about him driving—it was common for the children of the handful of families still living on Ranoch to be regularly driving in their teens. Even the local police would turn a blind eye beyond the farmhouse where there were few roads, and even fewer cars. But on council roads about town, a boy of barely sixteen driving a Range Rover would be challenged. Reluctantly, Alastair turned the wheel in the opposite direction. Calum wasn’t sure if Alastair wanted to avoid being arrested or simply didn’t want to risk missing out on the evening he planned for all of three hours—pretty much the extent of the boy’s ability to think ahead. Alastair banged the steering wheel with two fists. “Fuckin’ hell. I can drive better than half the old farts in the village,” he protested.</p>

<p>Calum had observed his brother’s mood could change quickly like that. From cheerful to angry and bitter, like flipping a coin. If Calum didn’t do anything, Alastair might be stuck in that bad mood for the rest of the night, and that would not bode well for either of them. Alastair wasn’t always so volatile. Before he started clashing with Dad, the boys were close and often the only source of entertainment was each other. They spent many days playing silly games on the mountain which invariably resulted them coming home mucky from head to toe. That was before the fights; shouting matches with Dad that resulted in Alastair being confined to his room, often after a belting that left angry streaks criss-crossing his buttocks. He claimed it didn’t hurt that much, but Calum saw something change in his brother with every application of the belt. He became sullen, less joyful, with a tendency for random cruelty. Lately he had taken to giving Calum a “knuckling”—a knuckle forcefully dug between Calum’s ribs with a twist to maximize discomfort. He did it with such regularity that he often hit a bruise from the previous knuckling.</p>

<p>“There is beer in the boot,” Calum offered. He had helped his mother carry an entire pack of beer from the village shop to the Rover that day. Twelve tall cans of strong lager, of the brand their father like to drink while watching television. The pack was heavy, and the fridge was full, so it remained in boot—and would still be there.</p>

<p>“Seriously?” Alastair’s tone lightened.</p>

<p>“Aye,” Calum confirmed.</p>

<p>“Fuck aye, little brother!” Alastair floored the accelerator and tore the Rover up the mountain, kicking up fresh gravel behind them.</p>

<hr />

<p>Alastair followed the gravel track uphill, in what seemed like a route scribbled on paper by a toddler. Never a straight line, sometimes the track crossed a stream, only to cross back to the other side a few yards later, then deviate around an outcrop of rock, briefly pointing away and not towards the summit where they were heading. Dad explained to them as young boys that the route was not planned, rather it was worn in by successive generations of vehicles seeking to minimize the incline.</p>

<p>What little second-hand sunlight they had when setting out soon diminished, leaving only the Rover’s headlights to illuminate the track—so overgrown to the point it that it became hard to distinguish from the heather and grass that surrounded it. The boys talked as they drove. Mostly it was Alastair lamenting about the new girl in his class, Catriona with black hair, who had taken to teasing him about his name. <em>Alastair Alastair, Alistair MacAlastair</em>, she would chant, much to the delight of the other kids in class, who gleefully joined in. Kids that would previously have been too afraid of Alastair to tease him like that were now saying it directly to his face, and he could do nothing about it because hitting a girl was shameful. To make matters worse, he <em>liked</em> Catriona, who he described as a <em>stoater</em> while also telling Calum she wasn’t <em>that</em> pretty. When it came to girls, Alastair rarely made any sense to Calum and had learned it was best not to point out such contradictions.</p>

<p>Calum slowed the Rover to a crawl. Leaning over the steering wheel, he admitted that he had probably lost the track ten minutes ago. They had been heading for a plateau around two thirds of the way to the summit where there was a car-park of sorts and a few decaying picnic tables placed there for hikers and day-trippers. It had served as the starting point for the Sealg for many years, but it didn’t look like they would reach it without back-tracking and Alastair was not one for back-tracking.</p>

<p>“Where are we?” Calum asked.</p>

<p>“No fuckin’ clue. But this is a good spot. Those old farts don’t know everything.” Alastair parked and left the Rover. He returned with two cans of lager, handing one to Calum. “Drink up bro. It puts hair on your balls.” The brother’s drank and ate the biscuits. Alastair drank with gusto, while Calum sipped. Calum didn’t much care for the bitter drink and would have chosen a Cola given the chance. Alastair finished his lager with a satisfied <em>ahhh</em>. “Is it time?”</p>

<p>Calum checked his watch. Well past sun-down. “It’s time,” he confirmed.</p>

<p>“Let’s do it.” Alastair jumped out the Rover. Calum followed, leaving behind half a can of lager. Alastair surveyed the contents of the boot and reached for another can of lager. “One for the road,” he said, depositing the can in an army-surplus ruck-pack then adding another lager for good measure. “What else?”</p>

<p>“Torch.” Calum said.</p>

<p>“Aye. Torch. You numpty. It’s dark.” Alastair fished out the camping torch, switched it on and banged the red plastic housing. The torch was the kind with a handle and a big square battery that could last several hours on a single charge. Calum was concerned it might not be fully charged, but it seemed pointless to raise that concern to Alastair who was clearly committed to the enterprise and would in all likelihood do it in the dark if he had to. “Here, you carry these,” Alastair said, handing Calum the backpack and torch.</p>

<p>Alastair retrieved the Browning from the back-seat and stuffed the blanket and loose shells into Calum’s rucksack. They set out facing the summit, Ranoch village at their back.</p>

<hr />

<p>Alastair walked with the business end of the Browning resting on his shoulder, while Calum held a little back, keeping the torch leveled on the terrain ahead. Alastair talked as they walked, mostly about Catriona and how annoying she was, while Calum focused on his flashlight duties. Behind them, the Rover grew smaller and dimmer, finally merging with the night sky. With the Rover out of view it felt as though they were adrift in an ocean of heather. Unsure of what lay ahead, the boys continued their march up the bank of the mountain in silence.</p>

<p>The brothers reached an outcrop of exposed granite, its feldspar flecks caught the torchlight like tiny Christmas lights. “Break time,” Alastair said, setting the Browning down next to the rock. He pulled out a lager from Calum’s rucksack, offering it first to his brother, who declined with a hand gesture, before cracking it open and taking a gulp himself.</p>

<p>“What if we don’t find anything?” Calum asked.</p>

<p>Alastair swallowed a mouthful of lager and hesitated before speaking. “If we don’t find anything, then—” he left his response hanging, building suspense in Calum who suspected his brother had started the sentence before knowing how he would complete it. “—then we join the French Foreign Legion,” Alastair said with a sense of satisfaction. It was an in-joke. Calum had told Alastair about the French Foreign Legion, which Calum himself had learned about from a novel. “Mon Dieu, Pepe le Pew,” Alastair said. They both laughed at Alastair’s cartoonish French accent. The joke confirmed that Calum’s suspicions that his brother’s plan was as reckless as it seemed and without consideration for the consequences.</p>

<p>The boys reclined against the rocks, while Alastair drank. Ranoch village was visible in the distance as a yellowish bloom of light from a smattering of street-lamps and windows. The emerging full-moon lifted the landscape just enough to make out the topology of the mountain slope which somehow seemed disconnected from the tiny village as though Ranoch mountain and Ranoch village were separate ethereal realms and not a single land mass.</p>

<p>“Pretty,” Calum remarked.</p>

<p>Alastair laughed. “Aye, its pretty. But we are not tourists. Our mission is a sacred one, entrusted to us by our fore-fathers.” Alastair mimicked his Father’s pompous tone, expecting to elicit a laugh from his younger brother. Calum didn’t respond to his brother’s jape. He had heard a noise from a little further up the mountain and had turned his head to listen for it. “What is it?” asked Alastair.</p>

<p>Calum held up a hand to silence his brother. There it was again. The noise he had heard moments ago, repeated. Unmistakably it was a growl produced by an animal. “Get the Browning,” Calum said, coldly.</p>

<p>Alastair grabbed the Browning propped up against the rocks. They walked slowly in the direction of the noise, while Calum scanned the foreground with a beam of focused torchlight.</p>

<p>Alastair hadn’t yet heard the noise for himself. “Is it a brollachan?” he asked.</p>

<p>“Do they growl?”</p>

<p>Alastair admitted he didn’t think so, but held the shotgun in front of him all the same. The brothers walked steadily forward, intent and silent, approaching the source of the growls which had grown louder and—in the brother’s minds—angrier. They traced the sound to a mound of dirt, not so far away. Alastair raised the browning to eye height, carefully lining up the sight-bead with the mound as they stalked. The growls stopped before they reached the mound. Concerned they had been spotted, the brother’s froze in their tracks. Then a pair of piercing eyes suspended in a stout face erupted from behind the mound. Alastair pulled the Browning trigger which clicked impotently. Calum yelped, nearly dropping the torch.</p>

<p>“Badger!” Calum said, noting the round body and sturdy legs of the creature bolting up the mountain out of reach of the torchlight.</p>

<p>“Fuckin’ badger,” Alastair said, lowered the Browning. He looked to his bother, sheepishly. “Forgot the shells.”</p>

<p>“You would have got him.”</p>

<p>“Damn right I would have got him. Blown him to Smithereens.”</p>

<p>“What was it growling at?”</p>

<p>“I don’t know, bro. Do I look like David Attenborough?”</p>

<p>They walked the remaining few feet to the mound of dirt which had clearly been excavated from an adjacent pit. There, something or perhaps several somethings moved beneath the soil.</p>

<p>Alastair set the Browning down, knelt in front of the pit, and began brushing lose dirt away from the surface while Calum stood over him holding the torch. Calum couldn’t help but admire his brother’s nerve; he doubted he would have the guts to dig in a hole without knowing what manner of creatures were down there.</p>

<p>Alastair swept a final layer of dirt aside, revealing <em>fingers</em>. Human fingers. Slender and pale, they were moving, clawing at the earth, part of a hand apparently trying to dig its owner free.</p>

<p>Alastair scrambled to his feet.</p>

<p>“Holy fuckin’ shit. It is a brollachan. Has to be. Jesus, fuck.” He grabbed Calum and spun him around to retrieve a handful of shells from the rucksack. Alastair’s hand shook as he loaded the shotgun, at one point dropping a shell which almost ended up in the pit. He leveled the fully loaded shotgun at the pit, looking down at the hand clawing at the dirt. Another hand appeared near the first, peaking through the surface, moving in the same way. The brothers stood watching the coordinated motion of the hands.</p>

<p>“It’s like it is swimming,” Calum remarked.</p>

<p>“Aye. Swimming in dirt.”</p>

<p>“Is that how they all come out?”</p>

<p>“Dad never said. I think this is the first time anyone caught a brollachan before it hatched.”</p>

<p>“Are you going to shoot?”</p>

<p>Alastair lowered the gun. “No point.” He explained to Calum that when a rabbit went to ground there was no getting it. Shotgun pellets would shred the rabbit, but wouldn’t go far in dirt. The brollachan may as well be wearing a suit of armor while it was stuck in the ground.</p>

<p>“Should we dig it out?” Calum asked.</p>

<p>“No, dummy. It will bite us.”</p>

<p>“Right.”</p>

<p>“What are we going to do?”</p>

<p>“We wait until it digs itself out. Then we shoot it.” Alastair spoke with an air of certainty Calum had never observed in his brother before. For once he didn’t seem to be winging it.</p>

<p>The boys retreated to vantage point a little further up the hill where they watched the hands <em>swimming</em> in the filth and the mud, leaving a slow-motion wake of dirt. Gradually forearms were revealed. Pale skinned and caked in dirt, the arms writhed as they shoveled the peaty earth at a greater rate that the hands could alone. Later, the top of a head was exposed, topped with a tangled mass of matted hair.</p>

<p>The boys watched intently, fascinated by the progress of the creature being birthed by the mountain in front of them.</p>

<p>“Have you ever seen one. You know. Close up?” Calum asked.</p>

<p>Alastair admitted he had not. Of the three hunts he had been on, he had only ever seen a brollachan wrapped in tarpaulin, bundled and tied in the back of a truck. Dad was always been quite vague as to the appearance of the brollachan, but he had once asked his Uncle Joey who described his kill—a particularly vicious specimen—as having frog eyes, a mouthful of fangs and an forked tongue like an adder. Alastair related the story to Calum. “That’s why you have to get them early,” he explained, “changelings could become anyone and you would never know they were a brollachan. But when they hatch they are like monsters.”</p>

<p>Calum had heard this explanation before. It was family lore. His family, his uncles, and the neighbors on Ranoch. Homesteaders, game-keepers, and others living on the mountain who could trace their family back to the local area for generations. They defended the good Christian people against the brollachans—creatures that devoured children and would take on the appearance of the villagers to spread wickedness should they escape the mountain. He had read similar tales in the second-hand novels he liked to read in his bedroom. Different monsters, different good-guys, but not all that different to the tale of the Christians versus the brollachans he had grown up with. So similar, that he had started to doubt brollachans were real at all.</p>

<p>The Sealg was real enough—he knew that much. His uncles came round when the moon was full. They ate, they drank, they prayed, then they piled into trucks with their shotguns in high spirits and left. On hunt nights Calum would hear distant gunfire muffled and echoed in the night air. Dad would return in the small hours with a story of his or Uncle Joey’s bravery defending the mountain against the changelings. Calum had never seen any evidence of brollachan and concluded they were hunting ptarmigan which would appear in the freezer the next day. He never raised his suspicions with Alastair and at that moment was glad he did not. A brollachan hatching in front of his eyes was all the proof he needed.</p>

<p>In the pit, the brollachan had squirmed and excavated enough dirt to expose a head, caked in mud and tangled hair, hiding its features from Calum’s probing torchlight. Alastair moved to the edge of the pit, kneeling as close as he dare. Dangerously close to falling in it seemed to Calum.</p>

<p>“Careful,” warned Calum.</p>

<p>“Get the beer,” Alastair said, ignoring Calum’s concern.</p>

<p>Calum placed the torch on the ground so that it still illuminated the pit and bounded downhill to retrieve the beer. He didn’t quite understand Alastair’s need for the drink, or is father’s for that matter, but he had learned not to dally when his father requested a beer and extended the same privilege to his brother. Back at the pit, he handed the half can of lager to his brother. Alastair didn’t drink from the can. He poured the lager over the creatures face, washing away some of the grime. Then, in what appeared to Calum an act of immense bravery, Alastair began wiping at the remaining dirt and moving strands of hair away from its face. The face revealed from the beer cleansing was not monstrous. Its feature were soft, delicate, unmistakably feminine.</p>

<p>“It’s a girl,” Calum said. The creature raised an arm which was entirely free at that point. For a moment, Calum feared it would grab his brother by the throat and throttle him, but its hand merely rose to shade its eyes from the torch Calum had trained on its face.</p>

<p>“It’s not a girl. It’s a brollachan.”</p>

<p>“But why does it look like a girl,” Calum protested, “where’s the frog eyes and fangs?”</p>

<p>“It’s a brollachan.” Alastair’s tone was somber and resolute, telling Calum not to press his doubts any further. Alastair went back for the Browning. After checking a round was chambered he returned to the pit where he stood over the creature, barrels aimed squarely at the creature’s head. “You’re only a man on Ranoch after you bag your first brollachan,” Alastair said, sounding for all the world like their father. Alastair said again, “You’re only a man on Ranoch after you bag your first brollachan.” Calum heard him perfectly the first time around.</p>

<p>Calum wasn’t at all certain the creature was a brollachan. If it didn’t have frog eyes and fangs how could they be sure? But then he knew that a real person would have suffocated under all the dirt. If it wasn’t a person, what else could it be but a brollachan? The frustrating circular reasoning froze him to the spot, unable to act, desperate for new information that might allow him to break out of the cycle.</p>

<p>Through gritted teeth Alastair said, “You are only a man. On Ranoch. After you bag your first… brollachan.” The face in the pit looked up at Alastair as he spoke. The creature’s expression was without malice or any emotion that Calum could discern. It had stopped digging itself out of the earth and was gazing up at Alastair as though waiting for something. Alastair met its gaze down the barrel of the Browning.</p>

<p>Calum looked on, unable to see the face in the pit as anything other than a young woman. “Alastair. No. Don’t do it,” he pleaded.</p>

<p>After what felt like an eternity to Calum, his brother sighed, breaking eye contact with the face in the pit and lowering the gun. “Fuck you, Dad,” he said. Alastair placed the gun on the ground before climbing into the pit where he began excavating dirt around the creature’s limbs with his hands. He worked with the zeal of a life guard pulling an incapacitated swimmer from of the ocean. Calum joined his brother ripping tangled roots and hurling clods of dirt out of the pit. Soon the torso was exposed and the girl-creature was revealed to be more girl that creature. With the weight of dirt removed from her upper body, the girl was more able to contribute to digging and was soon wriggling free while the boys worked around her. Once she pulled her legs free, the girl climbed out of the pit after the boys, partially aided by Alastair who extended a hand and pulled her over the threshold of the pit.</p>

<p>Out of the pit, there was nothing to suggested she was anything other than a flesh and blood girl, naked, filthy, and shivering in the cold night air. Calum ran to get the blanket from the rucksack which he draped over the girl’s shoulders for warmth and to cover her nakedness.</p>

<p>“Let’s get her to the Rover,” said Alastair.</p>

<p>Calum agreed. He didn’t have any other suggestion to offer. The night had become a rescue mission, and getting the girl to safety suited him much better than a hunt.</p>

<p>With Calum back on torch duty, the boys made their way back down the mountainside. Alastair with his arm around the girl holding blanket in place, guided her over the rough train. With the Rover in view, Alastair handed Calum the keys and suggested he go get the engine started and turn on the heating.</p>

<p>Calum bounded down the mountain in the direction of the Rover which he found where he expected it to be. Climbing in the driver side, he turned the ignition and switched on the heater. Soon warmth radiated from somewhere behind the dash. When Alastair arrived with the girl, he opened the passenger side door and guided her in, before joining her on the oversized passenger seat of the Series III.</p>

<p>“Drive safe little brother. Catriona has had a rough night,” Alastair said.</p>

<p>“Catriona?”</p>

<p>“That’s her name. She’s from Ireland.”</p>

<p>Catriona turned to Calum and spoke, with a gentle Irish accent. “That’s right. I grew up in Belfast.”</p>

<p>Calum was taken aback by the strange coincidence she had the same name as Alastair’s girl-enemy at school, but concluded that was the least odd thing about her presence that night and said nothing about it.</p>

<p>Calum adjusted the driver seat for his smaller frame and turned the Rover around, choosing to focus on the driving rather than dwell on the strange events of that night. Soon enough he located the track they had lost earlier.</p>

<p>As Calum drove, peering over the steering wheel, his brother talked with Catriona about many things: his love of western movies, his aptitude for sports and distaste for mathematics, but never how she had come to be buried in the peat. It seemed a strange omission to Calum who considered asking her himself, but the pair were engaged such an intense conversation as to never allow Calum the opportunity. By the time the farmhouse was in sight, Alastair and Catriona were laughing and giggling like firm friends.</p>

<p>At the farmhouse the gate was open and the house lights were all on. Calum guided the Rover up the driveway over the tire-marks they had made earlier. They parked a short distance from the front-door.</p>

<p>Calum jumped out while Alastair helped Catriona down from the Rover and lead her to the door, where their parent’s stood like sentinels guiding the entryway.</p>

<p>“This is Catriona,” Alastair said.</p>

<p>To Calum’s surprise his parents welcomed them in without another word from him or his brother. It was like he wasn’t there—his father, smiling broadly, put an arm around Alastair while Catriona was ushered away by their mother.</p>]]></content><author><name>Will McGugan</name></author><category term="fiction" /><category term="living-mountain" /><summary type="html"><![CDATA[2. Sealg]]></summary></entry><entry><title type="html">Stop, don’t Slop</title><link href="http://willmcgugan.github.io/stop-dont-slop/" rel="alternate" type="text/html" title="Stop, don’t Slop" /><published>2026-06-23T00:00:00+00:00</published><updated>2026-06-23T00:00:00+00:00</updated><id>http://willmcgugan.github.io/stop-dont-slop</id><content type="html" xml:base="http://willmcgugan.github.io/stop-dont-slop/"><![CDATA[<p>So you find a bug in an Open Source project and wish to spend your tokens solving that issue for the good of humanity. Your fingers hover over the keyboard, trembling in anticipation of the glorious prompt that will unblock your fellow developers. Before you type “FIx issue X make no mistaks” Stop!</p>

<p>AI is a modern marvel, but a Thanos level click of the fingers it is not. To prompt the best fix <em>you</em> need context. You need to diagnose the issue while considering the broader implications of your changes. I’m a maintainer of several open source packages, and let me tell you that well over half of issue reports incorrectly attribute the source of the bug and they often have grave misunderstandings about what the correct behavior is. No matter how good your AI is, if you give it a bum steer it may produce garbage.</p>

<p>I’m faced with a few options for AI PRs, which I will list in order:</p>

<ol>
  <li>Review them.</li>
  <li>Merge them without a full review.</li>
  <li>Reject them.</li>
</ol>

<p>Option 1 takes work, especially given AI’s tendency for loquacious bloviation. To figure out if the mechanical megabrain has solved the issue correctly requires that I solve it myself. The time taken to do this dwarfs the time taken to type the prompt.</p>

<p>Option 2 would work for a while. Users would be happy—for a while. But each change that strays from the big picture design or introduces an edge case or compromises an invariant, degrades the code. It’s like taking a photocopy of a photocopy. Fuck, that dates me. It’s like taking a JPEG of a JPEG.</p>

<p>Option 3 makes me look like the jerk. I’m not the jerk. You are not the jerk. There is no jerk here, both have good motivations. Unless the PR was submitted by your OpenFlaw, sorry, OpenClaw. Then you are the jerk. You are spending silly money to inconvenience Open Source maintainers, and I have no time for you.</p>

<p>Realistically, option 3 is the only practical solution for now.</p>

<p>I’d like to clarify that I’m not an AI doomer. We developers will all have to come to terms with a new way of working. But for libraries used by millions you need to be precious about every line, and that can only be done by a knowledgeable human or an AI under supervision of such a human. If you want to use AI to contribute to any of my projects I ask that you know enough that you <em>could</em> have written every line, even if AI did the grunt work for you.</p>

<p>Before I go, let me point out that every project described as being created by AI ships with the majority of code in dependencies created by mammalian brains; imperfect, squishy, sometimes cranky, brains consisting of water, lipids, and protein. I don’t know for how much longer that will be the case, but while it is: Stop, don’t slop.</p>]]></content><author><name>Will McGugan</name></author><category term="tech" /><category term="AI" /><summary type="html"><![CDATA[So you find a bug in an Open Source project and wish to spend your tokens solving that issue for the good of humanity. Your fingers hover over the keyboard, trembling in anticipation of the glorious prompt that will unblock your fellow developers. Before you type “FIx issue X make no mistaks” Stop!]]></summary></entry><entry><title type="html">AI_POLICY.md</title><link href="http://willmcgugan.github.io/ai-pr-policy/" rel="alternate" type="text/html" title="AI_POLICY.md" /><published>2026-02-11T00:00:00+00:00</published><updated>2026-02-11T00:00:00+00:00</updated><id>http://willmcgugan.github.io/ai-pr-policy</id><content type="html" xml:base="http://willmcgugan.github.io/ai-pr-policy/"><![CDATA[<p>If you maintain Open Source software, you will likely have encountered AI slop PRs.</p>

<p>Not all AI authored code can be considered slop, which is why a blanket ban on AI would be counterproductive.
My definition of “slop” is work that is AI generated, with very little involvement by the human operator.
It may seem like a good deal if somebody is spending their tokens to help your project, but without a passing understanding of the project or issue in question, the author can’t always prompt their way to a good solution.</p>

<p>As far as I can tell, most AI slop PRs are generated by a relatively small number of individuals.
They tend to arrive in batches, and I can see the author has submitted dozens or even 100s of PRs to other projects.
The work is typically a poor solution, not required, or simply broken. And the author will never follow up on comments.</p>

<p>It is in effect a DDOS for FOSS maintainers; it takes much longer to review the PR than it did to create it.</p>

<p>Nonetheless, I still feel bad about closing a PR without comment.
But at the same time resentful at having to spend time formulating a response, that will likely be ignored.</p>

<p>So I plan to include a text file in my project, to clarify my stance on AI PRs.
I’m calling this <code class="language-plaintext highlighter-rouge">AI_POLICY.md</code>.
I did consider adding an AI policy to <code class="language-plaintext highlighter-rouge">CONTRIBUTING.md</code>, but that file tends to be used to inform <em>how</em> to contribute, which seems a different purpose entirely.</p>

<p>I’m hoping this could become a standard file, and AI agents would refer to this when generating a PR.
Until then, I can link to it when I close slop PRs.</p>

<p>If something like this exists already, or there is a more agent-friendly way of doing this, then let me know.</p>

<p>Here’s the text I’m going with.
I don’t think this is particularly challenging to meet, and only a slightly higher bar than what I’d expect from a mammalian brain.</p>

<h2 id="ai_policymd">AI_POLICY.md</h2>

<p>This project accepts AI generated Pull Requests, as long as the following guidelines are met.</p>

<ul>
  <li>The Pull Request must fill in the repository’s pull request template.</li>
  <li>The Pull Request must identify itself as AI generated, including the name of the agent used.</li>
  <li>The Pull Request must link to a issue or discussion where a solution has been approved by a maintainer (@willmcgugan).</li>
</ul>

<p>The maintainer reserves the right to close PRs without comment if the above are not met.</p>

<h2 id="update">Update</h2>

<p>Turns out <code class="language-plaintext highlighter-rouge">AI_POLICY.md</code> is being used in a bunch of projects, for this purpose.</p>

<p>Oddly, Claude told me there was no standard for this.
I suspect this is an organically emerging “standard”, and I hope it is adopted by more projects!</p>]]></content><author><name>Will McGugan</name></author><category term="tech" /><category term="AI" /><summary type="html"><![CDATA[If you maintain Open Source software, you will likely have encountered AI slop PRs.]]></summary></entry><entry><title type="html">Good AI, Bad AI - the experiment</title><link href="http://willmcgugan.github.io/good-ai-bad-ai/" rel="alternate" type="text/html" title="Good AI, Bad AI - the experiment" /><published>2026-01-10T00:00:00+00:00</published><updated>2026-01-10T00:00:00+00:00</updated><id>http://willmcgugan.github.io/good-ai-bad-ai</id><content type="html" xml:base="http://willmcgugan.github.io/good-ai-bad-ai/"><![CDATA[<p>If you are in tech, or possibly even if you aren’t, your social feeds are likely awash with AI.
Most developers seem to be either all-in or passionately opposed to AI (with a leaning towards the all-in camp).
Personally I think the needle is hovering somewhere between bad and good.</p>

<h2 id="good-ai">Good AI</h2>

<p>AI for writing code is a skill <em>multiplier</em>.</p>

<p>We haven’t reached the point where a normie can say “Photoshop, but easier to use”.
Will we ever?
But for now it seems those who are already skilled in what they are asking the AI to do, are getting the best results.</p>

<p>I’ve seen accomplished developers on X using AI to realize their projects in a fraction of the time.
These are developers who absolutely <em>could</em> write every line that the LLM produces.
They choose not to, because time is their most precious commodity.</p>

<p>Why is this <em>good</em> AI?
It means that skills acquired in the age before AI <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> are still valuable.
We have a little time before mindless automatons force senior developers into new careers as museum exhibits, tapping on their mechanical keyboards in front of gawping school kids, next to the other fossils,</p>

<h2 id="bad-ai">Bad AI</h2>

<p>The skill multiplier effect may not be enough to boost inexperienced (or mediocre) developers to a level they would like.
But AI use does seem to apply a greater boost to the Dunning-Kruger effect.</p>

<p>If you maintain an Open Source project you may be familiar with AI generated Pull Requests. Easily identifiable by long bullet lists in the description, these PRs are often from developers who copied an issue from a project into their prompt, prefixed with the words “please fix”.</p>

<p>These drive-by AI PRs generate work for the FOSS developer.
They can look superficially correct, but it takes time to figure out if the changes really do satisfy the requirements.
The maintainer can’t use the usual signals to cut through the noise when reviewing AI generated PRs.
Copious amounts of (passing) tests and thorough documentation are no longer a signal that the PR won’t miss the point, either subtly or spectacularly.</p>

<p>This is bad AI (more accurately a bad <em>outcome</em>), because it typically takes more time for the maintainer to review such PRs than the creator took to type in the prompt.
And those that contribute such PRs rarely respond to requests for changes.</p>

<p>In the past you could get around this with a blanket ban on AI generated code.
Now, I think developers would be foolish to do that.
Good code is good code, whether authored by a fleshy mammalian brain or a mechanical process.
And it is undeniable that AI code can be <em>good</em> code.</p>

<h2 id="the-experiment">The Experiment</h2>

<p>This makes me wonder if the job of maintainer could be replaced with AI.</p>

<p>I want to propose an experiment…</p>

<p>Let’s create a repository with some initial AI generated code: “Photoshop, but easier to use” is as a starting point as good as any.
An AI agent will review issues, respond via comments, and may tag the issue with “todo” or close it if it doesn’t reach a bar for relevance and quality.</p>

<p>PRs are accepted for “todo” issues and will be reviewed, discussed, and ultimately merged or closed by the AI.
These PRs may be human or AI generated—the AI doesn’t care (as if it could).</p>

<p>Note that PRs could modify any of the prompts used by the AI, and those edits will be reviewed by the AI in the same way as any other file.</p>

<p>Would the end result be quality software or a heinous abomination, succeeding only in creating a honeypot for prompt-injection attacks?</p>

<p>I have no intention of making this happen.
But if somebody does, tell me how it goes.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>Feels like a long time, but there has only been a single Fast and Furious movie made since the advent of the AI age. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Will McGugan</name></author><category term="tech" /><category term="AI" /><summary type="html"><![CDATA[If you are in tech, or possibly even if you aren’t, your social feeds are likely awash with AI. Most developers seem to be either all-in or passionately opposed to AI (with a leaning towards the all-in camp). Personally I think the needle is hovering somewhere between bad and good.]]></summary></entry><entry><title type="html">Toad is a unified experience for AI in the terminal</title><link href="http://willmcgugan.github.io/toad-released/" rel="alternate" type="text/html" title="Toad is a unified experience for AI in the terminal" /><published>2025-12-18T00:00:00+00:00</published><updated>2025-12-18T00:00:00+00:00</updated><id>http://willmcgugan.github.io/toad-released</id><content type="html" xml:base="http://willmcgugan.github.io/toad-released/"><![CDATA[<p>My startup for terminals wrapped up mid-2025 when the funding ran dry.
So I don’t have money, but what I do have are a very particular set of skills.
Skills I have acquired over a very long career convincing terminals they are actually GUIs.</p>

<p>Skills which I have used to create a terminal app that offers a more pleasant experience for agentic coding.
Toad (a play on <em>Textual Code</em>) is a front-end for AI tools such as <a href="https://openhands.dev/">OpenHands</a>, <a href="https://www.claude.com/product/claude-code">Claude Code</a>, <a href="https://geminicli.com/">Gemini CLI</a>, and many more. 
All of which run seamlessly under a single terminal UI, thanks to the <a href="https://agentclientprotocol.com/protocol/initialization">ACP</a> protocol.</p>

<p>At the time of writing, Toad supports 12 agent CLIs, and I expect many more to come online soon.</p>

<p>Here’s a screenshot:</p>

<p><img src="../images/toad-released/toad-1.png" alt="Toad UI" /></p>

<p>So what does Toad offer over the CLI apps from big tech?</p>

<p>It has most of the UI interactions users have come to expect from agentic coding, but hopefully more refined.
For instance the “@” character to bring in files into the context. Here’s Toad’s implementation:</p>

<p><img src="../images/toad-released/fuzzy-file.gif" alt="Toad fuzzy files" /></p>

<p>A snappy <em>fuzzy</em> search which filters patterns from the project’s <code class="language-plaintext highlighter-rouge">.gitignore</code> (if there is one).</p>

<p>The prompt editor offers an experience which you might be surprised to find in a terminal.
You can navigate and select with the keyboard and mouse, select, cut, copy, paste, etc.
The prompt will highlight Markdown as you type (even syntax highlighting code fences <em>before</em> you close them).</p>

<p><img src="../images/toad-released/prompt.gif" alt="Toad prompt" /></p>

<p>Toad has really nice Markdown streaming, based on the techniques I described <a href="https://willmcgugan.github.io/streaming-markdown/">here</a>.
It remains fast with large documents, and renders everything from tables to syntax highlighted code fences.</p>

<p><img src="../images/toad-released/stream.gif" alt="Toad Markdown streaming" /></p>

<p>Many other tools either don’t bother to render the Markdown, or they do a fairly half-hearted job.</p>

<p>Another goal I had for Toad was to integrate a shell.
I wanted the conversation with AI to feel like a natural extension of a traditional terminal based workflow.</p>

<p>Most tools stop at displaying monochrome output from commands.
Some will break if you run something interactive, like a TUI.
Toad doesn’t have this limitation, and will let you run all your CLI apps with full color, interactivity, and mouse support.</p>

<p>At the time of writing the only terminal based agentic coding tool I know of that runs dynamic commands inline is Gemini.</p>

<p><img src="../images/toad-released/htop.gif" alt="Toad running htop" /></p>

<p>Toad adopts the convention of using a <code class="language-plaintext highlighter-rouge">!</code> character to introduce a shell command.
There is also a list of commands in settings which will automatically trigger shell mode.
In practice, this means that you rarely need to explicitly introduce shell commands—just type what’s on your mind.</p>

<p>Toad borrows tab completion from the shell.
You’ll appreciate this if you have worked in the terminal long enough to commit this interaction to muscle memory.
Hit tab to complete the command or path.
If there is more than one possibility you can hit tab again to cycle through them, and enter to accept.</p>

<p><img src="../images/toad-released/tabcomplete.gif" alt="Toad tab complete" /></p>

<p>In addition to the shell, Toad implements a few concepts from Jupyter notebooks.
You can cursor through previous conversation, moving a logical block at a time, and interact with it again.
At the moment that feature is used as a convenience to copy content to the clipboard or prompt, and a few other niceties like exporting a SVG.</p>

<p><img src="../images/toad-released/cursor-block.png" alt="Cursor block" /></p>

<p>Toad will lean more heavily in to this kind of interaction in the future.</p>

<h2 id="friends-of-toad">Friends of Toad</h2>

<p>I was very fortunate to collaborate with <a href="https://openhands.dev/">OpenHands</a>, who are doing some amazing work in this space. Check out their <a href="https://www.openhands.dev/blog/20251218-openhands-toad-collaboration">blog post</a> on Toad!</p>

<p>I also collaborated with <a href="https://huggingface.co">Hugging Face</a> on this release. Check out their blog post on their <a href="https://huggingface.co/toad-hf-inference-explorers">inference explorers</a>!</p>

<h2 id="try-toad">Try Toad</h2>

<p>When this post is live you will be able to install Toad yourself.</p>

<p>The work is ongoing: a few missing features and interface improvements to be done, but Toad is solid enough to use as your daily driver for AI.
I used it to create <a href="https://www.batrachian.ai">batrachian.ai</a>, where you will find install instructions.</p>

<p>For more details, see the <a href="https://github.com/batrachianai/toad">Toad</a> repository.</p>

<p>I need a break (sabbaticals are tiring), but I’ll be picking things up in 2026.
I’m hoping that by the time my year off ends, Toad could become my full-time gig.
If you want to help make that happen, consider <a href="https://github.com/sponsors/willmcgugan">sponsoring my work</a>.</p>]]></content><author><name>Will McGugan</name></author><category term="text" /><category term="toad" /><category term="ai" /><summary type="html"><![CDATA[My startup for terminals wrapped up mid-2025 when the funding ran dry. So I don’t have money, but what I do have are a very particular set of skills. Skills I have acquired over a very long career convincing terminals they are actually GUIs.]]></summary></entry><entry><title type="html">The Toad Report #3</title><link href="http://willmcgugan.github.io/toad-report-3/" rel="alternate" type="text/html" title="The Toad Report #3" /><published>2025-11-17T00:00:00+00:00</published><updated>2025-11-17T00:00:00+00:00</updated><id>http://willmcgugan.github.io/toad-report-3</id><content type="html" xml:base="http://willmcgugan.github.io/toad-report-3/"><![CDATA[<p>Welcome to the third issue of the Toad Report. If you are new here, Toad is a universal interface for API I am currently building.</p>

<p>To date, most of the my work on Toad has been focussed on building the “conversation” view where the user can converse and interact with their chosen AI agent.
This has come together rather well, with a polished enough user experience for <a href="https://huggingface.co/">Hugging Face</a> to start building integrations with their technology!
And all before Toad’s official release.</p>

<div style="display: flex; justify-content: center;">
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Some technologies are indistinguishable from magic... <a href="https://twitter.com/willmcgugan?ref_src=twsrc%5Etfw">@willmcgugan</a> <a href="https://t.co/6idsU3dIDa">pic.twitter.com/6idsU3dIDa</a></p>&mdash; Shaun Smith (@evalstate) <a href="https://twitter.com/evalstate/status/1990347931249954872?ref_src=twsrc%5Etfw">November 17, 2025</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>

<p>The conversation view can be considered the body of Toad.
But a body needs a head.
In the case of Toad, it needs an interface where the user can find, install, and launch agents.
Which is what Ive been working on recently.</p>

<p>The following will be the first view the user will see if they launch <code class="language-plaintext highlighter-rouge">toad</code> with no arguments:</p>

<p><img src="../images/toadreport3/store1.png" alt="Toad Store" /></p>

<p>From here the user can navigate the (growing) list of compatible agents.
When they select one of interest, Toad will pop up a dialog with information (in beautiful markdown) regarding the agent.</p>

<p>In this dialog is a pull down list of possible actions associated with the agent—where there will typically be at least an “install” action.</p>

<p><img src="../images/toadreport3/store2.png" alt="Toad Store" /></p>

<p>Clicking the “Go” button downloads and installs the agent without ever leaving the app:</p>

<p><img src="../images/toadreport3/store3.png" alt="Toad Store" /></p>

<p>When an agent is installed, it is placed in the “quick launch” area.
Each entry in the quick launch has a digit associated, so they can jump straight to that agent.</p>

<p><img src="../images/toadreport3/store4.png" alt="Toad Store" /></p>

<p>When an agent is selected (quick launch or other), the user can press space to launch the conversation view and begin their agentic coding session.</p>

<p>I wanted the experience to be as friction free as possible.
There are many coding agents out there, but not all of them have the same visibility as those offered by big tech.
I’m hoping this will promote the less well funded agents.</p>

<p>Here’s a video a recorded of the installation process.
The interface is a little older than the screenshots, but you should get the idea…</p>

<iframe width="100%" style="aspect-ratio:16/11;" src="https://www.youtube.com/embed/xZvHS7wMFlk" title="toad store" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<h2 id="found-this-interesting">Found this interesting?</h2>

<p>Follow me on the socials where I will be posting regular updates.
You can also join the <a href="https://discord.gg/Enf6Z3qhVr">Textual Discord Server</a> if you want to chat with me or the Textual community.</p>

<p>Join the <code class="language-plaintext highlighter-rouge">#toad</code> channel if you would like an invite to the Toad repository. I’ll be sending more out in a week or two.</p>

<p>Thanks for reading!</p>]]></content><author><name>Will McGugan</name></author><category term="tech" /><category term="toad" /><category term="ai" /><summary type="html"><![CDATA[Welcome to the third issue of the Toad Report. If you are new here, Toad is a universal interface for API I am currently building.]]></summary></entry><entry><title type="html">A Developer’s experience with weight loss injections</title><link href="http://willmcgugan.github.io/weight-loss/" rel="alternate" type="text/html" title="A Developer’s experience with weight loss injections" /><published>2025-11-06T00:00:00+00:00</published><updated>2025-11-06T00:00:00+00:00</updated><id>http://willmcgugan.github.io/weight-loss</id><content type="html" xml:base="http://willmcgugan.github.io/weight-loss/"><![CDATA[<p>This is a personal account of my experiences taking weight loss medication.
Quite a departure from my usual content.</p>

<p>I have no doubt that you are smart enough <em>not</em> to take medical advice from some random nerd on the internet, but let me say it anyway: none of the following is medical advice.
I want to share my experiences and perspectives in addition to a vibe-coded tool, but I’m not trying to convince you of anything.
Please don’t take my word for anything health related—talk to a medical professional first!</p>

<p>Got it? Good.</p>

<p>One of my main goals from my year off was to lose weight, which had been creeping upwards over the years.
When I started my sabbatical in June I had reached 100kg which pushed me just over the threshold from overweight to obese.</p>

<p>Of course this shocked me.
Doubly so, because I didn’t feel that big.
If I were to walk out of my house on any given day I would pass plenty of other folk with much larger waistlines than mine.
Living in a country 🏴󠁧󠁢󠁳󠁣󠁴󠁿 were deep frying is a religion and “juice” doesn’t contain fruit, clearly gave me a false perspective.</p>

<p><a href="https://en.wikipedia.org/wiki/Deep-fried_Mars_bar"><img src="../images/DeepFriedMarsBar.jpg" alt="Scottish food" /></a>
<em>Scottish food</em></p>

<p>Although I didn’t feel so large, I was very much aware of a number of weight related health issues dragging my quality of life downwards.
For years I had managed these issue, but I could see they weren’t going to improve without losing weight.</p>

<p>There was a time (~10 years ago) when I was in good shape and my weight was stable.
I attributed this to running.
A 5km three times a week and the occasional 10km plus some resistance training meant I could eat more-or-less what I wanted.
The turning point was when I developed a <em>herniated disc</em>.
An hour’s run would be followed by 48 hours of constant back pain.</p>

<p>Incidentally, a herniated disc must be the dumbest flaw in the human body.
The human spine is a miraculous thing, but the “discs” (essentially washers that separate vertebrae) are prone to (literal) bursting.
Around 50% of the population have a herniated disc by the age of 50.
Most cause no symptoms, but in some people (like myself) the bulging disc presses on a nerve, causing pain.
If there were a git repository for the human body, I would surely file a passive-aggressive issue.
I might remark on that issue how it was clearly a poor choice to install a component with 50 year life span into something expected to last at least 80 years.</p>

<p>Exercises recommended by a physio didn’t help (they actually made it worse).
Heat packs, cold packs, ibuprofen, and massage offered only short term relief.</p>

<p>When I stopped running for a few days the pain became an occasional sharp piercing pain rather than a constant ache.
Not great, but bearable.</p>

<p>And so ended my running career.</p>

<p>I replaced the running with nothing at all.
Other than walking (more as my default method of transport) I didn’t really exercise.
I can’t attribute this entirely to the back pain.
There are several forms of exercise that don’t inflame the back pain, such as swimming.
I just didn’t find anything that I enjoyed doing regularly in the same way as running.</p>

<p>My diet is fairly healthy—for a Scot at least.
I suspect I am in the top 0.1% percentile in the country for eating vegetables (and I’m not counting potato).
My downfall is more sweet foods, which I typically indulge in my morning pastry and coffee.
The rest of the day I try to eat healthy.
I watch portion size and routinely deny myself things I would enjoy eating (trust me: if I ate all the sweet things I wanted to, my diet would be 90% cinnamon buns).</p>

<p>Alas, this wasn’t enough to keep the weight down.
The scales don’t lie, and they were telling me I was getting heaver over time, which meant I was consuming more calories than I was expending.
But how many more calories was I eating?</p>

<p>Turns out that is easy to calculate.
There are approximately 7,700 calories in 1kg of human fat (eww—try not to imagine 1kg of fat).
I had gained 8.5kg in 1400 days, which works out as a ~47 calorie excess per day.
Around half an apple’s worth.</p>

<p>Half an apple?
Two or three additional mouthfuls a day is all it takes to put you on a trajectory to being overweight / obese and all the health issues that entails.
Yeah, well that was an eye opener.</p>

<p>If you are gaining or losing weight yourself, you might want to try this tool I vide-coded with <a href="https://willmcgugan.github.io/categories/#toad">Toad</a> and Claude:</p>

<div class="calorie-calculator">
    <h3>Excess Calorie Calculator</h3>
    
    <div class="form-group">
        <label for="startWeight">Starting Weight (kg)</label>
        <input type="number" id="startWeight" step="0.1" placeholder="e.g., 70.0" />
    </div>
    
    <div class="form-group">
        <label for="endWeight">Ending Weight (kg)</label>
        <input type="number" id="endWeight" step="0.1" placeholder="e.g., 73.5" />
    </div>
    
    <div class="form-group">
        <label for="startDate">Start Date</label>
        <input type="date" id="startDate" />
    </div>
    
    <div class="form-group">
        <label for="endDate">End Date</label>
        <input type="date" id="endDate" />
    </div>
    
    <button class="calculate-btn" onclick="calculateCalories()">Calculate</button>
    
    <div class="error" id="error"></div>
    
    <div class="results" id="results">
        <h3>Results</h3>
        <div class="result-item">
            <div class="result-label">Weight Change:</div>
            <div class="result-value" id="weightChange"></div>
        </div>
        <div class="result-item">
            <div class="result-label">Time Period:</div>
            <div class="result-value" id="timePeriod"></div>
        </div>
        <div class="result-item">
            <div class="result-label">Total Excess Calories:</div>
            <div class="result-value" id="totalCalories"></div>
        </div>
        <div class="result-item">
            <div class="result-label">Excess Calories Per Day:</div>
            <div class="result-value" id="caloriesPerDay"></div>
        </div>
    </div>
</div>

<style>
    .calorie-calculator {
        max-width: 500px;
        margin: 20px auto;
        padding: 20px;
        border: 1px solid #ddd;
        border-radius: 8px;
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
        background-color: #f9f9f9;
    }
    
    .calorie-calculator h2 {
        margin-top: 0;
        color: #333;
        font-size: 1.5em;
    }
    
    .form-group {
        margin-bottom: 15px;
    }
    
    .form-group label {
        display: block;
        margin-bottom: 5px;
        font-weight: 500;
        color: #555;
    }
    
    .form-group input {
        width: 100%;
        padding: 8px;
        border: 1px solid #ccc;
        border-radius: 4px;
        box-sizing: border-box;
        font-size: 14px;
    }
    
    .form-group input:focus {
        outline: none;
        border-color: #4CAF50;
    }
    
    .calculate-btn {
        width: 100%;
        padding: 10px;
        background-color: #4CAF50;
        color: white;
        border: none;
        border-radius: 4px;
        font-size: 16px;
        font-weight: 500;
        cursor: pointer;
        margin-top: 10px;
    }
    
    .calculate-btn:hover {
        background-color: #45a049;
    }
    
    .results {
        margin-top: 20px;
        padding: 15px;
        background-color: white;
        border-radius: 4px;
        border-left: 4px solid #4CAF50;
        display: none;
    }
    
    .results.show {
        display: block;
    }
    
    .results h3 {
        margin-top: 0;
        color: #333;
        font-size: 1.2em;
    }
    
    .result-item {
        margin: 10px 0;
        padding: 8px 0;
        border-bottom: 1px solid #eee;
    }
    
    .result-item:last-child {
        border-bottom: none;
    }
    
    .result-label {
        font-weight: 500;
        color: #666;
    }
    
    .result-value {
        font-size: 1.1em;
        color: #333;
        font-weight: 600;
    }
    
    .result-value.positive {
        color: #d32f2f;
    }
    
    .result-value.negative {
        color: #388e3c;
    }
    
    .error {
        color: #d32f2f;
        font-size: 14px;
        margin-top: 5px;
        display: none;
    }
    
    .error.show {
        display: block;
    }
</style>

<script>
    const CALORIES_PER_KG = 7700;

    function calculateDaysBetween(startDate, endDate) {
        const start = new Date(startDate);
        const end = new Date(endDate);
        const diffTime = end - start;
        const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24));
        return diffDays;
    }

    function calculateTotalExcessCalories(weightStart, weightEnd) {
        const weightChange = weightEnd - weightStart;
        return weightChange * CALORIES_PER_KG;
    }

    function showError(message) {
        const errorDiv = document.getElementById('error');
        errorDiv.textContent = message;
        errorDiv.classList.add('show');
        document.getElementById('results').classList.remove('show');
    }

    function hideError() {
        document.getElementById('error').classList.remove('show');
    }

    function calculateCalories() {
        hideError();

        // Get input values
        const startWeight = parseFloat(document.getElementById('startWeight').value);
        const endWeight = parseFloat(document.getElementById('endWeight').value);
        const startDate = document.getElementById('startDate').value;
        const endDate = document.getElementById('endDate').value;

        // Validate inputs
        if (!startWeight || !endWeight || !startDate || !endDate) {
            showError('Please fill in all fields');
            return;
        }

        if (startWeight <= 0 || endWeight <= 0) {
            showError('Weight values must be positive');
            return;
        }

        const days = calculateDaysBetween(startDate, endDate);

        if (days <= 0) {
            showError('End date must be after start date');
            return;
        }

        // Calculate results
        const weightChange = endWeight - startWeight;
        const totalExcessCalories = calculateTotalExcessCalories(startWeight, endWeight);
        const caloriesPerDay = totalExcessCalories / days;

        // Display results
        document.getElementById('weightChange').textContent = 
            `${weightChange > 0 ? '+' : ''}${weightChange.toFixed(1)} kg`;
        
        document.getElementById('timePeriod').textContent = 
            `${days} day${days !== 1 ? 's' : ''}`;
        
        const totalCaloriesElement = document.getElementById('totalCalories');
        totalCaloriesElement.textContent = 
            `${totalExcessCalories > 0 ? '+' : ''}${totalExcessCalories.toFixed(0)} kcal`;
        totalCaloriesElement.className = 'result-value ' + (totalExcessCalories > 0 ? 'positive' : 'negative');
        
        const caloriesPerDayElement = document.getElementById('caloriesPerDay');
        caloriesPerDayElement.textContent = 
            `${caloriesPerDay > 0 ? '+' : ''}${caloriesPerDay.toFixed(0)} kcal/day`;
        caloriesPerDayElement.className = 'result-value ' + (caloriesPerDay > 0 ? 'positive' : 'negative');

        // Show results
        document.getElementById('results').classList.add('show');
    }

    // Allow Enter key to trigger calculation
    document.querySelectorAll('input').forEach(input => {
        input.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                calculateCalories();
            }
        });
    });

    // Set default dates (today and 2 months ago)
    const today = new Date();
    const twoMonthsAgo = new Date();
    twoMonthsAgo.setMonth(today.getMonth() - 2);
    
    document.getElementById('endDate').valueAsDate = today;
    document.getElementById('startDate').valueAsDate = twoMonthsAgo;
</script>

<p>So the weight gain is no mystery—I was simply eating to excess.
The solution was also no mystery.
I would have have to stop consuming that additional 47 calories a day to stabilize my weight.
And then reduce it further to reverse the trend.</p>

<p>If I were to subtract <em>another</em> 47 calories in addition to the 47 excess calories, then I would lose weight at the same rate I had previously been gaining.
In other words, eating 94 calories less a day I would return to my healthy weight (~80kg) in about 9 years.</p>

<p>Screw that.</p>

<p>I have a year off to focus on my health, not 9 years.
Losing 20kg in a year would require a 422kcal deficit, on top of the 47 excess I had been eating.</p>

<p>That’s quite doable with healthier food choices and exercise.
I could give up my morning pastry and take up swimming.
But its hard to avoid hearing about weight loss medications, and after looking into it I was tempted.
Ultimately I settled on Mounjaro as it is reported to lead to the greatest weight loss.</p>

<p>The medication comes in a format described as “pen”.
In reality of course it is a syringe, albeit a cleverly designed one designed to deliver 4 measured doses.</p>

<p>I don’t have a problem with needles but I was a little apprehensive about injecting myself.
I needn’t have been.
The needle is tiny (less than 1cm and almost as thin as a human hair), and only needs to go just under the skin to a fat layer.
You bring it down in a stabbing motion and press a button at the top of the “pen” until it delivers the dose.</p>

<p><img src="../images/pulp-fiction-stab.gif" alt="Pulp fiction stab" /></p>

<p>In the first week it was immediately apparent that the medication was doing something.
It did suppress my appetite, but in those first weeks I consciously didn’t eat much at all as any meal resulted in gastric symptoms.
I’ll spare you the details, but that first month the weight loss was dramatic.
The second month was a little better and I could really appreciate the reduction in my appetite.</p>

<p>My wife and I have a running joke.
When I’m hungry I tell her “if I don’t eat in the next 15 minutes I am going to <em>die</em>”.
She replies “give it a try”.
Well I never did give it a try until recently and it turns out she was right.
The sensation of hunger was far less urgent, and I could put it off for way more than 15 minutes.
And when I did eat, I felt like I was done after a very small portion.</p>

<p>Paradoxically I also found that my energy levels were positively brimming during the first two months.
From morning until evening I had loads of energy and of course I wasn’t suffering from a post-lunch slump or evening sluggishness.
I was still suffering from stomach issues, but the increase in energy and clear weight-loss felt like fair compensation.</p>

<p>The stomach issues improved somewhat but were relatively constant throughout the whole experience.
Alas the high energy levels disappeared after two months or so.
The weight loss was rapid, averaging 1kg a week, which is borderline concerning.
I always ate to my appetite and intentionally chose nutritious high-energy foods, hoping to slow down the weight loss just a bit.
But I just couldn’t face eating after a point.</p>

<p>At about 3 months or so after starting Mounjaro I started experiencing another symptom: frequent head-rushes.
I would stand up from a sitting or laying position and instantly feel woozy.
Often leaning against the wall in case I blacked out (I never did).
I would be back to normal after 30 seconds, but this occurred often enough to be a worry.</p>

<p>This turned out to be only indirectly related to the Mounjaro.
I had been on blood pressure medication for a couple of years, and with my blood pressure coming down naturally from the weight loss the medication was too effective.
My GP reduced the medication by half and monitored my blood pressure for another month.
The head-rushes abated and I eventually come off the blood pressure medication altogether.
What a result!</p>

<p>My back pain has also improved.
It hasn’t gone away, but the frequency and intensity of bad-back days has reduced remarkably.
If that wasn’t enough, I haven’t had a single bout of <a href="https://www.nhsinform.scot/illnesses-and-conditions/stomach-liver-and-gastrointestinal-tract/gastro-oesophageal-reflux-disease-gord/">GORD</a> since losing the weight.</p>

<p>It’s now 5 months on since I started Mounjaro, and I have taken my last dose.
I lost just over 20kg which puts me in my ideal weight bracket.
It has been no cake-walk, but I consider the months-long stomach ache to be worth it for the health benefits it has delivered.
I’m looking forward to enjoying food again, but I’m highly motivated not to eat the 47 calories a day that made me obese.</p>

<p>Reflecting on the wider impacts of Mounjaro and similar drugs.
These must surely be the largest change to public health since anti-biotics.
Many of the conditions that kill people in their 50s onwards are made worse if not outright caused by being overweight or obese.
If everyone can get their weight under control it will dramatically reduce rates of diabetes, heart disease, stroke, and cancer.
We will all be living longer more productive lives as a result.</p>

<p>Let me finish by re-iterating that I’m not giving health advice.
Talk to a doctor if you are considering taking any medication, not a Python developer.</p>]]></content><author><name>Will McGugan</name></author><category term="personal" /><category term="weight-loss" /><summary type="html"><![CDATA[This is a personal account of my experiences taking weight loss medication. Quite a departure from my usual content.]]></summary></entry><entry><title type="html">The Toad Report #2</title><link href="http://willmcgugan.github.io/toad-report-2/" rel="alternate" type="text/html" title="The Toad Report #2" /><published>2025-11-01T00:00:00+00:00</published><updated>2025-11-01T00:00:00+00:00</updated><id>http://willmcgugan.github.io/toad-report-2</id><content type="html" xml:base="http://willmcgugan.github.io/toad-report-2/"><![CDATA[<p>Welcome to the second issue of The Toad Report. If you are new here, Toad is a universal interface for AI I am currently building.</p>

<p>Things are moving (hopping) fast in the Toad world.
I recently implemented the <a href="https://agentclientprotocol.com/protocol/initialization">Agent Client Protocol</a> in Toad, which means that Toad can now act as a front-end for Gemini, Claude, Codex, and a variety of other agentic coding solutions.</p>

<p>This is very exciting, as you can now use all these services from a single terminal interface.
And the UX is already leaps and hops ahead of big tech’s CLIs.</p>

<p>Here is a video I recorded of Toad running Claude and Gemini head-to-head.</p>

<iframe width="100%" style="aspect-ratio:16/11;" src="https://www.youtube.com/embed/OGGVdPZTc8E" title="claude v gemini" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<h2 id="welcome-openhands">Welcome OpenHands</h2>

<p>I’m very happy to welcome <a href="https://github.com/OpenHands/OpenHands">OpenHands</a> as my first corporate sponsor!
These guys are pioneers in agentic coding, and I look forward to getting OpenHands running on Toad.</p>

<h2 id="toads-shell">Toad’s shell</h2>

<p>Claude tells me that there is no species of toad that has a shell.
But Toad with a capital T does.</p>

<p>Having an integrated shell within agentic coding tools just makes sense.
But if Toad’s shell can’t match the basic features developers have developed muscle memory for, then it may as well not have a shell at all.
So in the last week I have added a number of traditional shell features.</p>

<p>The first is <em>history</em>: The ability to navigate through your recent shell commands and potentially re-use one.
Pressing <code class="language-plaintext highlighter-rouge">up</code> or <code class="language-plaintext highlighter-rouge">down</code> in Toad’s prompt will move through the history.
Here it is in action:</p>

<p><img src="../images/toadreport2/history.gif" alt="Toad History" /></p>

<p>Toad will offer to auto-complete commands from the history (in addition to some pre-configured favorites).
Hitting <code class="language-plaintext highlighter-rouge">return</code> will accept the suggestion, while <code class="language-plaintext highlighter-rouge">escape</code> will dismiss it.</p>

<p>Here is Toad auto-completing shell commands:</p>

<p><img src="../images/toadreport2/auto-complete-shell.gif" alt="Toad auto complete shell" /></p>

<p>Finally, still in the realm of auto-completion, Toad will auto-complete filenames and paths.
If you hit <code class="language-plaintext highlighter-rouge">tab</code>, then Toad will look for any matching files or directories.
If it finds a single file, it will insert that filename.
If it finds more than one, it will insert any common characters and suggest the remaining characters in the filename.
You can hit <code class="language-plaintext highlighter-rouge">tab</code> again to cycle through those suggestions, and <code class="language-plaintext highlighter-rouge">return</code> or <code class="language-plaintext highlighter-rouge">escape</code> to accept or cancel.</p>

<p>Here is path auto-completion in action:</p>

<p><img src="../images/toadreport2/autocomplete.gif" alt="Toad auto complete paths" /></p>

<h2 id="found-this-interesting">Found this interesting?</h2>

<p>Follow me on the socials where I will be posting regular updates.
You can also join the <a href="https://discord.gg/Enf6Z3qhVr">Textual Discord Server</a> if you want to chat with me or the Textual community.</p>

<p>Join the <code class="language-plaintext highlighter-rouge">#toad</code> channel if you would like an invite to the Toad repository. I’ll be sending more out in a week or two.</p>

<p>Thanks for reading!</p>]]></content><author><name>Will McGugan</name></author><category term="tech" /><category term="toad" /><category term="ai" /><summary type="html"><![CDATA[Welcome to the second issue of The Toad Report. If you are new here, Toad is a universal interface for AI I am currently building.]]></summary></entry><entry><title type="html">Three fascinating Toad facts (the last one blew my mind)</title><link href="http://willmcgugan.github.io/facts-about-toads/" rel="alternate" type="text/html" title="Three fascinating Toad facts (the last one blew my mind)" /><published>2025-09-28T00:00:00+00:00</published><updated>2025-09-28T00:00:00+00:00</updated><id>http://willmcgugan.github.io/facts-about-toads</id><content type="html" xml:base="http://willmcgugan.github.io/facts-about-toads/"><![CDATA[<h3 id="toads-are-frogs">Toads are frogs</h3>

<p>Toads are a <em>common name</em> given to certain species of frog, which are characterized by dry leathery skin, short legs, and a bumps on their back.
But “toad” is not a biological classification; two toads of different species may not be more closely related that a frog and a toad.
A possible exception would be the Bufonidae family in which all members are known as toads (although some may also be called frogs).</p>

<h3 id="toads-are-long-lived">Toads are long lived</h3>

<p>Toads can be surprisingly long lived, reaching 10-12 years in the wild. While others have been recorded living 30 years in captivity.</p>

<h3 id="toad-has-agent-client-protocol-support">Toad has Agent Client Protocol support</h3>

<p>The universal agentic coding application currently known as Toad has added support for <a href="https://agentclientprotocol.com/overview/introduction">Agent Client Protocol</a>, developed by <a href="https://zed.dev/">Zed industries</a>.</p>

<p>Toad now provides an alternative terminal-based front-end to Gemini CLI, and Claude CLI, with no flicker and a greatly enhanced User Interface.</p>

<iframe width="100%" style="aspect-ratio:3840/2160" src="https://www.youtube.com/embed/TzBLW2eFmag" title="Introduction to agentic coding with Toad" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>For further updates and chat about amphibians, join the <code class="language-plaintext highlighter-rouge">#toad</code> channel on the <a href="https://discord.gg/Enf6Z3qhVr">Textualize Discord Server</a>.</p>]]></content><author><name>Will McGugan</name></author><category term="tech" /><category term="toad" /><category term="AI" /><summary type="html"><![CDATA[Toads are frogs]]></summary></entry><entry><title type="html">The Toad Report #1</title><link href="http://willmcgugan.github.io/toad-report-1/" rel="alternate" type="text/html" title="The Toad Report #1" /><published>2025-08-28T00:00:00+00:00</published><updated>2025-08-28T00:00:00+00:00</updated><id>http://willmcgugan.github.io/toad-report-1</id><content type="html" xml:base="http://willmcgugan.github.io/toad-report-1/"><![CDATA[<p>Welcome to the inaugural issue of the Toad Report, an irregular series where I document updates to Toad—my terminal interface for agentic coding and all things AI.</p>

<p>To quickly recap: Toad is intended to be a <em>universal</em> front-end to AI services, which is entirely agnostic to the models and providers, while providing an altogether more humane user-experience.</p>

<iframe width="100%" style="aspect-ratio:16/11;" src="https://www.youtube.com/embed/fSE44AuiC8k" title="Toad Report 1 - video demonstration" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>

<p>Recently I’ve been working on the prompt input, which will be the focus of this post.</p>

<h2 id="the-prompt-input">The Prompt Input</h2>

<p>Like all good things in computing, Toad presents you with a flashing cursor and space to write something.</p>

<p>Toad’s text input follows a number of conventions established by agentic coding tools.
There is plenty of room for innovation here, but if it ain’t broke don’t fix it — so the interactions will feel quite familiar to most devs (although I do intend to address a number of usability and quality of life issues left on the table).</p>

<p><img src="../images/toadreport1/prompt.gif" alt="The flashing cursor is the software developer's chisel and the empty prompt their block of marble" /></p>

<p>The input is a competent text area with much of what you might expect from a browser or desktop app.
You can select text with both the mouse and the cursor, cut, copy, paste, undo and redo.</p>

<p><img src="../images/toadreport1/babies.gif" alt="Toad Text Area" /></p>

<p>The input highlights Markdown quite well.
You can see this occurring in the previous animation, but it really comes in to its own when writing code fences where it can highlight a variety of different languages.
In the future I can see code fences grow a bunch of editing features like smart indentation and LSP support.</p>

<p><img src="../images/toadreport1/fib.gif" alt="Syntax highlighting" /></p>

<p>The default mode for the input is for editing the “prompt” for the large language model.
If you want to enter a shell command you can type a “!” or “$” to enter shell mode.
The prompt symbol and the highlight color changes, so you know can be sure which mode you are in.</p>

<p><img src="../images/toadreport1/shell.gif" alt="Shell commands" /></p>

<p>Additionally, there are a number of blessed commands (which will ultimately be editable in the config) that trigger shell mode.
For the most part Toad will know wether you want to run a command or send a prompt to the AI.
And if you ever do want to send something which looks like a shell command to the LLM, you can hit escape to cancel shell mode.</p>

<p>Typing a forward slash brings up the slash command auto-complete.
You can navigate the available slash commands by moving the cursor through the list, or continue typing and have it narrow down the search, then right to insert the suggested command.</p>

<p>I haven’t implemented any slash commands as yet, but I expect this list to grow.
I also plan on implementing the custom command system supported by other agentic coding tools.</p>

<p><img src="../images/toadreport1/slash.gif" alt="Slash commands" /></p>

<p>Hitting the <code class="language-plaintext highlighter-rouge">@</code> key brings up a list of all the files in the project.
These can be refined by entering a <em>fuzzy</em> search, which matches paths with the letters you enter, but not necessarily contiguously.
This is way more intuitive that in sounds: you can start typing the name of the file and it will typically put it at the top of the list after a few keystrokes, or a enter a few characters from elsewhere in the path to match a subdirectory.</p>

<p><img src="../images/toadreport1/files.gif" alt="Files" /></p>

<p>There is also a tree view of the project docked to the left side of the screen.
While not primarily designed to add paths to the prompt, it would be a nice feature to select a file in the tree and have it populate the prompt.</p>

<h2 id="found-this-interesting">Found this interesting?</h2>

<p>Follow me on the socials where I will be posting regular updates.
You can also join the <a href="https://discord.gg/Enf6Z3qhVr">Textual Discord Server</a> if you want to chat with me or the Textual community.</p>]]></content><author><name>Will McGugan</name></author><category term="tech" /><category term="toad" /><category term="ai" /><summary type="html"><![CDATA[Welcome to the inaugural issue of the Toad Report, an irregular series where I document updates to Toad—my terminal interface for agentic coding and all things AI.]]></summary></entry></feed>