Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions home-snipe/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# env files (can opt-in for committing if needed)
.env*

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
169 changes: 169 additions & 0 deletions home-snipe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
# TinyFish - HDB Deal Sniper

**Live Demo:** https://home-snipe.vercel.app
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Use a markdown link instead of a bare URL.

This avoids MD034 and keeps formatting consistent.

✏️ Suggested change
-**Live Demo:** https://home-snipe.vercel.app
+**Live Demo:** [home-snipe.vercel.app](https://home-snipe.vercel.app)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
**Live Demo:** https://home-snipe.vercel.app
**Live Demo:** [home-snipe.vercel.app](https://home-snipe.vercel.app)
🧰 Tools
🪛 markdownlint-cli2 (0.18.1)

3-3: Bare URL used

(MD034, no-bare-urls)

🤖 Prompt for AI Agents
In `@home-snipe/README.md` at line 3, Replace the bare URL after the "**Live
Demo:**" text with a Markdown link so the README uses proper link syntax and
avoids MD034; specifically change the string "**Live Demo:**
https://home-snipe.vercel.app" to use a link like "**Live Demo:** [Live
Demo](https://home-snipe.vercel.app)" (or similar descriptive link text) to keep
formatting consistent.


Real-time Singapore HDB resale deal finder that uses the **Source → Extract → Present** pipeline pattern. Gemini generates property listing URLs, Mino browser agents scrape them in parallel, and Gemini analyzes results to identify underpriced deals.

**Status**: ✅ Working

---

## Demo

![HDB Deal Sniper Demo](demo.jpg)

---

## How Mino API is Used

The Mino API powers browser automation for this use case. See the code snippet below for implementation details.

### Code Snippet

```bash
npm install
export MINO_API_KEY=your_key
export GEMINI_API_KEY=your_key
npm run dev
```

---

## How to Run

### Prerequisites

- Node.js 18+
- Mino API key (get from [mino.ai](https://mino.ai))

### Setup

1. Clone the repository:
```bash
git clone https://github.com/tinyfish-io/TinyFish-cookbook
cd TinyFish-cookbook/home-snipe
```

2. Install dependencies:
```bash
npm install
```

3. Create `.env.local` file:
```bash
MINO_API_KEY=xxx # Browser automation
GEMINI_API_KEY=xxx # URL generation + deal analysis
```

4. Run the development server:
```bash
npm run dev
```

5. Open [http://localhost:3000](http://localhost:3000) in your browser

---

## Architecture Diagram

```mermaid
flowchart TB
subgraph Input[USER INPUT]
Form[Town + Flat Type + Discount %]
end
subgraph Phase1[PHASE 1: URL GENERATION]
Gemini1[Gemini AI]
URLs[10 Property URLs]
end
subgraph Phase2[PHASE 2: PARALLEL SCRAPING]
A1[Agent 1]
A2[Agent 2]
A3[Agent 3]
A10[Agent 10...]
end
subgraph Phase3[PHASE 3: DEAL ANALYSIS]
Gemini2[Gemini AI]
Deals[Underpriced Deals]
end
subgraph Output[RESULTS]
UI[Live Results Sidebar]
end
Form --> Gemini1
Gemini1 --> URLs
URLs --> A1
URLs --> A2
URLs --> A3
URLs --> A10
A1 --> Gemini2
A2 --> Gemini2
A3 --> Gemini2
A10 --> Gemini2
Gemini2 --> Deals
Deals --> UI
A1 -.-> UI
A2 -.-> UI
A3 -.-> UI
A10 -.-> UI
```

```mermaid
sequenceDiagram
participant U as User
participant FE as Frontend
participant API as API Route
participant G as Gemini AI
participant M as Mino Agents
U->>FE: Select town, flat type, discount
FE->>API: POST /api/search
API->>G: Generate property URLs
G-->>API: 10 URLs from property sites
API->>M: Launch 10 parallel agents
M-->>API: Stream live URLs
API-->>FE: Forward streaming URLs
FE-->>U: Show live agent grid
M-->>API: Extract listings
API-->>FE: Stream raw listings
FE-->>U: Update results sidebar
API->>G: Analyze for deals
G-->>API: Underpriced listings
API-->>FE: DEALS_FOUND
FE-->>U: Highlight deals
```

```mermaid
classDiagram
class RawListing {
+string address
+string block
+string street
+string town
+string flatType
+string floorLevel
+string sqft
+number askingPrice
+string timePosted
+string agentName
+string agentPhone
+string listingUrl
+string source
}
class DealResult {
+string address
+string town
+string flatType
+number askingPrice
+number marketValue
+number discountPercent
+string timePosted
+string reasoning
}
class AgentStatus {
+number id
+string url
+string status
+string streamingUrl
+string[] steps
}
```


Loading