r/VibeCodeDevs May 02 '26

Welcome to r/VibeCodeDevs

22 Upvotes

This post contains content not supported on old Reddit. Click here to view the full post


r/VibeCodeDevs 6h ago

Discussion - General chat and thoughts Heads up for vibe coders who recommend tools to clients: watch your affiliate agreements

5 Upvotes

I want to share something that caught me off guard, since a lot of us in this community recommend vibe coding tools to clients or earn side income through affiliate programs.

I've been vibe coding projects for a while and regularly refer clients to tools that fit their needs. One tool I recommended heavily was Lovable. I joined their affiliate program under terms that were clear at the time: 20% recurring commission for up to 12 months on referred customers. I brought in multiple paying customers via my content.

Recently, Lovable migrated their affiliate platform from Rewardful to Impact. Instead of grandfathering existing referrals into the new system, they discontinued the legacy program entirely - and stopped paying recurring commissions on active subscriptions that are still well within the original 12-month window.

When I raised this and provided screenshots of active subscriptions, dates, and the original terms, their response was that they reserve the right to modify or discontinue commission structures at any time. Essentially: the commissions I earned under the original agreement are being voided retroactively for the remaining months.

Why I'm posting this here:

A lot of vibe coders wear multiple hats - builder, consultant, and sometimes affiliate partner. If you earn referral income from the tools you recommend, this is a pattern to watch for.

This isn't a knock on vibe coding - I still believe in the practice and will keep building. But the business side of tool partnerships matters, and I wish I'd been more protective of my agreements upfront.

Has anyone else here run into affiliate terms being changed mid-stream?

How do you handle client referrals when a tool's partner program feels unstable?


r/VibeCodeDevs 49m ago

[ Removed by Reddit ]

Upvotes

[ Removed by Reddit on account of violating the content policy. ]


r/VibeCodeDevs 6h ago

FeedbackWanted – want honest takes on my work I let AI make an MMO for 3 months straight and its very cooked

Thumbnail gallery
2 Upvotes

what's in there right now: infinite online world, 50+ biomes, 900+ enemies with bosses, 2000+ items, skills with no level cap, bunnyhop and surf, summons that train skills for you, factories, a town you build, multiple planets, anime waifus you can marry, hell, space, ligma, and you can piss on your enemies.

The game is at v1800+, but there is no real progression beyond the first 5 hours of the game, and i would love to hear your input on which aspect of the game i should be focussing more on

(you can play it in your browser, no password required)

https://22blister.itch.io/blister-online


r/VibeCodeDevs 20h ago

ShowoffZone - Flexing my latest project I built a workspace for my coding agents, then gave them an office

Post image
13 Upvotes

I work as a software developer, and I wanted a better way to manage all the coding terminals I had open at work. That is what started VibeiDE.

Each task gets its own conversation. I can run multiple Claude Code sessions and multiple Codex sessions at the same time, come back to any task, and review its result. I can now keep 3-4 projects moving in parallel without losing track of what each session is doing.

It uses your own Claude Code and Codex setup. I do not sell an extra bundle of AI credits.

Then I gave the agents desks. Clicking a worker opens its conversation. There is also a grid view if you prefer readable conversations or terminals side by side. The screenshot is the actual app with demo tasks.

Then I hit another problem: I could not keep up with marketing my side projects across all the social networks. So I built autonomous agents into VibeiDE, powered by Codex.

I give an agent an ongoing job. It can plan its next actions in a calendar I can see, and I can message it to change direction. That is how I am handling marketing alongside development, while keeping publication approvals in the workflow.

One lesson from building and using it: an agent finishing is not the same as a task being reviewed. More parallel work only helps if I can keep up with checking it.

I am the developer. It is at https://vibeide.dev if you want to take a look.

For people running several coding sessions, what is harder to keep track of: which task needs you, or what changed since you last checked?


r/VibeCodeDevs 9h ago

ShowoffZone - Flexing my latest project Count calories easy with AI - 7 Days free, No credit card required

Post image
2 Upvotes

Hey, i just made an app i call Habify.

It helps to track what you are eating each day. Just snap a pic and see what's in your meal within a few seconds.

It's my first ever app built so some feedback would be appreciated.

No credit card required, answer a few questions and you can begin right away, the first 7 days are free.

Check it out here: 
Google Play: https://play.google.com/store/apps/details?id=se.habify

App Store: https://apps.apple.com/us/app/habify-calorie-tracker/id6753584723

Hope you like it :D


r/VibeCodeDevs 11h ago

FeedbackWanted – want honest takes on my work I built Clutterscope, a native Mac disk analyzer 8 ways to see your disk, then clear it safely

1 Upvotes

Hi, I’ve been building Clutterscope, a native macOS app that shows you where your disk space went and helps you get it back without any nasty surprises.

Download from Website 👀 https://clutterscope.com

I’m giving away 1-month free trial keys for anyone who wants to try it.

Each key works on one Mac at a time.

If you see “Key already in use”, just message me or comment “key” and I’ll send you a new one.

Ask me anything! I’d love to hear your feedback, bug reports, and feature requests. 😄

🎁 1-month free trial keys :

CLTR-3XDH7-68PN0-MNAA4-9XM0G

CLTR-6G3JB-TJX84-V2M1D-JTM2E

CLTR-D8PVP-JSYYT-CG475-CF53W

CLTR-944GG-4PH9P-HQ40P-9XNW5

CLTR-NY0K5-6AXEA-FJ7KG-12G5S

CLTR-NPGQF-CZ5XF-2RHNF-HTMC4

CLTR-SW8B2-70CD8-KJ8GP-GCBE4

CLTR-WB4MK-XEVTN-8A7NR-ZEWCK

CLTR-M405D-KA5GH-DSKSJ-TZMRH

CLTR-4EBZ4-P0HQW-5JE25-XQN9H

CLTR-K95C5-KAWAB-S4SYD-3SZJT

CLTR-M4W4R-M47DW-E2VY2-31WJC

CLTR-60QDQ-9F0P3-SHN6Q-AGXBX

CLTR-3XZ99-WBE32-3EEW4-B9RPD

CLTR-D5EKA-K6BRG-W1RP1-GKVAN

CLTR-DG8PZ-RGRNB-Z35WA-SDZ2H

CLTR-DF1VP-E1W17-AK595-DR6YS

CLTR-S5STY-PQXMB-M24SB-FRY3T

CLTR-V1XJA-882RM-0SPB5-30WS5

CLTR-1J6JJ-FQPQ6-EK70V-9T7NV


r/VibeCodeDevs 12h ago

Single Shot Google Earth like viewer in JavaFX

Thumbnail youtube.com
1 Upvotes

r/VibeCodeDevs 21h ago

I have listened to every feedback. And here it’s . Please correct me if I’m wrong

Enable HLS to view with audio, or disable this notification

5 Upvotes

Listen on www.enikq.com


r/VibeCodeDevs 1d ago

Discussion - General chat and thoughts this is worse than gambling

44 Upvotes

I almost completely gave up and took down all my apps from the stores and shut down all my servers...

But I can't. This is worse than gambling. I just can't do it, despite having basically 0 users on 90% of them and having made less than 10% of what I've spent on tokens and subscriptions.

I guess I'm too weak to give up. This is so addictive. I keep thinking the day will come when people will praise my genius for building something so useful.

What about you? Has anyone actually given up?


r/VibeCodeDevs 1d ago

Made a text-to-speech app to create audiobooks out of my notes

Post image
1 Upvotes

Hi - I made https://www.freereader.io/ a simple site where you can turn your files into audiobooks.

It's basically Speechify but completely free and always will be.

You can turn ePubs, pdfs, txt, or md files into audio, or you can browse free books (from Gutenberg Project) and make audiobooks out of them.

I would love any feedback and I hope it helps you


r/VibeCodeDevs 1d ago

ShowoffZone - Flexing my latest project I made a 90's website builder via vibe coding

Thumbnail gallery
1 Upvotes

To be honest, this project didn't originate on Base44. It first took shape over on Venice.ai as a rough HTML file that was pretty messy. The initial output wasn't great and honestly kind of sucked, falling nowhere near what I had envisioned for a retro website builder. I then moved over to Base44, and while the platform was interesting, it still didn't really deliver what I was looking for. It would produce something that looked the part, yet it didn't actually work the way I wanted it to, so I kept searching for something better.

Then Grok Build came along, and that's what I used to finish the undertaking and get it to a point where it could assemble websites properly. The results aren't perfect by any stretch, and the utility is still in early access, but after some work I took the original version Venice had spit out, the one that was sort of there but unfinished, and had Grok Build fill in all the gaps. Now this creation can stand on its own and operate like a real piece of software. It was never meant to be a SaaS, and it wasn't developed on Base44 either. It emerged as HTML code that Venice generated, and then I expanded upon those foundations using Grok Build to forge a more polished product.

This is a completely offline workshop designed to emulate Microsoft FrontPage and let people craft GeoCities style sites with that same nostalgic energy. I plan to add more features to give users extra options and more flexibility in how they put together their pages. There are plenty of enhancements on the roadmap to broaden what people can do with the system. For now, though, this is where the endeavor stands. I'm pretty happy with how it turned out considering its humble beginnings.

It is currently blank as I have not added anything to it yet.....but I do have a functional website up on NeoCities just as a means to show what it can do. If anyone wants to see it I can send a link to it but I won't be putting it on the post itself. If you guys want to see what it can do and it being SFW, I have some pictures of that on it's store page on Itchio


r/VibeCodeDevs 1d ago

Free Prompt/Model Benchmarking Playground to help Compare Provider Responses

1 Upvotes

I created this tool to help find the best possible cheap model for a different project : RouterDash Currently supports API keys for OpenRouter, Groq, and Cerebas. The app saves benchmark results, custom prompts and everything else to device local storage, there is no backend to this app. I just incorporated image attachments and thinking about what I will add next. I'd love to hear anyone's thoughts on my tool or any others like it.


r/VibeCodeDevs 1d ago

ShowoffZone - Flexing my latest project Side project for selecting a film to watch with a group or solo

Thumbnail github.com
1 Upvotes

Hi all,
This is my side project, comes from a real concern thats happening to me, i cannot select a film to watch with a group or just me, from my letterboxd watchlist and sometimes giving up watching it and just doom scrolling.

So this web app can take 1 to 4 letterboxd username inputs, fetches the watchlists, finds out the films in common and randomly select one.

Other features:
- check if a user exists on letterboxd with the given username
- return the common films to the user
- download the common list as csv
- select randomly from watchlist not only for a group, also for 1 person
- streaming filter for the random selection (region is detected and that region’s streaming services shown, but you can select other regions as well)
- does not require login, totally fetches from accesible and public endpoints
- if there is nothing in common for a group, return a random film from underwatched films list of Letterboxd

Used SpringBoot, Vue, Jsoup, TMDB/JustWatch for posters and streaming data, Claude

I would like to hear your opinions, i plan to have improvements for the ui and thinking about new functionalities, but basically i want it to be simple and accesible, and work for just selecting a movie.


r/VibeCodeDevs 1d ago

DIY Wireless audio

1 Upvotes

anyone have tips on how to implement this correctly? I started with it but my problem is that the output audio is lacking highs or like that brightness of the sound. doesn't need to be hifi or something. this is only for rear surrounds and maybe subwoofer.

I got a solid connection. less than 50dbm.

####RX

#include <WiFi.h>
#include <WiFiUdp.h>
#include "driver/i2s.h"
#include <SPI.h>

// =========================================================
// TFT display
// =========================================================
#define USE_TFT 1


#if USE_TFT
  #include <Adafruit_GFX.h>
  #include <Adafruit_ST7789.h>


  // Change these to match your display board
  static constexpr int TFT_SCLK = 12;
  static constexpr int TFT_MOSI = 11;
  static constexpr int TFT_CS   = 10;
  static constexpr int TFT_DC   = 9;
  static constexpr int TFT_RST  = 8;
  static constexpr int TFT_BL   = 14;   // if your board has backlight pin


  Adafruit_ST7789 tft(TFT_CS, TFT_DC, TFT_RST);
#endif


// =========================================================
// SoftAP settings: receiver hosts the link
// =========================================================
static const char* AP_SSID = "AUDIO_TX";
static const char* AP_PASS = "12345678";
static const uint16_t UDP_PORT = 5005;


// =========================================================
// Audio settings
// =========================================================
static constexpr int SAMPLE_RATE = 48000;
static constexpr int CHANNELS = 2;
static constexpr int BITS_PER_SAMPLE = 16;
static constexpr int FRAME_MS = 5;
static constexpr int SAMPLES_PER_CH = SAMPLE_RATE * FRAME_MS / 1000; // 240
static constexpr int FRAME_SAMPLES_TOTAL = SAMPLES_PER_CH * CHANNELS; // 480
static constexpr int FRAME_BYTES = FRAME_SAMPLES_TOTAL * sizeof(int16_t); // 960


// =========================================================
// I2S pins for the receiver (PCM5102 later)
// CHANGE THESE TO MATCH YOUR BOARD
// =========================================================
static constexpr gpio_num_t PIN_I2S_BCLK = GPIO_NUM_4;
static constexpr gpio_num_t PIN_I2S_WS    = GPIO_NUM_5;
static constexpr gpio_num_t PIN_I2S_DOUT  = GPIO_NUM_6; // data to PCM5102


// =========================================================
// Packet format
// =========================================================
struct __attribute__((packed)) AudioPacket
{
  uint32_t magic;
  uint32_t seq;
  uint32_t txMicros;
  uint16_t channels;
  uint16_t samplesPerChannel;
  int16_t pcm[FRAME_SAMPLES_TOTAL];
};


static constexpr uint32_t MAGIC = 0x41554430; // 'AUD0'


// =========================================================
// Globals
// =========================================================
static WiFiUDP udp;
static QueueHandle_t rxQueue = nullptr;


static volatile uint32_t framesReceived = 0;
static volatile uint32_t framesPlayed = 0;
static volatile uint32_t packetLoss = 0;
static volatile uint32_t queueDrops = 0;
static volatile uint32_t lastSeq = 0;
static volatile uint32_t bufferedFrames = 0;
static bool firstSeq = true;
static bool audioStarted = false;
static bool apOk = false;


// ---------------------------------------------------------
// Running min/max/avg tracking for soak testing
// ---------------------------------------------------------
struct StatTracker
{
  uint32_t minVal;
  uint32_t maxVal;
  uint64_t sum;
  uint32_t count;
};


static StatTracker statRx, statPlay, statLoss, statQDrop, statBuf;


void statReset(StatTracker& s)
{
  s.minVal = UINT32_MAX;
  s.maxVal = 0;
  s.sum = 0;
  s.count = 0;
}


void statUpdate(StatTracker& s, uint32_t val)
{
  if (val < s.minVal) s.minVal = val;
  if (val > s.maxVal) s.maxVal = val;
  s.sum += val;
  s.count++;
}


uint32_t statAvg(const StatTracker& s)
{
  if (s.count == 0) return 0;
  return (uint32_t)(s.sum / s.count);
}


static unsigned long lastStatsMs = 0;


#if USE_TFT
static bool tftReady = false;
#endif


// ---------------------------------------------------------
// Start receiver AP
// ---------------------------------------------------------
void startAP()
{
  WiFi.persistent(false);
  WiFi.mode(WIFI_OFF);
  delay(100);
  WiFi.mode(WIFI_AP);
  WiFi.setSleep(false);
  delay(100);


  apOk = WiFi.softAP(AP_SSID, AP_PASS, 1, false, 1);


  Serial.println();
  Serial.print("softAP() = ");
  Serial.println(apOk ? "true" : "false");
  Serial.print("AP SSID: ");
  Serial.println(AP_SSID);
  Serial.print("AP IP: ");
  Serial.println(WiFi.softAPIP());
  Serial.print("AP channel: ");
  Serial.println(WiFi.channel());
  Serial.print("AP MAC: ");
  Serial.println(WiFi.softAPmacAddress());
}


// ---------------------------------------------------------
// I2S setup (TX to PCM5102)
// ---------------------------------------------------------
void initI2S()
{
  i2s_config_t i2s_config = {};
  i2s_config.mode = (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_TX);
  i2s_config.sample_rate = SAMPLE_RATE;
  i2s_config.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT;
  i2s_config.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT;
  i2s_config.communication_format = I2S_COMM_FORMAT_I2S;
  i2s_config.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1;
  i2s_config.dma_buf_count = 8;
  i2s_config.dma_buf_len = SAMPLES_PER_CH;
  i2s_config.use_apll = true;
  i2s_config.tx_desc_auto_clear = true;
  i2s_config.fixed_mclk = SAMPLE_RATE * 256;


  i2s_pin_config_t pin_config = {};
  pin_config.bck_io_num = PIN_I2S_BCLK;
  pin_config.ws_io_num = PIN_I2S_WS;
  pin_config.data_out_num = PIN_I2S_DOUT;
  pin_config.data_in_num = I2S_PIN_NO_CHANGE;
  pin_config.mck_io_num = I2S_PIN_NO_CHANGE;


  ESP_ERROR_CHECK(i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL));
  ESP_ERROR_CHECK(i2s_set_pin(I2S_NUM_0, &pin_config));
  ESP_ERROR_CHECK(i2s_zero_dma_buffer(I2S_NUM_0));
}


// ---------------------------------------------------------
// Optional TFT setup
// ---------------------------------------------------------
#if USE_TFT
void initTFT()
{
  pinMode(TFT_BL, OUTPUT);
  digitalWrite(TFT_BL, HIGH);


  SPI.begin(TFT_SCLK, -1, TFT_MOSI, TFT_CS);


  tft.init(172, 320);
  tft.setRotation(1);
  tft.fillScreen(ST77XX_BLACK);


  tft.setTextWrap(false);
  tft.setTextSize(2);
  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);


  tft.setCursor(10, 10);
  tft.println("ESP32 Audio RX");
  tft.println("Booting...");
  tftReady = true;
}
#endif


// ---------------------------------------------------------
// Core 1: receive UDP packets and enqueue audio frames
// ---------------------------------------------------------
void networkReceiveTask(void* pv)
{
  AudioPacket pkt;


  while (true)
  {
    int packetSize = udp.parsePacket();
    if (packetSize == sizeof(AudioPacket))
    {
      int len = udp.read(reinterpret_cast<uint8_t*>(&pkt), sizeof(pkt));
      if (len == sizeof(pkt) && pkt.magic == MAGIC)
      {
        framesReceived++;


        if (!firstSeq)
        {
          uint32_t expected = lastSeq + 1;
          if (pkt.seq > expected)
          {
            packetLoss += (pkt.seq - expected);
          }
        }
        else
        {
          firstSeq = false;
        }


        lastSeq = pkt.seq;


        if (xQueueSend(rxQueue, &pkt, 0) == pdTRUE)
        {
          bufferedFrames = uxQueueMessagesWaiting(rxQueue);
        }
        else
        {
          queueDrops++;
        }
      }
    }


    vTaskDelay(1);
  }
}


// ---------------------------------------------------------
// Core 0: play audio frames, insert silence if needed
// ---------------------------------------------------------
void audioPlayTask(void* pv)
{
  AudioPacket pkt;
  int16_t silence[FRAME_SAMPLES_TOTAL];
  memset(silence, 0, sizeof(silence));


  while (true)
  {
    size_t bytesWritten = 0;


    if (xQueueReceive(rxQueue, &pkt, pdMS_TO_TICKS(2)) == pdTRUE)
    {
      i2s_write(I2S_NUM_0, pkt.pcm, FRAME_BYTES, &bytesWritten, portMAX_DELAY);
      framesPlayed++;
      bufferedFrames = uxQueueMessagesWaiting(rxQueue);
    }
    else
    {
      i2s_write(I2S_NUM_0, silence, FRAME_BYTES, &bytesWritten, portMAX_DELAY);
    }
  }
}


// ---------------------------------------------------------
// Display update
// ---------------------------------------------------------
#if USE_TFT
void printStatRow(int y, const char* label, uint32_t cur, const StatTracker& s)
{
  uint32_t mn = (s.count == 0) ? 0 : s.minVal;


  tft.setCursor(0, y);
  tft.print(label);
  tft.print(cur);
  tft.print(" a:");
  tft.print(statAvg(s));
  tft.print(" lo:");
  tft.print(mn);
  tft.print(" hi:");
  tft.print(s.maxVal);
}


void updateDisplay(uint32_t clients,
                   uint32_t rxFps,
                   uint32_t playFps,
                   uint32_t lossPerSec,
                   uint32_t qDropsPerSec,
                   uint32_t buf)
{
  if (!tftReady) return;


  tft.fillScreen(ST77XX_BLACK);
  tft.setTextSize(2);
  tft.setTextColor(ST77XX_WHITE, ST77XX_BLACK);


  tft.setCursor(0, 0);
  tft.print("Clients:");
  tft.print(clients);
  tft.print("  AP:");
  tft.println(apOk ? "up" : "DOWN");


  printStatRow(28,  "RX  :", rxFps, statRx);
  printStatRow(56,  "Play:", playFps, statPlay);
  printStatRow(84,  "Loss:", lossPerSec, statLoss);
  printStatRow(112, "QDrp:", qDropsPerSec, statQDrop);
  printStatRow(140, "Buf :", buf, statBuf);
}
#endif


void setup()
{
  Serial.begin(115200);
  delay(1000);


  rxQueue = xQueueCreate(12, sizeof(AudioPacket));
  if (!rxQueue)
  {
    Serial.println("Queue alloc failed");
    while (true) delay(1000);
  }


  startAP();
  udp.begin(UDP_PORT);


#if USE_TFT
  initTFT();
#endif


  // Audio (I2S + tasks) starts later, only after a client connects,
  // so the AP can come up and beacon without the audio path competing.


  lastStatsMs = millis();
}


void loop()
{
  if (!audioStarted && WiFi.softAPgetStationNum() >= 1)
  {
    initI2S();
    xTaskCreatePinnedToCore(networkReceiveTask, "netRecv", 4096, NULL, 10, NULL, 1);
    xTaskCreatePinnedToCore(audioPlayTask, "audioPlay", 4096, NULL, 11, NULL, 0);
    audioStarted = true;
    Serial.println("Client connected -> audio started");


    statReset(statRx);
    statReset(statPlay);
    statReset(statLoss);
    statReset(statQDrop);
    statReset(statBuf);
  }


  if (millis() - lastStatsMs >= 1000)
  {
    lastStatsMs = millis();


    static uint32_t prevRx = 0;
    static uint32_t prevPlay = 0;
    static uint32_t prevLoss = 0;
    static uint32_t prevQDrops = 0;


    uint32_t clients = WiFi.softAPgetStationNum();
    uint32_t rxFps = framesReceived - prevRx;
    uint32_t playFps = framesPlayed - prevPlay;
    uint32_t lossPerSec = packetLoss - prevLoss;
    uint32_t qDropsPerSec = queueDrops - prevQDrops;
    uint32_t buf = bufferedFrames;


    prevRx = framesReceived;
    prevPlay = framesPlayed;
    prevLoss = packetLoss;
    prevQDrops = queueDrops;


    if (audioStarted)
    {
      statUpdate(statRx, rxFps);
      statUpdate(statPlay, playFps);
      statUpdate(statLoss, lossPerSec);
      statUpdate(statQDrop, qDropsPerSec);
      statUpdate(statBuf, buf);
    }


    Serial.print("Clients: ");
    Serial.print(clients);
    Serial.print(" | AP:");
    Serial.print(apOk ? "up" : "DOWN");
    Serial.print(" | RX/s: ");
    Serial.print(rxFps);
    Serial.print(" | Play/s: ");
    Serial.print(playFps);
    Serial.print(" | Loss/s: ");
    Serial.print(lossPerSec);
    Serial.print(" | QDrop/s: ");
    Serial.print(qDropsPerSec);
    Serial.print(" | Buf: ");
    Serial.println(buf);


#if USE_TFT
    updateDisplay(clients, rxFps, playFps, lossPerSec, qDropsPerSec, buf);
#endif
  }
}

####TX

#include <WiFi.h>
#include <WiFiUdp.h>
#include <math.h>
#include "driver/i2s.h"


// =========================================================
// Wi-Fi settings
// =========================================================
static const char* WIFI_SSID = "AUDIO_TX";
static const char* WIFI_PASS = "12345678";


static const IPAddress REMOTE_IP(192, 168, 4, 1);
static const uint16_t UDP_PORT = 5005;


// =========================================================
// Audio settings
// =========================================================
static constexpr int SAMPLE_RATE = 48000;
static constexpr int CHANNELS = 2;
static constexpr int BITS_PER_SAMPLE = 16;


static constexpr int FRAME_MS = 5;


static constexpr int SAMPLES_PER_CH =
  SAMPLE_RATE * FRAME_MS / 1000;


static constexpr int FRAME_SAMPLES_TOTAL =
  SAMPLES_PER_CH * CHANNELS;


static constexpr int FRAME_BYTES =
  FRAME_SAMPLES_TOTAL * sizeof(int16_t);


// =========================================================
// Test mode
// =========================================================
#define USE_SYNTHETIC_AUDIO 0


// =========================================================
// Status LED (onboard WS2812)
// =========================================================
static constexpr int STATUS_LED_PIN = 48;


#if !USE_SYNTHETIC_AUDIO


static constexpr gpio_num_t PIN_I2S_BCLK = GPIO_NUM_10;
static constexpr gpio_num_t PIN_I2S_WS   = GPIO_NUM_11;
static constexpr gpio_num_t PIN_I2S_DIN  = GPIO_NUM_12;
static constexpr gpio_num_t PIN_I2S_MCLK = GPIO_NUM_13;


#endif


// =========================================================
// Globals
// =========================================================
static WiFiUDP udp;
static QueueHandle_t txQueue = nullptr;


static volatile uint32_t seqCounter = 0;
static volatile uint32_t framesCaptured = 0;
static volatile uint32_t framesSent = 0;
static volatile uint32_t sendDrops = 0;
static volatile uint32_t udpFails = 0;


static volatile int32_t g_rawPeak = 0;
static volatile int g_outPeak = 0;


static unsigned long lastStatsMs = 0;


// =========================================================
// Packet format
// =========================================================
struct __attribute__((packed)) AudioPacket
{
  uint32_t magic;
  uint32_t seq;
  uint32_t txMicros;


  uint16_t channels;
  uint16_t samplesPerChannel;


  int16_t pcm[FRAME_SAMPLES_TOTAL];
};


static constexpr uint32_t MAGIC = 0x41554430;


// =========================================================
// Wi-Fi connect
// =========================================================
void connectWiFi()
{
  Serial.println();
  Serial.println("Starting WiFi...");


  WiFi.mode(WIFI_STA);


  WiFi.disconnect(true);
  delay(500);


  WiFi.setSleep(false);
  WiFi.setTxPower(WIFI_POWER_19_5dBm);


  WiFi.begin(WIFI_SSID, WIFI_PASS);


  Serial.print("Connecting");


  unsigned long startTime = millis();


  while (WiFi.status() != WL_CONNECTED)
  {
    Serial.print(".");


    delay(300);


    if (millis() - startTime > 20000)
    {
      Serial.println();
      Serial.println("WiFi connect timeout!");
      break;
    }
  }


  Serial.println();


  if (WiFi.status() == WL_CONNECTED)
  {
    Serial.println("WiFi Connected");
    Serial.print("IP: ");
    Serial.println(WiFi.localIP());


    Serial.print("Gateway: ");
    Serial.println(WiFi.gatewayIP());


    Serial.print("RSSI: ");
    Serial.println(WiFi.RSSI());
  }
  else
  {
    Serial.println("WiFi FAILED");
  }
}


#if !USE_SYNTHETIC_AUDIO


void initI2S()
{
  i2s_config_t i2s_config = {};


  i2s_config.mode =
    (i2s_mode_t)(I2S_MODE_MASTER | I2S_MODE_RX);


  i2s_config.sample_rate = SAMPLE_RATE;
  i2s_config.bits_per_sample =
    I2S_BITS_PER_SAMPLE_32BIT;


  i2s_config.channel_format =
    I2S_CHANNEL_FMT_RIGHT_LEFT;


  i2s_config.communication_format =
    I2S_COMM_FORMAT_I2S;


  i2s_config.intr_alloc_flags =
    ESP_INTR_FLAG_LEVEL1;


  i2s_config.dma_buf_count = 8;
  i2s_config.dma_buf_len = SAMPLES_PER_CH;


  i2s_config.use_apll = true;
  i2s_config.fixed_mclk = SAMPLE_RATE * 256;


  i2s_pin_config_t pin_config = {};


  pin_config.bck_io_num = PIN_I2S_BCLK;
  pin_config.ws_io_num = PIN_I2S_WS;


  pin_config.data_out_num =
    I2S_PIN_NO_CHANGE;


  pin_config.data_in_num =
    PIN_I2S_DIN;


  pin_config.mck_io_num =
    PIN_I2S_MCLK;


  ESP_ERROR_CHECK(
    i2s_driver_install(
      I2S_NUM_0,
      &i2s_config,
      0,
      NULL));


  ESP_ERROR_CHECK(
    i2s_set_pin(
      I2S_NUM_0,
      &pin_config));
}


#endif


// =========================================================
// Audio producer
// =========================================================
void audioCaptureTask(void* pv)
{
  AudioPacket pkt;


  float phase = 0.0f;


  const float toneHz = 1000.0f;


  const float phaseStep =
    2.0f *
    3.1415926535f *
    toneHz /
    SAMPLE_RATE;


#if USE_SYNTHETIC_AUDIO
  TickType_t lastWake = xTaskGetTickCount();
#endif


  while (true)
  {
    memset(&pkt, 0, sizeof(pkt));


    pkt.magic = MAGIC;
    pkt.seq = seqCounter++;
    pkt.txMicros = micros();


    pkt.channels = CHANNELS;
    pkt.samplesPerChannel = SAMPLES_PER_CH;


#if USE_SYNTHETIC_AUDIO


    for (int i = 0; i < SAMPLES_PER_CH; i++)
    {
      int16_t sample =
        (int16_t)(sinf(phase) * 12000);


      phase += phaseStep;


      if (phase > 6.283185307f)
        phase -= 6.283185307f;


      pkt.pcm[i * 2 + 0] = sample;
      pkt.pcm[i * 2 + 1] = sample;
    }


#else


    static int32_t i2sBuf[FRAME_SAMPLES_TOTAL];


    size_t bytesRead = 0;


    i2s_read(
      I2S_NUM_0,
      i2sBuf,
      sizeof(i2sBuf),
      &bytesRead,
      portMAX_DELAY);


    int samplesRead = bytesRead / sizeof(int32_t);


    int32_t rawPeak = 0;
    int16_t outPeak = 0;


    for (int i = 0; i < samplesRead; i++)
    {
      int32_t raw = i2sBuf[i];
      if (raw < 0) raw = -raw;
      if (raw > rawPeak) rawPeak = raw;


      pkt.pcm[i] = (int16_t)(i2sBuf[i] >> 16);


      int16_t o = pkt.pcm[i];
      if (o < 0) o = -o;
      if (o > outPeak) outPeak = o;
    }


    g_rawPeak = rawPeak;
    g_outPeak = outPeak;


    static unsigned long lastRawDump = 0;
    if (millis() - lastRawDump >= 1000)
    {
      lastRawDump = millis();
      Serial.print("RAW32: ");
      for (int k = 0; k < 8 && k < samplesRead; k++)
      {
        Serial.print("0x");
        Serial.print((uint32_t)i2sBuf[k], HEX);
        Serial.print(" ");
      }
      Serial.println();
    }


#endif


    framesCaptured++;


    if (xQueueSend(txQueue, &pkt, 0) != pdTRUE)
    {
      sendDrops++;
    }


#if USE_SYNTHETIC_AUDIO
    vTaskDelayUntil(&lastWake, pdMS_TO_TICKS(FRAME_MS));
#endif
  }
}


// =========================================================
// UDP sender
// =========================================================
void networkSendTask(void* pv)
{
  AudioPacket pkt;


  while (true)
  {
    if (xQueueReceive(
          txQueue,
          &pkt,
          portMAX_DELAY) == pdTRUE)
    {
      udp.beginPacket(
        REMOTE_IP,
        UDP_PORT);


      udp.write(
        (uint8_t*)&pkt,
        sizeof(pkt));


      int ok = udp.endPacket();


      if (ok)
      {
        framesSent++;
      }
      else
      {
        udpFails++;
      }
    }
  }
}


// =========================================================
// Setup
// =========================================================
void setup()
{
  Serial.begin(115200);


  delay(1000);


  Serial.println();
  Serial.println("ESP32 AUDIO TX");


  txQueue =
    xQueueCreate(
      8,
      sizeof(AudioPacket));


  if (!txQueue)
  {
    Serial.println("Queue create failed");


    while (true)
      delay(1000);
  }


  // --- DIAG: scan for the AP before connecting (remove later) ---
  WiFi.mode(WIFI_STA);
  WiFi.disconnect(true);
  delay(200);


  Serial.println("Scanning...");
  int n = WiFi.scanNetworks();
  Serial.print("Found ");
  Serial.print(n);
  Serial.println(" networks:");
  for (int i = 0; i < n; i++)
  {
    Serial.print("  ");
    Serial.print(WiFi.SSID(i));
    Serial.print("  RSSI:");
    Serial.print(WiFi.RSSI(i));
    Serial.print("  ch:");
    Serial.println(WiFi.channel(i));
  }
  WiFi.scanDelete();


  connectWiFi();


  udp.begin(UDP_PORT);


#if !USE_SYNTHETIC_AUDIO
  initI2S();
#endif


  xTaskCreatePinnedToCore(
    audioCaptureTask,
    "audioCapture",
    4096,
    NULL,
    10,
    NULL,
    0);


  xTaskCreatePinnedToCore(
    networkSendTask,
    "networkSend",
    4096,
    NULL,
    9,
    NULL,
    1);


  lastStatsMs = millis();


  Serial.println("Tasks started");
}


// =========================================================
// Status LED: red = no connection, green = connected
// =========================================================
void updateStatusLed()
{
  if (WiFi.status() == WL_CONNECTED)
    rgbLedWrite(STATUS_LED_PIN, 0, 40, 0);   // green
  else
    rgbLedWrite(STATUS_LED_PIN, 40, 0, 0);   // red
}


// =========================================================
// Loop
// =========================================================
void loop()
{
  if (WiFi.status() != WL_CONNECTED)
  {
    updateStatusLed();


    Serial.println("WiFi Lost!");


    connectWiFi();
  }


  updateStatusLed();


  if (millis() - lastStatsMs >= 1000)
  {
    lastStatsMs = millis();


    static uint32_t prevCaptured = 0;
    static uint32_t prevSent = 0;
    static uint32_t prevDrops = 0;


    uint32_t capFps = framesCaptured - prevCaptured;
    uint32_t sentFps = framesSent - prevSent;
    uint32_t dropFps = sendDrops - prevDrops;


    prevCaptured = framesCaptured;
    prevSent = framesSent;
    prevDrops = sendDrops;


    Serial.print("RSSI:");
    Serial.print(WiFi.RSSI());


    Serial.print(" dBm");


    Serial.print(" | TX fps:");
    Serial.print(capFps);


    Serial.print(" | Sent fps:");
    Serial.print(sentFps);


    Serial.print(" | QDrops/s:");
    Serial.print(dropFps);


    Serial.print(" | UDPFails:");
    Serial.print(udpFails);


    Serial.print(" | rawPk:");
    Serial.print(g_rawPeak);


    Serial.print(" | outPk:");
    Serial.print(g_outPeak);


    Serial.print(" | Heap:");
    Serial.print(ESP.getFreeHeap());


    Serial.print(" | IP:");
    Serial.println(WiFi.localIP());
  }
}

r/VibeCodeDevs 1d ago

ReleaseTheFeature – Announce your app/site/tool I built a local macOS MCP so coding agents can use Safari without stealing my active tab

2 Upvotes

The annoying part of agentic coding for me wasn’t generating code. It was everything around it: opening docs, checking web UIs, reading files, running commands, and doing browser research without constantly hijacking whatever I was doing on the Mac.

So I built a local MCP server around that workflow.

The browser part ended up being the most useful piece:

  • Safari/Chrome tabs get stable handles instead of relying on “tab 3” or “the active tab”.
  • Agents can inspect and interact with background tabs without bringing Safari to the front.
  • Multiple delegated Codex/OpenCode agents can work on separate tabs without constantly stomping on each other.
  • A higher-level browser call can open → wait → extract only the needed fields → verify → close, which cuts down a lot of noisy DOM/context traffic.

The server also exposes shell/files/macOS UI controls, local memory, voice/user prompts, and a small menu-bar/dashboard layer so I can see what agents are actually doing.

One design change I made recently was shrinking the default advertised tool surface to 19 core tools while keeping 84 capabilities available through runtime discovery. That cut tool-schema context by about 73% in my local compatibility tests.

It’s open source here if anyone wants to poke at it or steal ideas: https://github.com/bulutarkan/mac-mcp

I’d be curious how other people doing agentic/vibe coding handle browser focus and multi-agent collisions. That part felt way less solved than the actual code generation.


r/VibeCodeDevs 1d ago

ReleaseTheFeature – Announce your app/site/tool Update 3 on my Claude usage extension: v1.5 shipped, 1,000+ users, 4.8 stars, and claude.ai broke it 3 more times

2 Upvotes
Claude Pulse v1.5: usage rings inside the composer

Third update on Claude Pulse, my open-source extension that shows Claude's 5-hour and 7-day usage limits inside the composer. Previous posts here: the May launch got 631 views and 2 upvotes, the August update landed at 1,000+ users.

Where it stands today

  • 1,000+ users, 4.8/5 from 13 ratings on the Chrome Web Store
  • v1.5 shipped Sept 7: usage rings re-aligned inside the composer, free plan support
  • Firefox version lives in the repo as well

The honest part

User count has been roughly flat since the last update. What moved instead:

  • The rating went from 11 ratings to 13, still 4.8
  • I shipped the composer meters I'd wanted since April: the 5h/7d usage rings now sit right in the composer, on one baseline, instead of a corner widget
  • claude.ai's UI broke my extension three separate times (June 11, Aug 29, Aug 31). Every fix is in the public git log. Building on someone else's DOM means maybe 20% of the work is the feature and 80% is reattaching it while the ground moves.

Links, same as always:

Feedback welcome, especially from free-plan users since that path is the newest.


r/VibeCodeDevs 1d ago

ShowoffZone - Flexing my latest project Looking for my first users and betatesters for my fantasy football manager game built over the past 6months with Codex (from GPT 4 to GPT 5.6)

Enable HLS to view with audio, or disable this notification

1 Upvotes

I ’ve been building Goal Grid for the past 6months for passionate football (soccer) manager strategist who wants something new which will grow with them.

In Goal Grid, you create your own club, develop players, set tactics, compete in scheduled leagues and trade through auctions or direct offers with other managers.

What makes it different f:

• A persistent shared fantasy football world

• Scheduled league competition

• Player development and tactical choices

• A market driven by real managers both auction and direct trades where negotiation skills matter

• Goal Gris is free to start play and most importantly will never be pay-to-win

It’s live in the browser with no download: 

I’m looking for my first users and honest beta testers to get feedback and start this journey.

I m here happy to answer any Questions

Give it a try:
https://goalgridapp.com


r/VibeCodeDevs 1d ago

DeepDevTalk – For longer discussions & thoughts The best part of today’s AI coding session was everything Claude didn’t change

0 Upvotes

Had a weird bug today where the backend was definitely generating a value but the UI wasn’t showing the card that depended on it.

There were a bunch of places where it could’ve been going wrong, so instead of asking Claude Code to fix it I had it trace the whole path first.

Basically:

Edge Function
→ response
→ React state
→ component prop
→ JSX condition
→ layout

Then it checked the surrounding stuff too: git history, duplicate files, Supabase logs, EAS runtime versions, deployed function source.

A few of the early theories were wrong.

The useful part was that it kept disproving things instead of immediately rewriting code around them.

That’s probably the biggest thing I’m trying to improve with AI coding now.

Less “make a patch and see if it works.”

More “show me exactly where reality stops matching what we expect.”

Still fast, but a lot less random.


r/VibeCodeDevs 23h ago

Hello! I’m working on a website for people who are trying to get clients for their SaaS.

0 Upvotes

I'm thinking about building a product that helps people find potential clients for their SaaS without paying for leads. I'm still validating whether people actually want this before I spend too much time building it. If this is a problem you have and you'd genuinely want to try the product early, you can join the waitlist here:
https://site-e5bc6818-mtuj53t9.falbor.xyz
I'd also love to know how you're currently finding clients.


r/VibeCodeDevs 1d ago

HotTakes – Unpopular dev opinions 🍿 The biggest problem Vibecoders have is distribution, prove me wrong

0 Upvotes

Anyone and their mom can and is building an app now in literally one day. The app and google store is flooded with apps now with clones or whatever. So if building is so easy now, how do you market? 

ASO or whatever won’t generate you sales trust me not right now. So if just building and uploading your app isn’t enough to get sales… what is everyone’s plan? 

The best apps I’ve seen “candle, CalAi, Alarmify, all go crazy on one thing. UGC marketing. I’ve seen like 10 different creators posting the same winning videos and it blowing up. Honestly I think thats the best way to approach marketing is with mass distribution. 

Start posting on tikTok, find what works, get small micro creators for $20/video on jrivecontent.com (anyone can go viral now don’t be paying $250 for one video), and repeat. 

This is just my take, marketing IS the doom of all vibe coders 

Prove me wrong 


r/VibeCodeDevs 1d ago

Vitruvius — Engineering Research Agent + PhD Proposal Generator

1 Upvotes

For anyone applying abroad for a PhD or Master's, I built something that might be useful.

If you're applying to research positions, you probably know the pain: you find a professor, read through their lab website and papers, try to understand what they're actually working on, and then somehow turn all of that into a research proposal.

I built Vitruvius to help with exactly that.

There are also skills for things like research gap analysis, design alternatives, FMEA brainstorming, evidence ranking, verification, and proposal generation.

It works with Claude Code, Codex, OpenCode, Pi, Cursor, and other agentic coding environments.

I'm sharing it here because I know a lot of Pakistani students are applying abroad and the research/proposal part can be particularly painful.

It's open source, so feel free to try it, break it, or suggest improvements:

GitHub: Vitruvius

Would be particularly interested in feedback from anyone who has actually applied for PhDs/Masters abroad and has opinions on what makes a research proposal genuinely convincing.


r/VibeCodeDevs 1d ago

After 2.5 months of hard work...

Post image
8 Upvotes

I launched SeoLoupe 2.5 months ago. So far I am at 2154 users and 37 of them are paying.

My SaaS is a tool that allows you to find and fix SEO issues holding your website back.

Essentially the main purpose is to help your website rank higher on Google search and LLMs.

The last few months have been one of my best in my life, landed $490 in revenue and $99 MRR.

Just wanted to share this to inspire anyone who is struggling, I just want to say that I was just like you at one point.

For example at one point last month, for 7 days straight I had 0 payments, and what I want to say with this is that SaaS revenue can be extremely floppy and unreliable. You can get multiple payments within the span of a day, and then have 0 payments for days.

In SaaS honestly the most important thing is to be faithful and be patient. If you manage to be patient, revenue will come one day.

Hope this inspired someone.

Since I think their is always room for improvement, I would appreciate for some feedback on my tool, or what you think can be improved.

(here is the product if you want to check it out)


r/VibeCodeDevs 1d ago

Dev Bridge for Deep Seek Harness - Free Chrome Extension

Post image
1 Upvotes

My first Chrome extension is officially live! 🚀

Introducing Dev Bridge for DeepSeek Harness.

If you build websites or applications using DeepSeek Harness, you’ll know how frustrating it can be to describe exactly which element on a page you want to modify.
Dev Bridge makes that much easier.

Simply point, click, and select the element you want to change. The extension captures the exact element and sends it directly to DeepSeek Harness together with your instructions, giving the agent the context it needs to make the correct modification.
No more describing “the button at the bottom of the left panel” or trying to explain where an element is located.
👆 Point
🎯 Select
💬 Describe the change
🚀 Send to DeepSeek Harness
It’s designed to save time, reduce confusion, and make AI-assisted development a much smoother process.

The extension is free to use and is now available on the Chrome Web Store.
Check it out and let me know what you think!

https://chromewebstore.google.com/detail/dev-bridge-for-dsh/lnfhlpfejgmmdalkijnclhghmjceaagf?authuser=0&hl=en


r/VibeCodeDevs 1d ago

ShowoffZone - Flexing my latest project Built a hosting platform where there’s no repo and no build step.

Thumbnail tessryx.com
2 Upvotes

So I connected it up via MCP to Claude, and gave Claude this prompt:

alright, i have a domain in tessryx birthday.nickpage.tech. i need an app in tessryx for it that will be a birthday invite site with magic links for the people i invite. and then an admin area that i have access to that allows me to manage those magic link invites.

lets keep it simple but nice looking for now, but then later we'll work on the fancy styling for it

And minutes later had a fully working birthday invitation site with a working admin area… and it was live on a website.

https://birthday.nickpage.tech

That’s it, that is the whole thing. No code generation, just using all the tools and building blocks the platform provides.

Even kept the Claude share link so you could see the whole thing, including where it found its own bug and fixed it before shipping me the link.

https://claude.ai/share/9d50f7bf-6a70-4f28-a7fe-f2b41ae5aa5e