Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
84 commits
Select commit Hold shift + click to select a range
e085bd0
fix: prevent stale DEMO render; force drawn=false before nav; pulse f…
ReaganKibet May 26, 2026
a6b6228
security: move secrets to Netlify Functions; add /results URL routing…
ReaganKibet May 27, 2026
9984a57
chore: update allowed commands in settings
ReaganKibet May 27, 2026
65d55e2
feat: move scoring into score_jd tool via AI.generate (temp 0.2); upd…
ReaganKibet May 27, 2026
394fd98
chore: settings
ReaganKibet May 27, 2026
16d7e6d
feat: add Talent Safari logo as favicon
ReaganKibet May 27, 2026
b5084a1
Redesign adjacent agents + CTA section; improve brief card visibility
ReaganKibet May 27, 2026
4642bb3
Remove .claude/settings.local.json from git tracking
ReaganKibet May 27, 2026
c34196c
Widen score result parsing to cover all Lua API response shapes
ReaganKibet May 27, 2026
976855d
chore: update lua build artifacts (backup-manifest, skill yaml)
ReaganKibet May 27, 2026
376edce
Fix Ada persona: call score_jd immediately, never ask clarifying ques…
ReaganKibet May 27, 2026
cfd5ec1
chore: update lua build artifacts post-persona-deploy
ReaganKibet May 27, 2026
3f7bd9c
Fix 504 timeout: direct scoring endpoint bypasses Ada's chat routing
ReaganKibet May 27, 2026
34f774e
Revert scoring to direct browser API call — no Netlify middleman
ReaganKibet May 27, 2026
19536b6
Fix 504 for URL JDs: fetch-jd proxy + direct Lua AI call
ReaganKibet May 27, 2026
8a343c9
Fix scoring: route all JDs through Ada chat API directly from browser
ReaganKibet May 27, 2026
1e38dbc
Fix broken capture_lead and submit_cta: replace undefined LUA_CHAT_EN…
ReaganKibet May 27, 2026
2c98d5a
Fix score_jd: JSON text output + unique session IDs
ReaganKibet May 27, 2026
3053908
chore: sync lua build artifacts after score-role v1.0.18 push
ReaganKibet May 27, 2026
21872a1
Fix scoring: use score-jd.js (JSON text) after confirming AI.generate…
ReaganKibet May 27, 2026
8dd2033
Migrate hosting from Netlify to Vercel
scotty595 May 27, 2026
fa5e279
Route scoring through Ada's chat API; remove API key from browser
ReaganKibet May 27, 2026
8ea7bdb
Vercel: override buildCommand to no-op
scotty595 May 27, 2026
b67dc68
Merge Vercel migration; route scoring through Ada's chat API
ReaganKibet May 27, 2026
9eccafd
Merge remote-tracking branch 'lua/review/latest-updates'
ReaganKibet May 27, 2026
68c691e
Restore Netlify functions as shim until Vercel DNS goes live
ReaganKibet May 27, 2026
8d7ceb0
chore: sync lua artifacts after agent re-deploy (persona v20)
May 27, 2026
9c94aa3
fix: set outputDirectory to repo root so index.html is served
May 27, 2026
a8a7e82
feat(api): add per-IP sliding-window rate limit to all serverless han…
rares04 May 27, 2026
0df0bd0
feat: route scoring through Ada via AI.generate structuredOutput
rares04 May 27, 2026
ba65194
feat(score-role): dual-path scoring — structuredOutput with JSON-text…
rares04 May 27, 2026
2d52cfb
fix(score-role): AI.generate returns AiGenerateOutput directly, not w…
rares04 May 27, 2026
5b7fa6d
fix(score-role): smarter JSON extraction from text fallback
rares04 May 27, 2026
b6b65be
feat(score-role): drop JSON-text fallback now that platform structure…
rares04 May 27, 2026
3113ca8
fix(ui): hide the "Let's build your agent brief" wizard
rares04 May 27, 2026
ae43f61
feat(skills): fix Data.create API, add cta-submissions storage, incre…
ReaganKibet May 27, 2026
5efdcd7
chore: update lua.skill.yaml agentId to original Ada, bump skill vers…
ReaganKibet May 27, 2026
2be991b
feat(dev): add local dev server + npm run dev script
ReaganKibet May 28, 2026
45214af
Remove paste link (URL mode) functionality entirely
ReaganKibet May 28, 2026
a58226f
fix(agent): restore Ada persona after accidental boilerplate overwrite
rares04 May 28, 2026
52499da
fix(submit-cta): exclude JD from Slack post on Lua path
ReaganKibet May 28, 2026
768e77a
fix(lead-capture): fire capture_lead when results render
ReaganKibet May 29, 2026
ffdffcd
feat(ui): redesign adjacent-agents as Lua spectrum cards
ReaganKibet May 29, 2026
39bafb0
fix(scoring): resolve evaluation delivery failures on Slack and frontend
ReaganKibet Jun 1, 2026
99f18b6
fix(scoring): match inline maxDuration to vercel.json (120s)
ReaganKibet Jun 1, 2026
ca9f853
feat(api): implement streaming support for Lua chat proxy
dev1ashish Jun 1, 2026
7354c09
chore(debug): add build marker to verify which build is live
dev1ashish Jun 1, 2026
ead0b86
Merge pull request #2 from lua-ai-global/devashish/fixes
dev1-lua Jun 1, 2026
556d37e
Chore: removing deploy test banners
dev1ashish Jun 1, 2026
106ec59
fix(URL map): added URL mapping for forward and backward browser actions
dev1ashish Jun 1, 2026
fdb40a0
chore: update capture-lead skill + manifest
ReaganKibet Jun 2, 2026
672ea3a
feat(sheets): align lead capture + CTA payload with new sheet schema
ReaganKibet Jun 2, 2026
ee88f3d
fix: enrichment chat advances to Step 2 without scoring/capture
yashwardhansable Jun 3, 2026
b4cf1ad
Merge pull request #3 from lua-ai-global/yash/fixes
ReaganKibet Jun 3, 2026
a9d262e
feat(capture-lead): inline HTML email report + extended sheets schema
ReaganKibet Jun 3, 2026
2be603c
feat(hero): chat-first intake with Ada leading the conversation
yashwardhansable Jun 3, 2026
18ad6f1
Merge pull request #4 from lua-ai-global/yash/fixes
Yash-Lua Jun 3, 2026
d1f3d9a
Revert "Merge pull request #4 from lua-ai-global/yash/fixes"
yashwardhansable Jun 3, 2026
f63cd25
chore: force redeploy of rolled-back state
yashwardhansable Jun 3, 2026
043dd17
fix(capture-lead): only emit Slack/Sheets/email for a real lead
yashwardhansable Jun 3, 2026
3dc3241
docs: record chat-first redesign, rollback episode, and capture-lead fix
yashwardhansable Jun 3, 2026
16a1848
chore(deploy): capture-lead v1.0.34 live (manifest + backup manifest)
yashwardhansable Jun 3, 2026
a6b52ff
fix(capture-lead): only store evaluations Data for a real lead
yashwardhansable Jun 4, 2026
38c7e9a
docs(fixes): add bug_fix.md writeup + Data-primitive follow-up
yashwardhansable Jun 4, 2026
78dc0b2
docs(capture-lead): align tool description/context with real-lead gating
yashwardhansable Jun 4, 2026
49700f6
chore(deploy): capture-lead v1.0.35 live (Data-primitive fix)
yashwardhansable Jun 4, 2026
8fecad0
docs(llm): document the capture-lead phantom-lead fix (§13)
yashwardhansable Jun 4, 2026
c90e4c6
feat(ada): intake-mode questions on the four high-leverage dimensions
yashwardhansable Jun 4, 2026
fe5b1a5
feat(hero): re-ship chat-first intake on the 4-dimension brain
yashwardhansable Jun 4, 2026
008d867
feat(hero): refine chat-first hero UI — unified pill composer
yashwardhansable Jun 4, 2026
164166d
docs(llm): document chat-first hero re-ship + pill composer (§15)
yashwardhansable Jun 4, 2026
ac0dd59
feat(hero): shift chat box left + conditional job-title intake question
yashwardhansable Jun 4, 2026
9a4527c
feat(email): plan + assets + capture-lead refactor for Phase 3 email …
ReaganKibet Jun 5, 2026
daf7bd1
feat(cta): deep-link report-email CTAs into landing screens (F4)
yashwardhansable Jun 5, 2026
f1985ad
Merge pull request #5 from lua-ai-global/feat/cta-email-deep-link
ReaganKibet Jun 5, 2026
20b5d20
feat(email): CID-attached logos + submit_cta no-context guard
ReaganKibet Jun 5, 2026
76c012d
chore(deploy): record staged skill versions + v47 backup manifest
yashwardhansable Jun 5, 2026
3eb2a78
chore(deploy): record deployed prod versions (capture-lead v1.0.37, p…
yashwardhansable Jun 5, 2026
416cf3b
Merge pull request #6 from lua-ai-global/email-implementation-fixes
Yash-Lua Jun 5, 2026
f3daca2
fix(capture-lead): stop short_jd from silently dropping real leads
yashwardhansable Jun 9, 2026
b52e5a7
Merge pull request #7 from lua-ai-global/fix/short-jd-lead-capture
Yash-Lua Jun 9, 2026
80e32ad
docs(llm.md): document the short_jd dropped-leads fix (§16)
yashwardhansable Jun 9, 2026
e693cbd
feat(analytics): install Meta Pixel + full-funnel events
yashwardhansable Jun 9, 2026
d338383
Merge pull request #9 from lua-ai-global/fix/short-jd-lead-capture
Yash-Lua Jun 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 0 additions & 43 deletions .claude/settings.local.json

This file was deleted.

11 changes: 10 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
dist-v2/

node_modules
node_modules/

.env

# Claude Code local settings — contains approved bash commands with secrets
.claude/settings.local.json

# Local mock server (confirm frontend render without the slow upstream) — not for commit
mock-server.mjs
mock-check.mjs
148 changes: 136 additions & 12 deletions .lua/backup-manifest.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,142 @@
{
"lastHash": "e47bdc60bc8cef6a77170bcaa08d07ce2bfd430242df2b8b69fc8f194418ffcc",
"lastPushedAt": "2026-05-25T13:28:49.508Z",
"lastHash": "3593183c55e79306bbd8b16cdc95c92f38b8c24e1e828788525fccb0abe986f8",
"lastPushedAt": "2026-06-05T14:45:32.947Z",
"files": [
{
"relativePath": "api/_lib/origin.js",
"hash": "abc2037d9a2ad20e"
},
{
"relativePath": "api/_lib/rate-limit.js",
"hash": "086e410e25685975"
},
{
"relativePath": "api/_lib/stream-aggregate.js",
"hash": "252e08e4d10c2705"
},
{
"relativePath": "api/fetch-jd.js",
"hash": "1c548362212ba216"
},
{
"relativePath": "api/lua-chat.js",
"hash": "169fcb41a92086b0"
},
{
"relativePath": "api/slack-notify.js",
"hash": "77352a502849a493"
},
{
"relativePath": "build.md",
"hash": "4b80192c6471a386"
"hash": "4722e1e36284660f"
},
{
"relativePath": "changes.md",
"hash": "001ebaabc0f049c9"
},
{
"relativePath": "dev-server.mjs",
"hash": "7ae969c564777cae"
},
{
"relativePath": "docs/fixes/ada_persona.md",
"hash": "68c8cab666ced769"
},
{
"relativePath": "docs/fixes/bug_fix.md",
"hash": "07df360e65a9a31a"
},
{
"relativePath": "docs/fixes/fix_ada_flow.md",
"hash": "c6f46dc6c54420db"
},
{
"relativePath": "docs/fixes/UI_change.md",
"hash": "1511b4efa823e5cf"
},
{
"relativePath": "docs/llm.md/llm.md",
"hash": "fcd49fb3510ebb68"
},
{
"relativePath": "email-preview.html",
"hash": "3d541bd6f57a64fa"
},
{
"relativePath": "env.example",
"hash": "ead1850d272e4c59"
},
{
"relativePath": "index.html",
"hash": "c6e24e63fa8aa6d2"
"hash": "c27047560bef8dbb"
},
{
"relativePath": "lua.skill.yaml",
"hash": "cd09d861d731c2f3"
"hash": "603f990682f37e06"
},
{
"relativePath": "netlify.toml",
"hash": "2bc5bc6e341c5e81"
"hash": "7bcd116156bdee81"
},
{
"relativePath": "netlify/functions/fetch-jd.js",
"hash": "99372ecf4067d76b"
},
{
"relativePath": "netlify/functions/lua-chat.js",
"hash": "b8a3883e4b99c1a9"
},
{
"relativePath": "netlify/functions/score-jd.js",
"hash": "83da42d230e001ba"
},
{
"relativePath": "netlify/functions/slack-notify.js",
"hash": "eb8d2040c636852a"
},
{
"relativePath": "package.json",
"hash": "110536777933a2d1"
"hash": "d56bbe348b9f62fd"
},
{
"relativePath": "plan.md",
"hash": "e2ed46d402b4ed4b"
},
{
"relativePath": "public/lua-logo-full.png",
"hash": "eed9c85376590bff"
},
{
"relativePath": "public/lua-logo.png",
"hash": "0af27ad79ca12ed3"
},
{
"relativePath": "public/lua-logo.svg",
"hash": "74f974fe0c331daf"
},
{
"relativePath": "public/social-facebook.png",
"hash": "9070f98432588ddd"
},
{
"relativePath": "public/social-instagram.png",
"hash": "d83c19d486196643"
},
{
"relativePath": "public/social-linkedin.png",
"hash": "c3c32e06e79f35ac"
},
{
"relativePath": "public/talent-safari-logo.jpg",
"hash": "1802a5db225825a5"
},
{
"relativePath": "public/talent-safari-logo.png",
"hash": "bd44edad815d44bf"
},
{
"relativePath": "public/talent-safari-logo1.jpg",
"hash": "b2f21158b02085a1"
},
{
"relativePath": "public/talentsafari_logo.jpg",
Expand All @@ -38,9 +150,13 @@
"relativePath": "README.md",
"hash": "2ca2d2b3168e75e5"
},
{
"relativePath": "sheets-apps-script.gs",
"hash": "634b71f65a75a8e5"
},
{
"relativePath": "src/index.ts",
"hash": "2444f8afe5be524f"
"hash": "e96c585c90fbeb4d"
},
{
"relativePath": "src/skills/ada-chat.skill.ts",
Expand All @@ -52,19 +168,23 @@
},
{
"relativePath": "src/skills/capture-lead.skill.ts",
"hash": "07abb33d708827c9"
"hash": "fea1652d9b341d83"
},
{
"relativePath": "src/skills/email-assets.ts",
"hash": "fe0b285247485488"
},
{
"relativePath": "src/skills/score-role.skill.ts",
"hash": "6c1eeb871d522684"
"hash": "336d837f8454e942"
},
{
"relativePath": "src/skills/scrape-jd.skill.ts",
"hash": "ae4336460784add0"
"hash": "35d0e547fcbce515"
},
{
"relativePath": "src/skills/submit-cta.skill.ts",
"hash": "959e71e2d4166df1"
"hash": "dc40341bc7b3999e"
},
{
"relativePath": "src/skills/tools/CaptureLead.ts",
Expand All @@ -85,6 +205,10 @@
{
"relativePath": "tsconfig.json",
"hash": "748d6fffca1cc9ce"
},
{
"relativePath": "vercel.json",
"hash": "74835210ba9078b4"
}
]
}
43 changes: 43 additions & 0 deletions api/_lib/origin.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Shared origin allowlist for all /api/* functions.
//
// Allowed origins come from three sources:
// 1. ALLOWED_ORIGINS env var (comma-separated, set per environment in Vercel)
// 2. Vercel's auto-injected URLs: VERCEL_URL, VERCEL_BRANCH_URL, VERCEL_PROJECT_PRODUCTION_URL
// (these are hostnames without protocol — we prepend https:// before comparing)
// 3. Common local dev origins (vercel dev, vite, plain http servers)
//
// Defeats casual browser-based abuse from other sites. Curl/server-to-server requests
// with forged Origin headers can still hit the endpoint — for production-scale abuse
// protection, add a rate limiter (Upstash Redis / Vercel KV) keyed on req.headers
// ['x-forwarded-for'].

const DEFAULT_DEV_ORIGINS = [
'http://localhost:3000',
'http://localhost:5173',
'http://localhost:8000',
'http://localhost:8080',
'http://127.0.0.1:3000',
'http://127.0.0.1:5173',
];

function buildAllowedOrigins() {
const fromEnv = (process.env.ALLOWED_ORIGINS || '')
.split(',').map((o) => o.trim()).filter(Boolean);

const vercelHosts = [
process.env.VERCEL_URL,
process.env.VERCEL_BRANCH_URL,
process.env.VERCEL_PROJECT_PRODUCTION_URL,
].filter(Boolean);
const vercelOrigins = vercelHosts.map((h) => `https://${h}`);

return new Set([...fromEnv, ...vercelOrigins, ...DEFAULT_DEV_ORIGINS]);
}

export function isOriginAllowed(origin, host) {
if (!origin) return false;
const allowed = buildAllowedOrigins();
if (allowed.has(origin)) return true;
// Same-origin fallback: Origin host matches the request host (e.g. preview deploys).
try { return new URL(origin).host === host; } catch { return false; }
}
Loading