terminalhire 0.2.4 → 0.3.0
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/bin/jpi-bounties.js +2031 -0
- package/dist/bin/jpi-dispatch.js +1174 -473
- package/dist/bin/jpi-jobs.js +705 -276
- package/dist/bin/jpi-learn.js +442 -249
- package/dist/bin/jpi-login.js +700 -282
- package/dist/bin/jpi-profile.js +381 -213
- package/dist/bin/jpi-refresh.js +757 -311
- package/dist/bin/jpi-save.js +381 -213
- package/dist/bin/jpi-sync.js +502 -230
- package/dist/src/github-auth.js +3 -3
- package/dist/src/profile.js +313 -207
- package/dist/src/signal.js +364 -237
- package/package.json +3 -3
package/dist/bin/jpi-save.js
CHANGED
|
@@ -16,221 +16,347 @@ var init_types = __esm({
|
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
18
|
|
|
19
|
-
// ../../packages/core/src/
|
|
19
|
+
// ../../packages/core/src/vocab/graph.data.ts
|
|
20
|
+
var VOCAB_NODES;
|
|
21
|
+
var init_graph_data = __esm({
|
|
22
|
+
"../../packages/core/src/vocab/graph.data.ts"() {
|
|
23
|
+
"use strict";
|
|
24
|
+
VOCAB_NODES = [
|
|
25
|
+
// ── Languages ─────────────────────────────────────────────────────────────
|
|
26
|
+
{ id: "javascript", synonyms: ["js"], related: [{ to: "typescript", w: 0.6 }] },
|
|
27
|
+
{ id: "typescript", parents: ["javascript"], synonyms: ["ts"] },
|
|
28
|
+
{ id: "python", synonyms: ["py"] },
|
|
29
|
+
{ id: "go", synonyms: ["golang"] },
|
|
30
|
+
{ id: "rust" },
|
|
31
|
+
{ id: "java", related: [{ to: "kotlin", w: 0.45 }, { to: "scala", w: 0.4 }] },
|
|
32
|
+
{ id: "ruby" },
|
|
33
|
+
{ id: "elixir" },
|
|
34
|
+
{ id: "scala", related: [{ to: "java", w: 0.4 }] },
|
|
35
|
+
{ id: "kotlin", related: [{ to: "java", w: 0.45 }] },
|
|
36
|
+
{ id: "swift" },
|
|
37
|
+
{ id: "cpp", synonyms: ["c++"] },
|
|
38
|
+
{ id: "csharp", synonyms: ["c#"] },
|
|
39
|
+
{ id: "php" },
|
|
40
|
+
{ id: "haskell" },
|
|
41
|
+
{ id: "clojure" },
|
|
42
|
+
{ id: "r" },
|
|
43
|
+
{ id: "dart" },
|
|
44
|
+
// ── Frontend ──────────────────────────────────────────────────────────────
|
|
45
|
+
{
|
|
46
|
+
id: "react",
|
|
47
|
+
parents: ["javascript"],
|
|
48
|
+
synonyms: ["reactjs"],
|
|
49
|
+
related: [{ to: "nextjs", w: 0.55 }, { to: "vue", w: 0.4 }, { to: "svelte", w: 0.4 }, { to: "solidjs", w: 0.5 }, { to: "angular", w: 0.35 }]
|
|
50
|
+
},
|
|
51
|
+
{ id: "nextjs", parents: ["react"], synonyms: ["next", "next.js"], related: [{ to: "remix", w: 0.5 }] },
|
|
52
|
+
{ id: "vue", parents: ["javascript"], synonyms: ["vue.js"], related: [{ to: "nuxt", w: 0.6 }] },
|
|
53
|
+
{ id: "nuxt", parents: ["vue"], synonyms: ["nuxt.js"] },
|
|
54
|
+
{ id: "svelte", parents: ["javascript"], related: [{ to: "sveltekit", w: 0.65 }] },
|
|
55
|
+
{ id: "sveltekit", parents: ["svelte"] },
|
|
56
|
+
{ id: "angular", parents: ["typescript"], synonyms: ["angular.js", "angularjs"] },
|
|
57
|
+
{ id: "solidjs", parents: ["javascript"] },
|
|
58
|
+
{ id: "remix", parents: ["react"], synonyms: ["remix.run"] },
|
|
59
|
+
{ id: "astro", parents: ["javascript"], related: [{ to: "nextjs", w: 0.4 }] },
|
|
60
|
+
{ id: "qwik", parents: ["javascript"] },
|
|
61
|
+
{ id: "tailwind", parents: ["css"], synonyms: ["tailwindcss", "tw"] },
|
|
62
|
+
{ id: "css" },
|
|
63
|
+
{ id: "html" },
|
|
64
|
+
{ id: "redux", parents: ["react"] },
|
|
65
|
+
{ id: "vite", parents: ["frontend"] },
|
|
66
|
+
{ id: "webpack", parents: ["frontend"] },
|
|
67
|
+
{ id: "storybook", parents: ["frontend"] },
|
|
68
|
+
// ── Backend frameworks / runtimes ───────────────────────────────────────────
|
|
69
|
+
{
|
|
70
|
+
id: "nodejs",
|
|
71
|
+
parents: ["javascript"],
|
|
72
|
+
synonyms: ["node", "node.js"],
|
|
73
|
+
related: [{ to: "express", w: 0.5 }, { to: "fastify", w: 0.45 }, { to: "nestjs", w: 0.45 }]
|
|
74
|
+
},
|
|
75
|
+
{ id: "express", parents: ["nodejs"], synonyms: ["express.js", "expressjs"], related: [{ to: "fastify", w: 0.5 }] },
|
|
76
|
+
{ id: "fastify", parents: ["nodejs"] },
|
|
77
|
+
{ id: "nestjs", parents: ["nodejs"], synonyms: ["nest", "nest.js"] },
|
|
78
|
+
{ id: "hono", parents: ["nodejs"] },
|
|
79
|
+
{ id: "deno", parents: ["javascript"], related: [{ to: "nodejs", w: 0.5 }, { to: "bun", w: 0.5 }] },
|
|
80
|
+
{ id: "bun", parents: ["javascript"], related: [{ to: "nodejs", w: 0.5 }] },
|
|
81
|
+
{ id: "django", parents: ["python"], related: [{ to: "flask", w: 0.5 }, { to: "fastapi", w: 0.45 }] },
|
|
82
|
+
{ id: "fastapi", parents: ["python"], related: [{ to: "flask", w: 0.55 }, { to: "django", w: 0.45 }] },
|
|
83
|
+
{ id: "flask", parents: ["python"] },
|
|
84
|
+
{ id: "rails", parents: ["ruby"], synonyms: ["ruby-on-rails", "ror"] },
|
|
85
|
+
{ id: "spring", parents: ["java"], synonyms: ["spring-boot", "springboot"] },
|
|
86
|
+
{ id: "actix", parents: ["rust"] },
|
|
87
|
+
{ id: "gin", parents: ["go"] },
|
|
88
|
+
{ id: "phoenix", parents: ["elixir"] },
|
|
89
|
+
{ id: "laravel", parents: ["php"] },
|
|
90
|
+
{ id: "dotnet", parents: ["csharp"], synonyms: [".net", "asp.net", "dotnet-core"] },
|
|
91
|
+
// ── Infrastructure & DevOps ─────────────────────────────────────────────────
|
|
92
|
+
{ id: "kubernetes", synonyms: ["k8s", "kube"], related: [{ to: "docker", w: 0.5 }, { to: "helm", w: 0.55 }, { to: "terraform", w: 0.4 }, { to: "argocd", w: 0.45 }] },
|
|
93
|
+
{ id: "docker", parents: ["devops"], related: [{ to: "kubernetes", w: 0.5 }] },
|
|
94
|
+
{ id: "terraform", synonyms: ["tf"], related: [{ to: "pulumi", w: 0.55 }, { to: "ansible", w: 0.4 }, { to: "aws", w: 0.4 }] },
|
|
95
|
+
{ id: "pulumi", related: [{ to: "terraform", w: 0.55 }] },
|
|
96
|
+
{ id: "ansible" },
|
|
97
|
+
{ id: "aws", synonyms: ["amazon-web-services"], related: [{ to: "gcp", w: 0.4 }, { to: "azure", w: 0.4 }] },
|
|
98
|
+
{ id: "gcp", synonyms: ["google-cloud", "google-cloud-platform"], related: [{ to: "aws", w: 0.4 }, { to: "azure", w: 0.4 }] },
|
|
99
|
+
{ id: "azure", synonyms: ["microsoft-azure"], related: [{ to: "aws", w: 0.4 }] },
|
|
100
|
+
{ id: "ci-cd", synonyms: ["cicd", "jenkins", "circleci", "circle-ci", "travis"], related: [{ to: "github-actions", w: 0.6 }, { to: "gitlab-ci", w: 0.6 }] },
|
|
101
|
+
{ id: "github-actions", parents: ["ci-cd"], synonyms: ["github-action"] },
|
|
102
|
+
{ id: "gitlab-ci", parents: ["ci-cd"], synonyms: ["gitlab"] },
|
|
103
|
+
{ id: "linux" },
|
|
104
|
+
{ id: "nginx" },
|
|
105
|
+
{ id: "prometheus", parents: ["observability"], related: [{ to: "grafana", w: 0.6 }] },
|
|
106
|
+
{ id: "grafana", parents: ["observability"] },
|
|
107
|
+
{ id: "datadog", parents: ["observability"] },
|
|
108
|
+
{ id: "opentelemetry", parents: ["observability"], synonyms: ["otel"] },
|
|
109
|
+
{ id: "vercel", related: [{ to: "netlify", w: 0.5 }, { to: "nextjs", w: 0.4 }] },
|
|
110
|
+
{ id: "netlify" },
|
|
111
|
+
{ id: "fly", synonyms: ["fly.io"], related: [{ to: "railway", w: 0.5 }, { to: "render", w: 0.5 }] },
|
|
112
|
+
{ id: "railway", related: [{ to: "render", w: 0.5 }] },
|
|
113
|
+
{ id: "render" },
|
|
114
|
+
{ id: "cloudflare", synonyms: ["cloudflare-workers"] },
|
|
115
|
+
{ id: "helm", parents: ["kubernetes"] },
|
|
116
|
+
{ id: "argocd", parents: ["kubernetes"] },
|
|
117
|
+
{ id: "serverless", parents: ["devops"] },
|
|
118
|
+
// ── Databases & storage ─────────────────────────────────────────────────────
|
|
119
|
+
{ id: "postgresql", synonyms: ["postgres", "pg"], related: [{ to: "mysql", w: 0.45 }, { to: "sqlite", w: 0.4 }] },
|
|
120
|
+
{ id: "mysql", related: [{ to: "postgresql", w: 0.45 }] },
|
|
121
|
+
{ id: "sqlite" },
|
|
122
|
+
{ id: "mongodb", synonyms: ["mongo"] },
|
|
123
|
+
{ id: "redis", related: [{ to: "caching", w: 0.5 }] },
|
|
124
|
+
{ id: "elasticsearch", synonyms: ["elastic"], related: [{ to: "search", w: 0.55 }] },
|
|
125
|
+
{ id: "kafka", synonyms: ["apache-kafka"], related: [{ to: "rabbitmq", w: 0.5 }, { to: "message-queue", w: 0.55 }] },
|
|
126
|
+
{ id: "rabbitmq", related: [{ to: "message-queue", w: 0.55 }] },
|
|
127
|
+
{ id: "cassandra" },
|
|
128
|
+
{ id: "dynamodb", parents: ["aws"] },
|
|
129
|
+
{ id: "snowflake", parents: ["data-engineering"], related: [{ to: "clickhouse", w: 0.4 }] },
|
|
130
|
+
{ id: "clickhouse", parents: ["data-engineering"], related: [{ to: "duckdb", w: 0.35 }] },
|
|
131
|
+
{ id: "duckdb", parents: ["data-engineering"] },
|
|
132
|
+
{ id: "supabase", related: [{ to: "postgresql", w: 0.5 }, { to: "neon", w: 0.4 }] },
|
|
133
|
+
{ id: "planetscale", related: [{ to: "mysql", w: 0.5 }] },
|
|
134
|
+
{ id: "neon", related: [{ to: "postgresql", w: 0.5 }] },
|
|
135
|
+
{ id: "turso", related: [{ to: "sqlite", w: 0.5 }] },
|
|
136
|
+
{ id: "cockroachdb", related: [{ to: "postgresql", w: 0.45 }] },
|
|
137
|
+
{ id: "prisma", parents: ["backend"], synonyms: ["@prisma/client"], related: [{ to: "drizzle", w: 0.5 }, { to: "typeorm", w: 0.45 }, { to: "sequelize", w: 0.4 }] },
|
|
138
|
+
{ id: "drizzle", synonyms: ["drizzle-orm"], related: [{ to: "prisma", w: 0.5 }] },
|
|
139
|
+
{ id: "sequelize", related: [{ to: "typeorm", w: 0.4 }] },
|
|
140
|
+
{ id: "typeorm", related: [{ to: "prisma", w: 0.45 }] },
|
|
141
|
+
{ id: "sqlalchemy", parents: ["python"] },
|
|
142
|
+
// ── Data engineering & ML ───────────────────────────────────────────────────
|
|
143
|
+
{ id: "data-engineering", synonyms: ["data-eng"], related: [{ to: "spark", w: 0.5 }, { to: "airflow", w: 0.5 }, { to: "dbt", w: 0.45 }] },
|
|
144
|
+
{ id: "spark", parents: ["data-engineering"], synonyms: ["apache-spark"] },
|
|
145
|
+
{ id: "airflow", parents: ["data-engineering"], synonyms: ["apache-airflow"] },
|
|
146
|
+
{ id: "dbt", parents: ["data-engineering"] },
|
|
147
|
+
{ id: "ml", synonyms: ["machine-learning"], related: [{ to: "pytorch", w: 0.5 }, { to: "tensorflow", w: 0.5 }, { to: "scikit-learn", w: 0.5 }] },
|
|
148
|
+
{ id: "llm", parents: ["ml"], synonyms: ["llms", "genai", "generative-ai"], related: [{ to: "langchain", w: 0.5 }, { to: "rag", w: 0.55 }, { to: "openai", w: 0.45 }, { to: "anthropic", w: 0.45 }] },
|
|
149
|
+
{ id: "pytorch", parents: ["ml"], synonyms: ["torch"], related: [{ to: "tensorflow", w: 0.5 }] },
|
|
150
|
+
{ id: "tensorflow", parents: ["ml"], synonyms: ["keras", "tf-keras"] },
|
|
151
|
+
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }] },
|
|
152
|
+
{ id: "numpy", parents: ["python"] },
|
|
153
|
+
{ id: "scikit-learn", parents: ["ml"], synonyms: ["sklearn"] },
|
|
154
|
+
{ id: "jupyter", parents: ["python"] },
|
|
155
|
+
{ id: "langchain", parents: ["llm"], synonyms: ["llamaindex"] },
|
|
156
|
+
{ id: "huggingface", parents: ["ml"], synonyms: ["hugging-face"] },
|
|
157
|
+
{ id: "openai", parents: ["llm"] },
|
|
158
|
+
{ id: "anthropic", parents: ["llm"], synonyms: ["claude"] },
|
|
159
|
+
{ id: "rag", parents: ["llm"], synonyms: ["retrieval-augmented-generation"] },
|
|
160
|
+
{ id: "mlops", parents: ["ml"], related: [{ to: "devops", w: 0.4 }] },
|
|
161
|
+
// ── Mobile ──────────────────────────────────────────────────────────────────
|
|
162
|
+
{ id: "mobile", related: [{ to: "ios", w: 0.5 }, { to: "android", w: 0.5 }] },
|
|
163
|
+
{ id: "ios", parents: ["mobile", "swift"], related: [{ to: "android", w: 0.4 }] },
|
|
164
|
+
{ id: "android", parents: ["mobile"], related: [{ to: "kotlin", w: 0.4 }] },
|
|
165
|
+
{ id: "swiftui", parents: ["ios", "swift"] },
|
|
166
|
+
{ id: "react-native", parents: ["mobile", "react"], synonyms: ["reactnative"], related: [{ to: "flutter", w: 0.4 }, { to: "expo", w: 0.6 }] },
|
|
167
|
+
{ id: "flutter", parents: ["mobile", "dart"] },
|
|
168
|
+
{ id: "expo", parents: ["react-native"] },
|
|
169
|
+
{ id: "kotlin-multiplatform", parents: ["mobile", "kotlin"], synonyms: ["kmp"] },
|
|
170
|
+
// ── Domains / capabilities ──────────────────────────────────────────────────
|
|
171
|
+
{ id: "frontend", related: [{ to: "react", w: 0.4 }, { to: "css", w: 0.3 }] },
|
|
172
|
+
{ id: "backend", related: [{ to: "api-design", w: 0.4 }, { to: "microservices", w: 0.4 }] },
|
|
173
|
+
{ id: "devops", related: [{ to: "kubernetes", w: 0.4 }, { to: "ci-cd", w: 0.4 }, { to: "docker", w: 0.4 }] },
|
|
174
|
+
{ id: "authentication", synonyms: ["auth", "jwt", "saml", "passport", "auth0", "clerk", "nextauth"], related: [{ to: "oauth", w: 0.6 }, { to: "security", w: 0.5 }] },
|
|
175
|
+
{ id: "oauth", parents: ["authentication"], synonyms: ["oauth2", "oidc"], related: [{ to: "security", w: 0.4 }] },
|
|
176
|
+
{ id: "security", related: [{ to: "authentication", w: 0.5 }] },
|
|
177
|
+
{ id: "payments", synonyms: ["stripe", "braintree", "paddle", "lemonsqueezy", "@stripe/stripe-js"], related: [{ to: "billing", w: 0.6 }] },
|
|
178
|
+
{ id: "billing", synonyms: ["recurly", "chargebee"] },
|
|
179
|
+
{ id: "api-design", synonyms: ["rest", "restful", "rest-api"], related: [{ to: "graphql", w: 0.4 }, { to: "grpc", w: 0.4 }, { to: "backend", w: 0.4 }] },
|
|
180
|
+
{ id: "graphql", synonyms: ["gql"], related: [{ to: "trpc", w: 0.4 }] },
|
|
181
|
+
{ id: "trpc", related: [{ to: "graphql", w: 0.4 }] },
|
|
182
|
+
{ id: "grpc", synonyms: ["grpc-web"], related: [{ to: "microservices", w: 0.3 }] },
|
|
183
|
+
{ id: "microservices" },
|
|
184
|
+
{ id: "websockets", synonyms: ["ws", "socket.io"], related: [{ to: "realtime", w: 0.6 }] },
|
|
185
|
+
{ id: "realtime", synonyms: ["real-time"] },
|
|
186
|
+
{ id: "message-queue", synonyms: ["mq"] },
|
|
187
|
+
{ id: "caching", synonyms: ["cache"] },
|
|
188
|
+
{ id: "search", synonyms: ["full-text-search"] },
|
|
189
|
+
{ id: "observability", synonyms: ["o11y"], related: [{ to: "monitoring", w: 0.6 }] },
|
|
190
|
+
{ id: "monitoring", related: [{ to: "prometheus", w: 0.4 }] },
|
|
191
|
+
{ id: "testing", related: [{ to: "unit-testing", w: 0.5 }, { to: "e2e-testing", w: 0.5 }] },
|
|
192
|
+
{ id: "unit-testing", parents: ["testing"] },
|
|
193
|
+
{ id: "e2e-testing", parents: ["testing"], synonyms: ["e2e", "end-to-end-testing"] },
|
|
194
|
+
{ id: "jest", parents: ["testing"], related: [{ to: "vitest", w: 0.6 }, { to: "mocha", w: 0.5 }] },
|
|
195
|
+
{ id: "vitest", parents: ["testing"], related: [{ to: "jest", w: 0.6 }] },
|
|
196
|
+
{ id: "playwright", parents: ["e2e-testing"], related: [{ to: "cypress", w: 0.6 }] },
|
|
197
|
+
{ id: "cypress", parents: ["e2e-testing"] },
|
|
198
|
+
{ id: "mocha", parents: ["testing"] },
|
|
199
|
+
{ id: "pytest", parents: ["testing", "python"] },
|
|
200
|
+
{ id: "accessibility", synonyms: ["a11y"] },
|
|
201
|
+
{ id: "seo" },
|
|
202
|
+
{ id: "performance", synonyms: ["perf", "web-performance"] }
|
|
203
|
+
];
|
|
204
|
+
}
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
// ../../packages/core/src/vocab/closure.ts
|
|
208
|
+
function round3(n) {
|
|
209
|
+
return Math.round(n * 1e3) / 1e3;
|
|
210
|
+
}
|
|
211
|
+
function validateGraph(nodes) {
|
|
212
|
+
const ids = /* @__PURE__ */ new Set();
|
|
213
|
+
for (const n of nodes) {
|
|
214
|
+
if (ids.has(n.id)) throw new Error(`vocab: duplicate id "${n.id}"`);
|
|
215
|
+
ids.add(n.id);
|
|
216
|
+
}
|
|
217
|
+
const seenAlias = /* @__PURE__ */ new Map();
|
|
218
|
+
for (const n of nodes) {
|
|
219
|
+
for (const p of n.parents ?? []) {
|
|
220
|
+
if (p === n.id) throw new Error(`vocab: "${n.id}" lists itself as a parent`);
|
|
221
|
+
if (!ids.has(p)) throw new Error(`vocab: "${n.id}" parent "${p}" is not a defined id`);
|
|
222
|
+
}
|
|
223
|
+
for (const e of n.related ?? []) {
|
|
224
|
+
if (e.to === n.id) throw new Error(`vocab: "${n.id}" relates to itself`);
|
|
225
|
+
if (!ids.has(e.to)) throw new Error(`vocab: "${n.id}" related "${e.to}" is not a defined id`);
|
|
226
|
+
if (!(e.w > 0 && e.w <= 1)) throw new Error(`vocab: "${n.id}"\u2192"${e.to}" weight ${e.w} out of (0,1]`);
|
|
227
|
+
}
|
|
228
|
+
for (const s of n.synonyms ?? []) {
|
|
229
|
+
const alias = s.toLowerCase();
|
|
230
|
+
if (ids.has(alias)) throw new Error(`vocab: synonym "${alias}" collides with a canonical id`);
|
|
231
|
+
const prev = seenAlias.get(alias);
|
|
232
|
+
if (prev && prev !== n.id) throw new Error(`vocab: synonym "${alias}" maps to both "${prev}" and "${n.id}"`);
|
|
233
|
+
seenAlias.set(alias, n.id);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const visiting = /* @__PURE__ */ new Set();
|
|
237
|
+
const done = /* @__PURE__ */ new Set();
|
|
238
|
+
const parentMap = new Map(nodes.map((n) => [n.id, n.parents ?? []]));
|
|
239
|
+
const walk = (id, path) => {
|
|
240
|
+
if (done.has(id)) return;
|
|
241
|
+
if (visiting.has(id)) throw new Error(`vocab: parent cycle ${[...path, id].join(" \u2192 ")}`);
|
|
242
|
+
visiting.add(id);
|
|
243
|
+
for (const p of parentMap.get(id) ?? []) walk(p, [...path, id]);
|
|
244
|
+
visiting.delete(id);
|
|
245
|
+
done.add(id);
|
|
246
|
+
};
|
|
247
|
+
for (const n of nodes) walk(n.id, []);
|
|
248
|
+
}
|
|
249
|
+
function buildAdjacency(nodes) {
|
|
250
|
+
const adj = /* @__PURE__ */ new Map();
|
|
251
|
+
const add = (from, to, w) => {
|
|
252
|
+
let m = adj.get(from);
|
|
253
|
+
if (!m) adj.set(from, m = /* @__PURE__ */ new Map());
|
|
254
|
+
if (w > (m.get(to) ?? 0)) m.set(to, w);
|
|
255
|
+
};
|
|
256
|
+
for (const n of nodes) {
|
|
257
|
+
for (const p of n.parents ?? []) {
|
|
258
|
+
add(n.id, p, PARENT_UP);
|
|
259
|
+
add(p, n.id, PARENT_DOWN);
|
|
260
|
+
}
|
|
261
|
+
for (const e of n.related ?? []) {
|
|
262
|
+
add(n.id, e.to, e.w);
|
|
263
|
+
add(e.to, n.id, e.w);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return adj;
|
|
267
|
+
}
|
|
268
|
+
function closureFrom(source, adj) {
|
|
269
|
+
const best = /* @__PURE__ */ new Map();
|
|
270
|
+
for (const [t, w] of adj.get(source) ?? []) {
|
|
271
|
+
if (w >= DECAY_FLOOR) best.set(t, { w: round3(w), via: t });
|
|
272
|
+
}
|
|
273
|
+
const settled = /* @__PURE__ */ new Set([source]);
|
|
274
|
+
while (true) {
|
|
275
|
+
let u;
|
|
276
|
+
let uw = 0;
|
|
277
|
+
for (const [t, e] of best) {
|
|
278
|
+
if (!settled.has(t) && e.w > uw) {
|
|
279
|
+
u = t;
|
|
280
|
+
uw = e.w;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (!u) break;
|
|
284
|
+
settled.add(u);
|
|
285
|
+
const via = best.get(u).via;
|
|
286
|
+
for (const [t, we] of adj.get(u) ?? []) {
|
|
287
|
+
if (settled.has(t)) continue;
|
|
288
|
+
const cand = round3(uw * we);
|
|
289
|
+
if (cand >= DECAY_FLOOR && cand > (best.get(t)?.w ?? 0)) {
|
|
290
|
+
best.set(t, { w: cand, via });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
best.delete(source);
|
|
295
|
+
return best;
|
|
296
|
+
}
|
|
297
|
+
function buildGraph(nodes) {
|
|
298
|
+
validateGraph(nodes);
|
|
299
|
+
const ids = new Set(nodes.map((n) => n.id));
|
|
300
|
+
const synonyms = /* @__PURE__ */ new Map();
|
|
301
|
+
for (const n of nodes) {
|
|
302
|
+
for (const s of n.synonyms ?? []) synonyms.set(s.toLowerCase(), n.id);
|
|
303
|
+
}
|
|
304
|
+
const adj = buildAdjacency(nodes);
|
|
305
|
+
const closure = /* @__PURE__ */ new Map();
|
|
306
|
+
for (const n of nodes) closure.set(n.id, closureFrom(n.id, adj));
|
|
307
|
+
return { ids, synonyms, closure };
|
|
308
|
+
}
|
|
309
|
+
var PARENT_UP, PARENT_DOWN, DECAY_FLOOR;
|
|
310
|
+
var init_closure = __esm({
|
|
311
|
+
"../../packages/core/src/vocab/closure.ts"() {
|
|
312
|
+
"use strict";
|
|
313
|
+
PARENT_UP = 0.6;
|
|
314
|
+
PARENT_DOWN = 0.35;
|
|
315
|
+
DECAY_FLOOR = 0.25;
|
|
316
|
+
}
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
// ../../packages/core/src/vocab/types.ts
|
|
320
|
+
var init_types2 = __esm({
|
|
321
|
+
"../../packages/core/src/vocab/types.ts"() {
|
|
322
|
+
"use strict";
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
// ../../packages/core/src/vocab/index.ts
|
|
20
327
|
function normalize(tokens) {
|
|
21
328
|
const result = /* @__PURE__ */ new Set();
|
|
22
329
|
for (const raw of tokens) {
|
|
23
330
|
const lower = raw.toLowerCase().trim();
|
|
24
|
-
if (
|
|
331
|
+
if (GRAPH.ids.has(lower)) {
|
|
25
332
|
result.add(lower);
|
|
26
333
|
continue;
|
|
27
334
|
}
|
|
28
|
-
const mapped =
|
|
29
|
-
if (mapped
|
|
30
|
-
result.add(mapped);
|
|
31
|
-
}
|
|
335
|
+
const mapped = GRAPH.synonyms.get(lower);
|
|
336
|
+
if (mapped) result.add(mapped);
|
|
32
337
|
}
|
|
33
338
|
return Array.from(result);
|
|
34
339
|
}
|
|
35
|
-
var VOCABULARY, SYNONYMS
|
|
340
|
+
var GRAPH, VOCABULARY, SYNONYMS;
|
|
341
|
+
var init_vocab = __esm({
|
|
342
|
+
"../../packages/core/src/vocab/index.ts"() {
|
|
343
|
+
"use strict";
|
|
344
|
+
init_graph_data();
|
|
345
|
+
init_closure();
|
|
346
|
+
init_types2();
|
|
347
|
+
init_closure();
|
|
348
|
+
init_graph_data();
|
|
349
|
+
GRAPH = buildGraph(VOCAB_NODES);
|
|
350
|
+
VOCABULARY = [...GRAPH.ids];
|
|
351
|
+
SYNONYMS = Object.fromEntries(GRAPH.synonyms);
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
|
|
355
|
+
// ../../packages/core/src/vocabulary.ts
|
|
36
356
|
var init_vocabulary = __esm({
|
|
37
357
|
"../../packages/core/src/vocabulary.ts"() {
|
|
38
358
|
"use strict";
|
|
39
|
-
|
|
40
|
-
// Languages
|
|
41
|
-
"typescript",
|
|
42
|
-
"javascript",
|
|
43
|
-
"python",
|
|
44
|
-
"go",
|
|
45
|
-
"rust",
|
|
46
|
-
"java",
|
|
47
|
-
"ruby",
|
|
48
|
-
"elixir",
|
|
49
|
-
"scala",
|
|
50
|
-
"kotlin",
|
|
51
|
-
"swift",
|
|
52
|
-
"cpp",
|
|
53
|
-
"csharp",
|
|
54
|
-
"php",
|
|
55
|
-
"haskell",
|
|
56
|
-
"clojure",
|
|
57
|
-
"r",
|
|
58
|
-
// Frontend frameworks / libs
|
|
59
|
-
"react",
|
|
60
|
-
"nextjs",
|
|
61
|
-
"vue",
|
|
62
|
-
"nuxt",
|
|
63
|
-
"svelte",
|
|
64
|
-
"angular",
|
|
65
|
-
"solidjs",
|
|
66
|
-
"tailwind",
|
|
67
|
-
"css",
|
|
68
|
-
"html",
|
|
69
|
-
"graphql",
|
|
70
|
-
"trpc",
|
|
71
|
-
// Backend frameworks
|
|
72
|
-
"nodejs",
|
|
73
|
-
"express",
|
|
74
|
-
"fastify",
|
|
75
|
-
"nestjs",
|
|
76
|
-
"django",
|
|
77
|
-
"fastapi",
|
|
78
|
-
"flask",
|
|
79
|
-
"rails",
|
|
80
|
-
"spring",
|
|
81
|
-
"actix",
|
|
82
|
-
"gin",
|
|
83
|
-
"phoenix",
|
|
84
|
-
"laravel",
|
|
85
|
-
"dotnet",
|
|
86
|
-
// Infrastructure & DevOps
|
|
87
|
-
"kubernetes",
|
|
88
|
-
"docker",
|
|
89
|
-
"terraform",
|
|
90
|
-
"aws",
|
|
91
|
-
"gcp",
|
|
92
|
-
"azure",
|
|
93
|
-
"ci-cd",
|
|
94
|
-
"github-actions",
|
|
95
|
-
"linux",
|
|
96
|
-
"nginx",
|
|
97
|
-
"pulumi",
|
|
98
|
-
"ansible",
|
|
99
|
-
"prometheus",
|
|
100
|
-
"grafana",
|
|
101
|
-
"datadog",
|
|
102
|
-
"opentelemetry",
|
|
103
|
-
// Data & ML
|
|
104
|
-
"postgresql",
|
|
105
|
-
"mysql",
|
|
106
|
-
"sqlite",
|
|
107
|
-
"mongodb",
|
|
108
|
-
"redis",
|
|
109
|
-
"elasticsearch",
|
|
110
|
-
"kafka",
|
|
111
|
-
"rabbitmq",
|
|
112
|
-
"data-engineering",
|
|
113
|
-
"spark",
|
|
114
|
-
"airflow",
|
|
115
|
-
"dbt",
|
|
116
|
-
"ml",
|
|
117
|
-
"llm",
|
|
118
|
-
"pytorch",
|
|
119
|
-
"tensorflow",
|
|
120
|
-
"pandas",
|
|
121
|
-
"numpy",
|
|
122
|
-
// Domains / capabilities
|
|
123
|
-
"oauth",
|
|
124
|
-
"authentication",
|
|
125
|
-
"security",
|
|
126
|
-
"payments",
|
|
127
|
-
"billing",
|
|
128
|
-
"frontend",
|
|
129
|
-
"backend",
|
|
130
|
-
"devops",
|
|
131
|
-
"mobile",
|
|
132
|
-
"ios",
|
|
133
|
-
"android",
|
|
134
|
-
"api-design",
|
|
135
|
-
"microservices",
|
|
136
|
-
"websockets",
|
|
137
|
-
"testing",
|
|
138
|
-
"accessibility",
|
|
139
|
-
"seo",
|
|
140
|
-
"performance",
|
|
141
|
-
"observability",
|
|
142
|
-
"search",
|
|
143
|
-
"realtime"
|
|
144
|
-
];
|
|
145
|
-
SYNONYMS = {
|
|
146
|
-
// Kubernetes aliases
|
|
147
|
-
"k8s": "kubernetes",
|
|
148
|
-
"kube": "kubernetes",
|
|
149
|
-
// Auth / identity
|
|
150
|
-
"passport": "authentication",
|
|
151
|
-
"oauth2": "oauth",
|
|
152
|
-
"oidc": "oauth",
|
|
153
|
-
"jwt": "authentication",
|
|
154
|
-
"saml": "authentication",
|
|
155
|
-
"auth0": "authentication",
|
|
156
|
-
"clerk": "authentication",
|
|
157
|
-
"nextauth": "authentication",
|
|
158
|
-
// Payments
|
|
159
|
-
"@stripe/stripe-js": "payments",
|
|
160
|
-
"stripe": "payments",
|
|
161
|
-
"braintree": "payments",
|
|
162
|
-
"paddle": "payments",
|
|
163
|
-
"lemonsqueezy": "payments",
|
|
164
|
-
"recurly": "billing",
|
|
165
|
-
"chargebee": "billing",
|
|
166
|
-
// Framework / lib aliases
|
|
167
|
-
"next": "nextjs",
|
|
168
|
-
"next.js": "nextjs",
|
|
169
|
-
"nuxt.js": "nuxt",
|
|
170
|
-
"vue.js": "vue",
|
|
171
|
-
"angular.js": "angular",
|
|
172
|
-
"angularjs": "angular",
|
|
173
|
-
"express.js": "express",
|
|
174
|
-
"expressjs": "express",
|
|
175
|
-
"fastapi": "fastapi",
|
|
176
|
-
"nest": "nestjs",
|
|
177
|
-
"nest.js": "nestjs",
|
|
178
|
-
"sveltekit": "svelte",
|
|
179
|
-
// Language aliases
|
|
180
|
-
"ts": "typescript",
|
|
181
|
-
"js": "javascript",
|
|
182
|
-
"py": "python",
|
|
183
|
-
"golang": "go",
|
|
184
|
-
"c++": "cpp",
|
|
185
|
-
"c#": "csharp",
|
|
186
|
-
".net": "dotnet",
|
|
187
|
-
"asp.net": "dotnet",
|
|
188
|
-
// DB aliases
|
|
189
|
-
"postgres": "postgresql",
|
|
190
|
-
"pg": "postgresql",
|
|
191
|
-
"mongo": "mongodb",
|
|
192
|
-
"elastic": "elasticsearch",
|
|
193
|
-
// Cloud aliases
|
|
194
|
-
"amazon web services": "aws",
|
|
195
|
-
"google cloud": "gcp",
|
|
196
|
-
"google cloud platform": "gcp",
|
|
197
|
-
"microsoft azure": "azure",
|
|
198
|
-
// CI/CD aliases
|
|
199
|
-
"github actions": "github-actions",
|
|
200
|
-
"circle ci": "ci-cd",
|
|
201
|
-
"circleci": "ci-cd",
|
|
202
|
-
"jenkins": "ci-cd",
|
|
203
|
-
"gitlab ci": "ci-cd",
|
|
204
|
-
"travis": "ci-cd",
|
|
205
|
-
// Mobile
|
|
206
|
-
"react native": "mobile",
|
|
207
|
-
"flutter": "mobile",
|
|
208
|
-
"expo": "mobile",
|
|
209
|
-
// AI / ML
|
|
210
|
-
"openai": "llm",
|
|
211
|
-
"anthropic": "llm",
|
|
212
|
-
"langchain": "llm",
|
|
213
|
-
"llamaindex": "llm",
|
|
214
|
-
"hugging face": "ml",
|
|
215
|
-
"huggingface": "ml",
|
|
216
|
-
"scikit-learn": "ml",
|
|
217
|
-
"sklearn": "ml",
|
|
218
|
-
// Data pipeline
|
|
219
|
-
"apache kafka": "kafka",
|
|
220
|
-
"apache spark": "spark",
|
|
221
|
-
"apache airflow": "airflow",
|
|
222
|
-
// Misc
|
|
223
|
-
"tailwindcss": "tailwind",
|
|
224
|
-
"tw": "tailwind",
|
|
225
|
-
"gql": "graphql",
|
|
226
|
-
"ws": "websockets",
|
|
227
|
-
"socket.io": "websockets",
|
|
228
|
-
"jest": "testing",
|
|
229
|
-
"vitest": "testing",
|
|
230
|
-
"playwright": "testing",
|
|
231
|
-
"cypress": "testing"
|
|
232
|
-
};
|
|
233
|
-
VOCAB_SET = new Set(VOCABULARY);
|
|
359
|
+
init_vocab();
|
|
234
360
|
}
|
|
235
361
|
});
|
|
236
362
|
|
|
@@ -238,6 +364,7 @@ var init_vocabulary = __esm({
|
|
|
238
364
|
var init_matcher = __esm({
|
|
239
365
|
"../../packages/core/src/matcher.ts"() {
|
|
240
366
|
"use strict";
|
|
367
|
+
init_vocabulary();
|
|
241
368
|
}
|
|
242
369
|
});
|
|
243
370
|
|
|
@@ -273,11 +400,19 @@ var init_himalayas = __esm({
|
|
|
273
400
|
}
|
|
274
401
|
});
|
|
275
402
|
|
|
403
|
+
// ../../packages/core/src/feeds/entities.ts
|
|
404
|
+
var init_entities = __esm({
|
|
405
|
+
"../../packages/core/src/feeds/entities.ts"() {
|
|
406
|
+
"use strict";
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
276
410
|
// ../../packages/core/src/feeds/wwr.ts
|
|
277
411
|
var init_wwr = __esm({
|
|
278
412
|
"../../packages/core/src/feeds/wwr.ts"() {
|
|
279
413
|
"use strict";
|
|
280
414
|
init_vocabulary();
|
|
415
|
+
init_entities();
|
|
281
416
|
}
|
|
282
417
|
});
|
|
283
418
|
|
|
@@ -286,6 +421,24 @@ var init_hn = __esm({
|
|
|
286
421
|
"../../packages/core/src/feeds/hn.ts"() {
|
|
287
422
|
"use strict";
|
|
288
423
|
init_vocabulary();
|
|
424
|
+
init_entities();
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
// ../../packages/core/src/feeds/bounty-gate.ts
|
|
429
|
+
var init_bounty_gate = __esm({
|
|
430
|
+
"../../packages/core/src/feeds/bounty-gate.ts"() {
|
|
431
|
+
"use strict";
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
// ../../packages/core/src/feeds/github-bounties.ts
|
|
436
|
+
var init_github_bounties = __esm({
|
|
437
|
+
"../../packages/core/src/feeds/github-bounties.ts"() {
|
|
438
|
+
"use strict";
|
|
439
|
+
init_vocabulary();
|
|
440
|
+
init_entities();
|
|
441
|
+
init_bounty_gate();
|
|
289
442
|
}
|
|
290
443
|
});
|
|
291
444
|
|
|
@@ -303,6 +456,8 @@ var init_feeds = __esm({
|
|
|
303
456
|
init_himalayas();
|
|
304
457
|
init_wwr();
|
|
305
458
|
init_hn();
|
|
459
|
+
init_github_bounties();
|
|
460
|
+
init_bounty_gate();
|
|
306
461
|
GREENHOUSE_SLUGS_BY_TIER = {
|
|
307
462
|
bigco: [
|
|
308
463
|
"stripe",
|
|
@@ -411,13 +566,22 @@ var init_feeds = __esm({
|
|
|
411
566
|
}
|
|
412
567
|
});
|
|
413
568
|
|
|
414
|
-
// ../../packages/core/src/
|
|
569
|
+
// ../../packages/core/src/partners.ts
|
|
415
570
|
import { readFileSync } from "fs";
|
|
416
571
|
import { join } from "path";
|
|
417
572
|
import { fileURLToPath } from "url";
|
|
418
|
-
var
|
|
419
|
-
|
|
573
|
+
var EXAMPLE_BUYER, BUYER_REGISTRY;
|
|
574
|
+
var init_partners = __esm({
|
|
575
|
+
"../../packages/core/src/partners.ts"() {
|
|
420
576
|
"use strict";
|
|
577
|
+
EXAMPLE_BUYER = {
|
|
578
|
+
id: "northstar",
|
|
579
|
+
legalName: "Northstar Talent Partners",
|
|
580
|
+
matchCriteria: { roleTypes: ["full_time"] }
|
|
581
|
+
};
|
|
582
|
+
BUYER_REGISTRY = {
|
|
583
|
+
[EXAMPLE_BUYER.id]: EXAMPLE_BUYER
|
|
584
|
+
};
|
|
421
585
|
}
|
|
422
586
|
});
|
|
423
587
|
|
|
@@ -426,7 +590,7 @@ var init_indexer = __esm({
|
|
|
426
590
|
"../../packages/core/src/indexer.ts"() {
|
|
427
591
|
"use strict";
|
|
428
592
|
init_feeds();
|
|
429
|
-
|
|
593
|
+
init_partners();
|
|
430
594
|
}
|
|
431
595
|
});
|
|
432
596
|
|
|
@@ -447,7 +611,7 @@ var init_src = __esm({
|
|
|
447
611
|
init_matcher();
|
|
448
612
|
init_feeds();
|
|
449
613
|
init_indexer();
|
|
450
|
-
|
|
614
|
+
init_partners();
|
|
451
615
|
init_github();
|
|
452
616
|
}
|
|
453
617
|
});
|
|
@@ -546,10 +710,10 @@ function migrateTagWeights(profile) {
|
|
|
546
710
|
if (!profile.tagWeights) {
|
|
547
711
|
profile.tagWeights = {};
|
|
548
712
|
}
|
|
549
|
-
const
|
|
713
|
+
const seed = profile.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
550
714
|
for (const tag of profile.skillTags) {
|
|
551
715
|
if (!profile.tagWeights[tag]) {
|
|
552
|
-
profile.tagWeights[tag] = { count: 1, firstSeen:
|
|
716
|
+
profile.tagWeights[tag] = { count: 1, firstSeen: seed, lastSeen: seed, sessions: 1 };
|
|
553
717
|
}
|
|
554
718
|
}
|
|
555
719
|
}
|
|
@@ -575,7 +739,7 @@ async function writeProfile(profile) {
|
|
|
575
739
|
const blob = encrypt(JSON.stringify(profile), key);
|
|
576
740
|
writeFileSync(PROFILE_FILE, JSON.stringify(blob, null, 2), { encoding: "utf8" });
|
|
577
741
|
}
|
|
578
|
-
function accumulateSession(profile, tags, isEmployerContext, inferredSeniority) {
|
|
742
|
+
function accumulateSession(profile, tags, isEmployerContext, inferredSeniority, seniorityIsAuthoritative = false) {
|
|
579
743
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
580
744
|
let filtered = normalize(tags);
|
|
581
745
|
if (isEmployerContext) {
|
|
@@ -593,7 +757,9 @@ function accumulateSession(profile, tags, isEmployerContext, inferredSeniority)
|
|
|
593
757
|
}
|
|
594
758
|
}
|
|
595
759
|
if (inferredSeniority && !isEmployerContext) {
|
|
596
|
-
profile.
|
|
760
|
+
if (seniorityIsAuthoritative || !profile.github) {
|
|
761
|
+
profile.seniority = inferredSeniority;
|
|
762
|
+
}
|
|
597
763
|
}
|
|
598
764
|
}
|
|
599
765
|
async function accumulateTags(rawTokens, isEmployerContext, inferredSeniority) {
|
|
@@ -601,12 +767,14 @@ async function accumulateTags(rawTokens, isEmployerContext, inferredSeniority) {
|
|
|
601
767
|
accumulateSession(profile, rawTokens, isEmployerContext, inferredSeniority);
|
|
602
768
|
await writeProfile(profile);
|
|
603
769
|
}
|
|
604
|
-
function accumulateGitHubTags(profile, tags) {
|
|
770
|
+
function accumulateGitHubTags(profile, tags, inferredSeniority) {
|
|
605
771
|
accumulateSession(
|
|
606
772
|
profile,
|
|
607
773
|
tags,
|
|
608
774
|
/* isEmployerContext */
|
|
609
|
-
false
|
|
775
|
+
false,
|
|
776
|
+
inferredSeniority,
|
|
777
|
+
true
|
|
610
778
|
);
|
|
611
779
|
}
|
|
612
780
|
async function listSavedJobs() {
|