From Github Issues to Code

TL;DR: An experiment automating a progressive web app's maintenance by hooking mobile data collection directly to an issue-driven AI coding pipeline.

With the advent of coding agents like ClaudeCode and OpenCode, I have been able to convert many of my ideas into working applications. I have now ended up with a large number of applications that I regularly (but infrequently) use where the code does not change often.

There does come that occasional bug or feature that I want. At those instances, I find myself bound to my workstation, needing to download and build the app, and then stare at the LLM generating one token after another till the work is done. 

I wanted to see if we could move the entire maintenance loop for a such projects off a local dev machine into GitHub issues with an hosted LLM orchestrating the work. Shifting the entry point to an issue forces a clear discipline of making my prompts traceable while giving me the flexibility to "work from anywhere".

The project 

I tried this out on a project that was born out of curiosity. I recently visited the capital and found a lot of cars with a diplomatic license plates. With a kid is interested in international politics (thanks to Model UN), I thought this would be a fun way for them to understand what country the plate was mapped to, and learn about the country. 

I built the first version using Claude code, but have not changed the code much. Occasional bugs popped up, so I wanted a setup where I could add changes purely using Github issues. 

 

The Pipeline Automation

The repository uses GitHub Actions to orchestrate mutations and dependencies without local execution environments:

  • First Run: Triage relies on a strict label validation script. The workflow immediately strips labels unless they originate from a verified account, preventing unauthorized API usage and token resource depletion from random public traffic.
  • AI Generation: The orchestrator packages the issue text with repository formatting rules and testing constraints. It sends this prompt payload to an asynchronous coding agent to generate the change and open a pull request.
  • Inline Consolidation: Because GitHub suppresses secondary webhooks for standard tokens, a single workflow sequence handles the full chain: waiting for required checks, squash-merging, closing the issue, and initiating the final deployment.

With these three in place, I was able to open a github issue and label it. The prompt would then hand it over to Jules that would create a pull request, and merge and deploy after a successful run. 

 

Limitations

Operating a one-shot pipeline revealed structural limitations compared to interactive, command-line local development.

Prerequisite Research: Debugging mid-flight is not possible in this structure. I had to manually look up data variants on Google first to feed the issue template an exact, error-free description. A local command-line tool allows you to react incrementally to unexpected parser errors, adjusting the codebase iteratively based on stack traces. Here, any missing validation rule in the initial prompt results in a failed build that requires a new issue to resolve.

Visual Layout Blindness: The pipeline pushed and merged valid script modifications that frequently broke the interface layout. Because I was not actively inspecting terminal diffs or loading local dev servers, visual regressions went unnoticed until the code was live on the main branch. The system could easily optimize data parsing arrays while breaking CSS alignment, highlighting the risk of automated merges based purely on passing unit tests.

Future Ideas

We could make a layout-safe workflow by integrating structural snapshot tests directly into the pre-merge checks. I may be missing an existing GitHub action constraint, but running a headless visual check before the automated squash-merge would catch the interface bugs early. We should also look into configuring custom repository secrets to allow standard deployment webhooks to fire after an automated merge closes the issue, removing the need to embed subsequent triggers inside the primary orchestration file.

 

Until then, try out https://diplospot.github.io/, and open an issue if you find a bug or need a feature. Once I tag it, hopefully the pipeline can built it asynchronously ! 


Debugging React Native iOS Apps with Safari

React Native has great developer experience, and the debugging workflow is at the core of the workflows. Today, we use Chrome to debug JavaScript in React Native apps. In this blog, I explore an alternative approach to the debugging workflow using Safari.

How debugging works today

To start debugging, we open the developer menu (using Cmd+D) and select "Debug with Chrome". This action tells the Metro Packager to open the Chrome browser and the JavaScript code now runs on Chrome, instead of running on the device. A web socket connection between Chrome and the device/emulator via metro is responsible delivering the JS commands to Chrome, and sending the results of the statements back to the emulator.

Issues with Chrome as a Debugger

The entire debugger setup is pretty clever as it brings the classic web development workflow to mobile. However, there are a few issues with this setup
  1. The JS VM running on the device is JavaScript Core (JSC), and is different from V8/Chrome during debug mode. These JS VM differences could lead to hard to fix bugs.
  2. Communication during debug mode is over a web socket, which is inherently asynchronous. This poses a problem for cases when native modules expose synchronous APIs. The issue only gets larger Fabric and TurboModules, which have many more synchronous methods.
  3. Many developers currently using the JS Profiler in Chrome to understand the  performance of their React Native app. The profiles are not accurate since they have that web socket layer, introducing a level of network latency, which is not present in the real app.  

Using Safari

Turns out, Safari can be used to connect to apps that run JSC. For React Native apps, we can use Safari to debug JavaScript and use workflows like setting breakpoints, inspecting variables, etc. However, the JSC debugger in Safari does not use the network stack, which means that the sourcemap URL in the index.bundle file is not evaluated, leaving us to debug one giant JS file.
To work around this, we an use inline sourcemap that can be enabled by a single line change in the Appdelegate.m file.

In the file sourceURLForBridge, replace return [[RCTBundleURLProvider sharedSettings]...  with the following

[NSURL URLWithString:[[[[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil] absoluteString] stringByAppendingString:@"&inlineSourceMap=true" ]];

This line simply appends a inlineSourceMap=true, making metro return the sourecmaps with the index.bundle file.
Once this is setup, Safari can successfully recognize the sourcecmaps and open the source files correctly.



Next Steps


Note that this method works with emulators, it does not work with the device. Now that we have Safari working, I would also like to get the JS Profiler in Safari, to give us accurate JS execution information, which should help improving performance of the apps.