Customer feedback flows in as droplets. AI triages, builds, opens PRs. You merge. Done.
The world's first Feedback River UI β plus hosted Jal Studio, headless @jal_ai/jal npm, and Vendo as live proof on a real product.
| Live (production) | vendo-api.renuka-khirwadkarr.workers.dev |
| Try it (judges) | Homepage #try β one-click feature ideas |
| Attach a repo | /studio/onboard |
| See the river | #river β click droplets β Dual Lens |
| Vendo demo | /internal/login Β· buyer /dashboard |
| Docs | /docs |
| npm engine | @jal_ai/jal |
| Product domain | jal.app (DNS migration in progress) |
| Hackathon demo video | demo-output/jal-hackathon-demo.mp4 (~2 min) β npm run demo:record |
| UI refresh demo video | demo-output/jal-ui-demo.mp4 (~3 min, light theme + PR pipeline) β npm run demo:record:ui |
All links Β· 90-Second Demo Β· Try It Β· What's New Β· Quick Start Β· Documentation Β· Studio Β· Architecture Β· API
git clone https://github.com/buildwithrenuka/vendo.git && cd vendo && npm install && npm run devLive base URL: https://vendo-api.renuka-khirwadkarr.workers.dev
| What | Link |
|---|---|
| Homepage | vendo-api.renuka-khirwadkarr.workers.dev |
Try it (#try) |
One-click feature ideas |
Feedback River (#river) |
Interactive river + Dual Lens |
| Jal Studio β attach repo | /studio/onboard |
| Jal Studio β projects | /studio |
| In-app docs | /docs |
| Vendo β Google β Feedback | Sign in & submit |
| Vendo β buyer dashboard | /dashboard |
| Vendo β internal dev queue | /internal/login |
| API health | /api/health |
| What | Link |
|---|---|
| GitHub repo | github.com/buildwithrenuka/vendo |
| npm package | @jal_ai/jal on npm |
| Package README | packages/shipflow/README.md |
| What | Link / value |
|---|---|
| Product domain (target) | jal.app (DNS pending) |
| Email sender | hello@jal.app |
| What | Details |
|---|---|
| Final video (cinematic) | demo-output/jal-hackathon-demo.mp4 (~2 min 21 sec, 1080p) |
| Final video (new UI) | demo-output/jal-ui-demo.mp4 (~3 min, light theme + AI BuildβPR, 1080p) |
| Record | npm run demo:record Β· npm run demo:record:ui |
| Change background music | npm run demo:music Β· npm run demo:music:ui or npm run demo:music -- "https://youtube.com/watch?v=..." |
Upload jal-hackathon-demo.mp4 to your hackathon portal (or host on YouTube / Drive and paste that URL in the submission form).
Goal: Show something no other team has β feedback as a living river, not a spreadsheet.
| Step | Do this | What judges see |
|---|---|---|
| 1 | Open / (homepage) |
Hero + live pipeline animation (Request β Merge) |
| 2 | Scroll to #river |
Interactive river β click any droplet |
| 3 | Watch Dual Lens | Left = customer widget Β· Right = ship console Β· Same request |
| 4 | Scroll to #try |
One-click feature ideas β pre-filled forms for Jal Studio & Vendo |
| 5 | Go /studio/onboard |
Sign in β paste owner/repo β Repo Pour fills with AI context |
| 6 | Open /studio/projects/:id |
Real Feedback River inbox β enqueue β AI Build β PR β merge |
| 7 | Optional: /internal/login |
Vendo β same pipeline on a production procurement app |
One-liner for the panel: "Jal closes the loop from customer widget to merged GitHub PR β with a UI metaphor nobody else ships."
Jal is the product. Vendo is the live demo app (procurement) proving the same pipeline on a real product. Both run on one deploy β judges pick a path:
| Path | Who it's for | Start here | Pre-filled ideas |
|---|---|---|---|
| Jal Studio | Attach any GitHub repo | /studio/onboard |
Homepage #try β Studio cards |
| Vendo demo | See Jal on a real SaaS | Google sign-in β Feedback | Homepage #try β Vendo cards |
| Dev queue | Internal ship console | /internal/login |
Enqueue β AI Build β merge |
Jal Studio: public changelog from shipped feedback Β· Slack ping when PR ready Β· merge duplicate river droplets Β· widget theme from host brand
Vendo demo: bulk supplier CSV invite Β· GST invoice PO match Β· WhatsApp onboarding nudge Β· supplier scorecard PDF export
Click any card on #try β the form opens pre-filled. Submit and watch AI triage immediately.
Every product tool looks the same: lists, kanban, gray boxes.
Jal asks: what if feedback behaved like water?
flowchart TB
subgraph OLD["Every other tool"]
L1["Ticket #1847"]
L2["Backlog column"]
L3["Sprint board"]
end
subgraph JAL["Jal β Feedback River"]
D["Droplet on animated river"]
DL["Dual Lens split view"]
P["Position = pipeline stage"]
end
OLD -.->|"same data, dead UI"| JAL
style JAL fill:#021418,stroke:#00f5d4,color:#d4fff8
style OLD fill:#1a1a1a,stroke:#666,color:#999
| Primitive | What it replaces | Experience |
|---|---|---|
| Feedback River | Ticket list / inbox grid | Each request is a droplet on an SVG stream β left % = pipeline progress |
| Dual Lens | Single admin view | Customer lens (widget mock) β Ship lens (PR, tasks) β one stream, two truths |
| Repo Pour | "Connect GitHub" form | Liquid vessel fills as AI absorbs README + stack β onboarding as ritual |
| Nexus | Project list table | Projects orbit a central core β tributaries feeding one engine |
| Phosphor Abyss | Generic cyan SaaS | Color is narrative: cold phosphor intake β violet depth β coral ship |
Interactive proof: homepage #river Β· production UI: /studio/projects/:id
One continuous loop. Fully traceable. No black holes.
sequenceDiagram
autonumber
participant C as Customer
participant W as JalWidget
participant R as Feedback River
participant AI as OpenAI
participant GH as GitHub
C->>W: Submit feature / bug
W->>R: Droplet appears upstream
R->>AI: Triage + assess
AI->>R: Planned + tasks
R->>AI: AI Build (repo context)
AI->>GH: Open PR
R->>AI: AI Review vs PRD
Note over R,GH: Human approves once
R->>GH: Merge PR
GH-->>C: Shipped (widget status)
| Stage | AI does | Human does |
|---|---|---|
| Triage | Classify, dedupe, scope, clarify | β |
| Plan | PRD outline + engineering tasks | Approve direction |
| Build | Read attached repo, implement, open PR | β |
| Review | Validate diff vs requirements | Fix or escalate |
| Ship | β | One-click merge |
|
Zero setup Β· browser-only Attach GitHub β AI scans context β drop widget β ship from UI. |
Full control Β· your infra Same pipeline as npm β triage, tasks, build, PR, merge. npm install @jal_ai/jalProfiles: |
Live proof Β· real product Procurement app with buyer widget + internal dev queue. Not a mock β production patterns. |
flowchart LR
F["π§ Feedback"] --> T["π§ Triage"]
T --> P["π Planned"]
P --> B["βοΈ Build + PR"]
B --> R["π Review"]
R --> S["π Shipped"]
style F fill:#021418,stroke:#00f5d4,color:#d4fff8
style T fill:#021418,stroke:#7c5cff,color:#e8e0ff
style S fill:#021418,stroke:#ff6b4a,color:#ffe8e0
Studio routes
| Route | Purpose |
|---|---|
/studio |
Nexus β all projects as tributaries |
/studio/onboard |
Pour repo β AI absorb β API key |
/studio/projects/:id |
Live river + Dual Lens + Ship console |
/studio/projects/:id/embed |
<JalWidget /> snippet + iframe |
/embed/:projectId |
Public embed page |
Studio API (/studio)
| Method | Path | Auth |
|---|---|---|
GET |
/studio/setup |
Public readiness check |
POST |
/studio/projects |
Session β project + jal_live_* key |
POST |
/studio/projects/:id/scan |
AI repo context scan |
GET |
/studio/projects/:id/inbox |
River droplets |
POST |
/studio/projects/:id/features/:id/build |
AI code β GitHub PR |
POST |
/studio/projects/:id/features/:id/approve-ship |
Merge PR |
POST |
/studio/feedback |
Bearer jal_live_* widget submit |
git clone https://github.com/buildwithrenuka/vendo.git
cd vendo && npm install
npm run build --workspace @vendo/shared
npm run build --workspace @vendo/forms
cp apps/api/.dev.vars.example apps/api/.dev.vars
cp apps/web/.env.example apps/web/.env
# SESSION_SECRET (32+ chars) Β· OPENAI_API_KEY Β· GITHUB_TOKEN for Studio
npm run db:migrate:local
npm run dev| Service | URL |
|---|---|
| Web | http://localhost:5173 |
| API | http://localhost:8787 |
| Health | GET /health |
| Studio | /studio/onboard |
| Docs | /docs β step-by-step guides (Expo-style) |
| Live | workers.dev deploy |
<JalWidget
projectId="your-project-id"
apiKey="jal_live_..."
productName="My App"
placement="bottom-right"
/>import { loadJalContext, triageFeatureRequest, runAiCodeBuilder } from "@jal_ai/jal";
const jal = loadJalContext({ JAL_PROFILE: "generic", JAL_PRODUCT_NAME: "My SaaS" });npm run seed:admin --workspace @vendo/api
# β /internal/login (admin / VendoAdmin123!)flowchart TB
subgraph Surface["Experience layer"]
LAND["Landing + #river demo"]
STU["Jal Studio"]
VEN["Vendo app"]
WID["JalWidget embed"]
end
subgraph Edge["Cloudflare edge"]
API["Hono Worker"]
D1[("D1 SQLite")]
end
subgraph Brain["@jal_ai/jal"]
TRI["Triage"]
BLDR["Code builder"]
REV["PR review"]
end
subgraph World["External"]
OAI["OpenAI"]
GH["GitHub"]
end
LAND & STU & VEN & WID --> API
API --> D1
API --> Brain
Brain --> OAI
Brain --> GH
style STU fill:#021418,stroke:#00f5d4,color:#d4fff8
style Brain fill:#021418,stroke:#7c5cff,color:#e8e0ff
vendo/
βββ apps/
β βββ api/ Cloudflare Worker β /studio, /dev, /buyer, β¦
β βββ web/ React 19 Β· Vite Β· Tailwind 4 Β· Feedback River UI
βββ packages/
β βββ shared/ Types Β· Jal project models Β· status labels
β βββ forms/ Zod schemas Β· field catalog
β βββ shipflow/ @jal_ai/jal β portable AI pipeline
βββ package.json
| Layer | Technology |
|---|---|
| Frontend | React 19 Β· Vite 6 Β· Tailwind CSS 4 Β· Sora + Figtree |
| API | Cloudflare Workers Β· Hono Β· D1 |
| AI | OpenAI β triage Β· codegen Β· PR review |
| GitHub | Repo scan Β· branch Β· PR Β· merge |
| Auth | Google OAuth Β· OIDC Β· employee login |
Jal's color system maps lifecycle to hue β not decoration, narrative.
| Token | Hex | Meaning |
|---|---|---|
| Phosphor | #00f5d4 |
New feedback Β· river flow |
| Current | #7c5cff |
Pipeline depth Β· dev lens |
| Coral | #ff6b4a |
Customer warmth Β· bugs Β· shipped |
| Abyss | #010a0f |
Deep trench background |
CSS: apps/web/src/index.css Β· Tokens: apps/web/src/lib/jal-brand.ts
Jal ships on jal.app. Vendo is the bundled demo app so judges can try the pipeline on a real procurement product without attaching their own repo.
| Module | Route | Jal integration |
|---|---|---|
| Buyer dashboard | /dashboard |
Feature request widget β AI triage |
| Internal queue | /internal |
Full dev pipeline β GitHub PRs |
| Supplier onboarding | /invite/:token |
Separate product surface |
Vendo-specific: WhatsApp invites Β· compliance forms Β· auto-approve rules Β· GST reconciliation (Enterprise)
Set GITHUB_REPO=buildwithrenuka/vendo for internal AI Build PRs.
Environment variables
| Variable | Required | Purpose |
|---|---|---|
SESSION_SECRET |
β | Cookie signing |
OPENAI_API_KEY |
π€ | AI pipeline |
GITHUB_TOKEN |
π | Repo scan + PR automation |
GITHUB_REPO |
π | Vendo internal PR target |
GOOGLE_CLIENT_* |
π | Studio + buyer auth |
Full list: apps/api/.dev.vars.example
Deploy
Live: https://vendo-api.renuka-khirwadkarr.workers.dev
Product domain: jal.app β add zone on Cloudflare, point NS, then enable custom domain in wrangler.jsonc
# One command β builds web + deploys Worker + static assets
npm run deploy:all --workspace @vendo/api
# First-time setup
npm run db:migrate:remote --workspace @vendo/api
cd apps/api && npx wrangler secret bulk .deploy-secrets.env # see .dev.vars.example
# After jal.app is on Cloudflare β Resend DNS records
npm run setup:dns --workspace @vendo/apiEmail sender: hello@jal.app (Resend domain verify required).
Database β 9 migrations on D1
| Migration | Adds |
|---|---|
0001β0008 |
Users, invites, forms, feature requests, dev queue, employees |
0009_jal_studio |
jal_projects, project-scoped feedback, API keys |
Scripts
npm run dev # API + web
npm run typecheck # All workspaces
npm run db:migrate:local # Local D1| Prefix | Purpose |
|---|---|
/studio |
Jal Studio β projects, river, widget, dev queue |
/dev |
Vendo internal queue |
/buyer |
Profiles Β· forms Β· feature requests |
/supplier |
Onboarding submissions |
/auth Β· /me |
Sessions |
| Free trial | Pro $49/mo | Team |
|---|---|---|
| 3 pipeline runs | Unlimited runs | SSO + SLA |
| 1 repo | Multi-repo | Custom context |
| Widget + triage | PR automation | Dedicated support |
Vendo: Standard (3 suppliers free) Β· Enterprise (GST, unlimited)
Feedback River Β· Dual Lens Β· Repo Pour Β· OpenAI β GitHub
βΆ Run the demo Β· Attach a repo Β· Try it #try Β· npm Β· GitHub
Built by buildwithrenuka Β· Private