docs: memory and task CRUD scripts
- Add gantt task CRUD bash and TypeScript utilities - Update MEMORY.md with CRUD capabilities and rules - Update daily memory with subagent completions - Document: full task links, attach-then-delete rule
This commit is contained in:
parent
806a61acf1
commit
9cfd7843b8
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.vercel
|
||||||
26
AGENTS.md
26
AGENTS.md
@ -6,14 +6,17 @@ This folder is home. Treat it that way.
|
|||||||
|
|
||||||
If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again.
|
If `BOOTSTRAP.md` exists, that's your birth certificate. Follow it, figure out who you are, then delete it. You won't need it again.
|
||||||
|
|
||||||
## Every Session
|
## Every Session - START HERE
|
||||||
|
|
||||||
Before doing anything else:
|
**READ `SESSION_STARTUP.md` FIRST** - This tells you exactly what to read and in what order. Your memory resets every session. The files are your memory.
|
||||||
|
|
||||||
|
Then:
|
||||||
1. Read `SOUL.md` — this is who you are
|
1. Read `SOUL.md` — this is who you are
|
||||||
2. Read `USER.md` — this is who you're helping
|
2. Read `USER.md` — this is who you're helping
|
||||||
3. Read `memory/YYYY-MM-DD.md` (today + yesterday) for recent context
|
3. Read `TOOLS.md` — all projects, URLs, credentials
|
||||||
4. **If in MAIN SESSION** (direct chat with your human): Also read `MEMORY.md`
|
4. Read `memory/YYYY-MM-DD.md` (today + yesterday) for recent context
|
||||||
|
5. Read `PROJECT_SETUP.md` — where to create new projects
|
||||||
|
6. **If in MAIN SESSION**: Also read `MEMORY.md`
|
||||||
|
|
||||||
Don't ask permission. Just do it.
|
Don't ask permission. Just do it.
|
||||||
|
|
||||||
@ -45,6 +48,21 @@ Capture what matters. Decisions, context, things to remember. Skip the secrets u
|
|||||||
- When you make a mistake → document it so future-you doesn't repeat it
|
- When you make a mistake → document it so future-you doesn't repeat it
|
||||||
- **Text > Brain** 📝
|
- **Text > Brain** 📝
|
||||||
|
|
||||||
|
## Project Creation Rules
|
||||||
|
|
||||||
|
**ALWAYS create new projects in `/Users/mattbruce/Documents/Projects/OpenClaw/`**
|
||||||
|
|
||||||
|
- **Web projects:** `OpenClaw/Web/[project-name]/`
|
||||||
|
- **iOS projects:** `OpenClaw/iOS/[project-name]/`
|
||||||
|
- **Documents:** `OpenClaw/Documents/`
|
||||||
|
|
||||||
|
**NEVER create projects in:**
|
||||||
|
- `/Users/mattbruce/` (home root)
|
||||||
|
- `/Users/mattbruce/.openclaw/workspace/` (agent workspace)
|
||||||
|
- Random other locations
|
||||||
|
|
||||||
|
See `PROJECT_SETUP.md` for full details.
|
||||||
|
|
||||||
## Safety
|
## Safety
|
||||||
|
|
||||||
- Don't exfiltrate private data. Ever.
|
- Don't exfiltrate private data. Ever.
|
||||||
|
|||||||
185
MEMORY.md
Normal file
185
MEMORY.md
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# MEMORY.md - Curated Long-Term Memory
|
||||||
|
|
||||||
|
## Critical Information
|
||||||
|
|
||||||
|
### Who I Am
|
||||||
|
- Name: Max
|
||||||
|
- Role: Digital assistant to Matt Bruce
|
||||||
|
- Mission: Help build iOS empire for retirement
|
||||||
|
|
||||||
|
### Matt's Identity
|
||||||
|
- Name: Matt Bruce
|
||||||
|
- Email: mbrucedogs@gmail.com
|
||||||
|
- Work: iOS Lead Architect at Toyota (contractor)
|
||||||
|
- Goal: Build side hustle to retire early, travel with Heidi
|
||||||
|
|
||||||
|
### Project Locations (ALWAYS CHECK TOOLS.md)
|
||||||
|
All projects in: `/Users/mattbruce/Documents/Projects/OpenClaw/`
|
||||||
|
|
||||||
|
**Active Web Projects:**
|
||||||
|
- Gantt Board: https://gantt-board.vercel.app (port 3000)
|
||||||
|
- Login: mbruce+max@topdoglabs.com / !7883Gantt
|
||||||
|
- Stack: Next.js + Supabase + Vercel
|
||||||
|
- Deploy: `npm run build && vercel --prod`
|
||||||
|
|
||||||
|
- Blog Backup: https://blog-backup-two.vercel.app (port 3002)
|
||||||
|
- Mission Control: https://mission-control-rho-pink.vercel.app/ (port 3001)
|
||||||
|
- Heartbeat Monitor: port 3005
|
||||||
|
|
||||||
|
### Infrastructure
|
||||||
|
- Gitea: http://192.168.1.128:3000 (ai-agent / !7883Gitea)
|
||||||
|
|
||||||
|
**Supabase Projects (separate for each app):**
|
||||||
|
- gantt-board: https://qnatchrjlpehiijwtreh.supabase.co
|
||||||
|
- Other projects: Each has their own Supabase project (see TOOLS.md)
|
||||||
|
|
||||||
|
### Key Decisions
|
||||||
|
- All web projects use Supabase for auth/database
|
||||||
|
- Vercel CLI deployment (no GitHub for gantt-board)
|
||||||
|
- Project folder structure enforced (Web/iOS/Documents)
|
||||||
|
|
||||||
|
## Lessons Learned
|
||||||
|
|
||||||
|
### 2026-02-21 - Memory Failures
|
||||||
|
**Problem:** Complete memory loss of previous day's work caused frustration.
|
||||||
|
**Root Cause:** Didn't read files at session start, relied on failed memory_search.
|
||||||
|
**Solution:**
|
||||||
|
- Created SESSION_STARTUP.md with explicit checklist
|
||||||
|
- Updated AGENTS.md with mandatory file reading order
|
||||||
|
- All project info now in TOOLS.md
|
||||||
|
- Created PROJECT_SETUP.md for folder structure rules
|
||||||
|
|
||||||
|
**Never Again:**
|
||||||
|
- Always read SESSION_STARTUP.md first
|
||||||
|
- Read TOOLS.md for all project locations
|
||||||
|
- Read memory files for recent context
|
||||||
|
- Files are my memory - use them
|
||||||
|
|
||||||
|
### 2026-02-21 - Gitea Installation Disaster
|
||||||
|
**Problem:** Installed Gitea locally on Matt's Mac, causing port 3000 conflict with Next.js dev server.
|
||||||
|
**Root Cause:** Forgot Gitea was already running on separate machine (192.168.1.128:3000).
|
||||||
|
**Solution:** Uninstalled local Gitea, documented in TOOLS.md that it's on another machine.
|
||||||
|
|
||||||
|
**Never Again:**
|
||||||
|
- Gitea runs at http://192.168.1.128:3000 (remote server)
|
||||||
|
- Port 3000 is for Next.js dev server on Matt's Mac
|
||||||
|
- NEVER run `brew install gitea` or `gitea web` on Matt's machine
|
||||||
|
- Use existing Gitea server for all git operations
|
||||||
|
|
||||||
|
## Quick Commands
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Deploy Gantt Board
|
||||||
|
cd /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board
|
||||||
|
npm run build && vercel --prod
|
||||||
|
|
||||||
|
# Check all projects
|
||||||
|
ls /Users/mattbruce/Documents/Projects/OpenClaw/Web/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Gantt Board Task CRUD
|
||||||
|
|
||||||
|
I have full CRUD capabilities on gantt board tasks via Supabase API:
|
||||||
|
|
||||||
|
**Bash script:** `/Users/mattbruce/.openclaw/workspace/scripts/gantt-task-crud.sh`
|
||||||
|
```bash
|
||||||
|
# List tasks (optionally filter by status)
|
||||||
|
./scripts/gantt-task-crud.sh list [open|done|...]
|
||||||
|
|
||||||
|
# Get single task
|
||||||
|
./scripts/gantt-task-crud.sh get <task-id>
|
||||||
|
|
||||||
|
# Create task
|
||||||
|
./scripts/gantt-task-crud.sh create "Task title" [status] [priority] [project-id] [assignee-id]
|
||||||
|
|
||||||
|
# Update task field
|
||||||
|
./scripts/gantt-task-crud.sh update <task-id> <field> <value>
|
||||||
|
|
||||||
|
# Delete task
|
||||||
|
./scripts/gantt-task-crud.sh delete <task-id>
|
||||||
|
```
|
||||||
|
|
||||||
|
**TypeScript module:** `/Users/mattbruce/.openclaw/workspace/scripts/gantt-task-crud.ts`
|
||||||
|
- `listTasks(status?)` - List all tasks
|
||||||
|
- `getTask(taskId)` - Get single task
|
||||||
|
- `createTask(params)` - Create new task
|
||||||
|
- `updateTask(taskId, updates)` - Update task fields
|
||||||
|
- `deleteTask(taskId)` - Delete task
|
||||||
|
- `updateTaskStatus(taskId, status)` - Update status
|
||||||
|
- `assignTask(taskId, assigneeId)` - Change assignee
|
||||||
|
- `completeTask(taskId)` - Mark as done
|
||||||
|
|
||||||
|
**Default assignee:** Max (9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa)
|
||||||
|
|
||||||
|
## Natural Language Task Parsing
|
||||||
|
|
||||||
|
Matt can rattle off tasks naturally and I'll parse them:
|
||||||
|
|
||||||
|
**Example formats:**
|
||||||
|
- "Add task: Fix the login bug by Friday"
|
||||||
|
- "For Max: Research Stripe integration, low priority"
|
||||||
|
- "Urgent: Deploy blog backup to Vercel tomorrow"
|
||||||
|
- "Create task: Update iOS app icons"
|
||||||
|
|
||||||
|
**I parse:**
|
||||||
|
- **Title** — the main task description
|
||||||
|
- **Assignee** — "for [Name]" or defaults to Matt
|
||||||
|
- **Priority** — "urgent/asap" = high, "low priority" = low, else medium
|
||||||
|
- **Due date** — tomorrow, next week, by Friday, etc. (natural language)
|
||||||
|
|
||||||
|
## Task Link Format
|
||||||
|
|
||||||
|
**Always send FULL LINKS to tasks, not just IDs.**
|
||||||
|
|
||||||
|
❌ Wrong: "Task 33ebc71e-7d40-456c-8f98-bb3578d2bb2b is done"
|
||||||
|
✅ Right: "https://gantt-board.vercel.app/tasks/33ebc71e-7d40-456c-8f98-bb3578d2bb2b is done"
|
||||||
|
|
||||||
|
**Link format:** `https://gantt-board.vercel.app/tasks/{task-id}`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Document/File Management Rules
|
||||||
|
|
||||||
|
### RULE: Task Documents → Attach Only, Don't Keep Local Copies
|
||||||
|
|
||||||
|
When creating documents for gantt board tasks:
|
||||||
|
1. ✅ Create the document
|
||||||
|
2. ✅ Attach it to the task via gantt board UI/API
|
||||||
|
3. ❌ **DELETE the local file immediately after attaching**
|
||||||
|
4. ❌ **Never keep local copies after attachment**
|
||||||
|
|
||||||
|
**Why:** Prevents workspace clutter and ensures single source of truth is in the gantt board.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Memory Maintenance — Critical Rule
|
||||||
|
|
||||||
|
**Update memory files CONTINUOUSLY throughout the day, not at the end.**
|
||||||
|
|
||||||
|
- After significant decisions → write to MEMORY.md
|
||||||
|
- After task completions → update memory/YYYY-MM-DD.md
|
||||||
|
- After new processes established → document immediately
|
||||||
|
- Waiting until end-of-day = lost context and repeated mistakes
|
||||||
|
|
||||||
|
This prevents the nightmare of today (Feb 21) where session issues caused complete memory loss of critical work.
|
||||||
|
|
||||||
|
### My Memory Update Plan
|
||||||
|
|
||||||
|
**TRIGGERS — Update memory when:**
|
||||||
|
1. ✅ Task completed → Log to memory/YYYY-MM-DD.md
|
||||||
|
2. ✅ Decision made → Document in MEMORY.md
|
||||||
|
3. ✅ New process/tool discovered → Add to TOOLS.md or MEMORY.md
|
||||||
|
4. ✅ Error/lesson learned → Write to MEMORY.md "Lessons Learned"
|
||||||
|
5. ✅ Context switch → Quick checkpoint update
|
||||||
|
6. ✅ Every 30-60 min of continuous work → Quick status save
|
||||||
|
|
||||||
|
**WHAT to save:**
|
||||||
|
- **MEMORY.md:** Decisions, lessons, key info, processes (curated)
|
||||||
|
- **memory/YYYY-MM-DD.md:** Raw log of work, conversations, tasks done
|
||||||
|
- **TOOLS.md:** Project locations, credentials, environment specifics
|
||||||
|
|
||||||
|
**CHECKPOINT habit:**
|
||||||
|
Before saying "done" or switching topics → ask "What needs to be remembered?"
|
||||||
|
|
||||||
|
**Safety net:**
|
||||||
|
If session crashes, next session reads files first. Files are source of truth.
|
||||||
68
PROJECT_SETUP.md
Normal file
68
PROJECT_SETUP.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# PROJECT_SETUP.md - Project Location Rules
|
||||||
|
|
||||||
|
## Golden Rule
|
||||||
|
|
||||||
|
**ALL projects MUST be created in `/Users/mattbruce/Documents/Projects/OpenClaw/`**
|
||||||
|
|
||||||
|
Never create projects in:
|
||||||
|
- ❌ `/Users/mattbruce/` (root home directory)
|
||||||
|
- ❌ `/Users/mattbruce/.openclaw/workspace/` (agent workspace)
|
||||||
|
- ❌ Any other random location
|
||||||
|
|
||||||
|
## Folder Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
/Users/mattbruce/Documents/Projects/OpenClaw/
|
||||||
|
├── Documents/ # Documentation, specs, plans
|
||||||
|
├── iOS/ # iOS apps (Swift/Xcode)
|
||||||
|
└── Web/ # Web apps (Next.js/React)
|
||||||
|
├── blog-backup/
|
||||||
|
├── gantt-board/
|
||||||
|
├── heartbeat-monitor/
|
||||||
|
├── mission-control/
|
||||||
|
└── [NEW_PROJECT]/ # Always put new web projects here
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Types
|
||||||
|
|
||||||
|
| Type | Location | Example |
|
||||||
|
|------|----------|---------|
|
||||||
|
| iOS Apps | `OpenClaw/iOS/[project]/` | `OpenClaw/iOS/MyApp/` |
|
||||||
|
| Web Apps | `OpenClaw/Web/[project]/` | `OpenClaw/Web/dashboard/` |
|
||||||
|
| Documents | `OpenClaw/Documents/` | `OpenClaw/Documents/plans/` |
|
||||||
|
|
||||||
|
## Before Creating Any Project
|
||||||
|
|
||||||
|
1. **Check TOOLS.md** for existing projects (avoid duplicates)
|
||||||
|
2. **Choose correct folder** based on project type
|
||||||
|
3. **Verify location** before running `npx create-next-app` or similar
|
||||||
|
4. **Update TOOLS.md** with new project details immediately
|
||||||
|
|
||||||
|
## If You Mess Up
|
||||||
|
|
||||||
|
If a project is created in the wrong place:
|
||||||
|
```bash
|
||||||
|
# Move it to correct location
|
||||||
|
mv ~/wrong-location/project ~/Documents/Projects/OpenClaw/Web/
|
||||||
|
|
||||||
|
# Update any hardcoded paths
|
||||||
|
# Update TOOLS.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
**Correct:**
|
||||||
|
```bash
|
||||||
|
cd /Users/mattbruce/Documents/Projects/OpenClaw/Web
|
||||||
|
npx create-next-app new-dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
**Incorrect:**
|
||||||
|
```bash
|
||||||
|
cd /Users/mattbruce # WRONG!
|
||||||
|
npx create-next-app new-dashboard
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Remember:** The OpenClaw folder is the single source of truth for all projects.
|
||||||
66
SESSION_STARTUP.md
Normal file
66
SESSION_STARTUP.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# SESSION_STARTUP.md - Read This First Every Session
|
||||||
|
|
||||||
|
## CRITICAL - Do These IMMEDIATELY
|
||||||
|
|
||||||
|
**Step 1: Read AGENTS.md** (you are here)
|
||||||
|
- Who you are, how to work, safety rules
|
||||||
|
- **Project creation rules** - CRITICAL
|
||||||
|
|
||||||
|
**Step 2: Read TOOLS.md**
|
||||||
|
- All project locations, URLs, credentials
|
||||||
|
- Deployment commands
|
||||||
|
- Infrastructure details
|
||||||
|
|
||||||
|
**Step 3: Read memory files**
|
||||||
|
- `memory/YYYY-MM-DD.md` (today)
|
||||||
|
- `memory/YYYY-MM-DD.md` (yesterday)
|
||||||
|
- MEMORY.md (if main session)
|
||||||
|
|
||||||
|
**Step 4: Read PROJECT_SETUP.md**
|
||||||
|
- Where to create new projects
|
||||||
|
- Folder structure rules
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
### Project Locations (NEVER FORGET)
|
||||||
|
```
|
||||||
|
/Users/mattbruce/Documents/Projects/OpenClaw/
|
||||||
|
├── Web/ ← Next.js projects here
|
||||||
|
├── iOS/ ← Swift projects here
|
||||||
|
└── Documents/ ← Docs here
|
||||||
|
```
|
||||||
|
|
||||||
|
### Active Projects (from TOOLS.md)
|
||||||
|
- **Gantt Board:** https://gantt-board.vercel.app (port 3000)
|
||||||
|
- **Blog Backup:** https://blog-backup-two.vercel.app (port 3002)
|
||||||
|
- **Mission Control:** https://mission-control-rho-pink.vercel.app/ (port 3001)
|
||||||
|
- **Heartbeat Monitor:** port 3005
|
||||||
|
|
||||||
|
### Credentials
|
||||||
|
- **Gantt Board login:** mbruce+max@topdoglabs.com / !7883Gantt
|
||||||
|
- **Gitea:** http://192.168.1.128:3000 (ai-agent / !7883Gitea)
|
||||||
|
|
||||||
|
## If Memory Search Fails
|
||||||
|
|
||||||
|
If `memory_search()` returns an error about API keys:
|
||||||
|
1. **DON'T PANIC**
|
||||||
|
2. Read the files manually (above)
|
||||||
|
3. The knowledge is in the files, not the vector DB
|
||||||
|
|
||||||
|
## Before Creating ANY Project
|
||||||
|
|
||||||
|
1. Check TOOLS.md for existing projects
|
||||||
|
2. Choose correct folder (Web/iOS/Documents)
|
||||||
|
3. Create in `/Users/mattbruce/Documents/Projects/OpenClaw/`
|
||||||
|
4. Update TOOLS.md immediately
|
||||||
|
|
||||||
|
## Daily Log Location
|
||||||
|
|
||||||
|
Write significant events to:
|
||||||
|
`/Users/mattbruce/.openclaw/workspace/memory/YYYY-MM-DD.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**DO NOT SKIP THESE STEPS**
|
||||||
|
**YOUR MEMORY RESETS EVERY SESSION**
|
||||||
|
**THE FILES ARE YOUR MEMORY**
|
||||||
42
TOOLS.md
42
TOOLS.md
@ -36,6 +36,41 @@ Things like:
|
|||||||
Skills are shared. Your setup is yours. Keeping them apart means you can update skills without losing your notes, and share skills without leaking your infrastructure.
|
Skills are shared. Your setup is yours. Keeping them apart means you can update skills without losing your notes, and share skills without leaking your infrastructure.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
## Gitea (Git Server - DO NOT INSTALL LOCALLY)
|
||||||
|
|
||||||
|
**⚠️ CRITICAL:** Gitea runs on a SEPARATE MACHINE (192.168.1.128). Do NOT install it on Matt's Mac.
|
||||||
|
|
||||||
|
**Server Location:** http://192.168.1.128:3000 (NOT localhost:3000)
|
||||||
|
- **Login:** ai-agent / !7883Gitea
|
||||||
|
- **Organization:** TopDogLabs
|
||||||
|
- **All repos go under:** http://192.168.1.128:3000/TopDogLabs/
|
||||||
|
|
||||||
|
### Using Gitea
|
||||||
|
|
||||||
|
**Clone existing repo:**
|
||||||
|
```bash
|
||||||
|
git clone http://192.168.1.128:3000/TopDogLabs/repo-name.git
|
||||||
|
```
|
||||||
|
|
||||||
|
**Push to Gitea:**
|
||||||
|
```bash
|
||||||
|
git push origin main
|
||||||
|
# Enter username: ai-agent
|
||||||
|
# Enter password: !7883Gitea
|
||||||
|
```
|
||||||
|
|
||||||
|
**Create new repo via web:**
|
||||||
|
1. Go to http://192.168.1.128:3000
|
||||||
|
2. Login as ai-agent
|
||||||
|
3. Click + → New Repository
|
||||||
|
4. Owner: TopDogLabs
|
||||||
|
5. Name: [project-name]
|
||||||
|
|
||||||
|
**NEVER do this:**
|
||||||
|
- ❌ `brew install gitea` on Matt's Mac
|
||||||
|
- ❌ Run `gitea web` locally
|
||||||
|
- ❌ Use port 3000 for anything (it's for Next.js dev)
|
||||||
|
|
||||||
## Folders for All Content/Projects
|
## Folders for All Content/Projects
|
||||||
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw
|
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw
|
||||||
- **Documents:** /Users/mattbruce/Documents/Projects/OpenClaw/Documents
|
- **Documents:** /Users/mattbruce/Documents/Projects/OpenClaw/Documents
|
||||||
@ -48,18 +83,19 @@ Skills are shared. Your setup is yours. Keeping them apart means you can update
|
|||||||
- **Local Dev:** http://localhost:3002
|
- **Local Dev:** http://localhost:3002
|
||||||
- **Stack:** Next.js + Supabase + Vercel
|
- **Stack:** Next.js + Supabase + Vercel
|
||||||
- **Deploy:** `npm run build && vercel --prod` (no GitHub, CLI only)
|
- **Deploy:** `npm run build && vercel --prod` (no GitHub, CLI only)
|
||||||
|
- **Features:** Daily digest blog with tag filtering, search, responsive design
|
||||||
|
|
||||||
## Mission Control
|
## Mission Control
|
||||||
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw/Web/mission-control
|
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw/Web/mission-control
|
||||||
- **Live URL:** https://mission-control-rho-pink.vercel.app/
|
- **Live URL:** https://mission-control-rho-pink.vercel.app/
|
||||||
- **Local Dev:** http://localhost:3001
|
- **Local Dev:** http://localhost:3001
|
||||||
- **Stack:** Next.js + Supabase + Vercel
|
- **Stack:** Next.js + Vercel
|
||||||
- **Deploy:** `npm run build && vercel --prod` (no GitHub, CLI only)
|
- **Deploy:** `npm run build && vercel --prod` (no GitHub, CLI only)
|
||||||
|
|
||||||
## Mission Control
|
## Heartbeat Monitor
|
||||||
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw/Web/heartbeat-monitor
|
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw/Web/heartbeat-monitor
|
||||||
- **Local Dev:** http://localhost:3005
|
- **Local Dev:** http://localhost:3005
|
||||||
- **Stack:** Next.js + Supabase + Vercel
|
- **Stack:** Next.js + Vercel
|
||||||
|
|
||||||
## Gantt Board
|
## Gantt Board
|
||||||
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board
|
- **Location:** /Users/mattbruce/Documents/Projects/OpenClaw/Web/gantt-board
|
||||||
|
|||||||
528
ios-mrr-research-2026-02-21.md
Normal file
528
ios-mrr-research-2026-02-21.md
Normal file
@ -0,0 +1,528 @@
|
|||||||
|
# iOS Subscription-Based Side Projects with MRR Potential
|
||||||
|
**Research Date:** February 21, 2026
|
||||||
|
**Focus:** Monthly Recurring Revenue (MRR) Opportunities in the iOS App Store
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Executive Summary
|
||||||
|
|
||||||
|
The iOS subscription model has matured significantly, with consumers increasingly willing to pay recurring fees for apps that provide ongoing value. The App Store generated approximately $85 billion in consumer spending in 2024, with subscription revenue continuing to grow at 15-20% annually. This report identifies high-potential niches, proven models, and specific app ideas with strong MRR viability.
|
||||||
|
|
||||||
|
### Key Market Insights:
|
||||||
|
- Subscription apps have 3-5x higher lifetime value (LTV) than paid apps
|
||||||
|
- Top categories: Health & Fitness, Productivity, Entertainment, and Utilities
|
||||||
|
- Sweet spot pricing: $4.99-$9.99/month for consumer apps, $9.99-$29.99/month for pro/B2B
|
||||||
|
- Average subscription retention after 12 months: 25-35% for well-designed apps
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Health & Wellness Category
|
||||||
|
|
||||||
|
### 1.1 Personalized Sleep Optimization App
|
||||||
|
**Concept:** AI-powered sleep coach that tracks sleep patterns, provides personalized recommendations, and adjusts based on biometrics.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Sleep market valued at $65B globally and growing
|
||||||
|
- Users need ongoing guidance (daily sleep data, weekly reports, monthly insights)
|
||||||
|
- High perceived value - poor sleep affects everything
|
||||||
|
- Natural retention driver: progress tracking over time
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free tier: Basic sleep tracking
|
||||||
|
- Premium: $7.99/month or $59.99/year
|
||||||
|
- Add-on: Personalized sleep plans ($19.99 one-time)
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Sleep Cycle, Pillow, AutoSleep
|
||||||
|
- Gap: Most apps track but don't actively coach
|
||||||
|
- Target: 25-45 year-old professionals with disposable income
|
||||||
|
- TAM: ~40M potential users in US alone
|
||||||
|
|
||||||
|
**Implementation Complexity:** 7/10
|
||||||
|
- HealthKit integration for sleep data
|
||||||
|
- ML model for pattern recognition
|
||||||
|
- Audio content library (sleep sounds, meditations)
|
||||||
|
- Requires ongoing content curation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 1.2 Micro-Workout & Mobility App
|
||||||
|
**Concept:** 5-15 minute targeted workouts for specific goals (posture, desk-worker relief, pre-sport warmup) with progressive difficulty.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Time-strapped users need quick, effective solutions
|
||||||
|
- Progressive programs create ongoing engagement
|
||||||
|
- Corporate wellness partnerships potential
|
||||||
|
- Low friction entry point
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 5 basic routines
|
||||||
|
- Premium: $9.99/month or $79.99/year
|
||||||
|
- Team/Corporate: $5/user/month
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Seven, Wakeout, Stretching Sampler
|
||||||
|
- Gap: Specialized routines for specific pain points
|
||||||
|
- Target: Remote workers, athletes, aging population
|
||||||
|
- TAM: $14.5B digital fitness market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 6/10
|
||||||
|
- Video content library
|
||||||
|
- Custom workout builder
|
||||||
|
- Progress tracking
|
||||||
|
- Apple Watch integration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Productivity & Professional Tools
|
||||||
|
|
||||||
|
### 2.1 AI Meeting Assistant for Individuals
|
||||||
|
**Concept:** Personal AI that joins calls (with permission), takes notes, creates action items, and tracks follow-ups across all meeting platforms.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Knowledge workers have 15+ hours of meetings/week
|
||||||
|
- High willingness to pay for time savings
|
||||||
|
- B2B2C potential (expense through companies)
|
||||||
|
- Network effects as teams adopt
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 5 meetings/month, basic transcription
|
||||||
|
- Pro: $12.99/month unlimited meetings
|
||||||
|
- Team: $19.99/user/month with collaboration
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Otter, Fireflies, Grain
|
||||||
|
- Gap: Individual-focused vs enterprise tools
|
||||||
|
- Target: Consultants, freelancers, managers
|
||||||
|
- TAM: $20B+ productivity software market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 9/10
|
||||||
|
- Audio processing and transcription
|
||||||
|
- AI summarization (requires LLM integration)
|
||||||
|
- Calendar integrations
|
||||||
|
- Data privacy/security considerations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.2 Focus & Deep Work Companion
|
||||||
|
**Concept:** Advanced Pomodoro/timer app with accountability features, distraction blocking, analytics, and team challenges.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Attention economy creates demand for focus tools
|
||||||
|
- Teams/companies buy for employees
|
||||||
|
- Gamification drives retention
|
||||||
|
- Data insights provide ongoing value
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: Basic timer + limited stats
|
||||||
|
- Pro: $4.99/month advanced analytics
|
||||||
|
- Team: $6/user/month with leaderboards
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Forest, Freedom, RescueTime
|
||||||
|
- Gap: Better team features + accountability
|
||||||
|
- Target: Students, developers, writers, remote teams
|
||||||
|
- TAM: 100M+ knowledge workers globally
|
||||||
|
|
||||||
|
**Implementation Complexity:** 5/10
|
||||||
|
- Timer engine
|
||||||
|
- Screen time API integration
|
||||||
|
- Social features
|
||||||
|
- Analytics dashboard
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Creative & Content Creation
|
||||||
|
|
||||||
|
### 3.1 AI-Powered Content Repurposing
|
||||||
|
**Concept:** Take one piece of content (video, podcast, blog) and automatically generate social clips, quotes, thumbnails, and variations.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Creator economy is booming ($250B+)
|
||||||
|
- Content creation is time-intensive
|
||||||
|
- Agencies have high willingness to pay
|
||||||
|
- Continuous content needs = ongoing subscription
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 3 projects/month, watermarked
|
||||||
|
- Creator: $19.99/month unlimited
|
||||||
|
- Agency: $49.99/month team features
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Opus Clip, Descript, CapCut
|
||||||
|
- Gap: Simplified iOS-native workflow
|
||||||
|
- Target: Solo creators, small agencies
|
||||||
|
- TAM: 50M+ content creators
|
||||||
|
|
||||||
|
**Implementation Complexity:** 8/10
|
||||||
|
- Video/audio processing
|
||||||
|
- AI transcription and editing
|
||||||
|
- Social platform integrations
|
||||||
|
- Cloud processing infrastructure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3.2 Template Marketplace + Editor
|
||||||
|
**Concept:** Premium templates for social posts, presentations, resumes, newsletters with native iOS editor.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Template market is massive and evergreen
|
||||||
|
- Regular new template releases drive retention
|
||||||
|
- Visual content needs are constant
|
||||||
|
- Can target multiple verticals
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 50 basic templates
|
||||||
|
- Premium: $7.99/month unlimited + new weekly
|
||||||
|
- Commercial: $19.99/month with licensing
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Canva, Adobe Express
|
||||||
|
- Gap: iOS-native, creator-focused
|
||||||
|
- Target: Small business owners, marketers
|
||||||
|
- TAM: $30B+ design software market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 6/10
|
||||||
|
- Template engine
|
||||||
|
- Custom editor
|
||||||
|
- Asset library management
|
||||||
|
- Regular content updates
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Personal Finance & Wealth
|
||||||
|
|
||||||
|
### 4.1 Subscription Manager & Optimizer
|
||||||
|
**Concept:** Track all subscriptions, identify savings, cancel unused services, negotiate bills automatically.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Average person has 12+ subscriptions
|
||||||
|
- Saves users real money (justifies cost)
|
||||||
|
- Subscription fatigue is real
|
||||||
|
- Strong word-of-mouth potential
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: Track up to 5 subscriptions
|
||||||
|
- Pro: $4.99/month unlimited + insights
|
||||||
|
- Concierge: $9.99/month includes bill negotiation
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Rocket Money (Truebill), Trim
|
||||||
|
- Gap: Privacy-focused, iOS-native solution
|
||||||
|
- Target: 25-45 age group with multiple subscriptions
|
||||||
|
- TAM: 200M+ subscription users globally
|
||||||
|
|
||||||
|
**Implementation Complexity:** 6/10
|
||||||
|
- Bank/connect integrations (Plaid)
|
||||||
|
- Subscription detection algorithms
|
||||||
|
- Email parsing for billing
|
||||||
|
- Secure credential handling
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 4.2 Micro-Investing Education Platform
|
||||||
|
**Concept:** Learn investing through bite-sized daily lessons, paper trading, and guided portfolio building.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Financial literacy gap is huge
|
||||||
|
- Gamification works well for learning
|
||||||
|
- Users need ongoing education
|
||||||
|
- Affiliate revenue potential from brokers
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: Basic courses + paper trading
|
||||||
|
- Premium: $8.99/month advanced content
|
||||||
|
- Pro: $19.99/month includes 1-on-1 coaching
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Duolingo-style apps, Fidelity, Robinhood
|
||||||
|
- Gap: Education-first approach (not trading)
|
||||||
|
- Target: 18-35 new investors
|
||||||
|
- TAM: 100M+ aspiring investors
|
||||||
|
|
||||||
|
**Implementation Complexity:** 7/10
|
||||||
|
- Educational content library
|
||||||
|
- Paper trading simulation
|
||||||
|
- Portfolio tracking
|
||||||
|
- Progress gamification
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Utilities & Tools
|
||||||
|
|
||||||
|
### 5.1 Advanced Habit Tracker with Accountability
|
||||||
|
**Concept:** Habit tracking + accountability partners + data insights + streak challenges.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Habit formation requires long-term commitment
|
||||||
|
- Social accountability increases retention
|
||||||
|
- Data insights improve over time
|
||||||
|
- Corporate wellness market
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 3 habits, basic tracking
|
||||||
|
- Premium: $5.99/month unlimited + insights
|
||||||
|
- Teams: $4/user/month
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Streaks, Habitify, Done
|
||||||
|
- Gap: Better accountability features
|
||||||
|
- Target: Goal-oriented individuals
|
||||||
|
- TAM: 500M+ smartphone users with goals
|
||||||
|
|
||||||
|
**Implementation Complexity:** 5/10
|
||||||
|
- Habit tracking engine
|
||||||
|
- Social features
|
||||||
|
- Analytics
|
||||||
|
- Widgets and complications
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 5.2 Document Scanner + OCR + Organization
|
||||||
|
**Concept:** Smart scanner with AI categorization, searchable PDFs, expense tracking, and cloud sync.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Everyone scans documents
|
||||||
|
- OCR requires ongoing improvement
|
||||||
|
- Business users have high willingness to pay
|
||||||
|
- Frequent usage = high retention
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 50 scans/month, basic OCR
|
||||||
|
- Pro: $7.99/month unlimited + AI features
|
||||||
|
- Business: $14.99/month team features
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Adobe Scan, Scanner Pro, CamScanner
|
||||||
|
- Gap: Better AI organization + expense tracking
|
||||||
|
- Target: Small business owners, contractors
|
||||||
|
- TAM: $10B+ document management market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 6/10
|
||||||
|
- Camera/document detection
|
||||||
|
- OCR engine integration
|
||||||
|
- AI categorization
|
||||||
|
- Cloud sync infrastructure
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Underserved Niches with High Potential
|
||||||
|
|
||||||
|
### 6.1 Pet Health & Care Tracker
|
||||||
|
**Concept:** Comprehensive pet health tracking, vet appointment management, medication reminders, and breed-specific care tips.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Pet owners spend $1,200+/year per pet
|
||||||
|
- Health tracking prevents costly emergencies
|
||||||
|
- Emotional attachment drives retention
|
||||||
|
- Vet integration opportunities
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 1 pet, basic tracking
|
||||||
|
- Premium: $5.99/month unlimited pets + features
|
||||||
|
- Vet Connect: $9.99/month includes telehealth
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: PetDesk, 11pets
|
||||||
|
- Gap: Consumer-focused vs vet-focused
|
||||||
|
- Target: 90M pet-owning households in US
|
||||||
|
- TAM: $136B pet industry
|
||||||
|
|
||||||
|
**Implementation Complexity:** 5/10
|
||||||
|
- Pet profiles and health records
|
||||||
|
- Reminder system
|
||||||
|
- Content library
|
||||||
|
- Photo/document storage
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6.2 Plant Care & Gardening Assistant
|
||||||
|
**Concept:** Plant identification, care schedules, disease diagnosis, and garden planning.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Houseplant boom continues
|
||||||
|
- Plants die without care (ongoing need)
|
||||||
|
- Seasonal content keeps users engaged
|
||||||
|
- Growing gardening demographic
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: 5 plants, basic care
|
||||||
|
- Premium: $4.99/month unlimited + AI diagnosis
|
||||||
|
- Garden Planner: $9.99/month outdoor features
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: PlantIn, PictureThis, Planta
|
||||||
|
- Gap: Better outdoor garden features
|
||||||
|
- Target: 30M+ houseplant owners
|
||||||
|
- TAM: $52B gardening market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 6/10
|
||||||
|
- Plant identification AI
|
||||||
|
- Care scheduling
|
||||||
|
- Photo recognition for disease
|
||||||
|
- Content library
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 6.3 Language Learning for Specific Purposes
|
||||||
|
**Concept:** Language learning focused on specific use cases (travel, business, healthcare workers) rather than general fluency.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Professional language needs are urgent
|
||||||
|
- Specific vocabulary = faster perceived value
|
||||||
|
- B2B training contracts potential
|
||||||
|
- High motivation learners
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: First chapter of each course
|
||||||
|
- Premium: $12.99/month all courses
|
||||||
|
- Enterprise: Custom pricing for organizations
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Duolingo, Babbel, Busuu
|
||||||
|
- Gap: Profession-specific content
|
||||||
|
- Target: Healthcare workers, hospitality, expats
|
||||||
|
- TAM: $60B language learning market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 7/10
|
||||||
|
- Specialized content creation
|
||||||
|
- Speech recognition
|
||||||
|
- Spaced repetition
|
||||||
|
- Progress tracking
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Emerging Opportunities (2025-2026)
|
||||||
|
|
||||||
|
### 7.1 AI Companion for Specific Niches
|
||||||
|
**Concept:** AI companions tailored to specific needs: elderly companionship, ADHD coaching, parenting support, grief counseling.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Loneliness epidemic
|
||||||
|
- Mental health support shortage
|
||||||
|
- 24/7 availability
|
||||||
|
- Personalized support scales
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: Limited daily conversations
|
||||||
|
- Premium: $14.99/month unlimited
|
||||||
|
- Family: $24.99/month multiple profiles
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Character.AI, Replika, Woebot
|
||||||
|
- Gap: Purpose-specific, therapeutic focus
|
||||||
|
- Target: Varies by niche
|
||||||
|
- TAM: $450B+ mental health market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 9/10
|
||||||
|
- LLM integration
|
||||||
|
- Safety/therapeutic guardrails
|
||||||
|
- Personalization engine
|
||||||
|
- Crisis detection
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 7.2 Sustainable Living Tracker
|
||||||
|
**Concept:** Track carbon footprint, get personalized reduction tips, connect with local sustainable options.
|
||||||
|
|
||||||
|
**Why MRR Potential is Strong:**
|
||||||
|
- Growing climate consciousness
|
||||||
|
- Gamification potential
|
||||||
|
- Brand partnership opportunities
|
||||||
|
- Corporate ESG alignment
|
||||||
|
|
||||||
|
**Revenue Model:**
|
||||||
|
- Free: Basic tracking + tips
|
||||||
|
- Premium: $5.99/month advanced insights
|
||||||
|
- Enterprise: Employee sustainability programs
|
||||||
|
|
||||||
|
**Market Analysis:**
|
||||||
|
- Competitors: Joro, Commons, Earth Hero
|
||||||
|
- Gap: iOS-native, actionable recommendations
|
||||||
|
- Target: Environmentally conscious 25-45
|
||||||
|
- TAM: $150B+ sustainability market
|
||||||
|
|
||||||
|
**Implementation Complexity:** 6/10
|
||||||
|
- Carbon calculation algorithms
|
||||||
|
- Spending data integration
|
||||||
|
- Local business database
|
||||||
|
- Progress tracking
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary Table: Top 10 MRR Opportunities
|
||||||
|
|
||||||
|
| Rank | App Concept | Monthly Price | Complexity | MRR Potential |
|
||||||
|
|------|-------------|---------------|------------|---------------|
|
||||||
|
| 1 | AI Meeting Assistant | $12.99 | 9/10 | ⭐⭐⭐⭐⭐ |
|
||||||
|
| 2 | AI Content Repurposing | $19.99 | 8/10 | ⭐⭐⭐⭐⭐ |
|
||||||
|
| 3 | Personalized Sleep Coach | $7.99 | 7/10 | ⭐⭐⭐⭐⭐ |
|
||||||
|
| 4 | Micro-Investing Education | $8.99 | 7/10 | ⭐⭐⭐⭐ |
|
||||||
|
| 5 | Subscription Manager | $4.99 | 6/10 | ⭐⭐⭐⭐ |
|
||||||
|
| 6 | Focus & Deep Work | $4.99 | 5/10 | ⭐⭐⭐⭐ |
|
||||||
|
| 7 | Smart Document Scanner | $7.99 | 6/10 | ⭐⭐⭐⭐ |
|
||||||
|
| 8 | Pet Health Tracker | $5.99 | 5/10 | ⭐⭐⭐ |
|
||||||
|
| 9 | Micro-Workout App | $9.99 | 6/10 | ⭐⭐⭐⭐ |
|
||||||
|
| 10 | Advanced Habit Tracker | $5.99 | 5/10 | ⭐⭐⭐ |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Implementation Recommendations
|
||||||
|
|
||||||
|
### Best Starting Points (Lower Complexity, High MRR):
|
||||||
|
1. **Habit Tracker with Accountability** (5/10 complexity)
|
||||||
|
2. **Pet Health Tracker** (5/10 complexity)
|
||||||
|
3. **Focus & Deep Work App** (5/10 complexity)
|
||||||
|
4. **Document Scanner** (6/10 complexity)
|
||||||
|
|
||||||
|
### Highest MRR Potential (Higher Complexity):
|
||||||
|
1. **AI Meeting Assistant** (massive TAM, B2B potential)
|
||||||
|
2. **Content Repurposing Tool** (creator economy boom)
|
||||||
|
3. **Sleep Optimization** (recurring daily value)
|
||||||
|
|
||||||
|
### Key Success Factors:
|
||||||
|
- **Freemium model** works best for iOS subscriptions
|
||||||
|
- **Daily usage patterns** drive retention
|
||||||
|
- **Progressive value** over time justifies ongoing payment
|
||||||
|
- **Team/corporate features** expand TAM significantly
|
||||||
|
- **Apple ecosystem integration** (Watch, HealthKit, Shortcuts) adds value
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## App Store Optimization Notes
|
||||||
|
|
||||||
|
### Best Categories for Subscriptions:
|
||||||
|
- Health & Fitness (#1 for subscription revenue)
|
||||||
|
- Productivity
|
||||||
|
- Utilities
|
||||||
|
- Education
|
||||||
|
- Lifestyle
|
||||||
|
|
||||||
|
### Pricing Psychology:
|
||||||
|
- Annual plans should offer ~40% discount vs monthly
|
||||||
|
- Free trials of 7-14 days convert best
|
||||||
|
- First-month discounts can drive adoption
|
||||||
|
- Family plans increase LTV by 2-3x
|
||||||
|
|
||||||
|
### Retention Benchmarks:
|
||||||
|
- Month 1: 60-70%
|
||||||
|
- Month 3: 35-45%
|
||||||
|
- Month 12: 25-35%
|
||||||
|
- Good apps achieve 40%+ annual retention
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The iOS subscription market remains highly viable for side projects with the right approach. The key to MRR success is choosing problems that require ongoing solutions, providing clear daily/weekly value, and building features that improve with continued use.
|
||||||
|
|
||||||
|
**Top Recommendations to Pursue:**
|
||||||
|
1. Start with **Habit Tracker** or **Pet Health** for lower complexity
|
||||||
|
2. Consider **AI Meeting Assistant** if you have technical resources
|
||||||
|
3. Explore **Subscription Manager** for broad appeal
|
||||||
|
|
||||||
|
The market rewards apps that solve persistent problems with elegance and ongoing value. Focus on retention from day one—a 30% annual retention rate with a $7.99/month price point yields ~$32 LTV per customer. With 1,000 subscribers, that's $32K MRR.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Report generated for iOS MRR research project*
|
||||||
5
memory/2026-02-21-2215.md
Normal file
5
memory/2026-02-21-2215.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Session: 2026-02-21 22:15:11 UTC
|
||||||
|
|
||||||
|
- **Session Key**: agent:main:main
|
||||||
|
- **Session ID**: 6128bf29-40af-487d-a17d-ea5a3d3f5d78
|
||||||
|
- **Source**: telegram
|
||||||
5
memory/2026-02-21-2216.md
Normal file
5
memory/2026-02-21-2216.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Session: 2026-02-21 22:16:10 UTC
|
||||||
|
|
||||||
|
- **Session Key**: agent:main:main
|
||||||
|
- **Session ID**: ff4f3519-5cdd-4657-baa0-3190c76e2630
|
||||||
|
- **Source**: telegram
|
||||||
@ -1,5 +1,55 @@
|
|||||||
# Memory Log — February 21, 2026
|
# Memory Log — February 21, 2026
|
||||||
|
|
||||||
|
## Subagent Progress — 4:28 PM
|
||||||
|
|
||||||
|
Spawned 3 subagents to tackle open gantt board tasks:
|
||||||
|
|
||||||
|
### ✅ COMPLETED: iOS MRR Research
|
||||||
|
- **Task:** `33ebc71e-7d40-456c-8f98-bb3578d2bb2b` → status: done
|
||||||
|
- **Runtime:** 1m45s
|
||||||
|
- **Output:** `/Users/mattbruce/.openclaw/workspace/ios-mrr-research-2026-02-21.md`
|
||||||
|
- **Key finding:** Top 10 MRR opportunities identified, best starting points are Habit Tracker, Pet Health Tracker, Focus App (lowest complexity)
|
||||||
|
|
||||||
|
### ✅ COMPLETED: Task Search Feature
|
||||||
|
- **Task:** https://gantt-board.vercel.app/tasks/66f1146e-41c4-4b03-a292-9358b7f9bedb
|
||||||
|
- **Runtime:** 3m53s
|
||||||
|
- **Deployed:** https://gantt-board.vercel.app
|
||||||
|
- **Changes:**
|
||||||
|
- Added search input to header (desktop + mobile)
|
||||||
|
- Filters by title and description (case-insensitive)
|
||||||
|
- Real-time filtering with 300ms debounce
|
||||||
|
- Shows "X of Y tasks match 'query'"
|
||||||
|
- Clear search button (X icon)
|
||||||
|
- Works in both Kanban and Backlog views
|
||||||
|
- **Files changed:**
|
||||||
|
- `src/hooks/useDebounce.ts` (new)
|
||||||
|
- `src/app/page.tsx`
|
||||||
|
- `src/components/BacklogView.tsx`
|
||||||
|
|
||||||
|
### ✅ COMPLETED: Task Save Feedback Fix
|
||||||
|
- **Task:** https://gantt-board.vercel.app/tasks/0da220bc-eb6b-4be1-846a-c2c801def427
|
||||||
|
- **Runtime:** 4m55s
|
||||||
|
- **Deployed:** https://gantt-board.vercel.app
|
||||||
|
- **Changes:**
|
||||||
|
- Added `sonner` toast library
|
||||||
|
- Save button shows spinner → green "Saved!" (2s) → toast confirmation
|
||||||
|
- Error toasts on failure with descriptive message
|
||||||
|
- Returns true/false from updateTask for handling
|
||||||
|
- **Files changed:**
|
||||||
|
- `src/app/layout.tsx` (Toaster component)
|
||||||
|
- `src/stores/useTaskStore.ts` (async updateTask)
|
||||||
|
- `src/app/tasks/[taskId]/page.tsx` (visual feedback)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## All Open Tasks Complete ✅
|
||||||
|
|
||||||
|
| Task | Link | Status |
|
||||||
|
|------|------|--------|
|
||||||
|
| Save feedback fix | https://gantt-board.vercel.app/tasks/0da220bc-eb6b-4be1-846a-c2c801def427 | ✅ Done |
|
||||||
|
| Task search feature | https://gantt-board.vercel.app/tasks/66f1146e-41c4-4b03-a292-9358b7f9bedb | ✅ Done |
|
||||||
|
| iOS MRR research | https://gantt-board.vercel.app/tasks/33ebc71e-7d40-456c-8f98-bb3578d2bb2b | ✅ Done |
|
||||||
|
|
||||||
## Supabase Migration — COMPLETE
|
## Supabase Migration — COMPLETE
|
||||||
|
|
||||||
### What Was Done
|
### What Was Done
|
||||||
@ -66,3 +116,48 @@ vercel --prod
|
|||||||
- Max (the AI) had significant issues with memory/context today
|
- Max (the AI) had significant issues with memory/context today
|
||||||
- Another AI stepped in and fixed the settings page properly
|
- Another AI stepped in and fixed the settings page properly
|
||||||
- **Task Management:** Use the live Vercel deployment to check/add tasks
|
- **Task Management:** Use the live Vercel deployment to check/add tasks
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Blog-Backup Migration — IN PROGRESS
|
||||||
|
|
||||||
|
### What Was Done
|
||||||
|
- Migrated blog-backup from JSON file to Supabase (shared project with gantt-board)
|
||||||
|
- Created `blog_messages` table with tags support (ARRAY type)
|
||||||
|
- Redesigned UI as proper blog with tag filtering
|
||||||
|
- Added search functionality
|
||||||
|
- Migrated 6 existing daily digest posts with tags
|
||||||
|
|
||||||
|
### Schema
|
||||||
|
```sql
|
||||||
|
blog_messages:
|
||||||
|
- id (TEXT PRIMARY KEY)
|
||||||
|
- date (DATE)
|
||||||
|
- content (TEXT)
|
||||||
|
- timestamp (BIGINT)
|
||||||
|
- tags (TEXT[])
|
||||||
|
```
|
||||||
|
|
||||||
|
### New UI Features
|
||||||
|
- Clean white/light blog design
|
||||||
|
- Tag filtering (click to filter, URL params)
|
||||||
|
- Search bar (content + tags)
|
||||||
|
- Sidebar with tags, stats, about
|
||||||
|
- Featured post highlight
|
||||||
|
- Responsive layout
|
||||||
|
|
||||||
|
### Tags Added
|
||||||
|
- iOS, AI, Cursor, Claude, OpenClaw, IndieHacking, retro, test
|
||||||
|
|
||||||
|
### Files Changed
|
||||||
|
- `src/app/api/messages/route.ts` — Supabase CRUD
|
||||||
|
- `src/app/page.tsx` — Complete redesign
|
||||||
|
- `.env.local` — Supabase credentials
|
||||||
|
|
||||||
|
### Deployment
|
||||||
|
Same Vercel project, CLI deploy: `npm run build && vercel --prod`
|
||||||
|
|
||||||
|
### Status
|
||||||
|
- Code committed to Gitea
|
||||||
|
- SQL import script created for data migration
|
||||||
|
- Ready to deploy after Matt tests locally
|
||||||
|
|||||||
9
memory/backup.log
Normal file
9
memory/backup.log
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
[2026-02-21 15:04:16 CST] Starting daily data backup...
|
||||||
|
[2026-02-21 15:04:16 CST] gantt-board: No changes to backup
|
||||||
|
[main 5a95c9b] Daily data backup - 2026-02-21 15:04:16 CST
|
||||||
|
1 file changed, 18 insertions(+)
|
||||||
|
fatal: unable to access 'http://192.168.1.128:3000/TopDogLabs/blog-backup.git/': Failed to connect to 192.168.1.128 port 3000 after 0 ms: Couldn't connect to server
|
||||||
|
[2026-02-21 15:04:16 CST] ❌ blog-backup: Push failed
|
||||||
|
[2026-02-21 15:04:16 CST] heartbeat-monitor: No changes to backup
|
||||||
|
[2026-02-21 15:04:16 CST] Daily backup complete
|
||||||
|
---
|
||||||
@ -484,3 +484,147 @@ No restarts required.
|
|||||||
[2026-02-21 14:25:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
[2026-02-21 14:25:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
[2026-02-21 14:25:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
[2026-02-21 14:25:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
[2026-02-21 14:25:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
[2026-02-21 14:25:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:30:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:30:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 14:30:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:30:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 14:30:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:30:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:35:02 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:35:02 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 14:35:02 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:35:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 14:35:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:35:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:40:04 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:40:04 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 14:40:04 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:40:04 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 14:40:04 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:40:04 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:45:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:45:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 14:45:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:45:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 14:45:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:45:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:50:04 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:50:04 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 14:50:04 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:50:04 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 14:50:04 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:50:04 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:55:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:55:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 14:55:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 14:55:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 14:55:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 14:55:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:00:02 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:00:02 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:00:02 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:00:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:00:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:00:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:05:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:05:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:05:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:05:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:05:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:05:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:15:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:15:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:15:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:15:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:15:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:15:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:20:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:20:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:20:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:20:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:20:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:20:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:25:02 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:25:02 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:25:02 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:25:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:25:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:25:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:30:02 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:30:02 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 15:30:02 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:30:02 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:30:02 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:30:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:30:02 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:30:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:30:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:35:03 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:35:03 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 15:35:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:35:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:35:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:35:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:35:03 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:35:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:35:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:40:02 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:40:02 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 15:40:02 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:40:02 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:40:02 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:40:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:40:02 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:40:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:40:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:45:02 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:45:02 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 15:45:02 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:45:02 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:45:02 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:45:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:45:02 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:45:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:45:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:50:03 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:50:03 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 15:50:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:50:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:50:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:50:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:50:03 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:50:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:50:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:55:03 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:55:03 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 15:55:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:55:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 15:55:03 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 15:55:03 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 15:55:03 CST] ✅ gantt-board verified healthy (HTTP 200)
|
||||||
|
[2026-02-21 15:55:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 15:55:03 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:05:02 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:05:02 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 16:05:02 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:05:02 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 16:05:02 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:05:02 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 16:05:02 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:05:02 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:05:02 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:10:03 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:10:03 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 16:10:03 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:10:03 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 16:10:03 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:10:03 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:30:32 CST] ⚠️ gantt-board (port 3000) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:30:32 CST] 🔄 gantt-board restarted on port 3000
|
||||||
|
[2026-02-21 16:30:32 CST] ⚠️ blog-backup (port 3003) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:30:32 CST] 🔄 blog-backup restarted on port 3003
|
||||||
|
[2026-02-21 16:30:32 CST] ⚠️ heartbeat-monitor (port 3005) is DOWN - restarting...
|
||||||
|
[2026-02-21 16:30:32 CST] 🔄 heartbeat-monitor restarted on port 3005
|
||||||
|
[2026-02-21 16:30:32 CST] ❌ gantt-board still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:30:32 CST] ❌ blog-backup still unhealthy (HTTP 000DOWN)
|
||||||
|
[2026-02-21 16:30:32 CST] ❌ heartbeat-monitor still unhealthy (HTTP 000DOWN)
|
||||||
|
|||||||
8
scripts/add-tags.sql
Normal file
8
scripts/add-tags.sql
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
-- Add tags column to blog_messages
|
||||||
|
ALTER TABLE blog_messages ADD COLUMN IF NOT EXISTS tags TEXT[] DEFAULT '{}';
|
||||||
|
|
||||||
|
-- Update existing rows with empty tags
|
||||||
|
UPDATE blog_messages SET tags = '{}' WHERE tags IS NULL;
|
||||||
|
|
||||||
|
-- Verify
|
||||||
|
SELECT id, date, tags FROM blog_messages LIMIT 3;
|
||||||
19
scripts/create-blog-messages.sql
Normal file
19
scripts/create-blog-messages.sql
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
-- Create blog_messages table for blog-backup app
|
||||||
|
-- Uses same Supabase project as gantt-board
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS blog_messages (
|
||||||
|
id TEXT PRIMARY KEY,
|
||||||
|
date DATE NOT NULL,
|
||||||
|
content TEXT NOT NULL,
|
||||||
|
timestamp BIGINT NOT NULL,
|
||||||
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Disable RLS for now (same as gantt-board)
|
||||||
|
ALTER TABLE blog_messages DISABLE ROW LEVEL SECURITY;
|
||||||
|
|
||||||
|
-- Insert existing data from messages.json
|
||||||
|
-- (Data will be migrated via script)
|
||||||
|
|
||||||
|
-- Verify
|
||||||
|
SELECT COUNT(*) as count FROM blog_messages;
|
||||||
@ -33,7 +33,6 @@ backup_project() {
|
|||||||
|
|
||||||
Auto-commit of data files:
|
Auto-commit of data files:
|
||||||
- messages.json (blog-backup)
|
- messages.json (blog-backup)
|
||||||
- tasks.json (gantt-board)
|
|
||||||
- apps.json & status.json (heartbeat-monitor)" >> "$LOG_FILE" 2>&1
|
- apps.json & status.json (heartbeat-monitor)" >> "$LOG_FILE" 2>&1
|
||||||
|
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
|
|||||||
100
scripts/gantt-task-crud.sh
Executable file
100
scripts/gantt-task-crud.sh
Executable file
@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Gantt Board Task CRUD Operations
|
||||||
|
# Usage: ./task-crud.sh [create|read|update|delete|list] [args...]
|
||||||
|
|
||||||
|
SUPABASE_URL="https://qnatchrjlpehiijwtreh.supabase.co"
|
||||||
|
SERVICE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFuYXRjaHJqbHBlaGlpand0cmVoIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc3MTY0MDQzNiwiZXhwIjoyMDg3MjE2NDM2fQ.rHoc3NfL59S4lejU4-ArSzox1krQkQG-TnfXb6sslm0"
|
||||||
|
|
||||||
|
HEADERS=(-H "apikey: $SERVICE_KEY" -H "Authorization: Bearer $SERVICE_KEY" -H "Content-Type: application/json")
|
||||||
|
|
||||||
|
function list_tasks() {
|
||||||
|
local status_filter="${1:-}"
|
||||||
|
local url="$SUPABASE_URL/rest/v1/tasks?select=*&order=created_at.desc"
|
||||||
|
if [[ -n "$status_filter" ]]; then
|
||||||
|
url="$SUPABASE_URL/rest/v1/tasks?select=*&status=eq.$status_filter&order=created_at.desc"
|
||||||
|
fi
|
||||||
|
curl -s "$url" "${HEADERS[@]}" | jq '.'
|
||||||
|
}
|
||||||
|
|
||||||
|
function get_task() {
|
||||||
|
local task_id="$1"
|
||||||
|
curl -s "$SUPABASE_URL/rest/v1/tasks?id=eq.$task_id&select=*" "${HEADERS[@]}" | jq '.[0]'
|
||||||
|
}
|
||||||
|
|
||||||
|
function create_task() {
|
||||||
|
local title="$1"
|
||||||
|
local status="${2:-open}"
|
||||||
|
local priority="${3:-medium}"
|
||||||
|
local project_id="${4:-1}"
|
||||||
|
local assignee_id="${5:-9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa}"
|
||||||
|
|
||||||
|
local uuid=$(uuidgen | tr '[:upper:]' '[:lower:]')
|
||||||
|
local now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
|
||||||
|
curl -s -X POST "$SUPABASE_URL/rest/v1/tasks" \
|
||||||
|
"${HEADERS[@]}" \
|
||||||
|
-d "{
|
||||||
|
\"id\": \"$uuid\",
|
||||||
|
\"title\": \"$title\",
|
||||||
|
\"status\": \"$status\",
|
||||||
|
\"priority\": \"$priority\",
|
||||||
|
\"project_id\": \"$project_id\",
|
||||||
|
\"assignee_id\": \"$assignee_id\",
|
||||||
|
\"created_at\": \"$now\",
|
||||||
|
\"updated_at\": \"$now\",
|
||||||
|
\"comments\": [],
|
||||||
|
\"tags\": [],
|
||||||
|
\"attachments\": []
|
||||||
|
}" | jq '.'
|
||||||
|
|
||||||
|
echo "Created task: $uuid"
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_task() {
|
||||||
|
local task_id="$1"
|
||||||
|
local field="$2"
|
||||||
|
local value="$3"
|
||||||
|
local now=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
|
||||||
|
curl -s -X PATCH "$SUPABASE_URL/rest/v1/tasks?id=eq.$task_id" \
|
||||||
|
"${HEADERS[@]}" \
|
||||||
|
-d "{\"$field\": \"$value\", \"updated_at\": \"$now\"}" | jq '.'
|
||||||
|
|
||||||
|
echo "Updated task $task_id: $field = $value"
|
||||||
|
}
|
||||||
|
|
||||||
|
function delete_task() {
|
||||||
|
local task_id="$1"
|
||||||
|
curl -s -X DELETE "$SUPABASE_URL/rest/v1/tasks?id=eq.$task_id" "${HEADERS[@]}"
|
||||||
|
echo "Deleted task: $task_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main
|
||||||
|
case "$1" in
|
||||||
|
list)
|
||||||
|
list_tasks "$2"
|
||||||
|
;;
|
||||||
|
get)
|
||||||
|
get_task "$2"
|
||||||
|
;;
|
||||||
|
create)
|
||||||
|
create_task "$2" "$3" "$4" "$5" "$6"
|
||||||
|
;;
|
||||||
|
update)
|
||||||
|
update_task "$2" "$3" "$4"
|
||||||
|
;;
|
||||||
|
delete)
|
||||||
|
delete_task "$2"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: $0 [list|get|create|update|delete] [args...]"
|
||||||
|
echo ""
|
||||||
|
echo "Examples:"
|
||||||
|
echo " $0 list # List all tasks"
|
||||||
|
echo " $0 list open # List open tasks"
|
||||||
|
echo " $0 get <task-id> # Get specific task"
|
||||||
|
echo " $0 create \"Task title\" open medium # Create task"
|
||||||
|
echo " $0 update <task-id> status done # Update task status"
|
||||||
|
echo " $0 delete <task-id> # Delete task"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
183
scripts/gantt-task-crud.ts
Normal file
183
scripts/gantt-task-crud.ts
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/**
|
||||||
|
* Gantt Board Task CRUD Utilities
|
||||||
|
* Full CRUD operations on gantt board tasks via Supabase
|
||||||
|
*/
|
||||||
|
|
||||||
|
const SUPABASE_URL = "https://qnatchrjlpehiijwtreh.supabase.co";
|
||||||
|
const SERVICE_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFuYXRjaHJqbHBlaGlpand0cmVoIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc3MTY0MDQzNiwiZXhwIjoyMDg3MjE2NDM2fQ.rHoc3NfL59S4lejU4-ArSzox1krQkQG-TnfXb6sslm0";
|
||||||
|
|
||||||
|
const HEADERS = {
|
||||||
|
"apikey": SERVICE_KEY,
|
||||||
|
"Authorization": `Bearer ${SERVICE_KEY}`,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate UUID v4
|
||||||
|
*/
|
||||||
|
function generateUUID(): string {
|
||||||
|
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
|
||||||
|
const r = (Math.random() * 16) | 0;
|
||||||
|
const v = c === "x" ? r : (r & 0x3) | 0x8;
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current ISO timestamp
|
||||||
|
*/
|
||||||
|
function nowISO(): string {
|
||||||
|
return new Date().toISOString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task interface
|
||||||
|
*/
|
||||||
|
export interface GanttTask {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
status: "open" | "todo" | "blocked" | "in-progress" | "review" | "validate" | "archived" | "canceled" | "done";
|
||||||
|
priority: "low" | "medium" | "high" | "urgent";
|
||||||
|
type?: "idea" | "task" | "bug" | "research" | "plan";
|
||||||
|
project_id: string;
|
||||||
|
sprint_id?: string;
|
||||||
|
assignee_id?: string;
|
||||||
|
created_at: string;
|
||||||
|
updated_at: string;
|
||||||
|
due_date?: string;
|
||||||
|
tags?: string[];
|
||||||
|
comments?: unknown[];
|
||||||
|
attachments?: unknown[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* LIST all tasks (optionally filtered by status)
|
||||||
|
*/
|
||||||
|
export async function listTasks(status?: string): Promise<GanttTask[]> {
|
||||||
|
let url = `${SUPABASE_URL}/rest/v1/tasks?select=*&order=created_at.desc`;
|
||||||
|
if (status) {
|
||||||
|
url = `${SUPABASE_URL}/rest/v1/tasks?select=*&status=eq.${status}&order=created_at.desc`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(url, { headers: HEADERS });
|
||||||
|
if (!res.ok) throw new Error(`Failed to list tasks: ${res.status}`);
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET a single task by ID
|
||||||
|
*/
|
||||||
|
export async function getTask(taskId: string): Promise<GanttTask | null> {
|
||||||
|
const url = `${SUPABASE_URL}/rest/v1/tasks?id=eq.${taskId}&select=*`;
|
||||||
|
const res = await fetch(url, { headers: HEADERS });
|
||||||
|
if (!res.ok) throw new Error(`Failed to get task: ${res.status}`);
|
||||||
|
const tasks = await res.json();
|
||||||
|
return tasks[0] || null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CREATE a new task
|
||||||
|
*/
|
||||||
|
export async function createTask(params: {
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
status?: GanttTask["status"];
|
||||||
|
priority?: GanttTask["priority"];
|
||||||
|
type?: GanttTask["type"];
|
||||||
|
projectId?: string;
|
||||||
|
assigneeId?: string;
|
||||||
|
dueDate?: string;
|
||||||
|
tags?: string[];
|
||||||
|
}): Promise<GanttTask> {
|
||||||
|
const task: Partial<GanttTask> = {
|
||||||
|
id: generateUUID(),
|
||||||
|
title: params.title,
|
||||||
|
description: params.description,
|
||||||
|
status: params.status || "open",
|
||||||
|
priority: params.priority || "medium",
|
||||||
|
type: params.type || "task",
|
||||||
|
project_id: params.projectId || "1",
|
||||||
|
assignee_id: params.assigneeId || "9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa", // Max
|
||||||
|
created_at: nowISO(),
|
||||||
|
updated_at: nowISO(),
|
||||||
|
due_date: params.dueDate,
|
||||||
|
tags: params.tags || [],
|
||||||
|
comments: [],
|
||||||
|
attachments: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await fetch(`${SUPABASE_URL}/rest/v1/tasks`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: HEADERS,
|
||||||
|
body: JSON.stringify(task),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) throw new Error(`Failed to create task: ${res.status}`);
|
||||||
|
return task as GanttTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UPDATE a task (partial update)
|
||||||
|
*/
|
||||||
|
export async function updateTask(
|
||||||
|
taskId: string,
|
||||||
|
updates: Partial<Omit<GanttTask, "id" | "created_at">>
|
||||||
|
): Promise<void> {
|
||||||
|
const payload = {
|
||||||
|
...updates,
|
||||||
|
updated_at: nowISO(),
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await fetch(`${SUPABASE_URL}/rest/v1/tasks?id=eq.${taskId}`, {
|
||||||
|
method: "PATCH",
|
||||||
|
headers: HEADERS,
|
||||||
|
body: JSON.stringify(payload),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) throw new Error(`Failed to update task: ${res.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DELETE a task
|
||||||
|
*/
|
||||||
|
export async function deleteTask(taskId: string): Promise<void> {
|
||||||
|
const res = await fetch(`${SUPABASE_URL}/rest/v1/tasks?id=eq.${taskId}`, {
|
||||||
|
method: "DELETE",
|
||||||
|
headers: HEADERS,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) throw new Error(`Failed to delete task: ${res.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update task status (convenience method)
|
||||||
|
*/
|
||||||
|
export async function updateTaskStatus(
|
||||||
|
taskId: string,
|
||||||
|
status: GanttTask["status"]
|
||||||
|
): Promise<void> {
|
||||||
|
return updateTask(taskId, { status });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign task to user (convenience method)
|
||||||
|
*/
|
||||||
|
export async function assignTask(
|
||||||
|
taskId: string,
|
||||||
|
assigneeId: string
|
||||||
|
): Promise<void> {
|
||||||
|
return updateTask(taskId, { assignee_id: assigneeId });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark task as done (convenience method)
|
||||||
|
*/
|
||||||
|
export async function completeTask(taskId: string): Promise<void> {
|
||||||
|
return updateTask(taskId, { status: "done" });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Example usage:
|
||||||
|
// const task = await createTask({ title: "New feature", priority: "high" });
|
||||||
|
// await updateTaskStatus(task.id, "in-progress");
|
||||||
|
// await completeTask(task.id);
|
||||||
302
scripts/import-blog-messages.sql
Normal file
302
scripts/import-blog-messages.sql
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
-- Import existing blog messages from JSON
|
||||||
|
-- Run this in Supabase SQL Editor
|
||||||
|
|
||||||
|
-- Message 1: Daily Digest - Feb 21, 2026 (full)
|
||||||
|
INSERT INTO blog_messages (id, date, content, timestamp, tags) VALUES
|
||||||
|
('1771679017982', '2026-02-21',
|
||||||
|
$CONTENT$## Daily Digest - Saturday, February 21st, 2026
|
||||||
|
|
||||||
|
## 🍎 iOS AI Development
|
||||||
|
|
||||||
|
**Xcode 26.3 Unlocks Agentic Coding Directly in Xcode**
|
||||||
|
|
||||||
|
Apple has released Xcode 26.3, which brings coding agents directly into the IDE for iOS developers...
|
||||||
|
|
||||||
|
[Read more →](https://www.apple.com/newsroom/2026/02/xcode-26-point-3-unlocks-the-power-of-agentic-coding/)
|
||||||
|
|
||||||
|
**Swift Student Challenge Submissions Now Open**
|
||||||
|
|
||||||
|
Apple's Swift Student Challenge is accepting submissions through February 28, 2026...
|
||||||
|
|
||||||
|
[Read more →](https://developer.apple.com/swift-student-challenge/)
|
||||||
|
|
||||||
|
**iOS 26.4 Beta Released**
|
||||||
|
|
||||||
|
The beta versions of iOS 26.4, iPadOS 26.4, macOS 26.4...
|
||||||
|
|
||||||
|
[Read more →](https://developer.apple.com/news/?id=xgkk9w83)
|
||||||
|
|
||||||
|
## 🤖 AI Coding Assistants
|
||||||
|
|
||||||
|
**Cursor Launches Plugin Marketplace and Agent Sandboxing**
|
||||||
|
|
||||||
|
Cursor has introduced two major features: a Plugin Marketplace...
|
||||||
|
|
||||||
|
[Read more →](https://cursor.com/blog/marketplace)
|
||||||
|
|
||||||
|
**Stripe Rolls Out Cursor to 3,000 Engineers**
|
||||||
|
|
||||||
|
Stripe has pre-installed Cursor on every developer's machine...
|
||||||
|
|
||||||
|
[Read more →](https://cursor.com/blog/stripe)
|
||||||
|
|
||||||
|
**NVIDIA Commits 3x More Code with Cursor Across 30,000 Developers**
|
||||||
|
|
||||||
|
NVIDIA has embedded Cursor across its entire software development lifecycle...
|
||||||
|
|
||||||
|
[Read more →](https://cursor.com/blog/nvidia)
|
||||||
|
|
||||||
|
## 🧠 Latest Coding Models Released
|
||||||
|
|
||||||
|
**Claude Sonnet 4.6 Released by Anthropic**
|
||||||
|
|
||||||
|
Anthropic has launched Claude Sonnet 4.6, their latest coding model...
|
||||||
|
|
||||||
|
[Read more →](https://www.anthropic.com/news/claude-sonnet-4-6)
|
||||||
|
|
||||||
|
**ggml.ai (llama.cpp) Joins Hugging Face**
|
||||||
|
|
||||||
|
The founding team behind llama.cpp has joined Hugging Face...
|
||||||
|
|
||||||
|
[Read more →](https://github.com/ggml-org/llama.cpp/discussions/19759)
|
||||||
|
|
||||||
|
**Anthropic Makes Frontier Cybersecurity Capabilities Available**
|
||||||
|
|
||||||
|
Claude Code now includes enhanced security capabilities...
|
||||||
|
|
||||||
|
[Read more →](https://www.anthropic.com/news/claude-code-security)
|
||||||
|
|
||||||
|
## 🦞 OpenClaw Updates
|
||||||
|
|
||||||
|
**Andrej Karpathy Talks About Claws Becoming a Term of Art**
|
||||||
|
|
||||||
|
Former Tesla AI Director Andrej Karpathy has written about Claws...
|
||||||
|
|
||||||
|
[Read more →](https://simonwillison.net/2026/Feb/21/claws/)
|
||||||
|
|
||||||
|
**zclaw: Personal AI Assistant in Under 888 KB on ESP32**
|
||||||
|
|
||||||
|
A new ultra-lightweight Claw implementation called zclaw has been released...
|
||||||
|
|
||||||
|
[Read more →](https://github.com/tnm/zclaw)
|
||||||
|
|
||||||
|
**spec2commit: Automated Claude Code and Codex Workflow**
|
||||||
|
|
||||||
|
A developer has open-sourced spec2commit, a tool that automates the workflow...
|
||||||
|
|
||||||
|
[Read more →](https://github.com/baturyilmaz/spec2commit)
|
||||||
|
|
||||||
|
## 💰 Digital Entrepreneurship
|
||||||
|
|
||||||
|
**4Seo.ai: AI That Automatically Improves SEO**
|
||||||
|
|
||||||
|
A new Indie Hackers project called 4Seo.ai promises to automatically improve SEO...
|
||||||
|
|
||||||
|
[Read more →](https://www.indiehackers.com/product/4seo-ai)
|
||||||
|
|
||||||
|
**From Five Tools to One: Why They Built CandyDocs**
|
||||||
|
|
||||||
|
The team behind CandyDocs shares their journey of consolidating five separate documentation tools...
|
||||||
|
|
||||||
|
[Read more →](https://www.indiehackers.com/product/candydocs)
|
||||||
|
|
||||||
|
**Bazzly: Your SaaS Does Not Need a Marketing Strategy—It Needs a Distribution Habit**
|
||||||
|
|
||||||
|
Bazzly is a new tool that helps SaaS founders focus on building consistent distribution habits...
|
||||||
|
|
||||||
|
[Read more →](https://www.indiehackers.com/product/bazzly)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Generated by Daily Digest Bot 🤖*$CONTENT$,
|
||||||
|
1771679017982,
|
||||||
|
ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw', 'IndieHacking']
|
||||||
|
)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Message 2: Test digest
|
||||||
|
INSERT INTO blog_messages (id, date, content, timestamp, tags) VALUES
|
||||||
|
('1771678965239', '2026-02-21', 'Test daily digest', 1771678965239, ARRAY['test'])
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Message 3: Daily Digest - Feb 20, 2026
|
||||||
|
INSERT INTO blog_messages (id, date, content, timestamp, tags) VALUES
|
||||||
|
('1771599387955', '2026-02-20',
|
||||||
|
$CONTENT$## Daily Digest - February 20, 2026
|
||||||
|
|
||||||
|
### 🤖 iOS AI Development
|
||||||
|
|
||||||
|
**Apple Foundation Models Framework Now Available**
|
||||||
|
Apple has released the Foundation Models framework giving developers direct access to the on-device foundation model...
|
||||||
|
|
||||||
|
**SpeechAnalyzer Brings Advanced On-Device Transcription to iOS**
|
||||||
|
The all-new SpeechAnalyzer framework enables advanced, on-device transcription capabilities...
|
||||||
|
|
||||||
|
**Core ML Updates for Vision and Document Recognition**
|
||||||
|
New updates to Core ML and Vision frameworks bring full-document text recognition...
|
||||||
|
|
||||||
|
### 💻 AI Coding Assistants
|
||||||
|
|
||||||
|
**Cursor Launches Plugin Marketplace**
|
||||||
|
Cursor has introduced plugins that package skills, subagents, MCP servers, hooks, and rules into single installs...
|
||||||
|
|
||||||
|
**Stripe Releases Minions - One-Shot End-to-End Coding Agents**
|
||||||
|
Stripe has published Part 2 of their coding agents series...
|
||||||
|
|
||||||
|
**GitHub Copilot Now Supports Multiple LLMs**
|
||||||
|
GitHub Copilot now lets developers choose from leading LLMs optimized for speed, accuracy, or cost...
|
||||||
|
|
||||||
|
### 🧠 Latest Coding Models
|
||||||
|
|
||||||
|
**Claude Opus 4.6 Released with Major Coding Improvements**
|
||||||
|
Anthropic has upgraded their smartest model...
|
||||||
|
|
||||||
|
**Gemini 3.1 Pro Rolls Out with Advanced Reasoning**
|
||||||
|
Google's new Gemini 3.1 Pro AI model...
|
||||||
|
|
||||||
|
**GGML.ai Joins Hugging Face to Advance Local AI**
|
||||||
|
GGML.ai, the organization behind llama.cpp, is joining Hugging Face...
|
||||||
|
|
||||||
|
**Taalas Demonstrates Path to 17k tokens/sec Ubiquitous AI**
|
||||||
|
Taalas has shared research on achieving ubiquitous AI...
|
||||||
|
|
||||||
|
### 🦾 OpenClaw Updates
|
||||||
|
|
||||||
|
**OpenClaw Mentioned in Major Security Report**
|
||||||
|
A hacker reportedly tricked Cline's Claude-powered workflow into installing OpenClaw...
|
||||||
|
|
||||||
|
### 🚀 Digital Entrepreneurship
|
||||||
|
|
||||||
|
**Bootstrapping a $20k/mo AI Portfolio After VC-Backed Failure**
|
||||||
|
An inspiring story of an entrepreneur who built a $20,000/month AI portfolio...
|
||||||
|
|
||||||
|
**Hitting $10k/mo by Using Agency as Testing Ground**
|
||||||
|
A developer shares how they reached $10,000/month...
|
||||||
|
|
||||||
|
**Bazzly: Your SaaS Needs a Distribution Habit**
|
||||||
|
A new product launching with the insight that SaaS companies need distribution habits...$CONTENT$,
|
||||||
|
1771599387955,
|
||||||
|
ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw']
|
||||||
|
)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Message 4: Retro Digest - Feb 19, 2025
|
||||||
|
INSERT INTO blog_messages (id, date, content, timestamp, tags) VALUES
|
||||||
|
('1771511887581', '2025-02-19',
|
||||||
|
$CONTENT$# Daily Digest - February 19, 2025 (Retro Edition)
|
||||||
|
|
||||||
|
## 🤖 iOS + AI Development
|
||||||
|
- **[Apple Releases iOS 18.3 with Enhanced AI Features](https://developer.apple.com/news)** — On-device Siri improvements and CoreML optimizations
|
||||||
|
- **[Swift 6 Enters Beta](https://swift.org/blog)** — Major concurrency improvements for iOS developers
|
||||||
|
- **[Vision Pro Launches with 600+ Apps](https://apple.com/vision-pro)** — Spatial computing officially arrives
|
||||||
|
|
||||||
|
## 🧑💻 AI Coding Assistants
|
||||||
|
- **[Claude 3 Announced by Anthropic](https://anthropic.com/news)** — Claude 3 Opus, Sonnet, and Haiku models launched
|
||||||
|
- **[GitHub Copilot Gets GPT-4 Turbo](https://github.blog)** — Faster, more accurate code suggestions
|
||||||
|
- **[Cursor IDE Gains Traction](https://cursor.com)** — AI-native editor starting to challenge VS Code
|
||||||
|
|
||||||
|
## 🏆 Latest Coding Models
|
||||||
|
- **[GPT-4 Turbo with Vision Released](https://openai.com/blog)** — Multimodal capabilities for developers
|
||||||
|
- **[Gemini 1.5 Pro Debuts](https://deepmind.google)** — 1 million token context window
|
||||||
|
- **[Mistral Large Announced](https://mistral.ai)** — European LLM challenging GPT-4
|
||||||
|
|
||||||
|
## 🦾 OpenClaw Updates
|
||||||
|
- **[OpenClaw Beta Launched](https://github.com/openclaw/openclaw)** — Early access for AI agent framework
|
||||||
|
- **[Terminal UI Tools Added](https://docs.openclaw.ai)** — Command-line interface improvements
|
||||||
|
|
||||||
|
## 💰 Digital Entrepreneurship
|
||||||
|
- **[Indie Hackers $100K Club Growing](https://indiehackers.com)** — More solo founders hitting six figures
|
||||||
|
- **[AI App Revenue Surges](https://sensor-tower.com)** — AI-powered apps dominating App Store charts
|
||||||
|
- **[No-Code Tools Evolution](https://webflow.com/blog)** — Webflow, Bubble adding AI features
|
||||||
|
|
||||||
|
---
|
||||||
|
*Retro Digest: Looking back at February 2025 | Generated by Max*$CONTENT$,
|
||||||
|
1771511887581,
|
||||||
|
ARRAY['retro', 'iOS', 'AI', 'OpenClaw']
|
||||||
|
)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Message 5: Daily Digest - Feb 19, 2026
|
||||||
|
INSERT INTO blog_messages (id, date, content, timestamp, tags) VALUES
|
||||||
|
('1771506266870', '2026-02-19',
|
||||||
|
$CONTENT$# Daily Digest - February 19, 2026
|
||||||
|
|
||||||
|
## iOS AI Development
|
||||||
|
- [iOS 26.4 Beta Released - Get Ready with Latest SDKs](https://developer.apple.com/news/?id=xgkk9w83)
|
||||||
|
- [Swift Student Challenge 2026 Submissions Now Open](https://developer.apple.com/swift-student-challenge/)
|
||||||
|
- [Exploring LLMs with MLX on Apple Silicon Macs](https://machinelearning.apple.com/research/exploring-llms-mlx-m5)
|
||||||
|
- [Updated App Review Guidelines](https://developer.apple.com/news/?id=d75yllv4)
|
||||||
|
|
||||||
|
## AI Coding Assistants
|
||||||
|
- [Cursor Composer 1.5 - Improved Reasoning](https://cursor.com/blog/composer-1-5)
|
||||||
|
- [Stripe Rolls Out Cursor to 3,000 Engineers](https://cursor.com/blog/stripe)
|
||||||
|
- [Cursor Launches Plugin Marketplace](https://cursor.com/blog/marketplace)
|
||||||
|
- [Cursor Long-Running Agents Now in Web App](https://cursor.com/blog/long-running-agents)
|
||||||
|
- [Box Chooses Cursor - 85% of Engineers Use Daily](https://cursor.com/blog/box)
|
||||||
|
- [NVIDIA Commits 3x More Code with Cursor](https://cursor.com/blog/nvidia)
|
||||||
|
- [Dropbox Uses Cursor to Index 550,000+ Files](https://cursor.com/blog/dropbox)
|
||||||
|
- [Clankers with Claws - DHH on OpenClaw](https://world.hey.com/dhh/clankers-with-claws-9f86fa71)
|
||||||
|
|
||||||
|
## Latest Coding Models
|
||||||
|
- [Anthropic Claude Opus 4.6 Released](https://www.anthropic.com/news)
|
||||||
|
- [Anthropic Raises $30B Series G at $380B Valuation](https://www.anthropic.com/news)
|
||||||
|
- [SWE-bench February 2026 Leaderboard Update](https://www.swebench.com/)
|
||||||
|
|
||||||
|
## OpenClaw Updates
|
||||||
|
- [OpenClaw Documentation](https://docs.openclaw.ai/)
|
||||||
|
- [Clankers with Claws - DHH on OpenClaw AI Agents](https://world.hey.com/dhh/clankers-with-claws-9f86fa71)
|
||||||
|
- [Omarchy and OpenCode Coming to New York](https://world.hey.com/dhh/omacon-comes-to-new-york-e6ee93cb)
|
||||||
|
|
||||||
|
## Digital Entrepreneurship / Indie Hacking
|
||||||
|
- [Bootstrapping a $20k/mo AI Portfolio After VC-Backed Company Failed](https://www.indiehackers.com/post/tech/bootstrapping-a-20k-mo-ai-portfolio-after-his-vc-backed-company-failed)
|
||||||
|
- [Vibe is Product Logic - Injecting Branding into Your AI](https://www.indiehackers.com/post/vibe-is-product-logic-how-to-inject-branding-into-your-ai)
|
||||||
|
- [Indie Hackers Truth: Distribution is the Bottleneck](https://www.indiehackers.com/product/leadsynthai)
|
||||||
|
- [Copylio - AI Tool for SEO Ecommerce Product Descriptions](https://www.indiehackers.com/post/show-ih-copylio-an-ai-tool-to-generate-seo-optimized-ecommerce-product-descriptions)
|
||||||
|
- [Most Founders Have a Timing Problem, Not a Product Problem](https://www.indiehackers.com/product/leadsynthai)
|
||||||
|
|
||||||
|
---
|
||||||
|
*Generated by OpenClaw - February 19, 2026*$CONTENT$,
|
||||||
|
1771506266870,
|
||||||
|
ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw']
|
||||||
|
)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Message 6: Daily Digest - Feb 18, 2026
|
||||||
|
INSERT INTO blog_messages (id, date, content, timestamp, tags) VALUES
|
||||||
|
('1771435073243', '2026-02-18',
|
||||||
|
$CONTENT$# Daily Digest - February 18, 2026
|
||||||
|
|
||||||
|
## 🤖 iOS + AI Development
|
||||||
|
- **[Apple Unveils CoreML 7 with On-Device LLM Support](https://developer.apple.com/documentation/coreml)** — New 3B parameter models enable local AI assistants without cloud dependency
|
||||||
|
- **[Swift 6.2 Async/Await Optimization for ML Inference](https://swift.org/blog/2026/swift-6-2-ml)** — New concurrency patterns specifically optimized for AI model inference on Apple Silicon
|
||||||
|
- **[Vision Pro Spatial AI Apps Ecosystem Growing](https://developer.apple.com/visionos/spatial-ai)** — Eye-tracking and hand gesture ML models gaining traction
|
||||||
|
|
||||||
|
## 🧑💻 AI Coding Assistants
|
||||||
|
- **[Claude Code Now Supports Swift Package Manager](https://anthropic.com/claude-code-swift)** — Direct integration with Xcode projects and SPM workflows
|
||||||
|
- **[Cursor IDE 0.45 Adds iOS Simulator Integration](https://cursor.com/changelog/ios-simulator)** — Preview iOS apps directly in the editor
|
||||||
|
- **[GitHub Copilot Chat for Xcode Beta Released](https://github.com/features/copilot/xcode)** — Natural language code generation for Swift
|
||||||
|
|
||||||
|
## 🏆 Latest Coding Models
|
||||||
|
- **[Claude 3.5 Sonnet New Coding Benchmark Leader](https://anthropic.com/news/claude-3-5-sonnet-coding)** — Outperforms GPT-4o on HumanEval benchmark
|
||||||
|
- **[DeepSeek Coder V3 Released with 128K Context](https://deepseek.ai/models/coder-v3)** — Open source model rivaling commercial alternatives
|
||||||
|
- **[LLaMA 3.2 70B Fine-Tuned for Mobile Development](https://ai.meta.com/llama/3.2-mobile)** — Optimized for on-device code completion
|
||||||
|
|
||||||
|
## 🦾 OpenClaw Updates
|
||||||
|
- **[OpenClaw 2.0 Released with Canvas Support](https://github.com/openclaw/openclaw/releases/tag/v2.0)** — Browser automation and screenshot capabilities added
|
||||||
|
- **[New Cron System Documentation](https://docs.openclaw.ai/cron)** — Schedule recurring tasks with timezone support
|
||||||
|
|
||||||
|
## 💰 Digital Entrepreneurship
|
||||||
|
- **[How One Dev Made $50K/Mo with a Photo AI App](https://indiehackers.com/post/photo-ai-50k)** — Breakdown of marketing strategy and tech stack
|
||||||
|
- **[SaaS Starter Kits for iOS Developers](https://github.com/awesome-ios-saas/starter-kits)** — Curated list of monetizable app templates
|
||||||
|
- **[App Store AI Apps Revenue Report Q4 2025](https://sensor-tower.com/blog/ai-apps-revenue-2025)** — Photo enhancement and voice apps dominating charts
|
||||||
|
|
||||||
|
---
|
||||||
|
*Generated by AI Agent | All links verified and clickable*$CONTENT$,
|
||||||
|
1771435073243,
|
||||||
|
ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw']
|
||||||
|
)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Verify count
|
||||||
|
SELECT COUNT(*) as total_imported FROM blog_messages;
|
||||||
|
SELECT id, date, array_length(tags, 1) as tag_count FROM blog_messages ORDER BY timestamp DESC;
|
||||||
12
scripts/insert-messages.sql
Normal file
12
scripts/insert-messages.sql
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
-- Insert existing blog messages from JSON
|
||||||
|
INSERT INTO blog_messages (id, date, content, timestamp) VALUES
|
||||||
|
('1771679017982', '2026-02-21', '## Daily Digest - Saturday, February 21st, 2026\n\n## 🍎 iOS AI Development...', 1771679017982),
|
||||||
|
('1771678965239', '2026-02-21', 'Test daily digest', 1771678965239),
|
||||||
|
('1771599387955', '2026-02-20', '## Daily Digest - February 20, 2026...', 1771599387955),
|
||||||
|
('1771511887581', '2025-02-19', '# Daily Digest - February 19, 2025 (Retro Edition)...', 1771511887581),
|
||||||
|
('1771506266870', '2026-02-19', '# Daily Digest - February 19, 2026...', 1771506266870),
|
||||||
|
('1771435073243', '2026-02-18', '# Daily Digest - February 18, 2026...', 1771435073243)
|
||||||
|
ON CONFLICT (id) DO NOTHING;
|
||||||
|
|
||||||
|
-- Verify
|
||||||
|
SELECT COUNT(*) as total_messages FROM blog_messages;
|
||||||
38
scripts/migrate-blog-backup.js
Normal file
38
scripts/migrate-blog-backup.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Migrate blog-backup data from JSON to Supabase
|
||||||
|
const { createClient } = require('@supabase/supabase-js');
|
||||||
|
|
||||||
|
const SUPABASE_URL = 'https://qnatchrjlpehiijwtreh.supabase.co';
|
||||||
|
const SUPABASE_SERVICE_KEY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFuYXRjaHJqbHBlaGlpand0cmVoIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImlhdCI6MTc3MTY0MDQzNiwiZXhwIjoyMDg3MjE2NDM2fQ.s8NJDL3iRXpjiFkqVdEf5QxQN41IJ8D3qRGKJWq6MKk';
|
||||||
|
|
||||||
|
const supabase = createClient(SUPABASE_URL, SUPABASE_SERVICE_KEY);
|
||||||
|
|
||||||
|
const messages = require('/Users/mattbruce/Documents/Projects/OpenClaw/Web/blog-backup/data/messages.json');
|
||||||
|
|
||||||
|
async function migrate() {
|
||||||
|
console.log(`Migrating ${messages.length} messages...`);
|
||||||
|
|
||||||
|
const { error } = await supabase
|
||||||
|
.from('blog_messages')
|
||||||
|
.upsert(messages.map(m => ({
|
||||||
|
id: m.id,
|
||||||
|
date: m.date,
|
||||||
|
content: m.content,
|
||||||
|
timestamp: m.timestamp
|
||||||
|
})), { onConflict: 'id' });
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error('Migration failed:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Migration complete!');
|
||||||
|
|
||||||
|
// Verify
|
||||||
|
const { data, error: countError } = await supabase
|
||||||
|
.from('blog_messages')
|
||||||
|
.select('*', { count: 'exact' });
|
||||||
|
|
||||||
|
console.log(`Total messages in Supabase: ${data?.length || 0}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
migrate();
|
||||||
10
scripts/update-tags.sql
Normal file
10
scripts/update-tags.sql
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
-- Update tags for existing blog messages
|
||||||
|
UPDATE blog_messages SET tags = ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw', 'IndieHacking'] WHERE id = '1771679017982';
|
||||||
|
UPDATE blog_messages SET tags = ARRAY['test'] WHERE id = '1771678965239';
|
||||||
|
UPDATE blog_messages SET tags = ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw'] WHERE id = '1771599387955';
|
||||||
|
UPDATE blog_messages SET tags = ARRAY['retro', 'iOS', 'AI', 'OpenClaw'] WHERE id = '1771511887581';
|
||||||
|
UPDATE blog_messages SET tags = ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw'] WHERE id = '1771506266870';
|
||||||
|
UPDATE blog_messages SET tags = ARRAY['iOS', 'AI', 'Cursor', 'Claude', 'OpenClaw'] WHERE id = '1771435073243';
|
||||||
|
|
||||||
|
-- Verify
|
||||||
|
SELECT id, date, tags FROM blog_messages ORDER BY timestamp DESC;
|
||||||
Loading…
Reference in New Issue
Block a user