fraim 2.0.165 → 2.0.167
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/ai-hub/catalog.js +20 -27
- package/dist/src/ai-hub/server.js +418 -2
- package/dist/src/ai-hub/word-sideload.js +95 -0
- package/dist/src/cli/commands/org.js +40 -0
- package/dist/src/cli/commands/test-mcp.js +171 -0
- package/dist/src/cli/fraim.js +2 -0
- package/dist/src/cli/setup/first-run.js +242 -0
- package/dist/src/cli/utils/org-publish.js +98 -0
- package/dist/src/config/ai-manager-hiring.js +121 -0
- package/dist/src/config/compat.js +16 -0
- package/dist/src/config/feature-flags.js +25 -0
- package/dist/src/config/persona-capability-bundles.js +273 -0
- package/dist/src/config/persona-hiring.js +270 -0
- package/dist/src/config/portfolio-slug-overrides.js +17 -0
- package/dist/src/config/pricing.js +37 -0
- package/dist/src/config/stripe.js +43 -0
- package/dist/src/core/config-loader.js +9 -5
- package/dist/src/core/config-writer.js +75 -0
- package/dist/src/core/fraim-config-schema.generated.js +0 -21
- package/dist/src/core/utils/job-aliases.js +47 -0
- package/dist/src/core/utils/local-registry-resolver.js +8 -1
- package/dist/src/core/utils/workflow-parser.js +174 -0
- package/index.js +1 -1
- package/package.json +5 -1
- package/public/ai-hub/index.html +81 -0
- package/public/ai-hub/powerpoint-taskpane/index.html +236 -236
- package/public/ai-hub/powerpoint-taskpane/manifest.xml +29 -29
- package/public/ai-hub/review.css +13 -0
- package/public/ai-hub/script.js +414 -4
- package/public/ai-hub/styles.css +56 -0
- package/public/first-run/styles.css +73 -73
- package/public/portfolio/ashley.html +523 -0
- package/public/portfolio/auditya.html +83 -0
- package/public/portfolio/banke.html +83 -0
- package/public/portfolio/beza.html +659 -0
- package/public/portfolio/careena.html +632 -0
- package/public/portfolio/casey.html +568 -0
- package/public/portfolio/celia.html +490 -0
- package/public/portfolio/deidre.html +642 -0
- package/public/portfolio/gautam.html +597 -0
- package/public/portfolio/hari.html +469 -0
- package/public/portfolio/huxley.html +1354 -0
- package/public/portfolio/index.html +741 -0
- package/public/portfolio/maestro.html +518 -0
- package/public/portfolio/mandy.html +590 -0
- package/public/portfolio/mona.html +597 -0
- package/public/portfolio/pam.html +887 -0
- package/public/portfolio/procella.html +107 -0
- package/public/portfolio/qasm.html +569 -0
- package/public/portfolio/ricardo.html +489 -0
- package/public/portfolio/sade.html +560 -0
- package/public/portfolio/sam.html +654 -0
- package/public/portfolio/sechar.html +580 -0
- package/public/portfolio/sreya.html +599 -0
- package/public/portfolio/swen.html +601 -0
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="light">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>RECardo · AI Recruiter · FRAIM Portfolio</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet">
|
|
10
|
+
<style>
|
|
11
|
+
:root {
|
|
12
|
+
--accent: #14b8a6;
|
|
13
|
+
--accent-2: #0d9488;
|
|
14
|
+
--accent-light: #ccfbf1;
|
|
15
|
+
--text: #0a2420;
|
|
16
|
+
--text-2: #334155;
|
|
17
|
+
--muted: #64748b;
|
|
18
|
+
--bg: #f0fdfa;
|
|
19
|
+
--surface: #ffffff;
|
|
20
|
+
--surface-2: #f8fafc;
|
|
21
|
+
--border: #e2e8f0;
|
|
22
|
+
--shadow: 0 4px 24px rgba(10,36,32,.08);
|
|
23
|
+
--shadow-lg: 0 12px 40px rgba(10,36,32,.14);
|
|
24
|
+
--radius: 18px;
|
|
25
|
+
--radius-sm: 10px;
|
|
26
|
+
--green: #10b981;
|
|
27
|
+
--purple: #8b5cf6;
|
|
28
|
+
--amber: #f59e0b;
|
|
29
|
+
--red: #ef4444;
|
|
30
|
+
--code-bg: #0f172a;
|
|
31
|
+
--code-border: #1e293b;
|
|
32
|
+
}
|
|
33
|
+
[data-theme="dark"] {
|
|
34
|
+
--text: #e2e8f0; --text-2: #cbd5e1; --muted: #94a3b8;
|
|
35
|
+
--bg: #04131200; --bg: #061a18; --surface: #0d2420; --surface-2: #112e28;
|
|
36
|
+
--border: #1e3d38; --shadow: 0 4px 24px rgba(0,0,0,.35);
|
|
37
|
+
--shadow-lg: 0 12px 40px rgba(0,0,0,.5); --accent-light: #0c4a3e;
|
|
38
|
+
--code-bg: #020c0b; --code-border: #0d2420;
|
|
39
|
+
}
|
|
40
|
+
* { box-sizing: border-box; margin: 0; padding: 0; }
|
|
41
|
+
body { font-family: 'Inter', sans-serif; background: var(--bg); color: var(--text); min-height: 100vh; transition: background .3s, color .3s; }
|
|
42
|
+
code, pre, .mono { font-family: 'JetBrains Mono', 'Fira Code', monospace; }
|
|
43
|
+
|
|
44
|
+
.site-header { position: sticky; top: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; padding: 14px 32px; background: var(--surface); border-bottom: 1px solid var(--border); }
|
|
45
|
+
.brand { display: flex; align-items: center; gap: 10px; text-decoration: none; }
|
|
46
|
+
.brand-logo { width: 32px; height: 32px; border-radius: 8px; background: linear-gradient(135deg, #10b981, #059669); display: flex; align-items: center; justify-content: center; font-weight: 800; font-size: 14px; color: #fff; }
|
|
47
|
+
.brand-name { font-weight: 700; font-size: 15px; color: var(--text); }
|
|
48
|
+
.header-actions { display: flex; align-items: center; gap: 12px; }
|
|
49
|
+
.theme-btn { background: var(--surface-2); border: 1px solid var(--border); color: var(--muted); cursor: pointer; border-radius: 8px; padding: 7px 10px; font-size: 16px; }
|
|
50
|
+
|
|
51
|
+
.hero { max-width: 900px; margin: 56px auto 0; padding: 0 24px; text-align: center; }
|
|
52
|
+
.avatar-ring { display: inline-flex; align-items: center; justify-content: center; width: 96px; height: 96px; border-radius: 50%; background: linear-gradient(135deg, #14b8a6, #6366f1); margin-bottom: 24px; box-shadow: 0 0 0 6px var(--accent-light); overflow: hidden; }
|
|
53
|
+
.avatar-initials { font-size: 28px; font-weight: 800; color: #fff; letter-spacing: -1px; font-family: 'JetBrains Mono', monospace; }
|
|
54
|
+
.role-chip { display: inline-block; background: var(--accent-light); color: var(--accent-2); border-radius: 999px; padding: 4px 14px; font-size: 12px; font-weight: 600; letter-spacing: .04em; margin-bottom: 16px; }
|
|
55
|
+
.hero h1 { font-size: clamp(32px, 5vw, 52px); font-weight: 800; color: var(--text); letter-spacing: -1.5px; line-height: 1.1; margin-bottom: 16px; }
|
|
56
|
+
.hero h1 span { color: var(--accent); }
|
|
57
|
+
.hero p { font-size: 17px; color: var(--muted); max-width: 560px; margin: 0 auto 32px; line-height: 1.7; }
|
|
58
|
+
|
|
59
|
+
.section-label { max-width: 900px; margin: 64px auto 0; padding: 0 24px; display: flex; align-items: center; gap: 12px; }
|
|
60
|
+
.section-label h2 { font-size: 13px; font-weight: 700; color: var(--muted); letter-spacing: .08em; text-transform: uppercase; }
|
|
61
|
+
.section-divider { flex: 1; height: 1px; background: var(--border); }
|
|
62
|
+
|
|
63
|
+
.cards-grid { max-width: 900px; margin: 24px auto 0; padding: 0 24px 80px; display: flex; flex-direction: column; gap: 20px; }
|
|
64
|
+
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; transition: box-shadow .2s; }
|
|
65
|
+
.card:hover { box-shadow: var(--shadow-lg); }
|
|
66
|
+
.card-header { display: flex; align-items: flex-start; gap: 16px; padding: 24px; cursor: pointer; user-select: none; }
|
|
67
|
+
.card-icon { width: 48px; height: 48px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 22px; flex-shrink: 0; }
|
|
68
|
+
.card-meta { flex: 1; min-width: 0; }
|
|
69
|
+
.card-tag { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; margin-bottom: 6px; }
|
|
70
|
+
.card-title { font-size: 18px; font-weight: 700; color: var(--text); line-height: 1.25; margin-bottom: 6px; }
|
|
71
|
+
.card-subtitle { font-size: 13px; color: var(--muted); }
|
|
72
|
+
.card-toggle { font-size: 22px; color: var(--muted); transition: transform .3s; flex-shrink: 0; align-self: center; }
|
|
73
|
+
.card.open .card-toggle { transform: rotate(90deg); }
|
|
74
|
+
.card-body { display: none; border-top: 1px solid var(--border); padding: 28px; }
|
|
75
|
+
.card.open .card-body { display: block; }
|
|
76
|
+
|
|
77
|
+
.card-context { font-style: italic; color: var(--muted); font-size: 14px; line-height: 1.7; margin-bottom: 24px; padding: 14px 18px; background: var(--surface-2); border-radius: var(--radius-sm); border-left: 3px solid var(--accent); }
|
|
78
|
+
|
|
79
|
+
.narrative { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 16px; margin-bottom: 28px; }
|
|
80
|
+
@media (max-width: 640px) { .narrative { grid-template-columns: 1fr; } }
|
|
81
|
+
.narrative-step { background: var(--surface-2); border-radius: var(--radius-sm); padding: 16px; }
|
|
82
|
+
.step-label { font-size: 10px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 6px; }
|
|
83
|
+
.step-text { font-size: 13px; color: var(--text-2); line-height: 1.6; }
|
|
84
|
+
|
|
85
|
+
.artifact-label { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; display: flex; align-items: center; gap: 8px; }
|
|
86
|
+
.artifact-label::before { content: ''; display: block; width: 20px; height: 2px; background: var(--accent); border-radius: 2px; }
|
|
87
|
+
.source-ref { margin-top: 16px; font-size: 12px; color: var(--muted); }
|
|
88
|
+
.source-ref a { color: var(--accent); text-decoration: none; }
|
|
89
|
+
.source-ref a:hover { text-decoration: underline; }
|
|
90
|
+
|
|
91
|
+
/* ── ARTIFACT 1: Kanban ── */
|
|
92
|
+
.kanban-board {
|
|
93
|
+
background: var(--surface-2);
|
|
94
|
+
border: 1px solid var(--border);
|
|
95
|
+
border-radius: 14px;
|
|
96
|
+
padding: 20px;
|
|
97
|
+
overflow-x: auto;
|
|
98
|
+
}
|
|
99
|
+
.kanban-board-title { font-size: 14px; font-weight: 700; color: var(--text); margin-bottom: 4px; }
|
|
100
|
+
.kanban-board-sub { font-size: 12px; color: var(--muted); margin-bottom: 20px; }
|
|
101
|
+
.kanban-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; min-width: 580px; }
|
|
102
|
+
.kanban-col { background: var(--surface); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
|
|
103
|
+
.kanban-col-header { padding: 10px 14px; font-size: 12px; font-weight: 700; display: flex; align-items: center; justify-content: space-between; }
|
|
104
|
+
.kanban-count { font-size: 11px; font-weight: 800; background: rgba(255,255,255,.2); border-radius: 999px; padding: 2px 8px; }
|
|
105
|
+
.kanban-col-body { padding: 10px; display: flex; flex-direction: column; gap: 8px; }
|
|
106
|
+
.kanban-chip { background: var(--surface-2); border: 1px solid var(--border); border-radius: 8px; padding: 10px 12px; }
|
|
107
|
+
.kanban-chip-name { font-size: 12px; font-weight: 600; color: var(--text); margin-bottom: 6px; }
|
|
108
|
+
.kanban-chip-row { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
|
|
109
|
+
.kanban-skill-tag { font-size: 10px; font-weight: 700; border-radius: 999px; padding: 2px 8px; }
|
|
110
|
+
.kanban-match { font-size: 11px; font-weight: 800; color: var(--green); }
|
|
111
|
+
|
|
112
|
+
/* ── ARTIFACT 2: Before/After Job Post ── */
|
|
113
|
+
.before-after { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
|
|
114
|
+
@media (max-width: 640px) { .before-after { grid-template-columns: 1fr; } }
|
|
115
|
+
.ba-panel { border-radius: 12px; padding: 18px; }
|
|
116
|
+
.ba-panel.before { background: #fff5f5; border: 2px solid #fca5a5; opacity: .85; }
|
|
117
|
+
.ba-panel.after { background: #f0fdf4; border: 2px solid #86efac; }
|
|
118
|
+
[data-theme="dark"] .ba-panel.before { background: #2a1010; border-color: #7f1d1d; }
|
|
119
|
+
[data-theme="dark"] .ba-panel.after { background: #0a1f10; border-color: #14532d; }
|
|
120
|
+
.ba-label { font-size: 10px; font-weight: 800; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 12px; }
|
|
121
|
+
.ba-label.before { color: #ef4444; }
|
|
122
|
+
.ba-label.after { color: #16a34a; }
|
|
123
|
+
.ba-text { font-size: 13px; color: var(--text-2); line-height: 1.7; font-style: italic; }
|
|
124
|
+
.ba-panel.before .ba-text { color: #94a3b8; }
|
|
125
|
+
.ba-panel.after .ba-text { color: var(--text-2); font-style: normal; font-weight: 500; }
|
|
126
|
+
|
|
127
|
+
/* ── ARTIFACT 3: Interview Loop Table ── */
|
|
128
|
+
.interview-table-wrap {
|
|
129
|
+
background: var(--surface-2);
|
|
130
|
+
border: 1px solid var(--border);
|
|
131
|
+
border-radius: 14px;
|
|
132
|
+
overflow: hidden;
|
|
133
|
+
}
|
|
134
|
+
.interview-table-header { padding: 14px 18px; border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; }
|
|
135
|
+
.interview-table-title { font-size: 14px; font-weight: 700; color: var(--text); }
|
|
136
|
+
.interview-table { width: 100%; border-collapse: collapse; }
|
|
137
|
+
.interview-table th { font-size: 10px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); padding: 10px 14px; text-align: left; border-bottom: 1px solid var(--border); background: var(--surface); }
|
|
138
|
+
.interview-table td { font-size: 13px; color: var(--text-2); padding: 10px 14px; border-bottom: 1px solid var(--border); }
|
|
139
|
+
.interview-table tr:last-child td { border-bottom: none; }
|
|
140
|
+
.status-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: 700; border-radius: 999px; padding: 3px 10px; }
|
|
141
|
+
.status-done { background: #d1fae5; color: #065f46; }
|
|
142
|
+
.status-pending { background: #fef3c7; color: #92400e; }
|
|
143
|
+
[data-theme="dark"] .status-done { background: #064e3b; color: #6ee7b7; }
|
|
144
|
+
[data-theme="dark"] .status-pending { background: #451a03; color: #fcd34d; }
|
|
145
|
+
.timeline-bar { padding: 14px 18px; border-top: 1px solid var(--border); display: flex; align-items: center; gap: 12px; }
|
|
146
|
+
.timeline-label { font-size: 11px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .06em; white-space: nowrap; }
|
|
147
|
+
.timeline-track { flex: 1; height: 6px; background: var(--border); border-radius: 999px; position: relative; overflow: hidden; }
|
|
148
|
+
.timeline-fill { height: 100%; background: linear-gradient(90deg, var(--accent), #6366f1); border-radius: 999px; width: 100%; }
|
|
149
|
+
.timeline-days { font-size: 11px; font-weight: 800; color: var(--accent); white-space: nowrap; }
|
|
150
|
+
|
|
151
|
+
/* Footer */
|
|
152
|
+
.portfolio-footer { background: var(--surface); border-top: 1px solid var(--border); padding: 40px 24px; text-align: center; }
|
|
153
|
+
.footer-sub { margin-top: 20px; font-size: 12px; color: var(--muted); }
|
|
154
|
+
.footer-sub a { color: var(--accent); text-decoration: none; }
|
|
155
|
+
|
|
156
|
+
@media (max-width: 640px) {
|
|
157
|
+
.site-header { padding: 12px 16px; }
|
|
158
|
+
.hero { margin-top: 36px; }
|
|
159
|
+
.cards-grid { padding: 0 16px 60px; }
|
|
160
|
+
.card-header { padding: 18px; }
|
|
161
|
+
.card-body { padding: 18px; }
|
|
162
|
+
.section-label { margin-top: 40px; padding: 0 16px; }
|
|
163
|
+
.kanban-cols { grid-template-columns: repeat(2, 1fr); min-width: 0; }
|
|
164
|
+
}
|
|
165
|
+
</style>
|
|
166
|
+
</head>
|
|
167
|
+
<body>
|
|
168
|
+
|
|
169
|
+
<header class="site-header">
|
|
170
|
+
<a class="brand" href="/">
|
|
171
|
+
<div class="brand-logo">F</div>
|
|
172
|
+
<span class="brand-name">FRAIM</span>
|
|
173
|
+
</a>
|
|
174
|
+
<div class="header-actions">
|
|
175
|
+
<button class="theme-btn" onclick="toggleTheme()" title="Toggle dark mode">☾</button>
|
|
176
|
+
</div>
|
|
177
|
+
</header>
|
|
178
|
+
|
|
179
|
+
<section class="hero">
|
|
180
|
+
<div class="avatar-ring">
|
|
181
|
+
<img src="https://api.dicebear.com/9.x/notionists/svg?seed=RICARDO-recruiter&backgroundColor=ede9fe&radius=50" width="96" height="96" alt="RICARDO-recruiter avatar" style="border-radius:50%;">
|
|
182
|
+
</div>
|
|
183
|
+
<div class="role-chip">AI Recruiter</div>
|
|
184
|
+
<h1>Sourced, screened, scheduled.<br>You just do the <span>interviews</span>.</h1>
|
|
185
|
+
<p>RECardo runs full-cycle recruiting: sourcing candidates who actually fit, writing job posts engineers read, and coordinating interview loops without the calendar chaos.</p>
|
|
186
|
+
</section>
|
|
187
|
+
|
|
188
|
+
<div class="section-label">
|
|
189
|
+
<h2>Selected Work</h2>
|
|
190
|
+
<div class="section-divider"></div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div class="cards-grid">
|
|
194
|
+
|
|
195
|
+
<!-- Card 1: Candidate Pipeline -->
|
|
196
|
+
<div class="card open" id="card1">
|
|
197
|
+
<div class="card-header" onclick="toggleCard(1)">
|
|
198
|
+
<div class="card-icon" style="background:#ccfbf1;">🎯</div>
|
|
199
|
+
<div class="card-meta">
|
|
200
|
+
<div class="card-tag" style="color:#14b8a6;">Full-Cycle Recruiting</div>
|
|
201
|
+
<div class="card-title">12 qualified candidates in 72 hours</div>
|
|
202
|
+
<div class="card-subtitle">FRAIM · candidate-pipeline-management · fraim/ai-employee/jobs/</div>
|
|
203
|
+
</div>
|
|
204
|
+
<div class="card-toggle">›</div>
|
|
205
|
+
</div>
|
|
206
|
+
<div class="card-body">
|
|
207
|
+
<div class="card-context">An engineering team needed to hire a senior backend engineer. The role had been open for 6 weeks with 3 recruiter agency submissions — all mismatched on tech stack.</div>
|
|
208
|
+
<div class="narrative">
|
|
209
|
+
<div class="narrative-step">
|
|
210
|
+
<div class="step-label">The Problem</div>
|
|
211
|
+
<div class="step-text">The search process was moving quickly, but the resume whetting was inconsistent. 18 candidates with Java backgrounds were forwarded for a Go/PostgreSQL role. The hiring manager spent 8 hours reviewing 18 mismatched CVs.</div>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="narrative-step">
|
|
214
|
+
<div class="step-label">What RECardo Can Build</div>
|
|
215
|
+
<div class="step-text">Ran a sourcing sprint against the actual role requirements: Go + PostgreSQL + distributed systems, 4+ years, startup-comfortable, remote-open. Searched GitHub contributor profiles, LinkedIn active profiles, and HackerNews "Who is hiring?" — filtered on real code samples, not recruiter summaries.</div>
|
|
216
|
+
</div>
|
|
217
|
+
<div class="narrative-step">
|
|
218
|
+
<div class="step-label">Possible Outcome</div>
|
|
219
|
+
<div class="step-text">RECardo can typically surface 12 qualified candidates within 72 hours, all meeting the technical bar — compared to the 11% screen-in rate typical of agency pipelines. With RECardo sourcing, you can expect offers to close within 5 weeks, versus the 14-week industry average.</div>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
|
|
223
|
+
<div class="artifact-label">Live Artifact — Candidate Pipeline</div>
|
|
224
|
+
|
|
225
|
+
<div class="kanban-board">
|
|
226
|
+
<div class="kanban-board-title">Senior Backend Engineer · Pipeline</div>
|
|
227
|
+
<div class="kanban-board-sub">Go · PostgreSQL · Distributed Systems · Remote · Sourced by RECardo</div>
|
|
228
|
+
<div class="kanban-cols">
|
|
229
|
+
<div class="kanban-col">
|
|
230
|
+
<div class="kanban-col-header" style="background:#0d9488; color:#fff;">
|
|
231
|
+
Sourced <span class="kanban-count">18</span>
|
|
232
|
+
</div>
|
|
233
|
+
<div class="kanban-col-body">
|
|
234
|
+
<div class="kanban-chip">
|
|
235
|
+
<div class="kanban-chip-name">Go Engineer, 7yr exp</div>
|
|
236
|
+
<div class="kanban-chip-row">
|
|
237
|
+
<span class="kanban-skill-tag" style="background:#ccfbf1;color:#0d9488;">Go OSS</span>
|
|
238
|
+
<span class="kanban-match">94%</span>
|
|
239
|
+
</div>
|
|
240
|
+
</div>
|
|
241
|
+
<div class="kanban-chip">
|
|
242
|
+
<div class="kanban-chip-name">Distributed Systems Lead</div>
|
|
243
|
+
<div class="kanban-chip-row">
|
|
244
|
+
<span class="kanban-skill-tag" style="background:#ede9fe;color:#7c3aed;">Kafka</span>
|
|
245
|
+
<span class="kanban-match">88%</span>
|
|
246
|
+
</div>
|
|
247
|
+
</div>
|
|
248
|
+
<div class="kanban-chip">
|
|
249
|
+
<div class="kanban-chip-name">OSS contributor</div>
|
|
250
|
+
<div class="kanban-chip-row">
|
|
251
|
+
<span class="kanban-skill-tag" style="background:#dbeafe;color:#1d4ed8;">PostgreSQL</span>
|
|
252
|
+
<span class="kanban-match">91%</span>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
<div class="kanban-col">
|
|
258
|
+
<div class="kanban-col-header" style="background:#14b8a6; color:#fff;">
|
|
259
|
+
Screened <span class="kanban-count">12</span>
|
|
260
|
+
</div>
|
|
261
|
+
<div class="kanban-col-body">
|
|
262
|
+
<div class="kanban-chip">
|
|
263
|
+
<div class="kanban-chip-name">Backend Infra Eng</div>
|
|
264
|
+
<div class="kanban-chip-row">
|
|
265
|
+
<span class="kanban-skill-tag" style="background:#ccfbf1;color:#0d9488;">gRPC</span>
|
|
266
|
+
<span class="kanban-match">92%</span>
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
<div class="kanban-chip">
|
|
270
|
+
<div class="kanban-chip-name">Platform Engineer, 5yr</div>
|
|
271
|
+
<div class="kanban-chip-row">
|
|
272
|
+
<span class="kanban-skill-tag" style="background:#fef9c3;color:#a16207;">k8s</span>
|
|
273
|
+
<span class="kanban-match">87%</span>
|
|
274
|
+
</div>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
</div>
|
|
278
|
+
<div class="kanban-col">
|
|
279
|
+
<div class="kanban-col-header" style="background:#6366f1; color:#fff;">
|
|
280
|
+
Interview <span class="kanban-count">5</span>
|
|
281
|
+
</div>
|
|
282
|
+
<div class="kanban-col-body">
|
|
283
|
+
<div class="kanban-chip">
|
|
284
|
+
<div class="kanban-chip-name">Go / Postgres Eng</div>
|
|
285
|
+
<div class="kanban-chip-row">
|
|
286
|
+
<span class="kanban-skill-tag" style="background:#ede9fe;color:#7c3aed;">CockroachDB</span>
|
|
287
|
+
<span class="kanban-match">96%</span>
|
|
288
|
+
</div>
|
|
289
|
+
</div>
|
|
290
|
+
<div class="kanban-chip">
|
|
291
|
+
<div class="kanban-chip-name">Staff Backend Eng</div>
|
|
292
|
+
<div class="kanban-chip-row">
|
|
293
|
+
<span class="kanban-skill-tag" style="background:#ccfbf1;color:#0d9488;">Go Expert</span>
|
|
294
|
+
<span class="kanban-match">93%</span>
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
<div class="kanban-col">
|
|
300
|
+
<div class="kanban-col-header" style="background:#10b981; color:#fff;">
|
|
301
|
+
Offer <span class="kanban-count">1</span>
|
|
302
|
+
</div>
|
|
303
|
+
<div class="kanban-col-body">
|
|
304
|
+
<div class="kanban-chip">
|
|
305
|
+
<div class="kanban-chip-name">Distributed Systems Lead</div>
|
|
306
|
+
<div class="kanban-chip-row">
|
|
307
|
+
<span class="kanban-skill-tag" style="background:#d1fae5;color:#065f46;">Accepted</span>
|
|
308
|
+
<span class="kanban-match">97%</span>
|
|
309
|
+
</div>
|
|
310
|
+
</div>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</div>
|
|
315
|
+
|
|
316
|
+
<div class="source-ref">
|
|
317
|
+
Source: <a href="#">FRAIM · candidate-pipeline-management · fraim/ai-employee/jobs/candidate-pipeline-management.md</a>
|
|
318
|
+
</div>
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
|
|
322
|
+
<!-- Card 2: Job Posting & Sourcing -->
|
|
323
|
+
<div class="card" id="card2">
|
|
324
|
+
<div class="card-header" onclick="toggleCard(2)">
|
|
325
|
+
<div class="card-icon" style="background:#ccfbf1;">📝</div>
|
|
326
|
+
<div class="card-meta">
|
|
327
|
+
<div class="card-tag" style="color:#14b8a6;">Employer Brand</div>
|
|
328
|
+
<div class="card-title">The job post that engineers actually applied to</div>
|
|
329
|
+
<div class="card-subtitle">FRAIM · job-posting-and-sourcing · fraim/ai-employee/jobs/</div>
|
|
330
|
+
</div>
|
|
331
|
+
<div class="card-toggle">›</div>
|
|
332
|
+
</div>
|
|
333
|
+
<div class="card-body">
|
|
334
|
+
<div class="card-context">A startup's previous senior engineer job posting had received 3 applicants in 4 weeks on LinkedIn — all under-qualified.</div>
|
|
335
|
+
<div class="narrative">
|
|
336
|
+
<div class="narrative-step">
|
|
337
|
+
<div class="step-label">The Problem</div>
|
|
338
|
+
<div class="step-text">Most job postings are written for HR compliance, not for candidates. They list requirements without explaining why the work matters, mention "competitive salary" without a range, and describe culture as "fast-paced" — a phrase that has lost all meaning.</div>
|
|
339
|
+
</div>
|
|
340
|
+
<div class="narrative-step">
|
|
341
|
+
<div class="step-label">What RECardo Can Build</div>
|
|
342
|
+
<div class="step-text">Rewrote the posting using STAR format: the business problem the role solves, the concrete first 90 days, the real tech stack with versions, the actual compensation band ($180–220K base + equity), and a specific call to action for engineers who want to see the codebase before applying.</div>
|
|
343
|
+
</div>
|
|
344
|
+
<div class="narrative-step">
|
|
345
|
+
<div class="step-label">Possible Outcome</div>
|
|
346
|
+
<div class="step-text">A RECardo job posting rewrite can take applications from a trickle to 31+ in the first week (versus 3 in the prior 4 weeks). You can expect around 24 to meet the technical bar on initial review, and candidates who engage with specific project details in their applications — a signal they've done real pre-read rather than mass-applying.</div>
|
|
347
|
+
</div>
|
|
348
|
+
</div>
|
|
349
|
+
|
|
350
|
+
<div class="artifact-label">Live Artifact — Before / After Job Post</div>
|
|
351
|
+
|
|
352
|
+
<div class="before-after">
|
|
353
|
+
<div class="ba-panel before">
|
|
354
|
+
<div class="ba-label before">Before</div>
|
|
355
|
+
<div class="ba-text">We are a fast-paced startup looking for a rockstar engineer with 5+ years experience to join our team. Must have experience with backend systems. Competitive compensation.</div>
|
|
356
|
+
</div>
|
|
357
|
+
<div class="ba-panel after">
|
|
358
|
+
<div class="ba-label after">After</div>
|
|
359
|
+
<div class="ba-text">You'll architect our real-time data pipeline that processes 10M events/day. Stack: Go 1.21, PostgreSQL 16, Kafka 3.6. First 90 days: ship one major feature, own one service end-to-end. Comp: $180–220K + 0.2–0.5% equity. See the codebase: github.com/[company]/[repo]</div>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
|
|
363
|
+
<div class="source-ref">
|
|
364
|
+
Source: <a href="#">FRAIM · job-posting-and-sourcing · fraim/ai-employee/jobs/job-posting-and-sourcing.md</a>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
</div>
|
|
368
|
+
|
|
369
|
+
<!-- Card 3: Interview Coordination -->
|
|
370
|
+
<div class="card" id="card3">
|
|
371
|
+
<div class="card-header" onclick="toggleCard(3)">
|
|
372
|
+
<div class="card-icon" style="background:#ccfbf1;">📅</div>
|
|
373
|
+
<div class="card-meta">
|
|
374
|
+
<div class="card-tag" style="color:#14b8a6;">Candidate Experience</div>
|
|
375
|
+
<div class="card-title">5-round interview loop. Zero scheduling chaos.</div>
|
|
376
|
+
<div class="card-subtitle">FRAIM · interview-coordination · fraim/ai-employee/jobs/</div>
|
|
377
|
+
</div>
|
|
378
|
+
<div class="card-toggle">›</div>
|
|
379
|
+
</div>
|
|
380
|
+
<div class="card-body">
|
|
381
|
+
<div class="card-context">A candidate drop-off rate of 40% during the interview process (between screen and offer) was traced to scheduling delays — candidates waiting 4–5 days for each round to be scheduled.</div>
|
|
382
|
+
<div class="narrative">
|
|
383
|
+
<div class="narrative-step">
|
|
384
|
+
<div class="step-label">The Problem</div>
|
|
385
|
+
<div class="step-text">Scheduling a 5-round loop requires coordinating 7+ calendars across timezones. Each round requires finding mutual availability, sending invites, confirming prep materials, and following up on feedback forms. Manually, this takes 30–60 minutes per round.</div>
|
|
386
|
+
</div>
|
|
387
|
+
<div class="narrative-step">
|
|
388
|
+
<div class="step-label">What RECardo Can Build</div>
|
|
389
|
+
<div class="step-text">Automated the loop: collected interviewer availability once per week (30-minute standing block), batched all active candidates into available slots, sent each candidate a personalized prep brief (what the round covers, who they're meeting, what to expect), and followed up with interviewers 2 hours after each round for structured feedback using a scoring rubric.</div>
|
|
390
|
+
</div>
|
|
391
|
+
<div class="narrative-step">
|
|
392
|
+
<div class="step-label">Possible Outcome</div>
|
|
393
|
+
<div class="step-text">RECardo's interview coordination can reduce average time-between-rounds from 4.3 days to around 1.1 days. Candidate drop-off rates typically fall from 40% to 11% — and when the process runs cleanly, candidates often comment on it positively in their offer acceptance notes.</div>
|
|
394
|
+
</div>
|
|
395
|
+
</div>
|
|
396
|
+
|
|
397
|
+
<div class="artifact-label">Live Artifact — Interview Loop Timeline</div>
|
|
398
|
+
|
|
399
|
+
<div class="interview-table-wrap">
|
|
400
|
+
<div class="interview-table-header">
|
|
401
|
+
<span class="interview-table-title">Interview Loop · Senior Backend Engineer</span>
|
|
402
|
+
<span style="font-size:12px;color:var(--muted);">5 rounds · 5 days total</span>
|
|
403
|
+
</div>
|
|
404
|
+
<table class="interview-table">
|
|
405
|
+
<thead>
|
|
406
|
+
<tr>
|
|
407
|
+
<th>Round</th>
|
|
408
|
+
<th>Interviewer</th>
|
|
409
|
+
<th>Status</th>
|
|
410
|
+
<th>Date</th>
|
|
411
|
+
</tr>
|
|
412
|
+
</thead>
|
|
413
|
+
<tbody>
|
|
414
|
+
<tr>
|
|
415
|
+
<td><strong>Round 1</strong> — Phone Screen</td>
|
|
416
|
+
<td>RECardo (AI)</td>
|
|
417
|
+
<td><span class="status-badge status-done">✅ Done</span></td>
|
|
418
|
+
<td>May 12</td>
|
|
419
|
+
</tr>
|
|
420
|
+
<tr>
|
|
421
|
+
<td><strong>Round 2</strong> — Technical Screen</td>
|
|
422
|
+
<td>Lead Eng</td>
|
|
423
|
+
<td><span class="status-badge status-done">✅ Done</span></td>
|
|
424
|
+
<td>May 13</td>
|
|
425
|
+
</tr>
|
|
426
|
+
<tr>
|
|
427
|
+
<td><strong>Round 3</strong> — System Design</td>
|
|
428
|
+
<td>Staff Eng</td>
|
|
429
|
+
<td><span class="status-badge status-done">✅ Done</span></td>
|
|
430
|
+
<td>May 15</td>
|
|
431
|
+
</tr>
|
|
432
|
+
<tr>
|
|
433
|
+
<td><strong>Round 4</strong> — Cross-functional</td>
|
|
434
|
+
<td>PM + Design</td>
|
|
435
|
+
<td><span class="status-badge status-done">✅ Done</span></td>
|
|
436
|
+
<td>May 16</td>
|
|
437
|
+
</tr>
|
|
438
|
+
<tr>
|
|
439
|
+
<td><strong>Round 5</strong> — Executive</td>
|
|
440
|
+
<td>CTO</td>
|
|
441
|
+
<td><span class="status-badge status-pending">⏳ Scheduled</span></td>
|
|
442
|
+
<td>May 17 · 10am</td>
|
|
443
|
+
</tr>
|
|
444
|
+
</tbody>
|
|
445
|
+
</table>
|
|
446
|
+
<div class="timeline-bar">
|
|
447
|
+
<span class="timeline-label">Days 1→5 total</span>
|
|
448
|
+
<div class="timeline-track"><div class="timeline-fill"></div></div>
|
|
449
|
+
<span class="timeline-days">5 days · ↓ from 21.5 avg</span>
|
|
450
|
+
</div>
|
|
451
|
+
</div>
|
|
452
|
+
|
|
453
|
+
<div class="source-ref">
|
|
454
|
+
Source: <a href="#">FRAIM · interview-coordination · fraim/ai-employee/jobs/interview-coordination.md</a>
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
</div>
|
|
458
|
+
|
|
459
|
+
</div>
|
|
460
|
+
|
|
461
|
+
<footer class="portfolio-footer">
|
|
462
|
+
<div class="footer-sub">
|
|
463
|
+
Part of the <a href="/">FRAIM</a> · 18 AI employees available ·
|
|
464
|
+
<a href="/">View all employees</a> ·
|
|
465
|
+
<a href="/">FRAIM</a>
|
|
466
|
+
</div>
|
|
467
|
+
</footer>
|
|
468
|
+
|
|
469
|
+
<script>
|
|
470
|
+
function toggleTheme() {
|
|
471
|
+
const html = document.documentElement;
|
|
472
|
+
const isDark = html.getAttribute('data-theme') === 'dark';
|
|
473
|
+
html.setAttribute('data-theme', isDark ? 'light' : 'dark');
|
|
474
|
+
document.querySelector('.theme-btn').textContent = isDark ? '☾' : '☀';
|
|
475
|
+
}
|
|
476
|
+
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
|
477
|
+
document.documentElement.setAttribute('data-theme', 'dark');
|
|
478
|
+
document.querySelector('.theme-btn').textContent = '☀';
|
|
479
|
+
}
|
|
480
|
+
function toggleCard(num) {
|
|
481
|
+
const card = document.getElementById('card' + num);
|
|
482
|
+
const isOpen = card.classList.contains('open');
|
|
483
|
+
document.querySelectorAll('.card').forEach(c => c.classList.remove('open'));
|
|
484
|
+
if (!isOpen) { card.classList.add('open'); card.scrollIntoView({ behavior: 'smooth', block: 'nearest' }); }
|
|
485
|
+
}
|
|
486
|
+
</script>
|
|
487
|
+
|
|
488
|
+
</body>
|
|
489
|
+
</html>
|