# Projects & Experiments - Bagas Wastu

## Projects

### [Dekalytics](https://wastu.net/projects/dekalytics)

Turns product-test survey data into client Excel reports

- Client: Deka Insight
- Date: 2026
- Platforms: web
- Metrics:
  - Product tests: 50+ (Real client tests through the app through September 2026 (launched June 2026))
  - Sheets in a report: 30+ (Typical workbook. The coffee example in the gallery is 41.)

I built Dekalytics for [Deka Insight](https://dekainsight.com) to automate product-test reports.

In a typical test, hundreds of people try two products (like two coffee recipes) and answer a survey. Afterward, an analyst has to clean the data, run statistical tests, and build an Excel file with 30 to 50+ sheets for the client.

At Deka, that used to take 2 to 3 days using SPSS, complex formulas, and manual copy-pasting. With Dekalytics, the same work takes just a few minutes. Researchers open the report in their browser, share a view with the client, and ask for changes in chat without starting over.

## Why a normal form does not work

Writing Python to calculate means and percentages is easy, but every survey brings different rules. One project uses a 5-point rating scale while another uses 7 points. A client might want two income groups merged on the summary page, or ask for a completely new demographic cut after seeing the first draft.
A traditional web form with checkboxes and dropdowns for every rule would be impossible to build and annoying to fill out. Instead of forms, researchers just drop in their usual files, the Word questionnaire, raw data, and their Excel template, and talk to the agent in plain English or Bahasa Indonesia.

## How it works

Each project brings everything into one screen.

- **Chat:** The agent reads the questionnaire and data, writes Python behind the scenes to run the numbers, and creates `report.xlsx`. If the client changes their request, the analyst can stop the run or ask for adjustments directly in chat.
- **Laporan (Report viewer):** Researchers can view the full Excel file inside the browser, from the table of contents to each detailed data sheet, before downloading it.
- **Client share link:** Researchers can turn on a private link for the client. The client sees only the clean Excel report, without seeing the chat history or raw survey files.

## What I had to get right

### 1. Fast sandboxes on one server

At first, I tried hosted cloud sandboxes (E2B). But waiting 10 to 15 seconds for a cloud container to start is too slow when you are waiting in a chat room.

Dekalytics runs Next.js, Docker, Postgres, and Python together on a single VPS. The code runs instantly without waiting for a container to boot, and confidential survey data never leaves the server.

### 2. Matching agency standards and real statistics

I tested the agent by comparing its output against old reports made by human analysts.

At first, some statistical test results did not match. I found that the agent used paired t-tests because the same people tested both products. The older human files had sometimes treated the two groups as independent. In this case, the agent's math was actually more accurate for the study design.

Correct math was only the first step. The output also had to look exactly like Deka's reports: Top Box scores, Just About Right (JAR) tables, penalty analysis, and a clean table of contents across 40+ sheets. Dekalytics had to generate files that looked like they were made by a senior analyst.

### [MAIA](https://wastu.net/projects/maia)

An AI workspace built around tools that do more than chat

- Client: Mayar.id
- Date: 2025
- Platforms: web
- Metrics:
  - Research Time Saved: 95% (From hours of manual research to minutes)
  - Business Teams: 100+ (Business teams use it on MAIA)

For six months, I worked full-time with the team at [Mayar.id](https://mayar.id) to help build their AI product, [MAIA](https://maia.id). The goal was to build something more useful than another chat box: a set of tools that could do research, browse the web, and turn the results into reports.

## Beyond the chat box

Chat is a good interface, but it is not the whole product. Business teams wanted help researching competitors, collecting information from websites, and producing reports. Those jobs involve many small steps, and repeating them by hand gets old quickly.

## What I worked on

- **Deep Research**: Investigates a topic and gathers information from across the web.
- **MAIA Browser Operator**: Browses websites for details such as pricing and contact information.
- **PDF Paper & Web Report Generator**: Turns the collected information into a report that can be shared.

## Where it landed

These features became part of MAIA and are used by more than 100 business teams. Research that used to take hours can now be done in minutes. I liked seeing the tools leave the prototype stage and become part of somebody's workday.

### [Verbata](https://wastu.net/projects/verbata)

Codes open-ended survey answers into a codebook

- Client: Deka Insight
- Date: 2025
- Platforms: web
- Metrics:
  - Answers coded: 380k+ (Open-ended replies processed in production)
  - Live projects: 155 (Commercial research studies completed through September 2026)

In survey research, people often write open answers in their own words. Researchers call these answers "verbatims". To turn thousands of text answers into charts and numbers, analysts have to read each line and assign it a category label from a codebook.

At [Deka Insight](https://dekainsight.com), researchers and outside helpers spent 1 to 3 full days per project tagging rows in Excel. I sat with their team to see how they work, then built Verbata to do the coding automatically.

## Why embeddings did not work

At first, I tried using AI embeddings to group similar answers together. In theory, grouping similar text sounds simple.

In real Indonesian surveys, it failed. People type with heavy slang, typos, short words, and local languages like Javanese or Sundanese. The embedding model grouped words that just looked similar, instead of grouping answers with the same real meaning. The results were messy, and researchers still had to clean everything by hand.

So I dropped embeddings completely. Instead, Verbata sends the survey answers and the researcher's codebook straight to the language model. The model reads the actual context, picks the right code, and does not need any complex database index to maintain.

## Rebuilding for high-volume batch work

The first version (v1) was a small tool where researchers pasted text to get code suggestions. They used it on real projects for about two months. It proved the AI could code accurately, but the app was too slow for big files with thousands of rows.

To handle real client work, researchers needed a faster, batch-friendly workflow:

1. Upload Excel files directly without reformatting them.
2. Build or reuse a codebook hierarchy (**Net** → **Subnet** → **Code**, like _Taste_ → _Sweetness_ → _Too Sweet_).
3. Run batch jobs that code thousands of answers in a few minutes.
4. Review results in a clean table and quickly fix any edge cases.
5. Export the finished Excel file ready for reporting.

I rebuilt Verbata around this loop, adding nested codebooks, faster background batch processing, and review tools so researchers can finish full projects without hitting limits.

## How we divide the work

I handle the product design, code, and server infrastructure. Deka Insight's research team controls the codebooks, prompts, and final quality checks before sending reports to clients.

As of September 2026, Verbata has coded over 380,000 open-ended answers across 155 commercial projects.

### [TesIELTS](https://wastu.net/projects/tesielts)

A cheaper way to practise for the IELTS speaking test

- Client: undefined
- Date: 2024-2025
- Platforms: web
- Metrics:
  - Monthly Students: 100+ (Students preparing for IELTS exams)
  - Cost Reduction: 90% (More affordable than traditional tutoring)

In 2024, [Faiz](https://www.linkedin.com/in/afaizn) reached out about a problem he kept seeing. People in Indonesia wanted to study or work abroad, but IELTS preparation was expensive. Speaking was the awkward part: hire a tutor, or talk to yourself in your room and hope you were getting better.

Faiz had the English teaching and IELTS expertise. I had the technical skills. So we built [TesIELTS](https://tesielts.id) together.

This was my first SaaS with paying users. People were using it to prepare for an exam that could change where they lived and worked.

## The speaking problem

There were not many good ways to practise IELTS speaking without spending a lot of money. We wanted to give students useful feedback at a price they could afford, not pretend that an AI conversation was exactly the same as an examiner.

## The product

Faiz and I built [TesIELTS](https://tesielts.id) as an AI coach based on the real test format. Students talk with it and get feedback in four areas:

- **Fluency & Coherence**: How smooth and logical your speech sounds
- **Vocabulary**: The variety and quality of words you use
- **Grammar**: How correct and complex your sentences are
- **Pronunciation**: How clear and natural you sound

It listens for hesitation, checks grammar, and scores pronunciation. Students get a band score from 1 to 9 for each area, along with concrete suggestions for the next practice session.

## The difficult bit

The hardest part was making the feedback useful. The system had to deal with pauses, grammar, pronunciation, and the messy way people speak when they are nervous. Basic speech-to-text was not enough.

## After launch

More than 100 students use the platform each month. After we built and grew it, I left the company.

The useful lesson was not that AI can replace an examiner. It was that you need to define good feedback before you can automate any part of it.

### [Trendjacking](https://wastu.net/projects/trendjacking)

A tool for turning current trends into brand-specific ideas

- Client: DOKI.id
- Date: 2024-2025
- Platforms: web
- Metrics:
  - Time Saved: ↓ 1440x (From 1-5 days to just 5 minutes)
  - Trend Response Speed: ↓ 24h (Respond to trends while they're still fresh)

The team at [DOKI](https://doki.id) reached out with a problem. They work with brands like Danone Aqua, Fonterra, and Tokopedia. Their teams were spending one to five days finding trends, checking whether they fit a client, and turning them into a pitch. By then, the trend was usually over.

The useful window was short-form video: TikTok and Instagram Reels, where a trend can go from everywhere to nowhere in about 48 hours.

## Getting the data

The hard part was getting reliable data from TikTok and Instagram. Both platforms make scraping unpleasant, so I spent a lot of time reverse-engineering endpoints, rotating proxies, and dealing with rate limits. Instagram was particularly painful.

Collecting posts was only half the job. The system also had to look at the video, engagement, comments, and sentiment, then compare all of that with a brand's voice. A trend that works for Aqua may make no sense for Tokopedia.

## What it does

I built an AI recommendation engine that tags the content, watches the videos, checks engagement, and reads the comments. It turns a noisy stream of posts into a shortlist someone can work with.

Then it matches trends with specific brands. The system knows each client's voice and values, so it only suggests ideas that fit.

## What changed

The first pass now takes about five minutes instead of one to five days. That gives DOKI's creative team a chance to respond while a trend is still worth responding to.

It became part of DOKI's workflow for its larger clients. Seeing a thing that started as a rough idea turn into something people use every day was the best part.

### [Intervey](https://wastu.net/projects/intervey)

A survey that can ask follow-up questions

- Client: undefined
- Date: 2024
- Platforms: web

I spent months talking to managers, analysts, and market researchers about their survey tools. Same complaint every time: "We get surface-level answers that don't tell us anything useful." So I built [Intervey](https://intervey.wastu.net) as a proof of concept to see if AI could interview people better than static questionnaires.

The idea was simple: what if a survey could ask a follow-up when an answer was vague, or dig deeper when someone mentioned something interesting?

## What I learned

The technical part was not the hard part. The hard part was getting useful signals out of messy, emotional answers.

Hundreds of open-ended responses are not just a bigger spreadsheet. You need context, a way to catch contradictions, and prompts that encourage the system to dig deeper instead of summarizing everything into the same bland paragraph.

Reports were another problem. Turning "I feel frustrated sometimes but it's not terrible" into something a team can act on takes more than a summary button. That part took a lot of iteration.

## The prototype

The AI generates interview questions based on what you're trying to research. Then it conducts the interview, adapting based on each response. If someone gives a vague answer, it asks for specifics. If they mention something interesting, it follows up.

After the interview, it analyzes the responses and generates a report. The goal was to reduce the manual coding, not to pretend that the messy parts of research had disappeared.

## Where it stands

This project is shelved. No ETA on if I'll pick it back up. It proved the concept worked, but turning it into something people would pay for is a different problem.

I still use what I learned here in client work. Making an AI feel conversational is mostly about knowing when it should ask one more question instead of rushing to an answer.

## Experiments

### [CleanCopy](https://wastu.net/experiments/cleancopy)

Clean metadata and tracking from media and links before sharing

- Year: 2026
- Platforms: android
- Links: [GitHub](https://github.com/bgwastu/cleancopy), [Download APK](https://github.com/bgwastu/cleancopy/releases)

Every time I share a photo or link from my phone, it leaks stuff I don't want attached. Photos have GPS coordinates and camera serials in their EXIF data. Videos carry timestamps in MP4 atoms. Social media links are bloated with tracking tags like `utm_` and `fbclid`.

I used to strip these manually or run ad-hoc scripts, but doing that on a phone gets tedious fast. I just wanted something that works right from the Android share sheet or clipboard.

So I built CleanCopy.

## What it does

- **Photos**: Removes GPS locations, camera details, and timestamps, and transcodes HEIC to JPEG. It also detects motion photos so the embedded video doesn't get corrupted.
- **Videos**: Losslessly remuxes audio and video to scrub MP4 metadata atoms and creation dates in seconds without re-encoding.
- **Links**: Strips tracking queries using ClearURLs rules and unwraps redirect shorteners.
- **Saving**: Writes directly to the Downloads folder or copies the cleaned result back to your clipboard.

## How I use it

Whenever I want to share a picture or link, I share it directly to CleanCopy from the Android share sheet. If something is already in my clipboard, I just tap the CleanCopy tile in Quick Settings.

## Tech stack

Built with Kotlin and Jetpack Compose (Material 3). Uses AndroidX Media3 for video remuxing and ExifInterface for metadata parsing.

### [Connect Your Agent](https://wastu.net/experiments/connectyouragent)

Temporary command access for AI agents without VPNs or SSH keys

- Year: 2026
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/connectyouragent.com), [Try Connect Your Agent](https://cya.wastu.net)

## Problem

The story starts from my mom's printer. She couldn't add F4 paper size in Microsoft Word, so she asked me to help, but after a few minutes of troubleshooting and searching, I just couldn't find a solution.

I thought about using my own AI agent to fix the problem, but I didn't want to install Tailscale on her machine, deal with SSH keys, or leave permanent remote software running on her computer.

## Solution

So I built Connect Your Agent (CYA). It was a tiny weekend project that I built to give my agent temporary shell access to my agent.

It was quite simple to use, just create a session via web, run the one-line install command on the target machine, and paste the generated prompt into Claude Code, Codex, or whatever agent that we're using. No CLI, no VPN, no SSH keys or whatever else. As long as the target machine has an internet connection, it just works.

## How I use it

I also use CYA to mess around with my low-end home router. Now, I can ask my agent to mess around with OpenWrt configs without messing with the complicated network setup.

### [Meshflare](https://wastu.net/experiments/meshflare)

Cloudflare Zero Trust mesh and tunnel manager

- Year: 2026
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/meshflare), [Live Demo](https://meshflare-demo.wastu.workers.dev)

## Problem

I used to be the number one fan of Tailscale. It just worked, and having all my devices in a single mesh network was a lifesaver, especially back when I was still learning to manage my own servers (and messing things up constantly).

The problem is, on mobile, you only get one active VPN slot.

Here in Indonesia, that's a big deal. Local ISPs have notoriously bad peering with overseas services, and they block websites I visit every day, like Reddit. An always-on VPN wasn't optional for me; I had to run Cloudflare WARP for my everyday connection, which meant Tailscale had to go.

Over time, I moved my self-hosted stuff behind Cloudflare Tunnels and Access. Tailscale became this thing I only turned on once in a blue moon when I needed to SSH into an instance.

When Cloudflare launched WARP-to-WARP routing, it felt like the answer. But using it wasn't anything like Tailscale:

- You had to open the Cloudflare dashboard just to find a device's IP.
- No ✨ magic dns ✨.
- Cloudflare loves redesigning their dashboard, so every few months you're hunting for where settings moved.
- The split tunnel defaulted to exclude mode, which managed to lock me out of my own server more times than I'd like to admit lol.

## Solution

At first, I just hacked together a script that created magic DNS records automatically whenever a device showed up. That script quietly ran for about a year.

Eventually, I got tired of the Cloudflare dashboard stripping away the joy every time I needed to change a simple setting. So I built Meshflare to do what I actually wanted:

- See all my devices and their status in one clean view
- Set custom "magic dns" (`.mesh`) automatically whenever a new device connects
- Manage tunnels without getting lost in nested menus
- Block ads network-wide via DNS blocklists (basically Pi-hole inside Zero Trust)

## Tech stack

Runs serverless on Cloudflare Workers + D1, or self-hosted with Bun and SQLite. Built with React and TanStack Query.

### [Usagi](https://wastu.net/experiments/usagi)

Self-hosted usage board for AI provider accounts

- Year: 2026
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/usagi)

I wasn't satisfied with any existing solution for tracking AI usage across providers.

Nothing could handle the mix of OAuth providers like Codex and Antigravity alongside cookie-based ones like Cursor and OpenCode Go. And none of them tracked non-AI providers like Tavily or Exa at all.

I wanted a single board where I could see every quota, every reset timer, and every usage bar across all my accounts at a glance. So I built Usagi.

It supports OAuth with auto-refresh tokens (Codex, Antigravity), session cookies (Cursor, OpenCode Go), and plain API keys (Tavily, Exa, Composio, Command Code). You add your accounts, and the board refreshes usage data automatically.

## Supported providers

- **Codex** — OAuth (PKCE) with auto-refresh tokens; tracks 5-hour and weekly usage windows.
- **Antigravity** — Google OAuth (desktop flow) with auto-refresh; tracks Gemini and Claude & Other quota families, expandable per model.
- **OpenCode Go** — Session cookie authentication; auto-discovers workspaces and monitors 5-hour, weekly, and monthly windows.
- **Cursor** — Session cookie authentication (`WorkosCursorSessionToken`); tracks Pro plan usage, Auto + Composer quotas, and API limits.
- **Command Code** — Studio API key (`user_…`); tracks monthly plan credits alongside 5-hour and weekly limits.
- **Tavily** — API key authentication; tracks Researcher/Plan credits and key allowances.
- **Exa** — Team Management service key; monitors 3d, 7d, and 30d spend windows plus key budgets.
- **Composio** — Org API key (`oak_…`); monitors monthly tool-call quotas, Pro tool calls, and session limits.

I'll continue adding more providers over time as my workflow evolves and new tools make their way into my day-to-day stack.

## Tech stack

Built with React, Vite, and Hono. Runs self-hosted with Bun and SQLite, or as a Docker container. Credentials are encrypted at rest with AES when an encryption key is set.

### [Notestorm](https://wastu.net/experiments/notestorm)

Minimalist writing app with AI that keeps you in flow

- Year: 2025
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/notestorm), [Start writing](https://notestorm.wastu.net)

I built this scratchpad for those frustrating moments when I know what I want to say, but the words just won't come out. By the time I find the right words, I've completely lost my train of thought.

## What makes it different

Most note apps interrupt my flow. Notestorm keeps me writing by suggesting completions that match how I sound. I can skip the words I'm stuck on and keep the ideas flowing. Everything runs locally, my notes never leave my device.

## Features

- AI autocomplete that learns your writing style
- Multiple AI provider support (Google, Groq, Anthropic, OpenAI, OpenRouter)
- VS Code keybindings support
- Perfect for brainstorming, drafting emails, or scratch notes
- Optional Chrome built-in AI support (Canary only)

## How I use it

Quick brainstorming sessions, drafting emails before copying to Gmail, and temporary notes I know I'll delete later.

## Building it

Spent 5 days building this with TanStack Start, CodeMirror 6, and Vercel AI SDK. Getting the autocomplete UX right is the hardest part. When to trigger suggestions, which keyboard shortcuts feel natural, and keeping it instant.

### [Parsley](https://wastu.net/experiments/parsley)

AI document parser that transforms PDFs or images into structured JSON or CSV data

- Year: 2025
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/parsley), [Try Parsley](https://parsley.wastu.net)

I used to build custom OCR systems for every document type I needed to parse. Bank statements were especially tedious: hardcoded pixel positions, regex patterns for each bank's format, and brittle parsing logic that broke with every minor PDF template change. Then I'd need similar setups for invoices, receipts, forms.

## The solution

Rather than keep fighting with OCR, I built Parsley with LLMs. It understands the content directly and structures it as needed. If you ask for "customer name" it finds it, whether it's labeled "Bill To:", "Customer:", or hidden in a paragraph. No hardcoded positions or regex.

Your API keys are used directly in the web app, so documents go straight to Google or OpenRouter. I can't access them. Everything stays stateless.

## Features

- Custom schemas (define your own structure, or let AI generate it)
- Supports PDF (including password-protected) and images (PNG, JPEG, WebP)
- Multiple AI providers (Google Gemini, OpenRouter, your own keys)
- Demo mode with rate-limited free tier (no API key needed)
- Export as JSON or CSV
- API works with n8n, Zapier, or other automation tools

## How I use it

I run invoices through Parsley in n8n, extract the needed data, and send it straight to my accounting spreadsheet. Same approach for bank statements, receipts, forms, any document where I want structured data fast.

### [Cek Sandi](https://wastu.net/experiments/ceksandi)

Password strength checker using zxcvbn algorithm

- Year: 2024
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/ceksandi), [Check your password](https://ceksandi.wastu.net)

I built this password strength checker to give awareness to people and developers about proper password rules. The goal? So we don't end up with more entries on [dumbpasswordrules.com](https://dumbpasswordrules.com/).

## What makes it different

Most password checkers are simplistic. Uppercase, lowercase, numbers, symbols, done. Cek Sandi uses the [zxcvbn algorithm](https://www.usenix.org/conference/usenixsecurity16/technical-sessions/presentation/wheeler), the same tool security professionals use. It analyzes common words, keyboard patterns, and predictable substitutions to show how resistant your password actually is to cracking attempts.

## Features

- Accurate strength analysis using zxcvbn algorithm
- Tips for creating strong passwords (passphrases, not just random characters)
- Open source, you can inspect the code and verify its security
- Focused on Indonesian users with localized tips

Built with Next.js and Mantine, deployed on Cloudflare Pages.

### [DeleteX](https://wastu.net/experiments/deletex)

Selectively delete your content on X (formerly Twitter)

- Year: 2024
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/deletex), [Delete your X posts](https://deletex.wastu.net/)

I wanted to clean up my X timeline but didn't want to nuke everything. So I built this tool to selectively delete tweets, retweets, and likes based on whatever criteria I need.

## How it works

DeleteX uses your [X archive data](https://help.x.com/en/managing-your-account/how-to-download-your-x-archive) to generate a userscript that runs in your browser. The script only deletes what you selected. Everything happens locally in your browser, so your data never leaves your device.

## Tech stack

Built with Next.js and IndexedDB. The archive stays in the browser, where it can be searched and filtered without sending the data anywhere.

### [Moonlit](https://wastu.net/experiments/moonlit)

Slowed/nightcore effects for your favorite YouTube & TikTok videos

- Year: 2023
- Platforms: web
- Links: [GitHub](https://github.com/bgwastu/moonlit), [Listen to music](https://moonlit.wastu.net)

I'm kind of a weird person who can only focus when listening to nightcore or slowed+reverb looped music. So I built a music player that lets me customize playback speed and reverb in real-time.

## Features

- Change playback speed and reverb effect in real-time
- 3 default modes (slowed, normal, speed up) with a customizable mode
- Custom background for personalized aesthetics
- YouTube integration with quick link (youtubelit.com)

## The backstory

I used to reverse-engineer my audio driver just to access the legacy Realtek HD Audio Manager. It was the only way to change output audio pitch manually. I even wrote [a simple script](https://github.com/bgwastu/ytnc_cli) to convert YouTube songs into nightcore, but it was painfully slow and not very customizable.

At first, I was very reliant on AudioContext API for everything. But then I realized I could just use playback speed on the video element and only use AudioContext for reverb. Much simpler.

Building this taught me how audio and frequencies work, and more importantly, not to waste time writing features that nobody (including myself) would actually use.

### [XY Puzzle](https://wastu.net/experiments/xypuzzle)

Escape room-style puzzle for tech enthusiasts

- Year: 2023
- Platforms: web
- Links: [Try solving the puzzle](https://xy.wastu.net)

Five days before TeknumConf 2023, I had a random idea: what if my name card was a puzzle? Medium complexity escape room-style challenge that requires some cryptography knowledge, but nothing too deep.

## The story

I wanted something like [hacker.gifts](https://frantic.im/hacker-gifts/) but more accessible. Had three days to pull it off - one day for designing and ordering the card, two days for coding the puzzle using Next.js server components (which was brand new tech at the time, making things way harder than expected).

## The plot twist

After distributing the cards at the conference, no one could solve it. Maybe it was too hard, or maybe they just weren't motivated enough. So I recently updated the puzzle to be more accessible while keeping it challenging.

Building this pushed me to think creatively and gave me hands-on experience with the app router and server components. Try [the puzzle](https://xy.wastu.net) yourself, even without the name card.

