terminalhire 0.3.3 → 0.4.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 +514 -181
- package/dist/bin/jpi-dispatch.js +561 -197
- package/dist/bin/jpi-jobs.js +521 -183
- package/dist/bin/jpi-learn.js +53 -10
- package/dist/bin/jpi-login.js +537 -184
- package/dist/bin/jpi-profile.js +53 -10
- package/dist/bin/jpi-refresh.js +531 -192
- package/dist/bin/jpi-save.js +53 -10
- package/dist/bin/jpi-spinner.js +5 -8
- package/dist/bin/jpi-sync.js +53 -10
- package/dist/bin/spinner.js +14 -10
- package/dist/src/profile.js +28 -2
- package/dist/src/signal.js +28 -2
- package/package.json +1 -1
package/dist/bin/jpi-save.js
CHANGED
|
@@ -144,11 +144,11 @@ var init_graph_data = __esm({
|
|
|
144
144
|
{ id: "spark", parents: ["data-engineering"], synonyms: ["apache-spark"] },
|
|
145
145
|
{ id: "airflow", parents: ["data-engineering"], synonyms: ["apache-airflow"] },
|
|
146
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 }] },
|
|
147
|
+
{ id: "ml", synonyms: ["machine-learning"], related: [{ to: "pytorch", w: 0.5 }, { to: "tensorflow", w: 0.5 }, { to: "scikit-learn", w: 0.5 }, { to: "data-engineering", w: 0.4 }] },
|
|
148
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
149
|
{ id: "pytorch", parents: ["ml"], synonyms: ["torch"], related: [{ to: "tensorflow", w: 0.5 }] },
|
|
150
150
|
{ id: "tensorflow", parents: ["ml"], synonyms: ["keras", "tf-keras"] },
|
|
151
|
-
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }] },
|
|
151
|
+
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }, { to: "data-engineering", w: 0.45 }, { to: "spark", w: 0.4 }] },
|
|
152
152
|
{ id: "numpy", parents: ["python"] },
|
|
153
153
|
{ id: "scikit-learn", parents: ["ml"], synonyms: ["sklearn"] },
|
|
154
154
|
{ id: "jupyter", parents: ["python"] },
|
|
@@ -323,6 +323,46 @@ var init_types2 = __esm({
|
|
|
323
323
|
}
|
|
324
324
|
});
|
|
325
325
|
|
|
326
|
+
// ../../packages/core/src/vocab/extract.ts
|
|
327
|
+
var SOFT_DOMAIN, SYNONYM_ONLY;
|
|
328
|
+
var init_extract = __esm({
|
|
329
|
+
"../../packages/core/src/vocab/extract.ts"() {
|
|
330
|
+
"use strict";
|
|
331
|
+
init_vocab();
|
|
332
|
+
SOFT_DOMAIN = /* @__PURE__ */ new Set([
|
|
333
|
+
"frontend",
|
|
334
|
+
"backend",
|
|
335
|
+
"devops",
|
|
336
|
+
"security",
|
|
337
|
+
"payments",
|
|
338
|
+
"billing",
|
|
339
|
+
"microservices",
|
|
340
|
+
"caching",
|
|
341
|
+
"search",
|
|
342
|
+
"observability",
|
|
343
|
+
"monitoring",
|
|
344
|
+
"testing",
|
|
345
|
+
"accessibility",
|
|
346
|
+
"seo",
|
|
347
|
+
"performance",
|
|
348
|
+
"realtime",
|
|
349
|
+
"authentication",
|
|
350
|
+
"api-design"
|
|
351
|
+
]);
|
|
352
|
+
SYNONYM_ONLY = /* @__PURE__ */ new Set(["performance", "security", "seo"]);
|
|
353
|
+
for (const id of SYNONYM_ONLY) {
|
|
354
|
+
if (!SOFT_DOMAIN.has(id)) throw new Error(`extract: SYNONYM_ONLY "${id}" not in SOFT_DOMAIN`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// ../../packages/core/src/vocab/idf-background.ts
|
|
360
|
+
var init_idf_background = __esm({
|
|
361
|
+
"../../packages/core/src/vocab/idf-background.ts"() {
|
|
362
|
+
"use strict";
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
326
366
|
// ../../packages/core/src/vocab/index.ts
|
|
327
367
|
function normalize(tokens) {
|
|
328
368
|
const result = /* @__PURE__ */ new Set();
|
|
@@ -346,6 +386,8 @@ var init_vocab = __esm({
|
|
|
346
386
|
init_types2();
|
|
347
387
|
init_closure();
|
|
348
388
|
init_graph_data();
|
|
389
|
+
init_extract();
|
|
390
|
+
init_idf_background();
|
|
349
391
|
GRAPH = buildGraph(VOCAB_NODES);
|
|
350
392
|
VOCABULARY = [...GRAPH.ids];
|
|
351
393
|
SYNONYMS = Object.fromEntries(GRAPH.synonyms);
|
|
@@ -360,11 +402,20 @@ var init_vocabulary = __esm({
|
|
|
360
402
|
}
|
|
361
403
|
});
|
|
362
404
|
|
|
405
|
+
// ../../packages/core/src/github.ts
|
|
406
|
+
var init_github = __esm({
|
|
407
|
+
"../../packages/core/src/github.ts"() {
|
|
408
|
+
"use strict";
|
|
409
|
+
init_vocabulary();
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
363
413
|
// ../../packages/core/src/matcher.ts
|
|
364
414
|
var init_matcher = __esm({
|
|
365
415
|
"../../packages/core/src/matcher.ts"() {
|
|
366
416
|
"use strict";
|
|
367
417
|
init_vocabulary();
|
|
418
|
+
init_github();
|
|
368
419
|
}
|
|
369
420
|
});
|
|
370
421
|
|
|
@@ -594,14 +645,6 @@ var init_indexer = __esm({
|
|
|
594
645
|
}
|
|
595
646
|
});
|
|
596
647
|
|
|
597
|
-
// ../../packages/core/src/github.ts
|
|
598
|
-
var init_github = __esm({
|
|
599
|
-
"../../packages/core/src/github.ts"() {
|
|
600
|
-
"use strict";
|
|
601
|
-
init_vocabulary();
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
|
|
605
648
|
// ../../packages/core/src/index.ts
|
|
606
649
|
var init_src = __esm({
|
|
607
650
|
"../../packages/core/src/index.ts"() {
|
package/dist/bin/jpi-spinner.js
CHANGED
|
@@ -94,19 +94,16 @@ function buildContextVerbs(topMatches, sessionTags) {
|
|
|
94
94
|
if (overlap.length >= 2) {
|
|
95
95
|
const a = titleCase(overlap[0]);
|
|
96
96
|
const b = titleCase(overlap[1]);
|
|
97
|
-
headers = [`\u2726 Fits your ${a} + ${b} work`, `\u2726 A
|
|
97
|
+
headers = [`\u2726 Fits your ${a} + ${b} work`, `\u2726 A match for what you're building \u2014 link below`];
|
|
98
98
|
} else if (overlap.length === 1) {
|
|
99
99
|
const a = titleCase(overlap[0]);
|
|
100
|
-
headers = [`\u2726
|
|
100
|
+
headers = [`\u2726 Work in your ${a} stack \u2014 link below`, `\u2726 Your ${a} work \u2014 link in the tip below`];
|
|
101
101
|
} else {
|
|
102
|
-
headers = [`\u2726
|
|
102
|
+
headers = [`\u2726 Work that fits your stack`, `\u2726 A match for you \u2014 link in the tip below`];
|
|
103
103
|
}
|
|
104
104
|
const list = Array.isArray(topMatches) ? topMatches : [];
|
|
105
|
-
const
|
|
106
|
-
if (
|
|
107
|
-
const money = bounty.amountUSD != null ? `$${bounty.amountUSD.toLocaleString()} ` : "";
|
|
108
|
-
headers.unshift(`\u2726 \u{1F48E} A ${money}bounty in your stack \u2014 link below`);
|
|
109
|
-
}
|
|
105
|
+
const hasBounty = list.some((m) => m && m.source === "bounty");
|
|
106
|
+
if (hasBounty) headers.unshift(`\u2726 Roles + \u{1F48E} paid bounties in your stack \u2014 link below`);
|
|
110
107
|
return headers;
|
|
111
108
|
}
|
|
112
109
|
function buildSpinnerPool(topMatches, max = 6, opts = {}) {
|
package/dist/bin/jpi-sync.js
CHANGED
|
@@ -144,11 +144,11 @@ var init_graph_data = __esm({
|
|
|
144
144
|
{ id: "spark", parents: ["data-engineering"], synonyms: ["apache-spark"] },
|
|
145
145
|
{ id: "airflow", parents: ["data-engineering"], synonyms: ["apache-airflow"] },
|
|
146
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 }] },
|
|
147
|
+
{ id: "ml", synonyms: ["machine-learning"], related: [{ to: "pytorch", w: 0.5 }, { to: "tensorflow", w: 0.5 }, { to: "scikit-learn", w: 0.5 }, { to: "data-engineering", w: 0.4 }] },
|
|
148
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
149
|
{ id: "pytorch", parents: ["ml"], synonyms: ["torch"], related: [{ to: "tensorflow", w: 0.5 }] },
|
|
150
150
|
{ id: "tensorflow", parents: ["ml"], synonyms: ["keras", "tf-keras"] },
|
|
151
|
-
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }] },
|
|
151
|
+
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }, { to: "data-engineering", w: 0.45 }, { to: "spark", w: 0.4 }] },
|
|
152
152
|
{ id: "numpy", parents: ["python"] },
|
|
153
153
|
{ id: "scikit-learn", parents: ["ml"], synonyms: ["sklearn"] },
|
|
154
154
|
{ id: "jupyter", parents: ["python"] },
|
|
@@ -323,6 +323,46 @@ var init_types2 = __esm({
|
|
|
323
323
|
}
|
|
324
324
|
});
|
|
325
325
|
|
|
326
|
+
// ../../packages/core/src/vocab/extract.ts
|
|
327
|
+
var SOFT_DOMAIN, SYNONYM_ONLY;
|
|
328
|
+
var init_extract = __esm({
|
|
329
|
+
"../../packages/core/src/vocab/extract.ts"() {
|
|
330
|
+
"use strict";
|
|
331
|
+
init_vocab();
|
|
332
|
+
SOFT_DOMAIN = /* @__PURE__ */ new Set([
|
|
333
|
+
"frontend",
|
|
334
|
+
"backend",
|
|
335
|
+
"devops",
|
|
336
|
+
"security",
|
|
337
|
+
"payments",
|
|
338
|
+
"billing",
|
|
339
|
+
"microservices",
|
|
340
|
+
"caching",
|
|
341
|
+
"search",
|
|
342
|
+
"observability",
|
|
343
|
+
"monitoring",
|
|
344
|
+
"testing",
|
|
345
|
+
"accessibility",
|
|
346
|
+
"seo",
|
|
347
|
+
"performance",
|
|
348
|
+
"realtime",
|
|
349
|
+
"authentication",
|
|
350
|
+
"api-design"
|
|
351
|
+
]);
|
|
352
|
+
SYNONYM_ONLY = /* @__PURE__ */ new Set(["performance", "security", "seo"]);
|
|
353
|
+
for (const id of SYNONYM_ONLY) {
|
|
354
|
+
if (!SOFT_DOMAIN.has(id)) throw new Error(`extract: SYNONYM_ONLY "${id}" not in SOFT_DOMAIN`);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// ../../packages/core/src/vocab/idf-background.ts
|
|
360
|
+
var init_idf_background = __esm({
|
|
361
|
+
"../../packages/core/src/vocab/idf-background.ts"() {
|
|
362
|
+
"use strict";
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
|
|
326
366
|
// ../../packages/core/src/vocab/index.ts
|
|
327
367
|
function normalize(tokens) {
|
|
328
368
|
const result = /* @__PURE__ */ new Set();
|
|
@@ -346,6 +386,8 @@ var init_vocab = __esm({
|
|
|
346
386
|
init_types2();
|
|
347
387
|
init_closure();
|
|
348
388
|
init_graph_data();
|
|
389
|
+
init_extract();
|
|
390
|
+
init_idf_background();
|
|
349
391
|
GRAPH = buildGraph(VOCAB_NODES);
|
|
350
392
|
VOCABULARY = [...GRAPH.ids];
|
|
351
393
|
SYNONYMS = Object.fromEntries(GRAPH.synonyms);
|
|
@@ -360,11 +402,20 @@ var init_vocabulary = __esm({
|
|
|
360
402
|
}
|
|
361
403
|
});
|
|
362
404
|
|
|
405
|
+
// ../../packages/core/src/github.ts
|
|
406
|
+
var init_github = __esm({
|
|
407
|
+
"../../packages/core/src/github.ts"() {
|
|
408
|
+
"use strict";
|
|
409
|
+
init_vocabulary();
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
363
413
|
// ../../packages/core/src/matcher.ts
|
|
364
414
|
var init_matcher = __esm({
|
|
365
415
|
"../../packages/core/src/matcher.ts"() {
|
|
366
416
|
"use strict";
|
|
367
417
|
init_vocabulary();
|
|
418
|
+
init_github();
|
|
368
419
|
}
|
|
369
420
|
});
|
|
370
421
|
|
|
@@ -594,14 +645,6 @@ var init_indexer = __esm({
|
|
|
594
645
|
}
|
|
595
646
|
});
|
|
596
647
|
|
|
597
|
-
// ../../packages/core/src/github.ts
|
|
598
|
-
var init_github = __esm({
|
|
599
|
-
"../../packages/core/src/github.ts"() {
|
|
600
|
-
"use strict";
|
|
601
|
-
init_vocabulary();
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
|
|
605
648
|
// ../../packages/core/src/index.ts
|
|
606
649
|
var init_src = __esm({
|
|
607
650
|
"../../packages/core/src/index.ts"() {
|
package/dist/bin/spinner.js
CHANGED
|
@@ -101,19 +101,16 @@ function buildContextVerbs(topMatches, sessionTags) {
|
|
|
101
101
|
if (overlap.length >= 2) {
|
|
102
102
|
const a = titleCase(overlap[0]);
|
|
103
103
|
const b = titleCase(overlap[1]);
|
|
104
|
-
headers = [`\u2726 Fits your ${a} + ${b} work`, `\u2726 A
|
|
104
|
+
headers = [`\u2726 Fits your ${a} + ${b} work`, `\u2726 A match for what you're building \u2014 link below`];
|
|
105
105
|
} else if (overlap.length === 1) {
|
|
106
106
|
const a = titleCase(overlap[0]);
|
|
107
|
-
headers = [`\u2726
|
|
107
|
+
headers = [`\u2726 Work in your ${a} stack \u2014 link below`, `\u2726 Your ${a} work \u2014 link in the tip below`];
|
|
108
108
|
} else {
|
|
109
|
-
headers = [`\u2726
|
|
109
|
+
headers = [`\u2726 Work that fits your stack`, `\u2726 A match for you \u2014 link in the tip below`];
|
|
110
110
|
}
|
|
111
111
|
const list = Array.isArray(topMatches) ? topMatches : [];
|
|
112
|
-
const
|
|
113
|
-
if (
|
|
114
|
-
const money = bounty.amountUSD != null ? `$${bounty.amountUSD.toLocaleString()} ` : "";
|
|
115
|
-
headers.unshift(`\u2726 \u{1F48E} A ${money}bounty in your stack \u2014 link below`);
|
|
116
|
-
}
|
|
112
|
+
const hasBounty = list.some((m) => m && m.source === "bounty");
|
|
113
|
+
if (hasBounty) headers.unshift(`\u2726 Roles + \u{1F48E} paid bounties in your stack \u2014 link below`);
|
|
117
114
|
return headers;
|
|
118
115
|
}
|
|
119
116
|
function buildSpinnerPool(topMatches, max = 6, opts = {}) {
|
|
@@ -199,8 +196,15 @@ function buildTips(topMatches, baseUrl, max = 8) {
|
|
|
199
196
|
const perCompany = /* @__PURE__ */ new Map();
|
|
200
197
|
const COMPANY_CAP = 2;
|
|
201
198
|
const all = Array.isArray(topMatches) ? topMatches : [];
|
|
202
|
-
const
|
|
203
|
-
const
|
|
199
|
+
const bountyQ = all.filter((m) => m && m.source === "bounty");
|
|
200
|
+
const roleQ = interleaveBySource(all.filter((m) => m && m.source !== "bounty"));
|
|
201
|
+
const ordered = [];
|
|
202
|
+
let bi = 0;
|
|
203
|
+
let ri = 0;
|
|
204
|
+
while (bi < bountyQ.length || ri < roleQ.length) {
|
|
205
|
+
if (bi < bountyQ.length) ordered.push(bountyQ[bi++]);
|
|
206
|
+
if (ri < roleQ.length) ordered.push(roleQ[ri++]);
|
|
207
|
+
}
|
|
204
208
|
for (const m of ordered) {
|
|
205
209
|
if (!m || !m.title || !m.company || !m.id) continue;
|
|
206
210
|
const idx = String(m.id).indexOf(":");
|
package/dist/src/profile.js
CHANGED
|
@@ -137,11 +137,11 @@ var VOCAB_NODES = [
|
|
|
137
137
|
{ id: "spark", parents: ["data-engineering"], synonyms: ["apache-spark"] },
|
|
138
138
|
{ id: "airflow", parents: ["data-engineering"], synonyms: ["apache-airflow"] },
|
|
139
139
|
{ id: "dbt", parents: ["data-engineering"] },
|
|
140
|
-
{ id: "ml", synonyms: ["machine-learning"], related: [{ to: "pytorch", w: 0.5 }, { to: "tensorflow", w: 0.5 }, { to: "scikit-learn", w: 0.5 }] },
|
|
140
|
+
{ id: "ml", synonyms: ["machine-learning"], related: [{ to: "pytorch", w: 0.5 }, { to: "tensorflow", w: 0.5 }, { to: "scikit-learn", w: 0.5 }, { to: "data-engineering", w: 0.4 }] },
|
|
141
141
|
{ 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 }] },
|
|
142
142
|
{ id: "pytorch", parents: ["ml"], synonyms: ["torch"], related: [{ to: "tensorflow", w: 0.5 }] },
|
|
143
143
|
{ id: "tensorflow", parents: ["ml"], synonyms: ["keras", "tf-keras"] },
|
|
144
|
-
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }] },
|
|
144
|
+
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }, { to: "data-engineering", w: 0.45 }, { to: "spark", w: 0.4 }] },
|
|
145
145
|
{ id: "numpy", parents: ["python"] },
|
|
146
146
|
{ id: "scikit-learn", parents: ["ml"], synonyms: ["sklearn"] },
|
|
147
147
|
{ id: "jupyter", parents: ["python"] },
|
|
@@ -301,6 +301,32 @@ function buildGraph(nodes) {
|
|
|
301
301
|
return { ids, synonyms, closure };
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
// ../../packages/core/src/vocab/extract.ts
|
|
305
|
+
var SOFT_DOMAIN = /* @__PURE__ */ new Set([
|
|
306
|
+
"frontend",
|
|
307
|
+
"backend",
|
|
308
|
+
"devops",
|
|
309
|
+
"security",
|
|
310
|
+
"payments",
|
|
311
|
+
"billing",
|
|
312
|
+
"microservices",
|
|
313
|
+
"caching",
|
|
314
|
+
"search",
|
|
315
|
+
"observability",
|
|
316
|
+
"monitoring",
|
|
317
|
+
"testing",
|
|
318
|
+
"accessibility",
|
|
319
|
+
"seo",
|
|
320
|
+
"performance",
|
|
321
|
+
"realtime",
|
|
322
|
+
"authentication",
|
|
323
|
+
"api-design"
|
|
324
|
+
]);
|
|
325
|
+
var SYNONYM_ONLY = /* @__PURE__ */ new Set(["performance", "security", "seo"]);
|
|
326
|
+
for (const id of SYNONYM_ONLY) {
|
|
327
|
+
if (!SOFT_DOMAIN.has(id)) throw new Error(`extract: SYNONYM_ONLY "${id}" not in SOFT_DOMAIN`);
|
|
328
|
+
}
|
|
329
|
+
|
|
304
330
|
// ../../packages/core/src/vocab/index.ts
|
|
305
331
|
var GRAPH = buildGraph(VOCAB_NODES);
|
|
306
332
|
var VOCABULARY = [...GRAPH.ids];
|
package/dist/src/signal.js
CHANGED
|
@@ -127,11 +127,11 @@ var VOCAB_NODES = [
|
|
|
127
127
|
{ id: "spark", parents: ["data-engineering"], synonyms: ["apache-spark"] },
|
|
128
128
|
{ id: "airflow", parents: ["data-engineering"], synonyms: ["apache-airflow"] },
|
|
129
129
|
{ id: "dbt", parents: ["data-engineering"] },
|
|
130
|
-
{ id: "ml", synonyms: ["machine-learning"], related: [{ to: "pytorch", w: 0.5 }, { to: "tensorflow", w: 0.5 }, { to: "scikit-learn", w: 0.5 }] },
|
|
130
|
+
{ id: "ml", synonyms: ["machine-learning"], related: [{ to: "pytorch", w: 0.5 }, { to: "tensorflow", w: 0.5 }, { to: "scikit-learn", w: 0.5 }, { to: "data-engineering", w: 0.4 }] },
|
|
131
131
|
{ 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 }] },
|
|
132
132
|
{ id: "pytorch", parents: ["ml"], synonyms: ["torch"], related: [{ to: "tensorflow", w: 0.5 }] },
|
|
133
133
|
{ id: "tensorflow", parents: ["ml"], synonyms: ["keras", "tf-keras"] },
|
|
134
|
-
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }] },
|
|
134
|
+
{ id: "pandas", parents: ["python"], related: [{ to: "numpy", w: 0.6 }, { to: "data-engineering", w: 0.45 }, { to: "spark", w: 0.4 }] },
|
|
135
135
|
{ id: "numpy", parents: ["python"] },
|
|
136
136
|
{ id: "scikit-learn", parents: ["ml"], synonyms: ["sklearn"] },
|
|
137
137
|
{ id: "jupyter", parents: ["python"] },
|
|
@@ -291,6 +291,32 @@ function buildGraph(nodes) {
|
|
|
291
291
|
return { ids, synonyms, closure };
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
// ../../packages/core/src/vocab/extract.ts
|
|
295
|
+
var SOFT_DOMAIN = /* @__PURE__ */ new Set([
|
|
296
|
+
"frontend",
|
|
297
|
+
"backend",
|
|
298
|
+
"devops",
|
|
299
|
+
"security",
|
|
300
|
+
"payments",
|
|
301
|
+
"billing",
|
|
302
|
+
"microservices",
|
|
303
|
+
"caching",
|
|
304
|
+
"search",
|
|
305
|
+
"observability",
|
|
306
|
+
"monitoring",
|
|
307
|
+
"testing",
|
|
308
|
+
"accessibility",
|
|
309
|
+
"seo",
|
|
310
|
+
"performance",
|
|
311
|
+
"realtime",
|
|
312
|
+
"authentication",
|
|
313
|
+
"api-design"
|
|
314
|
+
]);
|
|
315
|
+
var SYNONYM_ONLY = /* @__PURE__ */ new Set(["performance", "security", "seo"]);
|
|
316
|
+
for (const id of SYNONYM_ONLY) {
|
|
317
|
+
if (!SOFT_DOMAIN.has(id)) throw new Error(`extract: SYNONYM_ONLY "${id}" not in SOFT_DOMAIN`);
|
|
318
|
+
}
|
|
319
|
+
|
|
294
320
|
// ../../packages/core/src/vocab/index.ts
|
|
295
321
|
var GRAPH = buildGraph(VOCAB_NODES);
|
|
296
322
|
var VOCABULARY = [...GRAPH.ids];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "terminalhire",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Local-first job matching for developers — ambient job matches in the Claude Code spinner. Matching runs on your machine; your profile never leaves it.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|