Easy-to-manage touch screens
Free, open-source touch screens. Guided USB setup, a drag-and-drop editor and local control. Made for Home Assistant.
Describe what's broken or snap a photo and get a one-trip parts list with aisle numbers for Home Depot, Lowe's and AutoZone. Free.
LifestyleJavaScript · HTMLGitHub @matthew-6741OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
AI trade assistant — describe the job, get a one-trip material list with aisle numbers
Taken from the repository README
Loading the full README. The saved excerpt is shown below.
Describe the job. Get a one-trip material list with aisle numbers.
Trades lose hours and margin on the second trip to the supply store — the fitting that didn't fit, the tool left back at the shop, the size that was wrong.
Ask Danny takes a job described the way someone actually says it:
and returns one list: materials with quantities and specs, the tools needed, a rough price, and the aisle number at Home Depot, Lowe's, or AutoZone.
The two problems this has to solveRead the full README ↗Describe the job. Get the steps, the parts, the cost, and where to find each part.
ask-danny-ai.com · Live, free beta
Trades lose hours and margin on the second trip to the supply store — the fitting that didn't fit, the tool left back at the shop, the size that was wrong.
Ask Danny takes a job described the way someone actually says it:
"My toilet keeps running"
and returns the steps to fix it plus one list: materials with quantities and specs, the tools needed, a rough price, and where each part is at Home Depot, Lowe's, or AutoZone.
Models invent products. A general model will happily produce a plausible part number for something that does not exist. So the server retrieves from a curated inventory (products.json, 249 products across 10 trade buckets) and injects the matches into its own prompt. Anything not in the inventory is included but marked low confidence.
Aisle numbers get the same treatment. A number is shown only when someone has checked it in that store; the model is told never to give one, and any that slips through is dropped. Every other part shows its department and section ("Plumbing — toilet repair"), and in four mapped Los Angeles Home Depots, which row that department is in and what it sits next to. No store has been checked yet, so today every part shows a department. The goal is 75–80% of shown aisle numbers correct at one store, and that ratio is the number worth improving before anything else.
Models sell the expensive part. Asked why an AC runs but does not cool, a model will reach for refrigerant. The usual answer is a $20 capacitor. The system prompt carries per-trade check-order guidance — capacitor before refrigerant, flapper before a new toilet, coils before a compressor, battery before a starter, jam wrench before a new disposal — because selling someone the costly part when a cheap one usually fixes it is the worst thing this tool can do.
There is also a hard stop above all of it: for a gas smell, a suspected leak, carbon monoxide, sparking or burning wiring, or standing water near live electricity, it returns no materials at all and says to leave and call the utility or the fire department. A short list of nothing plus the right instruction is the correct answer.
Several models answer independently, then one synthesises. This is not majority voting — a judge reads the drafts and produces a single list, weighing safety, technical correctness and compatibility.
Browser (index.html)
│
└── POST /api/council
│
▼
netlify/functions/ai-council.js
│
├── retrieval over products.json (server-side, not client-supplied)
├── system prompt built server-side (never accepted from the request)
├── persistent rate limit (Netlify Blobs — not enforcing yet, see Security)
│
├──► Gemini ─┐
├──► Groq ─┼──► drafts
│ │
└──► judge ───┘ synthesises one list
│
└── aisle numbers only from checked store data
If the council cannot be reached the client falls back to /api/ai, a single-model path that carries the same server-owned prompt and the same safety rules.
A circuit breaker opens after three consecutive failures from a provider and retries with a single trial request after a cooldown, so one sick provider does not slow every request.
| Voice input | Describe the job hands-free (Web Speech API) |
| Repair steps | 3 to 8 steps, safety first; none for hazards, only safe checks for pro work |
| Photo and video input | Show the problem instead of describing it; a video becomes four frames on the device |
| Store layouts | Where each department is in four mapped LA Home Depots, after asking for location once |
| Multi-store compare | Home Depot vs Lowe's, side by side |
| Tool checklist | What to bring, per trade |
| Offline mode | Last result cached for the truck |
| Quantity calculator | Coverage, runs and counts |
| Job history | Firestore when signed in, localStorage as a guest |
| Usage ring | How many free lists are left today |
Trades: Plumbing · HVAC · Carpentry · Auto · Appliance
Plans: free is 5 lists a day with up to 4 drafters, all on free-tier providers. Pro (40/hour, paid models) is built but not sold — verifyProToken() returns false until real accounts exist, and the tier is never taken from the request.
Architecture is easy to add and hard to justify. The thing that actually tells you whether this works is a set of real jobs and someone qualified marking the answers.
| Path | What it is |
|---|---|
eval/jobs.json | 58 jobs phrased as real people speak, 13 of them traps |
eval/run.js | Runs them against the live API, writes a CSV with columns for a tradesperson to grade |
eval/local-check.js | 200 checks against mocked providers — every deploy runs them and stops on a failure |
eval/run.js --compare claude | Runs every job through the free council and through Claude (Opus 5) with the identical prompt, and writes a blind A/B sheet for a grader plus a separate answer key. Answers whether the paid model is worth it before anyone pays for it. |
The traps are the interesting part: a gas smell must refuse rather than sell parts, an AC that won't cool must reach for the capacitor and not refrigerant, a humming disposal needs a jam wrench and not a new unit, a load-bearing wall needs an engineer, and a prompt injection must produce a normal list and leak nothing.
local-check.js runs both handlers in-process against scripted providers and has caught two ReferenceErrors that node --check could not see. Run it before every deploy.
body.system and forwarded it, which let anyone replace the instructions wholesale — safety rules included. It is now read and discarded./api/ai was *, which let any website spend our provider quota from a browser.verifiedAisles and the server trusted them, so a crafted request could assert any aisle it liked.connectLambda drops the URL that strong-consistency reads need. Each handler now installs it itself, and local-check.js tests that.LIST_KEY is set, so a copy of the store, or an export taken with a stolen admin token, is ciphertext. The blob key stays a hash of the address, so lookups never decrypt. Set it with netlify env:set LIST_KEY "$(openssl rand -base64 32)"..github/workflows/claude-security-review.yml). It needs a CLAUDE_API_KEY repository secret and skips itself without one; fork and Dependabot PRs never get the key.npm audit for vulnerable dependencies, CodeQL for the code itself, plus the same pre-deploy checks. Dependabot opens update PRs. See .github/workflows/security.yml.netlify.toml sets HSTS, X-Frame-Options: DENY, , a strict referrer policy, and a permissions policy denying camera, payment, USB and motion sensors.CSP: script-src allows no 'unsafe-inline'. Every inline onclick was replaced with delegated listeners, and the three remaining inline scripts are allowed by SHA-256 hash. eval/csp-hashes.js regenerates the hashes and local-check.js fails if they drift, because a stale hash blocks all JavaScript. style-src still allows 'unsafe-inline' for the inline CSS, which is lower risk since styles cannot execute.
To report a vulnerability, see SECURITY.md.
Analytics load only after the visitor accepts — Consent Mode defaults every category to denied before any tag can run, and declining is the same size and weight as accepting. Every user acknowledges that AI can be wrong and that they are 18 or older before using the app, and each result carries an AI-generated label on the result itself, so a printed or screenshotted list still says a machine wrote it.
Photos are sent to an AI provider to answer one request and are not stored. No face recognition, no biometric extraction. Job history for guests never leaves the device.
See privacy.html, terms.html and cookies.html.
python3 -m http.server 4173
Then open http://localhost:4173/index.html.
On localhost the page talks to a local Ollama model instead of the deployed functions (USE_LOCAL is set from the hostname), so the AI features need Ollama running.
Before any deploy:
node eval/local-check.js
| Path | What it is |
|---|---|
index.html | The entire client app |
products.json | Curated per-trade inventory used for retrieval |
netlify/functions/ai-council.js | The council: retrieval, prompt, drafters, judge, rate limiting |
netlify/functions/ai-proxy.js | Single-model fallback, same server-owned prompt |
eval/ | Job set, live harness, and pre-deploy checks |
netlify.toml | Security headers, CSP, redirects |
firestore.rules | Owner-only Firestore access rules |
privacy.html terms.html cookies.html | Disclosure, DMCA agent, AI policy |
Live and free while in beta. Accounts are not wired up yet — Firebase config is still a placeholder, so everyone is a guest and history stays on the device.
Material lists are generated by AI and are not checked by a licensed tradesperson. Verify quantities, specs and store locations before buying, and hire a professional for gas, electrical or structural work.
| Asset | Source | Licence |
|---|---|---|
| DM Sans | Google Fonts | SIL Open Font License 1.1 |
| Interface icons | Feather Icons, inlined as SVG | MIT |
og-image.png | Generated by this repo's own script | Ours |
Product data in products.json | Compiled by hand for this project | Ours |
Store names (Home Depot, Lowe's, AutoZone) and their colours are used to identify where an item is sold. No affiliation or endorsement is implied.
Source-available, not open source. See LICENSE.
© 2026 Matthew John Sanchez. All rights reserved.
nosniff