Easy-to-manage touch screens
무료 오픈소스 터치스크린으로 USB 설정 가이드, 드래그‑드롭 편집기, 로컬 제어를 제공하며 Home Assistant용으로 제작되었습니다
문제 상황을 설명하거나 사진을 찍으면 Home Depot·Lowe's·AutoZone의 통로 번호가 포함된 부품 목록을 한 번에 제공한다, 무료
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.
라이프스타일JavaScript · HTMLGitHub @matthew-6741온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기AI trade assistant — describe the job, get a one-trip material list with aisle numbers
저장소 README에서 가져옴
README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
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 solveREADME 전문 보기 ↗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