Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
206 commits
Select commit Hold shift + click to select a range
19e2567
feat: add db:migrate scripts (dev/deploy/reset) — proper migrations r…
BSalaeddin Apr 14, 2026
df94962
fix(local-dev): change ports away from Windows-excluded range 57956-5…
BSalaeddin Apr 14, 2026
b7d38c9
feat: Next.js reads coupon catalog from caramel_coupons (drop Prisma …
BSalaeddin Apr 14, 2026
e2df5a9
feat: per-IP rate limit + hostname validation on public coupon routes
BSalaeddin Apr 14, 2026
b3b3835
feat: harden public coupon API (headers + burst + origin + cache + caps)
BSalaeddin Apr 14, 2026
04472de
feat: cart category classifier + dynamic supported-stores in extension
aladdinb1 Apr 17, 2026
0933970
feat(extension): dev-mode auto-localhost + playwright e2e smoke test
aladdinb1 Apr 18, 2026
704ec5f
fix(coupons): filter on status='valid' after backend table merge
BSalaeddin Apr 25, 2026
4048225
feat(extension): try-verify-remove-retry loop, dynamic CSS/XPath sele…
BSalaeddin May 1, 2026
b2969a9
fix(extension): detectCouponError now compares to a baseline snapshot…
BSalaeddin May 2, 2026
8e6dfdc
fix(extension): detectCouponError requires code-echo or rejection-wor…
BSalaeddin May 2, 2026
5aedad3
fix(extension): success when committed AND row sticks after 1.2s — si…
BSalaeddin May 2, 2026
864656d
feat(extension): celebrate applied-code state distinctly from price-d…
BSalaeddin May 2, 2026
c511c9b
fix(extension): smart cart-signal waiter (poll up to 4s for success r…
BSalaeddin May 2, 2026
4997c48
fix(api/supported-stores): require ALL 5 contract fields, not just in…
BSalaeddin May 2, 2026
066ef47
fix(api/extension): exclude stores flagged metadata.extension_compati…
BSalaeddin May 2, 2026
cb3d69b
fix(extension): pick first visible+non-empty match in detectCouponError
BSalaeddin May 2, 2026
f1f0413
fix(extension): smart waiter uses _firstVisibleErrorEl too
BSalaeddin May 2, 2026
ab8603e
feat(extension): apply via full pointer+mouse+click sequence
BSalaeddin May 2, 2026
19c7856
fix(extension): canonical event-order pd→md→pu→mu→click + apply wait …
BSalaeddin May 4, 2026
af2d7ce
feat(coupons): surface pending coupons + verification badges (verifie…
BSalaeddin Jun 19, 2026
477ccaa
fix(security): remove hardcoded auth secret fallback; fix duplicate s…
BSalaeddin Jun 19, 2026
fcaf129
fix(security): increment POST+int-validate, expire api-key+cap, sourc…
BSalaeddin Jun 19, 2026
8a261e5
feat(extension): graceful degradation — early-exit, dismiss, copy-lis…
BSalaeddin Jun 23, 2026
d8ab2fc
fix(extension): remove Amazon hardcode, add fetch timeouts, SPA liste…
BSalaeddin Jun 24, 2026
e3109f5
chore(extension): remove orphaned amazon.js (no longer in manifest)
BSalaeddin Jun 24, 2026
2ed6617
fix(ext): boundary-aware domain matching in getDomainRecord (eliminat…
BSalaeddin Jun 26, 2026
3a0f51a
fix(ext): robust popup copy via caramelCopyText fallback + escape cou…
BSalaeddin Jun 26, 2026
28a2423
feat(ext): modern UI refresh — refined coupon ticket, SVG icons (no e…
BSalaeddin Jun 26, 2026
6b94376
Revert "feat(ext): modern UI refresh — refined coupon ticket, SVG ico…
BSalaeddin Jun 26, 2026
7fa4daa
polish(ext): quality pass on original popup — system font, crisper ti…
BSalaeddin Jun 26, 2026
9afaf6f
polish(ext): quality pass on on-page prompt + modals — kill infinite …
BSalaeddin Jun 26, 2026
cb565a0
polish(popup): top-right verified badge, icon+code copy button, softe…
BSalaeddin Jun 26, 2026
c7f6f62
polish(modals): code as monospace chip not underlined link; monospace…
BSalaeddin Jun 26, 2026
dddb001
fix(popup): flex title+badge row so wide status tags never overlap th…
BSalaeddin Jun 26, 2026
9f21226
polish(popup): redesign unsupported-site view — tag empty-state, stac…
BSalaeddin Jun 26, 2026
4e47d2f
polish(popup): ticket notches as clean mid-edge tears, not stray corn…
BSalaeddin Jun 26, 2026
502ec18
polish(popup): premium card pass — calmer dashed border, layered dept…
BSalaeddin Jun 26, 2026
fea0c5f
polish(ext): on-page prompt as clean horizontal toast — logo + title/…
BSalaeddin Jun 26, 2026
d70e653
polish(popup): remove ticket notch cut-out circles — dashed border ca…
BSalaeddin Jun 27, 2026
715f338
harden(ext): update_url dev-detection (drop management permission), e…
BSalaeddin Jun 28, 2026
ef00dfd
harden(ext): gate dev origins/#caramel-test/logs to dev installs, qAl…
BSalaeddin Jun 28, 2026
19046a2
harden(popup): escape user/domain in innerHTML, guard SW reply + DOM …
BSalaeddin Jun 28, 2026
70e3a25
redesign(popup): modern coupon card — left-aligned clean card + tear-…
BSalaeddin Jun 28, 2026
02acf62
harden(modals): wrap long codes in the savings/applied code chip so t…
BSalaeddin Jun 29, 2026
6aec563
fix(popup): never render blank when backend unreachable — graceful 'C…
BSalaeddin Jun 30, 2026
f14100b
fix(popup): size coupon list to viewport so card never overflows the …
BSalaeddin Jun 30, 2026
70e6aae
fix(popup): add -webkit-backdrop-filter for Safari/macOS so the popup…
BSalaeddin Jun 30, 2026
13f37b0
feat(popup): content-sized popup — compact for short lists, grows to …
BSalaeddin Jun 30, 2026
ac1aed5
a11y(popup): coupon cards keyboard-operable — role=button, tabindex, …
BSalaeddin Jun 30, 2026
689785b
a11y(popup): respect prefers-reduced-motion — neutralize logo bounce,…
BSalaeddin Jun 30, 2026
aa1a4a2
a11y(modals): on-page testing/final modals get role=dialog + aria-mod…
BSalaeddin Jun 30, 2026
6bad08b
feat(ext): graceful + honest handling when the promo box is missing —…
BSalaeddin Jun 30, 2026
9ec4019
a11y(prompt): on-page prompt keyboard-operable — role=button, tabinde…
BSalaeddin Jun 30, 2026
5f4aa01
ux(ext): testing modal opens with 'Checking this store for codes…' in…
BSalaeddin Jun 30, 2026
8fedf3b
fix(ext): re-detect dynamically-injected coupon field (bag drawer / S…
BSalaeddin Jun 30, 2026
aa37bdd
harden(ext): re-detection observer requires the coupon box/toggle to …
BSalaeddin Jun 30, 2026
b601d06
feat(ext): only prompt at checkout when codes actually exist — no emp…
BSalaeddin Jun 30, 2026
7d00125
fix(ext): cap coupon apply-flow runtime so the Applying overlay canno…
BSalaeddin Jul 1, 2026
4a091e0
fix(ext): credit a late-rendering discount so a valid code isn't repo…
BSalaeddin Jul 2, 2026
f728c9d
fix(ext): visibility-aware apply — reveal collapsed coupon accordions…
BSalaeddin Jul 2, 2026
ff89cd4
feat(ext): discount-link apply strategy via runtime cart.js capabilit…
BSalaeddin Jul 3, 2026
d78475d
feat(ext): honest-UX polish — remember tried codes across reload appl…
BSalaeddin Jul 3, 2026
4afe88e
fix(ext): count empty-to-text error transitions as attempt-caused so …
BSalaeddin Jul 3, 2026
9012be9
fix(ext): UI polish — remove black auto-focus ring (branded keyboard-…
BSalaeddin Jul 3, 2026
046d945
fix(ext): popup — branded keyboard focus rings on all controls (no bl…
BSalaeddin Jul 3, 2026
537547b
chore(ext): point unpacked/dev installs at dev.grabcaramel.com instea…
BSalaeddin Jul 3, 2026
71ed39e
chore(audit): Stage 0-1 codebase-audit artifacts (16 findings, verifi…
BSalaeddin Jul 10, 2026
0c0a991
chore(audit): record human go-signal — all 16 FIX, F-016 separate tra…
BSalaeddin Jul 11, 2026
9cac6fd
chore(audit): Stage 2 plans (15 findings) + cross-review rulings + ex…
BSalaeddin Jul 11, 2026
517a1b1
fix(F-004): vitest baseline + characterization pins + CI unit job
BSalaeddin Jul 11, 2026
e52dbee
fix(F-005): zod-validated env module + boot fail-fast + regenerated .…
BSalaeddin Jul 11, 2026
4e681b9
fix(F-009): delete Pages-Router fossils, truthful knip, oxlint + size…
BSalaeddin Jul 11, 2026
8231e1d
fix(F-003): server-only expire secret + identity-based rate-limit exe…
BSalaeddin Jul 11, 2026
014a55f
fix(F-002): route-error Sentry helper + honest decrypt/extension fail…
BSalaeddin Jul 11, 2026
0359cb4
fix(F-001): coupons-DB health probe + typed read boundary + schema-dr…
BSalaeddin Jul 11, 2026
19b91ef
fix(F-005): COUPONS_DATABASE_URL templates drop prisma-style ?schema=…
BSalaeddin Jul 11, 2026
ef85860
fix(F-011): operability runbook, error boundary, trace correlation, s…
BSalaeddin Jul 11, 2026
5777695
fix(F-006): single coupon-domain module + generated extension constan…
BSalaeddin Jul 11, 2026
125827b
fix(F-007): declarative withRoute pipeline across all API routes + ce…
BSalaeddin Jul 11, 2026
e947a1d
fix(F-006): generator emits prettier-formatted constants so the sync …
BSalaeddin Jul 11, 2026
2d9b962
fix(F-008): split shared-utils.js into 6 cohesive content-script file…
BSalaeddin Jul 11, 2026
12d675f
fix(F-008): extension-smoke e2e file inventory follows the shared-uti…
BSalaeddin Jul 11, 2026
48f5142
fix(F-013): type all exported any surfaces + no-explicit-any at error
BSalaeddin Jul 11, 2026
f34ceab
fix(F-015): remove stray/broken artifacts, rename app package to cara…
BSalaeddin Jul 11, 2026
93cde28
fix(F-014): patch crit/high vulns, drop dead react-awesome-button, pi…
BSalaeddin Jul 11, 2026
e6700f9
fix(F-012): cart-classifier eval suite + ai-evals CI gate + zod outpu…
BSalaeddin Jul 11, 2026
09d8dbb
fix(F-017): size cartClassifier token budget for reasoning models (ev…
BSalaeddin Jul 11, 2026
989fb6d
fix(F-010): onboarding docs rewritten to the post-fix reality
BSalaeddin Jul 11, 2026
0a806fd
fix(F-005): .env.example DB credentials match the compose-created car…
BSalaeddin Jul 11, 2026
145fb10
fix(F-010): LOCAL-DEV credential note reflects the corrected .env.exa…
BSalaeddin Jul 11, 2026
557842b
chore(audit): Stage 2-3 complete — 16 fixes on PR #111, plans, result…
BSalaeddin Jul 11, 2026
ce30875
docs(stage-4): CLAUDE.md + DESIGN.md — conventions with enforcement m…
BSalaeddin Jul 12, 2026
976a56d
chore(audit): Stage 4 complete — end-review SHIP, docs codified + col…
BSalaeddin Jul 12, 2026
15956ca
Merge branch 'audit/fixes-2026-07-10' into dev
BSalaeddin Jul 12, 2026
ea0481f
fix(NF-04): .gitattributes pins LF + root allowlist learns CLAUDE.md/…
BSalaeddin Jul 12, 2026
455ff53
fix(sources): query the real schema — drop phantom source_id join (dr…
BSalaeddin Jul 12, 2026
654fb36
fix(supported-stores): qualify stores on the fields the generic apply…
BSalaeddin Jul 12, 2026
fae5a92
fix(classify-cart): require extension origin — paid endpoint no longe…
BSalaeddin Jul 12, 2026
9d6b00b
fix(ext): checkout re-detection observes visibility attribute toggles…
BSalaeddin Jul 12, 2026
d2d2bc3
fix(ext): popup loader tracks the real fetch lifecycle instead of a 4…
BSalaeddin Jul 12, 2026
e54f77e
chore(audit): extension config trace + E2E-as-user report (cycle 1 fo…
BSalaeddin Jul 12, 2026
a70044e
fix(ext): size-limit content-scripts budget 92->98 kB (SI) — real pay…
BSalaeddin Jul 12, 2026
3fe2a26
chore(audit): E2E re-verification — 6 fixes confirmed, eBay auto-inje…
BSalaeddin Jul 12, 2026
1793c3a
refactor(coupons): repository module + structural drift gate + secrec…
BSalaeddin Jul 12, 2026
42f24ac
fix(coupons): tolerate producer discount_type casing/vocabulary + nul…
BSalaeddin Jul 12, 2026
4ac5a0b
chore(audit): coupons-DB architecture work — refactor + drift gate + …
BSalaeddin Jul 12, 2026
4e82ed6
chore: move audit working notes to a gitignored internal archive
BSalaeddin Jul 13, 2026
c611a0f
fix(e2e): evaluate content-script match patterns with real semantics
BSalaeddin Jul 14, 2026
8b1603b
fix(ci): move NEXT_PUBLIC_BASE_URL from workflow scope into the e2e-p…
BSalaeddin Jul 14, 2026
64de541
fix(extension-auth): surface login+authorize handler errors via handl…
BSalaeddin Jul 14, 2026
cbdea73
feat(extension-auth): gate OAuth session mint on the provider's verif…
BSalaeddin Jul 14, 2026
e6eb659
fix(extension-auth): return fresh name/image for returning users in t…
BSalaeddin Jul 14, 2026
0f062d8
refactor(extension-auth): delete the dead bearer self-fetch from the …
BSalaeddin Jul 14, 2026
784687d
fix(supported-site): make the store-suggestion form a real editable i…
BSalaeddin Jul 14, 2026
66b11f1
fix(coupons): populate the store filter from the filters endpoint (NF…
BSalaeddin Jul 14, 2026
e2b0e2b
fix(rate-limit): constant-time admin-secret comparison in isTrustedSe…
BSalaeddin Jul 14, 2026
166f620
fix(coupons): case-insensitive discount_type filter to match producer…
BSalaeddin Jul 14, 2026
52abd52
chore: remove stray root tailwind.config.js (NF-10)
BSalaeddin Jul 14, 2026
b5b5aab
chore(extension): delete stale apple-extension Xcode project (NF-08)
BSalaeddin Jul 14, 2026
906edb8
fix(health): constant-time bearer comparison in authorize()
BSalaeddin Jul 14, 2026
bbbb736
docs(extension): drop stale apple-extension references left by NF-08 …
BSalaeddin Jul 14, 2026
1b08ded
test(secrecy): gate prisma/schema.prisma against coupons-DB schema fa…
BSalaeddin Jul 14, 2026
439595b
test(gates): route-pipeline + env-door + eval-glob checks; route ALLO…
BSalaeddin Jul 14, 2026
acb07c7
test(gates): ban .only + e2e sleeps across suites; de-sleep visual-re…
BSalaeddin Jul 14, 2026
68e66bb
test(evals): lift junk-case confidence caps [0,0.6] to [0,1] + dated …
BSalaeddin Jul 14, 2026
74a4eee
chore(hygiene): tag test-quality-guardrails by its CLAUDE.md rule, no…
BSalaeddin Jul 14, 2026
7248100
chore(hygiene): scrub internal audit ids from tracked comments and tests
BSalaeddin Jul 14, 2026
fea8965
ci(checks-app): remove stale temporary audit branch from CI triggers
BSalaeddin Jul 14, 2026
e6a4eb9
ci(checks-app): run the dependency audit nightly on a schedule, gated…
BSalaeddin Jul 14, 2026
43dc9ee
ci(prettier): gate repo-root and .github files with a root-scoped pre…
BSalaeddin Jul 14, 2026
a25e67a
ci(extension): gate the extension with knip, mirroring the app's conf…
BSalaeddin Jul 14, 2026
c6b1a0f
chore(node): pin Node >=22 across engines and workflows, bump extensi…
BSalaeddin Jul 14, 2026
ce1fb07
feat(F-016): standalone output + root Dockerfile/entrypoint/.dockerig…
BSalaeddin Jul 14, 2026
23222e7
feat(F-016): root compose (web+postgres), dev=compose up, retire loca…
BSalaeddin Jul 14, 2026
4fbe05c
test(F-016): structural compose-parity gate
BSalaeddin Jul 14, 2026
3e9c6a9
ci(F-016): path-filtered compose-build smoke job
BSalaeddin Jul 14, 2026
73c212c
docs(F-016): compose-first README + LOCAL-DEV, move docs out of local…
BSalaeddin Jul 14, 2026
cc35614
chore(F-016): retire leftover redis CI port + repoint .env.example co…
BSalaeddin Jul 14, 2026
8b190bc
fix(F-016): platform env reaches web via root .env env_file + gate ro…
BSalaeddin Jul 14, 2026
1696ebd
fix(F-016): builder-stage placeholder env so next build's page-data c…
BSalaeddin Jul 14, 2026
0e90747
docs(F-016): truthful prod-cutover status + .gitattributes-era troubl…
BSalaeddin Jul 14, 2026
308ad15
fix(F-016): local-safe NEXT_PUBLIC_BASE_URL default in compose build …
BSalaeddin Jul 14, 2026
b6c0086
fix(F-016): build the app via pnpm directly in-image - turbo strict e…
BSalaeddin Jul 14, 2026
43fb9d2
fix(F-016): stage the prisma CLI via pinned npm prefix - pnpm symlink…
BSalaeddin Jul 14, 2026
3bf0518
fix(F-016): restart policy on web+postgres - fail-hard crashes stay l…
BSalaeddin Jul 14, 2026
33b5eda
feat(W1): coupon_signals table + secrecy allowlist for app-owned trus…
BSalaeddin Jul 14, 2026
26a50d8
feat(W1): couponSignals module + report endpoint + integration harness
BSalaeddin Jul 14, 2026
3e04da1
feat(W1): surface worked-ago on web card + popup, join signals into l…
BSalaeddin Jul 14, 2026
dde33fd
ci(W1): standing integration gate — real prisma against live Postgres
BSalaeddin Jul 14, 2026
e690288
fix(W1): attachSignals is non-fatal - a signal-DB error degrades the …
BSalaeddin Jul 14, 2026
6952c45
feat(W2): report worked/failed to the trust loop from the apply flow,…
BSalaeddin Jul 14, 2026
14046a5
feat(W3): app-owned catalog schema (Coupon/StoreConfig/Source) + synt…
BSalaeddin Jul 14, 2026
20f82f8
feat(W3): ingest endpoint + applyCatalogRows only-if-newer engine + I…
BSalaeddin Jul 14, 2026
27bf6da
feat(W4-D1): flip the 10 coupon reads onto the app Prisma catalog via…
BSalaeddin Jul 15, 2026
284351a
test(W4-D1): prove the flipped coupon reads against the live migrated…
BSalaeddin Jul 15, 2026
d48e1e0
feat(W4): flip the 3 coupon writes to app-owned tables + split record…
BSalaeddin Jul 15, 2026
9603f71
feat(W4-D3): health /db checks app catalog freshness, retire external…
BSalaeddin Jul 15, 2026
4a3faef
feat(W4-D3): COUPONS_DATABASE_URL optional (bridge-only) + loud boot log
BSalaeddin Jul 15, 2026
266f18c
chore(W4-D3): drop the deliberately-absent coupons DB from compose, k…
BSalaeddin Jul 15, 2026
34825be
feat(W4-D4): coupons bridge sync - replay the external catalog throug…
BSalaeddin Jul 15, 2026
4636a71
test(W4-D4): unit + end-to-end integration proof for the coupons brid…
BSalaeddin Jul 15, 2026
7181600
fix(W4): CI unit needs prisma generate + itest must strip prisma ?sch…
BSalaeddin Jul 15, 2026
219d161
docs(W5): invert coupons ownership narrative — app owns catalog, pipe…
BSalaeddin Jul 15, 2026
8a2c0ad
fix(FLAG-02): prod-scoped OSV audit gate replaces the retired pnpm-au…
BSalaeddin Jul 15, 2026
6c6766c
test(E-03): assert seeded catalog coupon card renders in coupons e2e
BSalaeddin Jul 15, 2026
073edbf
test(R-04): gate extension manifest twins against shared-field drift
BSalaeddin Jul 15, 2026
884cbde
test(E-05): real better-auth login success e2e against a seeded verif…
BSalaeddin Jul 15, 2026
45fb76b
fix(E-05): lazy prisma import - e2e-push has no generated client by d…
BSalaeddin Jul 15, 2026
fac0e8b
test(E-01): mint-extension-session re-auth proven against real DB con…
BSalaeddin Jul 15, 2026
11e05f3
test(E-02): extension e2e stages a patched temp copy pointing at the …
BSalaeddin Jul 15, 2026
74c4769
ci(E-02): wire the extension e2e suite into checks-extension with a r…
BSalaeddin Jul 15, 2026
389bbe6
docs(SA-7): DESIGN.md — F-016 landed for local/CI, NF-13 redis-not-pr…
BSalaeddin Jul 15, 2026
a5b82b2
docs(SA-7): RUNBOOK.md — redis-not-provisioned, compose deploy unit +…
BSalaeddin Jul 15, 2026
2da7c5b
docs(SA-7): CLAUDE.md — drop stale standing-red, add F-016 build trap…
BSalaeddin Jul 15, 2026
6776bf0
docs(SA-7): testing.md — codify the two-context e2e rule (hermetic vs…
BSalaeddin Jul 15, 2026
050298b
docs(SA-7): DESIGN.md — NF-03 closed by c611a0f, no standing red remains
BSalaeddin Jul 15, 2026
a37d3a4
fix(E-03): gate the synthetic seed anchor to hermetic runs, keep a de…
BSalaeddin Jul 15, 2026
238bce2
fix(SA-7): .env.example ships COUPONS_DATABASE_URL commented out + dr…
BSalaeddin Jul 15, 2026
fb483f0
docs(SA-7): RUNBOOK branch-protection contexts add unit, prettier-roo…
BSalaeddin Jul 15, 2026
35f748a
feat(uiux): PWA manifest on-brand colors + maskable icon + shortcuts;…
BSalaeddin Jul 16, 2026
6bacb93
feat(uiux): extension design tokens (light+dark) + styles.css tokeniz…
BSalaeddin Jul 16, 2026
cd517ae
feat(uiux): popup redesign — fluid shell, skeleton loader, SVG wordma…
BSalaeddin Jul 16, 2026
4b12cbf
feat(uiux): content UI in Shadow DOM — tokened content-ui.css, focus …
BSalaeddin Jul 16, 2026
46cd4a7
fix(uiux): 40px tap-target floor on coupons-view Logout; coupon-head …
BSalaeddin Jul 16, 2026
a7ba0e8
chore(uiux): iOS-sim Safari extension enable+verify automation (plist…
BSalaeddin Jul 16, 2026
7e8cbd2
fix(uiux): review pass — settings gear shows in signed-in coupons vie…
BSalaeddin Jul 16, 2026
458f90d
merge: extension UI/UX modernization (tokens, popup redesign, Shadow …
BSalaeddin Jul 16, 2026
9bd7203
feat(uiux): site-wide visual refinement — landing/marketing/auth poli…
BSalaeddin Jul 16, 2026
66d96eb
feat(uiux): 3D coupon-ticket welcome section — R3F scene, poster fall…
BSalaeddin Jul 24, 2026
5a18fde
test(e2e): exact-match hero welcome text — vault section adds two mor…
BSalaeddin Jul 24, 2026
524258d
Merge pull request #115 from DevinoSolutions/feat/uiux-site-refresh
BSalaeddin Jul 24, 2026
cee8734
feat(uiux): split hero — copy left, compact interactive 3D coupon rig…
BSalaeddin Jul 24, 2026
fc32586
perf(landing): keep three out of first-load JS — ticketMask extractio…
BSalaeddin Jul 24, 2026
1dcf252
fix(e2e): deterministic home-page images — eager+unoptimized marquee …
BSalaeddin Jul 24, 2026
be7c2a9
chore(deps): next 16.2.10 -> 16.2.11 (security patch release; clears …
BSalaeddin Jul 24, 2026
11f0cee
fix(e2e): run CI browser with reducedMotion (posters not SwiftShader …
BSalaeddin Jul 24, 2026
7204117
merge: split hero + 3D coupon vault, three kept out of first-load JS,…
BSalaeddin Jul 24, 2026
eeea721
feat(landing): single split hero — stats as 3 count-up coupon cards u…
BSalaeddin Jul 24, 2026
d7f4a93
merge: landing hero refinements — stats-as-coupons, inline CTAs, clea…
BSalaeddin Jul 24, 2026
661c9f7
feat(landing): hero stats as three same-size 3D coupon models with co…
BSalaeddin Jul 24, 2026
5649bd1
Merge pull request #119 from DevinoSolutions/feat/hero-3d-stats
BSalaeddin Jul 24, 2026
b944692
feat(landing): stat coupons float like the main model with in-canvas …
BSalaeddin Jul 25, 2026
91e43ba
Merge pull request #120 from DevinoSolutions/feat/hero-3d-stats-float
BSalaeddin Jul 25, 2026
cf58f08
fix(landing): hero canvas clip bleed, legible 3D stat text, warm dark…
BSalaeddin Jul 25, 2026
e7a41a0
Merge pull request #121 from DevinoSolutions/feat/hero-dark-polish
BSalaeddin Jul 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
30 changes: 30 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Docker does NOT read .gitignore — anything not excluded here enters the build
# context and can end up in image layers. Keep it slim; keep secrets + internal
# archives OUT.

# Dependencies / build outputs (reinstalled + rebuilt inside the image)
**/node_modules
**/.next
**/.turbo
**/dist
**/coverage
**/playwright-report
**/test-results
out

# Secrets & local env — never bake a secret into a layer (.env.example is public)
**/.env
**/.env.*
!**/.env.example
.secrets

# Internal, gitignored-local archives — secrecy forward-rule (DESIGN.md §2(k))
audit
apps/caramel-app/scripts/internal

# VCS / editor / OS
.git
.claude
.idea
.vscode
**/.DS_Store
16 changes: 16 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# NF-04: pin line endings so byte-exact gates (generated-file sync test) and
# prettier are deterministic on every OS regardless of core.autocrlf.
* text=auto eol=lf

# Binaries — never touch line endings.
*.png binary
*.jpg binary
*.jpeg binary
*.gif binary
*.ico binary
*.webp binary
*.woff binary
*.woff2 binary
*.ttf binary
*.zip binary
*.pdf binary
8 changes: 7 additions & 1 deletion .github/ISSUE_TEMPLATE/bug-report.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,29 @@ assignees: ''
---

## 🐛 Bug Description

A clear and concise description of what the bug is.

## 🔄 Steps to Reproduce

1. Go to '...'
2. Click on '...'
3. See error

## ✅ Expected Behavior

What you expected to happen.

## 📱 Environment

- **Browser:** (Chrome, Firefox, Safari)
- **Version:** (e.g., v1.2.3)
- **OS:** (Windows, macOS, Linux)

## 📸 Screenshots

If applicable, add screenshots.

## 📋 Additional Context
Any other context about the problem.

Any other context about the problem.
13 changes: 12 additions & 1 deletion .github/ISSUE_TEMPLATE/contribution.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ assignees: ''
---

## 🤝 Contribution Type

**What would you like to contribute?**

- [ ] Code (algorithms, features, bug fixes)
- [ ] Documentation (README, guides, tutorials)
- [ ] Testing (manual testing, automated tests)
Expand All @@ -16,26 +18,33 @@ assignees: ''
- [ ] Community (Discord moderation, user support)

## 🛠️ Your Experience

**Technical background:**

- [ ] Beginner developer
- [ ] Intermediate developer
- [ ] Senior developer
- [ ] Non-technical contributor

**Relevant skills:**

- Programming languages:
- Tools/frameworks:
- Previous open source experience:

## ⏰ Availability

**How much time can you commit?**

- [ ] A few hours per week
- [ ] Several hours per week
- [ ] Several hours per month
- [ ] One-time contribution

## 🎯 Specific Interests

**What areas interest you most?**

- [ ] Frontend development (React, CSS)
- [ ] Backend development (APIs, databases)
- [ ] Browser extension development
Expand All @@ -45,7 +54,9 @@ assignees: ''
- [ ] Documentation and guides

## 📋 Questions or Ideas

**Any specific questions about contributing or ideas you'd like to discuss?**

---
*Welcome to the Caramel community! We're excited to have you contribute! 🎉*

_Welcome to the Caramel community! We're excited to have you contribute! 🎉_
11 changes: 10 additions & 1 deletion .github/ISSUE_TEMPLATE/feature-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,17 @@ assignees: ''
---

## 💡 Feature Description

**Is your feature request related to a problem?**
A clear description of what the problem is. Ex. I'm frustrated when [...]

**Describe the solution you'd like:**
A clear description of what you want to happen.

## 🎯 Use Case

**Who would benefit from this feature?**

- [ ] Regular shoppers
- [ ] Power users
- [ ] Developers
Expand All @@ -24,19 +27,25 @@ A clear description of what you want to happen.
Describe the typical workflow or scenario.

## 🔧 Technical Details

**Implementation suggestions** (if you have any):

- API changes needed
- UI/UX considerations
- Performance implications

## 📊 Priority

**How important is this feature to you?**

- [ ] Nice to have
- [ ] Would be helpful
- [ ] Essential for my workflow

## 📋 Additional Context

Add any other context, mockups, or examples about the feature request here.

---
*Thank you for helping make Caramel better! 🎉*

_Thank you for helping make Caramel better! 🎉_
12 changes: 11 additions & 1 deletion .github/ISSUE_TEMPLATE/store-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,48 @@ assignees: ''
---

## 🏪 Store Information

**Store Name:**
**Store URL:**
**Store Category:** (e.g., fashion, electronics, retail, marketplace, education)
**Country/Region:** (e.g., US, EU, Global)

## 📊 Store Popularity

**Why should we prioritize this store?**

- [ ] Very popular in my region
- [ ] Frequently requested by users
- [ ] Has good coupon/discount programs
- [ ] Large user base
- [ ] Personal preference

**Estimated demand:**

- [ ] High (many users would benefit)
- [ ] Medium (some users would benefit)
- [ ] Low (niche audience)

## 🔗 Store Details

**Does this store have:**

- [ ] Regular sales/promotions
- [ ] Coupon codes
- [ ] Membership discounts
- [ ] Seasonal sales
- [ ] Student discounts

**Store size:**

- [ ] Large retailer (Amazon, Walmart level)
- [ ] Medium retailer (regional chain)
- [ ] Small/niche retailer

## 📋 Additional Context

**Any specific challenges or considerations:**

- Special checkout processes
- Regional restrictions
- Known coupon sources
Expand All @@ -49,4 +58,5 @@ assignees: ''
(Add any helpful context about the store)

---
*Thank you for helping make Caramel better! 🎉*

_Thank you for helping make Caramel better! 🎉_
122 changes: 122 additions & 0 deletions .github/workflows/ai-evals.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: AI Evals – Cart Classifier

# F-012 — standing eval gate for the repo's only LLM surface (cartClassifier
# -> openrouter -> /api/classify-cart). Mirrors checks-app.yml's setup
# steps and coupons-schema-drift.yml's loud-secret-check convention (no
# silent skip when a required secret is missing — see PLAN-F-012.md).
#
# PR: path-filtered to the AI surface so unrelated PRs never pay for (or
# see a stochastic red from) a live OpenRouter call. Nightly: catches a
# provider silently degrading/swapping the model with zero code change —
# the only thing that can. Dispatch: manual re-run / future model-swap
# comparisons.
on:
pull_request:
# audit/dev-2026-07-10 is TEMPORARY — remove when the audit branch
# merges (mirrors checks-app.yml's F-009 convention).
branches: [main, dev, audit/dev-2026-07-10]
paths:
- 'apps/caramel-app/src/lib/cartClassifier.ts'
- 'apps/caramel-app/src/lib/openrouter.ts'
- 'apps/caramel-app/src/lib/env.ts'
- 'apps/caramel-app/src/app/api/classify-cart/**'
- 'apps/caramel-app/evals/**'
- 'apps/caramel-app/vitest.eval.config.ts'
- 'apps/caramel-app/package.json'
- '.github/workflows/ai-evals.yml'
schedule:
# 09:00 UTC daily. Only actually arms once this workflow is on the
# default branch — GitHub only evaluates `schedule` there (see
# PLAN-F-012.md's "Human handoff").
- cron: '0 9 * * *'
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ai-evals-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
eval:
name: Cart classifier eval
runs-on: ubuntu-latest
timeout-minutes: 15
# Fork guard — a `pull_request` (not `pull_request_target`) from a fork
# never receives repo secrets anyway, but this makes the intent
# explicit and fails fast with a clear reason instead of a confusing
# downstream "secret missing" error on every fork PR.
if: |
github.event_name != 'pull_request' ||
github.event.pull_request.head.repo.full_name == github.repository

steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
with:
run_install: false

- uses: actions/setup-node@v4
with:
node-version: 22
cache: pnpm

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Verify OPENROUTER_API_KEY secret is configured
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
run: |
if [ -z "$OPENROUTER_API_KEY" ]; then
echo "::error::OPENROUTER_API_KEY secret is not set on this repository. Add it under Settings -> Secrets and variables -> Actions before this workflow can pass. See PLAN-F-012.md."
exit 1
fi

- name: Run cart-classifier evals
working-directory: ./apps/caramel-app
shell: bash
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}
# Raw vitest invocation, NOT the `eval` package.json script — that
# script's env-loading targets a local .env file, which CI never
# has; OPENROUTER_API_KEY above is real process env already.
# OPENROUTER_MODEL is deliberately NOT set here — leaving it unset
# means src/lib/env.ts's own zod default ('openai/gpt-5-mini') is
# the single source of truth for which model gets tested, so this
# workflow can never itself become a second, silently-drifting
# pin (exactly the failure mode F-012 exists to catch).
run: pnpm exec vitest run --config vitest.eval.config.ts | tee eval-report.txt

- name: Upload eval report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: cart-classifier-eval-report
path: apps/caramel-app/eval-report.txt
retention-days: 14

notify-on-nightly-failure:
name: Open issue on nightly failure
needs: eval
if: failure() && github.event_name == 'schedule'
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
steps:
- name: Open provider-drift issue
env:
GH_TOKEN: ${{ github.token }}
RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
# No --label: this repo's label set (checked via `gh label list`)
# has no AI/eval-specific label, and creating one out-of-band here
# would be a second silent failure mode (gh errors on an unknown
# label) if it ever drifted. The title makes the issue findable.
run: |
gh issue create \
--repo "${{ github.repository }}" \
--title "Nightly AI eval failed: cart classifier ($(date -u +%F))" \
--body "The nightly cart-classifier eval run failed on $(date -u +%F' '%T' UTC'). This can mean the OpenRouter model degraded/drifted, the OPENROUTER_API_KEY secret expired or was revoked, or a real regression landed in cartClassifier/openrouter. See the failed run: $RUN_URL"
Loading
Loading