diff --git a/.commandcode/settings.json b/.commandcode/settings.json index d373f99..a5ea5aa 100644 --- a/.commandcode/settings.json +++ b/.commandcode/settings.json @@ -32,7 +32,56 @@ "Shell(python3 -c import sys,json; d=json.load(sys.stdin); print('products:', len(d.get('products',[]))); print('tags:', [t['tagName'] for t in d.get('tags',[])][:12]) 2 >& 1)", "Shell(curl -s http://localhost:4174/src/styles.css 2 > /dev/null)", "Shell(printf:*)", - "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/apps/backend && python3 - <<'EOF' import re with open('dumps/local_8_aug.sql') as f: content = f.read() # Find all CREATE TABLE positions and all REFERENCES target tables create_positions = {} # table name -> line for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(', content): create_positions[m.group(1)] = content.count('\\n', 0, m.start()) + 1 # Verify each REFERENCES target is defined before the referencing CREATE errors = [] for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(([^;]*?)\\)', content, re.S): table = m.group(1) table_line = content.count('\\n', 0, m.start()) + 1 body = m.group(2) for ref in re.findall(r'REFERENCES `?([A-Za-z_]+)`?\\(', body): if ref in create_positions and create_positions[ref] > table_line: errors.append(f\"{table} (line {table_line}) references {ref} (defined line {create_positions[ref]})\") if errors: print(\"FAIL - out of order:\") for e in errors: print(\" \", e) else: print(\"PASS - all REFERENCES resolve to tables defined earlier\") EOF)" + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/apps/backend && python3 - <<'EOF' import re with open('dumps/local_8_aug.sql') as f: content = f.read() # Find all CREATE TABLE positions and all REFERENCES target tables create_positions = {} # table name -> line for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(', content): create_positions[m.group(1)] = content.count('\\n', 0, m.start()) + 1 # Verify each REFERENCES target is defined before the referencing CREATE errors = [] for m in re.finditer(r'CREATE TABLE(?: IF NOT EXISTS)? \"?([A-Za-z_]+)\"? \\(([^;]*?)\\)', content, re.S): table = m.group(1) table_line = content.count('\\n', 0, m.start()) + 1 body = m.group(2) for ref in re.findall(r'REFERENCES `?([A-Za-z_]+)`?\\(', body): if ref in create_positions and create_positions[ref] > table_line: errors.append(f\"{table} (line {table_line}) references {ref} (defined line {create_positions[ref]})\") if errors: print(\"FAIL - out of order:\") for e in errors: print(\" \", e) else: print(\"PASS - all REFERENCES resolve to tables defined earlier\") EOF)", + "Shell(find packages/db_helper_sqlite/src packages/db_helper_postgres/src -name \"*.ts\" | xargs wc -l | tail -5 && echo \"=== apps imports of db_helper ===\" && grep -rn \"db_helper\" apps packages --include=\"*.ts\" --include=\"*.tsx\" --include=\"*.json\" -l | grep -v node_modules | grep -v \"db_helper_sqlite/\\|db_helper_postgres/\\|\\.turbo\\|dist\" | sort -u)", + "Shell(cat apps/backend/wrangler.toml 2>/dev/null | head -30; echo \"=== package.json ===\"; cat apps/backend/package.json; echo \"=== how build/dev resolves ===\"; ls apps/backend/.wrangler/tmp/dev-*/worker.js 2>/dev/null | head -1 | xargs grep -o \"sqliteService\\|getAllSlotsWithProductsForCache\" 2>/dev/null | head -3; echo \"=== tsx alias config? ===\"; grep -rn \"tsx\\|alias\" apps/backend/package.json apps/backend/wrangler.toml 2>/dev/null | head; echo \"=== node_modules links ===\"; ls -la apps/backend/node_modules/ 2>/dev/null | grep -i \"db_helper\\|sqlite\\|postgres\" | head)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && for pkg in packages/db_helper_sqlite packages/db_helper_postgres; do echo \"########## $pkg ##########\"; for f in $(find $pkg/src -name \"*.ts\" | sort); do # relative imports only grep -oE \"from '(\\.\\.?/[^']+)'\" $f | sed \"s/from '//;s/'//\" | while read imp; do resolved=$(cd $(dirname $f) && node -e \"const p=require('path');try{const r=p.resolve('$imp');console.log(r.startsWith(process.cwd())?p.relative(process.cwd(),r):'')}catch(e){}\" 2>/dev/null) if [ -n \"$resolved\" ] && [ -f \"$resolved.ts\" ] || [ -n \"$resolved\" ] && [ -f \"$resolved\" ]; then echo \"$(echo $f | sed 's|^packages/||') -> $resolved\"; fi done; done; done 2>/dev/null | sort -u | grep -v \"db_index\\|schema.ts ->\" | head -80)", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); for (const pkg of [\"packages/db_helper_sqlite\", \"packages/db_helper_postgres\"]) { console.log(\"########## \" + pkg + \" ##########\"); const files = []; (function walk(d){ for (const e of fs.readdirSync(d)) { const p = path.join(d,e); if (fs.statSync(p).isDirectory()) walk(p); else if (e.endsWith(\".ts\")) files.push(p); } })(pkg); const edges = {}; for (const f of files) { const src = fs.readFileSync(f, \"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(src))) { const base = path.dirname(f); let target = path.resolve(base, m[1]); if (!fs.existsSync(target) && fs.existsSync(target + \".ts\")) target += \".ts\"; if (target.startsWith(process.cwd()) && fs.existsSync(target)) { const rel = path.relative(pkg, target); if (!rel.startsWith(\"..\")) { (edges[f] = edges[f] || []).push(rel); } } } } const allRel = files.map(f => path.relative(pkg, f)); const imported = new Set(Object.values(edges).flat()); const deadFiles = allRel.filter(r => r !== \"index.ts\" && !imported.has(r) && !r.includes(\"/db/seed\") && !r.includes(\"drizzle.config\")); // internal cross-file usage counts: who imports this rel path (excluding itself) for (const f of files) { const rel = path.relative(pkg, f); const importers = Object.entries(edges).filter(([src, tgts]) => tgts.includes(rel) && src !== f).map(([src]) => path.relative(pkg, src)); if (rel.endsWith(\".ts\") && importers.length) console.log(rel + \" <== imported by: \" + importers.join(\", \")); } console.log(\"--- files with NO internal importers (candidates for dead file): ---\"); console.log(deadFiles.join(\"\\n\")); } )", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); for (const pkg of [\"packages/db_helper_sqlite\", \"packages/db_helper_postgres\"]) { console.log(\"########## \" + pkg + \" ##########\"); const files = []; (function walk(d){ if (d.includes(\"node_modules\")) return; for (const e of fs.readdirSync(d)) { const p = path.join(d,e); if (fs.statSync(p).isDirectory()) walk(p); else if (e.endsWith(\".ts\")) files.push(p); } })(pkg); const imported = new Set(); const importers = {}; // target -> [sources] for (const f of files) { const src = fs.readFileSync(f, \"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(src))) { let target = path.resolve(path.dirname(f), m[1]); if (!fs.existsSync(target) && fs.existsSync(target + \".ts\")) target += \".ts\"; if (target.startsWith(pkg) && fs.existsSync(target)) { const rel = path.relative(pkg, target); imported.add(rel); (importers[rel] = importers[rel] || []).push(path.relative(pkg, f)); } } } const excluded = new Set([\"index.ts\",\"drizzle.config.ts\",\"src/db/seed.ts\",\"src/db/db_index.ts\",\"src/db/schema.ts\"]); const noImporter = files.map(f=>path.relative(pkg,f)).filter(r => !imported.has(r) && !excluded.has(r) && !r.includes(\"drizzle.config\")); console.log(\"Files never imported internally (incl. index.ts not importing them? checked separately):\"); for (const r of noImporter) console.log(\" \" + r); // now check which of those are imported by index.ts explicitly const idx = fs.readFileSync(path.join(pkg,\"index.ts\"),\"utf8\"); for (const r of noImporter) { const basename = path.basename(r, \".ts\"); if (!idx.includes(basename)) console.log(\" [also NOT in index.ts] \" + r); } } )", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); const pkg = \"packages/db_helper_sqlite\"; const idx = fs.readFileSync(path.join(pkg,\"index.ts\"),\"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(idx))) { const raw = m[1]; let target = path.resolve(pkg, raw); if (!fs.existsSync(target) && fs.existsSync(target+\".ts\")) target += \".ts\"; console.log(JSON.stringify(raw), \"exists:\", fs.existsSync(target), \"rel:\", path.relative(pkg, target), \"startsWithPkg:\", target.startsWith(pkg), \"target:\", target); } )", + "Shell(node -e const fs = require(\"fs\"), path = require(\"path\"); const cwd = process.cwd(); for (const pkg of [\"packages/db_helper_sqlite\", \"packages/db_helper_postgres\"]) { console.log(\"########## \" + pkg + \" ##########\"); const pkgAbs = path.resolve(pkg); const files = []; (function walk(d){ if (d.includes(\"node_modules\")) return; for (const e of fs.readdirSync(d)) { const p = path.join(d,e); if (fs.statSync(p).isDirectory()) walk(p); else if (e.endsWith(\".ts\")) files.push(p); } })(pkgAbs); const imported = new Set(); for (const f of files) { const src = fs.readFileSync(f, \"utf8\"); const re = /from\\s+[\\x27\"](\\.\\.?\\/[^\\x27\"]+)[\\x27\"]/g; let m; while ((m = re.exec(src))) { let target = path.resolve(path.dirname(f), m[1]); if (!fs.existsSync(target) && fs.existsSync(target + \".ts\")) target += \".ts\"; if (target.startsWith(pkgAbs) && fs.existsSync(target) && target !== f) { imported.add(path.relative(pkgAbs, target)); } } } const allRel = files.map(f => path.relative(pkgAbs, f)).sort(); console.log(\"Total ts files:\", allRel.length); for (const r of allRel) { if (r === \"index.ts\" || r.includes(\"drizzle.config\")) continue; if (!imported.has(r)) console.log(\" NEVER-IMPORTED FILE: \" + r); } } )", + "Shell(for:*)", + "Shell(do:*)", + "Shell(done:*)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && echo \"=== product.ts trpc import line & usage count ===\" && sed -n '1,40p' apps/backend/src/trpc/apis/admin-apis/apis/product.ts && echo \"=== count occurrences of each beyond import ===\" && for fn in checkUnitExists getProductImagesById replaceProductTags; do echo \"$fn: total=$(grep -c \"$fn\" apps/backend/src/trpc/apis/admin-apis/apis/product.ts)\"; done)", + "Shell(node -e const fs = require(\"fs\"); const parse = (p) => { const src = fs.readFileSync(p,\"utf8\"); const names = new Set(); // export { a, b as c, ... } from / re-export lists const re = /\\bexport\\s*\\{([^}]*)\\}/g; let m; while ((m = re.exec(src))) { const body = m[1]; for (let line of body.split(\",\")) { line = line.trim().replace(/\\/\\/.*$/,\"\").trim(); if (!line) continue; const asMatch = line.match(/^(.+?)\\s+as\\s+(.+)$/); if (asMatch) names.add(asMatch[2].trim()); else if (line.match(/^[A-Za-z_$][\\w$]*$/)) names.add(line); } } return names; }; const sqlite = parse(\"packages/db_helper_sqlite/index.ts\"); const pg = parse(\"packages/db_helper_postgres/index.ts\"); const onlySqlite = [...sqlite].filter(x=>!pg.has(x)).sort(); const onlyPg = [...pg].filter(x=>!sqlite.has(x)).sort(); console.log(\"ONLY IN SQLITE INDEX:\", onlySqlite.join(\", \")); console.log(\"ONLY IN POSTGRES INDEX:\", onlyPg.join(\", \")); )", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/packages/db_helper_postgres npx tsc --noEmit > /tmp/pg_tsc.log 2>&1 echo \"tsc exit: $?\" echo \"=== error count ===\"; grep -c \"error TS\" /tmp/pg_tsc.log echo \"=== errors touching shared types / banner / coupon / store / const / complaint / staff-user ===\" grep -E \"admin-apis/(banner|coupon|store|const|complaint|staff-user|slots|vendor-snippets|order)\\.ts\" /tmp/pg_tsc.log | head -20 echo \"=== total error files ===\" grep \"error TS\" /tmp/pg_tsc.log | grep -oE \"^[^(]+\" | sort -u)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/apps/web-ui && npx tsc --noEmit > /tmp/me_tsc.txt 2>&1; echo \"exit=$?\"; wc -l /tmp/me_tsc.txt; head -20 /tmp/me_tsc.txt)", + "Shell(sleep:*)", + "Shell(for p in /me /me/orders /me/addresses /me/coupons /me/complaints /me/edit-profile /me/terms; do code=$(curl -s -o /dev/null -w \"%{http_code}\" \"http://localhost:4175$p\"); echo \"$p -> $code\"; done)", + "Shell(curl -s http://localhost:4175/me)", + "Shell(pkill -f \"vite dev\" 2>/dev/null; pkill -f \"web-ui\" 2>/dev/null; echo \"stopped\")", + "Shell(npx playwright install chromium 2 >& 1)", + "Shell(npx playwright --version)", + "Shell(npx playwright test --list 2 >& 1)", + "Shell(curl -s http://localhost:4175/login)", + "Shell(curl -s -o /dev/null -w %{http_code}\\n http://localhost:4175/login)", + "Shell(grep -aiE \"error|fail\" /tmp/adminweb_dev.log | head -10 || echo \"no errors\"; pkill -f \"vite dev\" 2>/dev/null; pkill -f \"admin-web\" 2>/dev/null; echo \"stopped\")", + "Shell(git:*)", + "Shell(bun:*)", + "Shell(bunx playwright test --list -c ../playwright.config.ts 2 >& 1)", + "Shell([:*)", + "Shell(sed:*)", + "Shell(curl -s -o /dev/null -w %{http_code}\\n --max-time 4 http://localhost:4175/login 2 > /dev/null)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && bun run test:e2e > /tmp/e2e_run.log 2>&1; echo \"exit=$?\")", + "Shell(ps:*)", + "Shell(npx tsc --noEmit -p tests 2 >& 1)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && bun run test:e2e > /tmp/e2e_run2.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run2.log)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && sed -n '/```yaml/,/```/p' \"test-results/auth.setup.ts-authenticate-staff-user-setup/error-context.md\")", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && bun run test:e2e > /tmp/e2e_run3.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run3.log)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && npx tsc --noEmit -p tests 2>&1 | tail -5; echo \"tsc_exit=$?\"; bun run test:e2e > /tmp/e2e_run4.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run4.log)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && sed -n '/```yaml/,/```/p' \"test-results/specs-product-lifecycle-pr-e8d1e-e-→-update-→-slot-→-suspend-chromium/error-context.md\" | head -60)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && npx tsc --noEmit -p tests 2>&1 | tail -5; echo \"tsc_exit=$?\"; bun run test:e2e > /tmp/e2e_run5.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run5.log)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && sed -n '/```yaml/,/```/p' \"test-results/specs-product-lifecycle-pr-e8d1e-e-→-update-→-slot-→-suspend-chromium/error-context.md\" | head -50)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && bun run test:e2e > /tmp/e2e_run6.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run6.log)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && npx tsc --noEmit -p tests 2>&1 | tail -5; echo \"tsc_exit=$?\"; bun run test:e2e > /tmp/e2e_run7.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run7.log)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && sed -n '/```yaml/,/```/p' \"test-results/specs-product-lifecycle-pr-e8d1e-e-→-update-→-slot-→-suspend-chromium/error-context.md\" | head -45)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && grep -c \"add-slot-fab\" \"test-results/specs-product-lifecycle-pr-e8d1e-e-→-update-→-slot-→-suspend-chromium/error-context.md\"; grep -ao \"add-slot-fab\" \"test-results/specs-product-lifecycle-pr-e8d1e-e-→-update-→-slot-→-suspend-chromium/error-context.md\" | head; echo \"--- tail of snapshot:\"; sed -n '/```yaml/,/```/p' \"test-results/specs-product-lifecycle-pr-e8d1e-e-→-update-→-slot-→-suspend-chromium/error-context.md\" | tail -25)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && npx tsc --noEmit -p tests 2>&1 | tail -5; echo \"tsc_exit=$?\"; bun run test:e2e > /tmp/e2e_run8.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run8.log)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && npx tsc --noEmit -p tests 2>&1 | tail -5; echo \"tsc_exit=$?\"; bun run test:e2e > /tmp/e2e_run9.log 2>&1; echo \"exit=$?\" >> /tmp/e2e_run9.log)", + "Shell(DEBUG=pw:browser npx playwright test tests/specs/smoke.spec.ts 2 >& 1)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo && git diff product_to_sku_c1 -- apps/user-ui/hooks/cart-query-hooks.tsx apps/user-ui/hooks/useUploadToObjectStore.ts apps/user-ui/eas.json apps/user-ui/'(drawer)' 2>/dev/null; git diff product_to_sku_c1 -- \"apps/user-ui/app/(drawer)/(tabs)/me/addresses/index.tsx\" \"apps/user-ui/app/(drawer)/(tabs)/me/my-orders/index.tsx\" | head -160)", + "Shell(cd /Users/mohammedshafiuddin/WebDev/freshyo/packages/db_helper_sqlite && npx tsc --noEmit 2>&1 | tail -8; echo \"sqlite_exit=$?\"; echo \"=== user-ui ===\"; cd /Users/mohammedshafiuddin/WebDev/freshyo/apps/user-ui && npx tsc --noEmit 2>&1 | tee /tmp/uui_tsc.txt | tail -5; echo \"userui_errors=$(grep -cE 'error TS' /tmp/uui_tsc.txt)\")" ], "deny": [], "defaultMode": "default" diff --git a/.commandcode/taste/taste/taste.md b/.commandcode/taste/taste/taste.md index 60c4b9d..b261e42 100644 --- a/.commandcode/taste/taste/taste.md +++ b/.commandcode/taste/taste/taste.md @@ -1,4 +1,5 @@ # Taste +- Defines tunable/magic numbers as named module-level constants in the SAME file where they are used (e.g., `const TOKENS_PER_QUEUE_MESSAGE = 5` next to the code it configures, with a short explanatory comment) instead of inline literals or a shared/global config — explicitly stated: "Define 5 as a constant in the same file." Confidence: 0.7 - Prefers that the agent not run typechecks; instead, read the project's AGENTS.md for instructions on what to do/not do before finalizing work. Confidence: 0.9 - Judges completion by seeing the feature live in the running app ("I still don't see it on the /home route page"), so for data-driven features the agent must verify the app's actual runtime data source (API base URL, cache/backend) has the required data — not just that code builds and typechecks. Confirmed when the user signaled success only after the fix (pointing web-ui at the local backend with the tags data) made the section visible in the running app, and reconfirmed with the admin-ui product selector showing no products because it points at the production worker. Confidence: 0.9 - Prefers detailed analysis and explicit error/mistake checking before executing destructive operations, rather than just performing the action — e.g., before a git merge, or before deleting a row directly from the DB (asked "Can I simply delete the row from db. Will it cause any problems" about an unclaimed reserved coupon, expecting the agent to trace all referencing tables/FKs — couponUsages, couponApplicableUsers/Products — before answering). Confidence: 0.7 @@ -22,14 +23,15 @@ - Prefers test plans written for a non-technical audience, using plain-language, click-by-click instructions ("tap this", "type that", "check there") rather than technical terms or API names. Confidence: 0.9 - When updating or creating a document, prefers the agent first compare it against existing source documents, identify missing items or gaps, and add them in the same established format. Confidence: 0.9 - Dislikes nested headers in mobile/drawer navigation; prefers a single, shared header (e.g., the drawer header) and relies on device back buttons or gestures for returning to previous screens. Confidence: 0.9 -- After reviewing a presented plan, prefers brief, action-oriented approval (e.g., "nice. go ahead", "go ahead and implement") before implementation proceeds, expecting the agent to autonomously execute the already-presented plan. Confidence: 0.85 +- After reviewing a presented plan, prefers brief, action-oriented approval (e.g., "nice. go ahead", "go ahead and implement") before implementation proceeds, expecting the agent to autonomously execute the already-presented plan. Confidence: 0.9 - Wants feature parity maintained between the web-ui and user-ui apps (port logic/data patterns, rebuild UI per platform) — e.g., when he asks for a link in the cart page "at the coupons section" of @apps/user-ui/components/cart-page.tsx, he means mirror user-ui's coupons section (card, header, icon) in web-ui and add the requested link there; and conversely asks for features added in one app to be added to the sibling app "too" (e.g., "add the coupon redirection on the user-ui cart-page too"), expecting the agent to locate the equivalent component/route and replicate it. Confidence: 0.98 - Wants the web-ui home page section/component order to match the reference user-ui home page exactly (e.g., "on the home page have the order same as that of @apps/user-ui/.../home/index.tsx"), including when deciding placement of sections like Explore, Stores, Slots, and All Products. Confidence: 0.7 - Wants brand/logo spots to use the single real brand logo asset (shared across apps, e.g., the Freshyo splash logo) displayed as an image, not a generic/decorative icon (e.g., a "meat piece" Meat/Beef icon) — web-ui should be on par with user-ui and show the same logo; applies to favicon, PWA icons, and every in-UI branding spot (sidebar, topbar, login, home banner). Confidence: 0.85 -- Prefers dead-code audits to be documented in a markdown file. Confidence: 0.8 +- Prefers dead-code audits to be documented in a markdown file. Confidence: 0.9 - Prefers detailed technical documentation of system architecture, data models, flows, and integrations in markdown format. Confidence: 0.8 - Wants edge cases explicitly enumerated when documenting or analyzing existing code/systems. Confidence: 0.8 - Values end-to-end analysis of features (architecture, data model, flows, integrations, and edge cases) when asked to explain how something works. Confidence: 0.7 +- When creating a clone/mirror of an app on a different platform (e.g., a web version of a React Native app), expects EXACT replication — functionality and looks must match the reference app with zero changes ("not even a slight change is acceptable"). The tech stack is inherited from the existing clone, not the original. The exactness requirement applies per section and down to every sub-page: naming a section of the RN app (e.g., "the 'me' section and all its sub pages") means the entire subtree must be an exact replica of the mobile screens, and he will flag remaining gaps ("I see a lot of gaps") if any sub-screen diverges — so the agent should audit every sub-page, not just the section hub, against the RN source of truth. Confidence: 0.95 - Prefers unifying parallel data structures into a single instance rather than maintaining separate ones (e.g., one cart for flash and regular items instead of separate flash/regular carts). Confidence: 0.9 - Prefers using sentinel values in existing fields (e.g., slotId = 0) to distinguish special-case items rather than creating separate fields or structures. Confidence: 0.9 - Prefers handling special-case logic locally in the relevant component/file rather than globally or via parallel flows. Confidence: 0.85 @@ -90,6 +92,38 @@ er-ui/app/(drawer)/(tabs)/home/index.tsx, I want similar here") and expects the - For bulk/sequential generation from a code pattern (e.g., ABC12 → ABC13...), expects numbering to continue from the HIGHEST existing value so regeneration never re-emits already-entered codes — after entering ABC12, the next batch must start at ABC13, not restart at 12 (the first matching code). Confidence: 0.6 - Dislikes UI that renders transient loading states as definitive business states — e.g., the home page showed every item as "out of stock" until slot data loaded, because the out-of-stock check treated "no slot yet" (data not loaded) as genuinely out of stock. Expects a "data loaded" guard so the UI never flashes a wrong definitive status (out of stock) before data arrives, while still applying real out-of-stock detection once loaded. Confidence: 0.7 - When deleting a record, prefers the existing soft-delete/invalidate path over hard-deleting rows: the supported delete already sets `isInvalidated: true` (keeping history/audit and avoiding broken FK joins), and a raw hard delete should only be considered when confirmed nothing references the row (no usage records), with related rows (couponApplicableUsers/Products) removed transactionally to avoid orphans. Confidence: 0.75 +- When commissioning a dead-code audit of an app/package, expects a "close analysis" that is exhaustive across every category — dead, unreachable, and unused code: orphaned files, unreachable/unlinked routes, dormant or disabled-by-flag features, dead branches and commented-out blocks, and unused imports/exports — finding "every such code which serves no purpose" rather than only obviously-unreferenced files; findings should distinguish verified-dead items from merely dormant/judgment-call items. Confidence: 0.65 +- When an analysis/audit has been produced for one app in the monorepo, expects the same analysis run for the sibling apps too — after the user-ui dead-code audit he immediately asked "now do the same for the @apps/admin-ui" — applying the identical exhaustive methodology and document style to each named app. Confidence: 0.85 +- For analysis documents, expects a consistent naming pattern following the established convention (`user_ui_dpsk.md` → `admin_ui_dpsk.md`, i.e., `{app}_dpsk.md` at the repo root) rather than an ad-hoc filename — "make another md file with same naming pattern"; the `_dpsk.md` suffix also applies to cross-cutting topic analyses (e.g., `repeat_types_dpsk.md` for the repeated-types scan). Confidence: 0.9 +- When commissioning a cross-cutting audit/analysis, expects the scan to span the entire monorepo in one pass — every app, the backend, AND the shared packages (e.g., "scan the entire @apps/user-ui/ @apps/admin-ui/ @apps/backend/ and also entire @packages/") — not just one app or one area. Confidence: 0.65 +- Values type-level hygiene alongside runtime structures: wants repeated type declarations across the monorepo hunted down and classified (identical duplicates, near-identical/unifiable shapes, same-name-different-shape collisions) and documented in a report before any refactor, rather than fixing types piecemeal. Confidence: 0.6 + +- Requires the parallel DB-helper packages (db_helper_sqlite and db_helper_postgres) to not duplicate type definitions: they must share one canonical set of types and emit exactly the same data shape, since they represent the same business entities on different backends — stated directly: "they shouldn't duplicate types. They should emit exactly same type of data. They should share the types." Confidence: 0.9 + +- When the two DB-helper implementations diverge at the data-model level (sqlite is SKU-based with skuIds; the dormant postgres collapsed the SKU tier into productIds), the live/canonical model wins: the sqlite/SKU model — which packages/shared already standardizes on — is the source of truth and the dormant postgres helper is to be aligned/migrated to it (up to and including schema-level changes so even row types match), not the reverse. Confidence: 0.75 + +- The dedup directive is general, not limited to DB helpers: for types that are "exactly same but repeated" anywhere in the monorepo, move them into a shared package (@packages/shared), organize them there with proper comments, and export/reuse them from that one source — "Do this for all the types which are same and repeated" (stated when asking to address the duplicate-type spread repo-wide). Confidence: 0.9 + +- When organizing a shared type package, prefers to keep similar types together — all types that have identical properties should stay grouped/collocated so exact duplicates live side by side (e.g., clustering same-shaped types together in the shared files rather than scattering them). Confidence: 0.75 +- When he introduces a processing/batching parameter (e.g., a batch size such as "5 tokens per queue message"), expects it enforced end-to-end on BOTH sides of the pipeline — the write/enqueue producer AND the read/consumer/processing path — and follows up to confirm the read side honors the same limit ("we've also changed the code to read and process 5 tokens at a time right?"); a limit applied on only one side is treated as an incomplete change. Confidence: 0.6 +- Scrollable content (e.g., a product grid) must never be buried beneath a persistent floating UI element like the floating cart bar: pages that scroll above such a bar need sufficient bottom padding on the content container so the last row of items can scroll fully clear of the bar ("There should be enough padding in bottom. I see the last row of products buried beneath the floating cart bar. They should be scrollable"). Errs toward GENEROUS bottom spacing and iterates for more if it still feels tight — after the initial fix (matching siblings' mobile `pb-24`) he asked to bump it again ("it's improved but add some more padding"), landing at mobile `pb-32` / desktop `md:pb-16`. Expects the fix to follow the sibling pages' bottom-padding pattern but lean roomier rather than matching the minimum. Confidence: 0.85 +- Prefers an incremental "load more"/"Show More" reveal model over rendering the entire product list at once on listing/dashboard pages: show a fixed batch at a time (the user-ui dashboard's All Products list shows 21 items and adds another 21 per click, hiding the button once all are visible) and expects the same model replicated in the sibling web-ui app ("we aren't showing all the items at once. We have a load more model. Implement the same on the @apps/web-ui too"), matching the reference's batch size and button behavior. Confidence: 0.8 +- For browser/E2E test automation, prefers Playwright and wants the suite placed in a `tests/` folder at the project ROOT (not inside the app it targets) — "At the project root add a folder tests. I want playwright based tests". Confidence: 0.85 +- Wants E2E automation organized around long, multi-step, real user workflows executed in a SINGLE browser instance/session (e.g., add a product → update it → create a slot for it → suspend it), rather than split into isolated per-step tests — "I want to automate long tasks in a single instance". Confidence: 0.85 +- For the E2E harness itself: tests should drive whatever UI URL is targeted (no backend management from the harness), pull staff credentials from environment variables (not committed inline), and NOT auto-start the dev server — the app is assumed to be running. Confidence: 0.6 +- Wants automation tests (Playwright) to run with a VISIBLE browser, not headless — "I want to see the browser, I don't want it in headless mode" — so local runs should default to headed (CI may stay headless), with a convenience script/flag (e.g. `test:e2e:headed`, `HEADED=0/1`) to switch. Confidence: 0.85 +- Prefers names/labels displayed in FULL rather than truncated — e.g., product names in the cart drawer should wrap and show completely (text wrap / `break-words` instead of `truncate`) — "show the name full, if needed do text wrap". Confidence: 0.55 +- Wants the floating cart bar HIDDEN on routes where it is redundant — the cart page (including the flash cart alias) and the entire "me" section — and expects the condition to cover ALL child routes via a path-prefix check (`pathname.startsWith('/me')`) rather than matching only the parent route. Confidence: 0.6 +- Uses Bun as his package manager / package runner ("I use bun"), so whenever giving or documenting commands he expects `bun run