terminalhire 0.17.0 → 0.17.2
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 +204 -67
- package/dist/bin/jpi-chat-read.js +55 -22
- package/dist/bin/jpi-chat.js +57 -24
- package/dist/bin/jpi-claim.js +734 -39
- package/dist/bin/jpi-contribute.js +60 -21
- package/dist/bin/jpi-devs.js +188 -54
- package/dist/bin/jpi-dispatch.js +461 -121
- package/dist/bin/jpi-inbox.js +57 -24
- package/dist/bin/jpi-intro.js +53 -20
- package/dist/bin/jpi-jobs.js +188 -54
- package/dist/bin/jpi-learn.js +52 -19
- package/dist/bin/jpi-link.js +56 -2
- package/dist/bin/jpi-login.js +190 -56
- package/dist/bin/jpi-profile.js +52 -19
- package/dist/bin/jpi-project.js +186 -52
- package/dist/bin/jpi-refresh.js +195 -57
- package/dist/bin/jpi-save.js +52 -19
- package/dist/bin/jpi-spinner.js +506 -8
- package/dist/bin/jpi-sync.js +53 -20
- package/dist/bin/jpi-trajectory.js +131 -80
- package/dist/bin/peer-connect-prompt.js +1 -1
- package/dist/bin/spinner.js +507 -2
- package/dist/src/chat-client.js +24 -6
- package/dist/src/chat-keystore.js +23 -5
- package/dist/src/claims.js +9 -1
- package/dist/src/github-auth.js +2 -2
- package/dist/src/intro.js +53 -20
- package/dist/src/link.js +11 -1
- package/dist/src/profile.js +23 -5
- package/dist/src/repo-policy.js +77 -0
- package/dist/src/signal.js +21 -3
- package/dist/src/trajectory.js +98 -45
- package/package.json +1 -1
package/dist/bin/jpi-bounties.js
CHANGED
|
@@ -644,15 +644,90 @@ var init_vocabulary = __esm({
|
|
|
644
644
|
}
|
|
645
645
|
});
|
|
646
646
|
|
|
647
|
+
// ../../packages/core/src/feeds/bounty-gate.ts
|
|
648
|
+
function isDenylistedRepo(fullName) {
|
|
649
|
+
return DENYLIST_LC.has(fullName.toLowerCase());
|
|
650
|
+
}
|
|
651
|
+
function isAiBanRepo(fullName) {
|
|
652
|
+
const lc = fullName.toLowerCase();
|
|
653
|
+
const owner = lc.split("/")[0];
|
|
654
|
+
return AI_BAN_LC.has(lc) || AI_BAN_LC.has(owner);
|
|
655
|
+
}
|
|
656
|
+
function passesAntiFarm(amountUSD, stargazers) {
|
|
657
|
+
return !(amountUSD > HIGH_VALUE_USD && stargazers < HIGH_VALUE_MIN_STARS);
|
|
658
|
+
}
|
|
659
|
+
function ageDays(createdAtIso) {
|
|
660
|
+
const created = Date.parse(createdAtIso);
|
|
661
|
+
if (!Number.isFinite(created)) return 0;
|
|
662
|
+
return (Date.now() - created) / (1e3 * 60 * 60 * 24);
|
|
663
|
+
}
|
|
664
|
+
function passesMaturityGate(repo) {
|
|
665
|
+
if (isDenylistedRepo(repo.fullName)) return false;
|
|
666
|
+
if (isAiBanRepo(repo.fullName)) return false;
|
|
667
|
+
if (repo.archived || repo.disabled) return false;
|
|
668
|
+
if (repo.stargazers < MIN_REPO_STARS) return false;
|
|
669
|
+
if (ageDays(repo.createdAt) < MIN_REPO_AGE_DAYS) return false;
|
|
670
|
+
return true;
|
|
671
|
+
}
|
|
672
|
+
var DEFAULT_BOUNTY_REPOS, BOUNTY_REPO_DENYLIST, DENYLIST_LC, AI_BAN_DENYLIST, AI_BAN_LC, MAX_BOUNTIES_PER_REPO, MAX_BOUNTIES_PER_DISCOVERED_REPO, MIN_REPO_STARS, HIGH_VALUE_USD, HIGH_VALUE_MIN_STARS, MIN_REPO_AGE_DAYS;
|
|
673
|
+
var init_bounty_gate = __esm({
|
|
674
|
+
"../../packages/core/src/feeds/bounty-gate.ts"() {
|
|
675
|
+
"use strict";
|
|
676
|
+
DEFAULT_BOUNTY_REPOS = [
|
|
677
|
+
"tenstorrent/tt-metal",
|
|
678
|
+
"sequelize/sequelize",
|
|
679
|
+
"commaai/opendbc",
|
|
680
|
+
"aragon/hack",
|
|
681
|
+
"spacemeshos/app",
|
|
682
|
+
"archestra-ai/archestra",
|
|
683
|
+
"ucfopen/Obojobo",
|
|
684
|
+
"moorcheh-ai/memanto",
|
|
685
|
+
"PrismarineJS/mineflayer"
|
|
686
|
+
];
|
|
687
|
+
BOUNTY_REPO_DENYLIST = [
|
|
688
|
+
"SecureBananaLabs/bug-bounty",
|
|
689
|
+
// Meta-farm: a bounty PLATFORM whose own issues are an assignment-gated
|
|
690
|
+
// contributor queue ("please assign me, my chief") — an unsolicited PR won't
|
|
691
|
+
// merge, so it's not a real claimable bounty. Not structurally derivable from
|
|
692
|
+
// any fetched field, so it's a manual entry (also dropped from the allowlist).
|
|
693
|
+
"boundlessfi/boundless"
|
|
694
|
+
];
|
|
695
|
+
DENYLIST_LC = new Set(BOUNTY_REPO_DENYLIST.map((r) => r.toLowerCase()));
|
|
696
|
+
AI_BAN_DENYLIST = [
|
|
697
|
+
// Gentoo Council voted 6-0 (2024-04-14) to ban AI/ML-generated contributions
|
|
698
|
+
// project-wide. https://wiki.gentoo.org/wiki/Project:Council/AI_policy
|
|
699
|
+
"gentoo",
|
|
700
|
+
// NetBSD Commit Guidelines: code generated by an LLM/similar technology is
|
|
701
|
+
// "presumed to be tainted code, and must not be committed without prior
|
|
702
|
+
// written approval by core". https://www.netbsd.org/developers/commit-guidelines.html
|
|
703
|
+
"NetBSD"
|
|
704
|
+
// NOT listed (checked, deliberately excluded): QEMU's blanket AI-contribution
|
|
705
|
+
// ban is IN FLUX as of 2026-05 — a patch replacing it with a disclosure-based
|
|
706
|
+
// policy ("AI-used-for:" tag) was posted to qemu-devel and appears to have
|
|
707
|
+
// developer buy-in, so it is no longer a clean/current ban to key a hard
|
|
708
|
+
// supply-side drop on. https://www.theregister.com/ai-and-ml/2026/05/29/qemu-mulls-relaxing-ai-contribution-ban/
|
|
709
|
+
];
|
|
710
|
+
AI_BAN_LC = new Set(AI_BAN_DENYLIST.map((g) => g.toLowerCase()));
|
|
711
|
+
MAX_BOUNTIES_PER_REPO = 10;
|
|
712
|
+
MAX_BOUNTIES_PER_DISCOVERED_REPO = 3;
|
|
713
|
+
MIN_REPO_STARS = 5;
|
|
714
|
+
HIGH_VALUE_USD = 500;
|
|
715
|
+
HIGH_VALUE_MIN_STARS = 50;
|
|
716
|
+
MIN_REPO_AGE_DAYS = 30;
|
|
717
|
+
}
|
|
718
|
+
});
|
|
719
|
+
|
|
647
720
|
// ../../packages/core/src/feeds/contribution-gate.ts
|
|
648
721
|
function passesContributionGate(input) {
|
|
649
722
|
if (input.contributors === void 0) return false;
|
|
723
|
+
if (isAiBanRepo(input.fullName)) return false;
|
|
650
724
|
return input.stars >= MIN_STARS && input.contributors >= MIN_CONTRIBUTORS && !TRIVIAL_PR_TITLE.test(input.title) && !input.archived && !input.fork;
|
|
651
725
|
}
|
|
652
726
|
var MIN_STARS, MIN_CONTRIBUTORS, TRIVIAL_PR_TITLE;
|
|
653
727
|
var init_contribution_gate = __esm({
|
|
654
728
|
"../../packages/core/src/feeds/contribution-gate.ts"() {
|
|
655
729
|
"use strict";
|
|
730
|
+
init_bounty_gate();
|
|
656
731
|
MIN_STARS = 50;
|
|
657
732
|
MIN_CONTRIBUTORS = 10;
|
|
658
733
|
TRIVIAL_PR_TITLE = /^\s*(fix\s+typo|typo\b|update\s+readme|readme\b|docs?:|docs?\(|chore:|chore\(|style:|ci:|build:|bump\b|update\s+dependenc)/i;
|
|
@@ -1710,58 +1785,6 @@ var init_hn = __esm({
|
|
|
1710
1785
|
}
|
|
1711
1786
|
});
|
|
1712
1787
|
|
|
1713
|
-
// ../../packages/core/src/feeds/bounty-gate.ts
|
|
1714
|
-
function isDenylistedRepo(fullName) {
|
|
1715
|
-
return DENYLIST_LC.has(fullName.toLowerCase());
|
|
1716
|
-
}
|
|
1717
|
-
function passesAntiFarm(amountUSD, stargazers) {
|
|
1718
|
-
return !(amountUSD > HIGH_VALUE_USD && stargazers < HIGH_VALUE_MIN_STARS);
|
|
1719
|
-
}
|
|
1720
|
-
function ageDays(createdAtIso) {
|
|
1721
|
-
const created = Date.parse(createdAtIso);
|
|
1722
|
-
if (!Number.isFinite(created)) return 0;
|
|
1723
|
-
return (Date.now() - created) / (1e3 * 60 * 60 * 24);
|
|
1724
|
-
}
|
|
1725
|
-
function passesMaturityGate(repo) {
|
|
1726
|
-
if (isDenylistedRepo(repo.fullName)) return false;
|
|
1727
|
-
if (repo.archived || repo.disabled) return false;
|
|
1728
|
-
if (repo.stargazers < MIN_REPO_STARS) return false;
|
|
1729
|
-
if (ageDays(repo.createdAt) < MIN_REPO_AGE_DAYS) return false;
|
|
1730
|
-
return true;
|
|
1731
|
-
}
|
|
1732
|
-
var DEFAULT_BOUNTY_REPOS, BOUNTY_REPO_DENYLIST, DENYLIST_LC, MAX_BOUNTIES_PER_REPO, MAX_BOUNTIES_PER_DISCOVERED_REPO, MIN_REPO_STARS, HIGH_VALUE_USD, HIGH_VALUE_MIN_STARS, MIN_REPO_AGE_DAYS;
|
|
1733
|
-
var init_bounty_gate = __esm({
|
|
1734
|
-
"../../packages/core/src/feeds/bounty-gate.ts"() {
|
|
1735
|
-
"use strict";
|
|
1736
|
-
DEFAULT_BOUNTY_REPOS = [
|
|
1737
|
-
"tenstorrent/tt-metal",
|
|
1738
|
-
"sequelize/sequelize",
|
|
1739
|
-
"commaai/opendbc",
|
|
1740
|
-
"aragon/hack",
|
|
1741
|
-
"spacemeshos/app",
|
|
1742
|
-
"archestra-ai/archestra",
|
|
1743
|
-
"ucfopen/Obojobo",
|
|
1744
|
-
"moorcheh-ai/memanto",
|
|
1745
|
-
"PrismarineJS/mineflayer"
|
|
1746
|
-
];
|
|
1747
|
-
BOUNTY_REPO_DENYLIST = [
|
|
1748
|
-
"SecureBananaLabs/bug-bounty",
|
|
1749
|
-
// Meta-farm: a bounty PLATFORM whose own issues are an assignment-gated
|
|
1750
|
-
// contributor queue ("please assign me, my chief") — an unsolicited PR won't
|
|
1751
|
-
// merge, so it's not a real claimable bounty. Not structurally derivable from
|
|
1752
|
-
// any fetched field, so it's a manual entry (also dropped from the allowlist).
|
|
1753
|
-
"boundlessfi/boundless"
|
|
1754
|
-
];
|
|
1755
|
-
DENYLIST_LC = new Set(BOUNTY_REPO_DENYLIST.map((r) => r.toLowerCase()));
|
|
1756
|
-
MAX_BOUNTIES_PER_REPO = 10;
|
|
1757
|
-
MAX_BOUNTIES_PER_DISCOVERED_REPO = 3;
|
|
1758
|
-
MIN_REPO_STARS = 5;
|
|
1759
|
-
HIGH_VALUE_USD = 500;
|
|
1760
|
-
HIGH_VALUE_MIN_STARS = 50;
|
|
1761
|
-
MIN_REPO_AGE_DAYS = 30;
|
|
1762
|
-
}
|
|
1763
|
-
});
|
|
1764
|
-
|
|
1765
1788
|
// ../../packages/core/src/concurrency.ts
|
|
1766
1789
|
async function mapWithConcurrency(items, limit, fn) {
|
|
1767
1790
|
const results = new Array(items.length);
|
|
@@ -2413,6 +2436,7 @@ async function aggregateBounties(opts) {
|
|
|
2413
2436
|
const repo = j.bounty?.repoFullName?.toLowerCase();
|
|
2414
2437
|
if (repo) {
|
|
2415
2438
|
if (isDenylistedRepo(repo)) continue;
|
|
2439
|
+
if (isAiBanRepo(repo)) continue;
|
|
2416
2440
|
const titleKey = `${repo} ${normalizeBountyTitle(j.title)}`;
|
|
2417
2441
|
if (seenRepoTitles.has(titleKey)) continue;
|
|
2418
2442
|
const cap = allowlist.has(repo) ? MAX_BOUNTIES_PER_REPO : MAX_BOUNTIES_PER_DISCOVERED_REPO;
|
|
@@ -2750,6 +2774,7 @@ async function aggregateContributions(opts = {}) {
|
|
|
2750
2774
|
const title = decodeEntities(issue.title).trim();
|
|
2751
2775
|
const contributors = await repoContribCount(fullName);
|
|
2752
2776
|
if (!passesContributionGate({
|
|
2777
|
+
fullName,
|
|
2753
2778
|
stars: repo.stargazers_count,
|
|
2754
2779
|
contributors,
|
|
2755
2780
|
title,
|
|
@@ -2819,21 +2844,21 @@ var init_contributions = __esm({
|
|
|
2819
2844
|
});
|
|
2820
2845
|
|
|
2821
2846
|
// ../../packages/core/src/partners.ts
|
|
2822
|
-
import { readFileSync
|
|
2823
|
-
import { join
|
|
2847
|
+
import { readFileSync } from "fs";
|
|
2848
|
+
import { join } from "path";
|
|
2824
2849
|
import { fileURLToPath } from "url";
|
|
2825
2850
|
function resolveDataPath() {
|
|
2826
2851
|
try {
|
|
2827
2852
|
const dir = fileURLToPath(new URL("../../../data", import.meta.url));
|
|
2828
|
-
return
|
|
2853
|
+
return join(dir, "partner-roles.json");
|
|
2829
2854
|
} catch {
|
|
2830
|
-
return
|
|
2855
|
+
return join(process.cwd(), "data", "partner-roles.json");
|
|
2831
2856
|
}
|
|
2832
2857
|
}
|
|
2833
2858
|
function loadPartnerRoles() {
|
|
2834
2859
|
const filePath = resolveDataPath();
|
|
2835
2860
|
try {
|
|
2836
|
-
const raw =
|
|
2861
|
+
const raw = readFileSync(filePath, "utf-8");
|
|
2837
2862
|
const parsed = JSON.parse(raw);
|
|
2838
2863
|
if (!Array.isArray(parsed)) {
|
|
2839
2864
|
console.warn("[partners] partner-roles.json is not an array \u2014 skipping");
|
|
@@ -6345,16 +6370,113 @@ var init_legible = __esm({
|
|
|
6345
6370
|
}
|
|
6346
6371
|
});
|
|
6347
6372
|
|
|
6373
|
+
// ../../packages/core/src/credential/legible-trajectory.ts
|
|
6374
|
+
function signalLabel(signal) {
|
|
6375
|
+
if (signal.startsWith("lang:")) {
|
|
6376
|
+
const token = signal.slice("lang:".length);
|
|
6377
|
+
return LANG_LABELS[token] ?? token.toUpperCase();
|
|
6378
|
+
}
|
|
6379
|
+
if (CAP_LABELS[signal]) return CAP_LABELS[signal];
|
|
6380
|
+
if (signal.startsWith("cap:")) return signal.slice("cap:".length).replace(/-/g, " ");
|
|
6381
|
+
return signal;
|
|
6382
|
+
}
|
|
6383
|
+
function joinLabels(labels) {
|
|
6384
|
+
if (labels.length === 0) return "";
|
|
6385
|
+
if (labels.length === 1) return labels[0];
|
|
6386
|
+
return `${labels.slice(0, -1).join(", ")} and ${labels[labels.length - 1]}`;
|
|
6387
|
+
}
|
|
6388
|
+
function mentionable(entries) {
|
|
6389
|
+
return entries.filter((e) => Math.abs(e.delta) >= MENTION_DELTA).slice(0, MAX_NAMED).map((e) => signalLabel(e.signal));
|
|
6390
|
+
}
|
|
6391
|
+
function displayableDrift(entries) {
|
|
6392
|
+
return entries.filter((e) => Math.abs(e.delta) >= DISPLAY_DELTA_FLOOR);
|
|
6393
|
+
}
|
|
6394
|
+
function deriveTrajectoryNarrative(score) {
|
|
6395
|
+
const risingLabels = mentionable(score.headline.rising);
|
|
6396
|
+
const fallingLabels = mentionable(score.headline.falling);
|
|
6397
|
+
let momentum;
|
|
6398
|
+
if (risingLabels.length === 0 && fallingLabels.length === 0) {
|
|
6399
|
+
momentum = "Steady focus \u2014 no major shifts recently.";
|
|
6400
|
+
} else {
|
|
6401
|
+
const parts = [];
|
|
6402
|
+
if (risingLabels.length > 0) parts.push(`Trending toward ${joinLabels(risingLabels)}`);
|
|
6403
|
+
if (fallingLabels.length > 0) {
|
|
6404
|
+
parts.push(
|
|
6405
|
+
risingLabels.length > 0 ? `shifting away from ${joinLabels(fallingLabels)}` : `Shifting away from ${joinLabels(fallingLabels)}`
|
|
6406
|
+
);
|
|
6407
|
+
}
|
|
6408
|
+
momentum = `${parts.join(", ")}.`;
|
|
6409
|
+
}
|
|
6410
|
+
const liveLangs = score.liveStack.filter((s) => s.startsWith("lang:")).map(signalLabel);
|
|
6411
|
+
const liveCaps = score.liveStack.filter((s) => !s.startsWith("lang:")).map(signalLabel);
|
|
6412
|
+
const focusParts = [];
|
|
6413
|
+
if (liveLangs.length > 0) focusParts.push(`Ships in ${joinLabels(liveLangs)}`);
|
|
6414
|
+
if (liveCaps.length > 0) {
|
|
6415
|
+
const verb = liveLangs.length > 0 ? "works with" : "Works with";
|
|
6416
|
+
focusParts.push(`${verb} ${joinLabels(liveCaps)}`);
|
|
6417
|
+
}
|
|
6418
|
+
const focus = focusParts.length > 0 ? `${focusParts.join(" \xB7 ")}.` : "";
|
|
6419
|
+
return { momentum, focus, risingLabels, fallingLabels };
|
|
6420
|
+
}
|
|
6421
|
+
var LANG_LABELS, CAP_LABELS, MENTION_DELTA, DISPLAY_DELTA_FLOOR, MAX_NAMED;
|
|
6422
|
+
var init_legible_trajectory = __esm({
|
|
6423
|
+
"../../packages/core/src/credential/legible-trajectory.ts"() {
|
|
6424
|
+
"use strict";
|
|
6425
|
+
LANG_LABELS = {
|
|
6426
|
+
ts: "TypeScript",
|
|
6427
|
+
js: "JavaScript",
|
|
6428
|
+
py: "Python",
|
|
6429
|
+
rs: "Rust",
|
|
6430
|
+
go: "Go",
|
|
6431
|
+
rb: "Ruby",
|
|
6432
|
+
java: "Java",
|
|
6433
|
+
kt: "Kotlin",
|
|
6434
|
+
sql: "SQL",
|
|
6435
|
+
md: "Documentation"
|
|
6436
|
+
};
|
|
6437
|
+
CAP_LABELS = {
|
|
6438
|
+
"cap:ui-automation": "UI automation",
|
|
6439
|
+
"cap:deploys": "Deployment",
|
|
6440
|
+
"cap:project-mgmt": "Project tracking",
|
|
6441
|
+
"cap:product-research": "Product research",
|
|
6442
|
+
"cap:design": "Design",
|
|
6443
|
+
"cap:3d-modeling": "3D modeling",
|
|
6444
|
+
"cap:workflow-automation": "Workflow automation",
|
|
6445
|
+
"cap:agentic-workflow": "Agent orchestration",
|
|
6446
|
+
"mcp:custom": "Private integrations"
|
|
6447
|
+
};
|
|
6448
|
+
MENTION_DELTA = 0.05;
|
|
6449
|
+
DISPLAY_DELTA_FLOOR = 5e-4;
|
|
6450
|
+
MAX_NAMED = 3;
|
|
6451
|
+
}
|
|
6452
|
+
});
|
|
6453
|
+
|
|
6454
|
+
// ../../packages/core/src/short-token.ts
|
|
6455
|
+
import { createHash as createHash2 } from "crypto";
|
|
6456
|
+
function opportunityShortToken(id) {
|
|
6457
|
+
return createHash2("sha256").update(id, "utf8").digest("base64url").slice(0, 8);
|
|
6458
|
+
}
|
|
6459
|
+
var contributeShortToken;
|
|
6460
|
+
var init_short_token = __esm({
|
|
6461
|
+
"../../packages/core/src/short-token.ts"() {
|
|
6462
|
+
"use strict";
|
|
6463
|
+
contributeShortToken = opportunityShortToken;
|
|
6464
|
+
}
|
|
6465
|
+
});
|
|
6466
|
+
|
|
6348
6467
|
// ../../packages/core/src/index.ts
|
|
6349
6468
|
var src_exports = {};
|
|
6350
6469
|
__export(src_exports, {
|
|
6470
|
+
AI_BAN_DENYLIST: () => AI_BAN_DENYLIST,
|
|
6351
6471
|
ASHBY_SLUGS_BY_TIER: () => ASHBY_SLUGS_BY_TIER,
|
|
6472
|
+
CAP_LABELS: () => CAP_LABELS,
|
|
6352
6473
|
DECAY_FLOOR: () => DECAY_FLOOR,
|
|
6353
6474
|
DEFAULT_ASHBY_SLUGS: () => DEFAULT_ASHBY_SLUGS,
|
|
6354
6475
|
DEFAULT_BOUNTY_REPOS: () => DEFAULT_BOUNTY_REPOS,
|
|
6355
6476
|
DEFAULT_GREENHOUSE_SLUGS: () => DEFAULT_GREENHOUSE_SLUGS,
|
|
6356
6477
|
DEFAULT_LEVER_SLUGS: () => DEFAULT_LEVER_SLUGS,
|
|
6357
6478
|
DEFAULT_WORKABLE_SLUGS: () => DEFAULT_WORKABLE_SLUGS,
|
|
6479
|
+
DISPLAY_DELTA_FLOOR: () => DISPLAY_DELTA_FLOOR,
|
|
6358
6480
|
EXAMPLE_BUYER: () => EXAMPLE_BUYER,
|
|
6359
6481
|
FEEDS: () => FEEDS,
|
|
6360
6482
|
GRAPH: () => GRAPH,
|
|
@@ -6363,7 +6485,9 @@ __export(src_exports, {
|
|
|
6363
6485
|
INTRO_ACCEPTED_TTL_MS: () => INTRO_ACCEPTED_TTL_MS,
|
|
6364
6486
|
INTRO_ALLOWED_FIELDS: () => INTRO_ALLOWED_FIELDS,
|
|
6365
6487
|
INTRO_PENDING_TTL_MS: () => INTRO_PENDING_TTL_MS,
|
|
6488
|
+
LANG_LABELS: () => LANG_LABELS,
|
|
6366
6489
|
LEVER_SLUGS_BY_TIER: () => LEVER_SLUGS_BY_TIER,
|
|
6490
|
+
MENTION_DELTA: () => MENTION_DELTA,
|
|
6367
6491
|
MIN_CONTRIBUTORS: () => MIN_CONTRIBUTORS,
|
|
6368
6492
|
MIN_STARS: () => MIN_STARS,
|
|
6369
6493
|
STRONG_MATCH_THRESHOLD: () => STRONG_MATCH_THRESHOLD,
|
|
@@ -6388,12 +6512,15 @@ __export(src_exports, {
|
|
|
6388
6512
|
composeIntroEmail: () => composeIntroEmail,
|
|
6389
6513
|
computeAcceptanceCredential: () => computeAcceptanceCredential,
|
|
6390
6514
|
computeAcceptanceCredentialPublic: () => computeAcceptanceCredentialPublic,
|
|
6515
|
+
contributeShortToken: () => contributeShortToken,
|
|
6391
6516
|
coreTagsFromTitle: () => coreTagsFromTitle,
|
|
6392
6517
|
decorate: () => decorate,
|
|
6393
6518
|
decryptMessage: () => decryptMessage,
|
|
6394
6519
|
deriveLegibleProfile: () => deriveLegibleProfile,
|
|
6395
6520
|
deriveResumeTrend: () => deriveResumeTrend,
|
|
6396
6521
|
deriveSharedKey: () => deriveSharedKey,
|
|
6522
|
+
deriveTrajectoryNarrative: () => deriveTrajectoryNarrative,
|
|
6523
|
+
displayableDrift: () => displayableDrift,
|
|
6397
6524
|
encryptMessage: () => encryptMessage,
|
|
6398
6525
|
expandWeighted: () => expandWeighted,
|
|
6399
6526
|
extractSkillTags: () => extractSkillTags,
|
|
@@ -6413,15 +6540,19 @@ __export(src_exports, {
|
|
|
6413
6540
|
introActorRole: () => introActorRole,
|
|
6414
6541
|
introRateLimitCheck: () => introRateLimitCheck,
|
|
6415
6542
|
introRetentionAction: () => introRetentionAction,
|
|
6543
|
+
isAiBanRepo: () => isAiBanRepo,
|
|
6416
6544
|
isBounty: () => isBounty,
|
|
6417
6545
|
isContribution: () => isContribution,
|
|
6418
6546
|
isOverIntroLimit: () => isOverIntroLimit,
|
|
6547
|
+
joinLabels: () => joinLabels,
|
|
6548
|
+
labelFor: () => labelFor,
|
|
6419
6549
|
lever: () => lever,
|
|
6420
6550
|
loadPartnerRoles: () => loadPartnerRoles,
|
|
6421
6551
|
looksLikeEngRole: () => looksLikeEngRole,
|
|
6422
6552
|
match: () => match,
|
|
6423
6553
|
normalize: () => normalize,
|
|
6424
6554
|
opire: () => opire,
|
|
6555
|
+
opportunityShortToken: () => opportunityShortToken,
|
|
6425
6556
|
pageMatches: () => pageMatches,
|
|
6426
6557
|
passesContributionGate: () => passesContributionGate,
|
|
6427
6558
|
passesMaturityGate: () => passesMaturityGate,
|
|
@@ -6433,6 +6564,7 @@ __export(src_exports, {
|
|
|
6433
6564
|
safetyNumber: () => safetyNumber,
|
|
6434
6565
|
sameLogin: () => sameLogin,
|
|
6435
6566
|
setStatus: () => setStatus,
|
|
6567
|
+
signalLabel: () => signalLabel,
|
|
6436
6568
|
tokenize: () => tokenize,
|
|
6437
6569
|
validateGraph: () => validateGraph,
|
|
6438
6570
|
validateIntroPayload: () => validateIntroPayload,
|
|
@@ -6455,6 +6587,8 @@ var init_src = __esm({
|
|
|
6455
6587
|
init_chatCrypto();
|
|
6456
6588
|
init_job_status();
|
|
6457
6589
|
init_legible();
|
|
6590
|
+
init_legible_trajectory();
|
|
6591
|
+
init_short_token();
|
|
6458
6592
|
}
|
|
6459
6593
|
});
|
|
6460
6594
|
|
|
@@ -6466,9 +6600,9 @@ var init_keytar = __esm({
|
|
|
6466
6600
|
}
|
|
6467
6601
|
});
|
|
6468
6602
|
|
|
6469
|
-
// node-file:/Users
|
|
6603
|
+
// node-file:/private/tmp/claude-501/-Users-ericgang-job-placement-inline/3ffac25b-ca95-4a86-9e17-a4cf326551de/scratchpad/rel2/node_modules/keytar/build/Release/keytar.node
|
|
6470
6604
|
var require_keytar = __commonJS({
|
|
6471
|
-
"node-file:/Users
|
|
6605
|
+
"node-file:/private/tmp/claude-501/-Users-ericgang-job-placement-inline/3ffac25b-ca95-4a86-9e17-a4cf326551de/scratchpad/rel2/node_modules/keytar/build/Release/keytar.node"(exports, module) {
|
|
6472
6606
|
"use strict";
|
|
6473
6607
|
init_keytar();
|
|
6474
6608
|
try {
|
|
@@ -6758,22 +6892,23 @@ var init_profile = __esm({
|
|
|
6758
6892
|
});
|
|
6759
6893
|
|
|
6760
6894
|
// bin/jpi-bounties.js
|
|
6895
|
+
init_src();
|
|
6761
6896
|
import { readFileSync as readFileSync4 } from "fs";
|
|
6762
6897
|
import { join as join4 } from "path";
|
|
6763
6898
|
import { homedir as homedir3 } from "os";
|
|
6764
6899
|
import { createInterface } from "readline";
|
|
6765
6900
|
|
|
6766
6901
|
// bin/cache-store.js
|
|
6767
|
-
import { readFileSync, writeFileSync, mkdirSync, renameSync } from "fs";
|
|
6768
|
-
import { join } from "path";
|
|
6902
|
+
import { readFileSync as readFileSync2, writeFileSync, mkdirSync, renameSync } from "fs";
|
|
6903
|
+
import { join as join2 } from "path";
|
|
6769
6904
|
import { homedir } from "os";
|
|
6770
|
-
var TERMINALHIRE_DIR = process.env.TERMINALHIRE_DIR ||
|
|
6771
|
-
var INDEX_CACHE_FILE =
|
|
6772
|
-
var
|
|
6905
|
+
var TERMINALHIRE_DIR = process.env.TERMINALHIRE_DIR || join2(homedir(), ".terminalhire");
|
|
6906
|
+
var INDEX_CACHE_FILE = join2(TERMINALHIRE_DIR, "index-cache.json");
|
|
6907
|
+
var SCHEMA_VERSION2 = 1;
|
|
6773
6908
|
var tmpCounter = 0;
|
|
6774
6909
|
function readCacheEntry() {
|
|
6775
6910
|
try {
|
|
6776
|
-
return JSON.parse(
|
|
6911
|
+
return JSON.parse(readFileSync2(INDEX_CACHE_FILE, "utf8"));
|
|
6777
6912
|
} catch {
|
|
6778
6913
|
return null;
|
|
6779
6914
|
}
|
|
@@ -6784,7 +6919,7 @@ function updateIndexCache(patch) {
|
|
|
6784
6919
|
const entry = {
|
|
6785
6920
|
...existing,
|
|
6786
6921
|
...patch,
|
|
6787
|
-
schemaVersion:
|
|
6922
|
+
schemaVersion: SCHEMA_VERSION2,
|
|
6788
6923
|
ts: Date.now()
|
|
6789
6924
|
};
|
|
6790
6925
|
const tmp = `${INDEX_CACHE_FILE}.${process.pid}.${tmpCounter++}.tmp`;
|
|
@@ -6852,13 +6987,15 @@ function printBounty(i, job, score, reason, matchedTags) {
|
|
|
6852
6987
|
const scoreStr = score > 0 ? ` \xB7 match ${Math.round(score * 100)}%` : "";
|
|
6853
6988
|
const prs = b.competingOpenPRs;
|
|
6854
6989
|
const contend = prs != null && prs > 0 ? ` \xB7 \u26A0 ${prs} PR${prs === 1 ? "" : "s"} in flight` : "";
|
|
6990
|
+
const ref = opportunityShortToken(job.id);
|
|
6855
6991
|
console.log(`
|
|
6856
|
-
${i + 1}. ${linkTitle(job.title, job.url)}`);
|
|
6992
|
+
${i + 1}. ${linkTitle(job.title, job.url)} [${ref}]`);
|
|
6857
6993
|
console.log(` ${formatAmount(b)}${effort} \xB7 ${b.repoFullName ?? job.company}${stars}${scoreStr}${contend}`);
|
|
6858
6994
|
if (reason) console.log(` ${reason}`);
|
|
6859
6995
|
if (matchedTags && matchedTags.length) console.log(` Tags matched: ${matchedTags.slice(0, 5).join(", ")}`);
|
|
6860
6996
|
console.log(` id: ${job.id}`);
|
|
6861
6997
|
console.log(` Claim: ${b.claimUrl ?? job.url}`);
|
|
6998
|
+
console.log(` \u2192 terminalhire claim ${ref}`);
|
|
6862
6999
|
}
|
|
6863
7000
|
async function run() {
|
|
6864
7001
|
try {
|
|
@@ -422,10 +422,43 @@ var init_vocabulary = __esm({
|
|
|
422
422
|
}
|
|
423
423
|
});
|
|
424
424
|
|
|
425
|
+
// ../../packages/core/src/feeds/bounty-gate.ts
|
|
426
|
+
var BOUNTY_REPO_DENYLIST, DENYLIST_LC, AI_BAN_DENYLIST, AI_BAN_LC;
|
|
427
|
+
var init_bounty_gate = __esm({
|
|
428
|
+
"../../packages/core/src/feeds/bounty-gate.ts"() {
|
|
429
|
+
"use strict";
|
|
430
|
+
BOUNTY_REPO_DENYLIST = [
|
|
431
|
+
"SecureBananaLabs/bug-bounty",
|
|
432
|
+
// Meta-farm: a bounty PLATFORM whose own issues are an assignment-gated
|
|
433
|
+
// contributor queue ("please assign me, my chief") — an unsolicited PR won't
|
|
434
|
+
// merge, so it's not a real claimable bounty. Not structurally derivable from
|
|
435
|
+
// any fetched field, so it's a manual entry (also dropped from the allowlist).
|
|
436
|
+
"boundlessfi/boundless"
|
|
437
|
+
];
|
|
438
|
+
DENYLIST_LC = new Set(BOUNTY_REPO_DENYLIST.map((r) => r.toLowerCase()));
|
|
439
|
+
AI_BAN_DENYLIST = [
|
|
440
|
+
// Gentoo Council voted 6-0 (2024-04-14) to ban AI/ML-generated contributions
|
|
441
|
+
// project-wide. https://wiki.gentoo.org/wiki/Project:Council/AI_policy
|
|
442
|
+
"gentoo",
|
|
443
|
+
// NetBSD Commit Guidelines: code generated by an LLM/similar technology is
|
|
444
|
+
// "presumed to be tainted code, and must not be committed without prior
|
|
445
|
+
// written approval by core". https://www.netbsd.org/developers/commit-guidelines.html
|
|
446
|
+
"NetBSD"
|
|
447
|
+
// NOT listed (checked, deliberately excluded): QEMU's blanket AI-contribution
|
|
448
|
+
// ban is IN FLUX as of 2026-05 — a patch replacing it with a disclosure-based
|
|
449
|
+
// policy ("AI-used-for:" tag) was posted to qemu-devel and appears to have
|
|
450
|
+
// developer buy-in, so it is no longer a clean/current ban to key a hard
|
|
451
|
+
// supply-side drop on. https://www.theregister.com/ai-and-ml/2026/05/29/qemu-mulls-relaxing-ai-contribution-ban/
|
|
452
|
+
];
|
|
453
|
+
AI_BAN_LC = new Set(AI_BAN_DENYLIST.map((g) => g.toLowerCase()));
|
|
454
|
+
}
|
|
455
|
+
});
|
|
456
|
+
|
|
425
457
|
// ../../packages/core/src/feeds/contribution-gate.ts
|
|
426
458
|
var init_contribution_gate = __esm({
|
|
427
459
|
"../../packages/core/src/feeds/contribution-gate.ts"() {
|
|
428
460
|
"use strict";
|
|
461
|
+
init_bounty_gate();
|
|
429
462
|
}
|
|
430
463
|
});
|
|
431
464
|
|
|
@@ -519,23 +552,6 @@ var init_hn = __esm({
|
|
|
519
552
|
}
|
|
520
553
|
});
|
|
521
554
|
|
|
522
|
-
// ../../packages/core/src/feeds/bounty-gate.ts
|
|
523
|
-
var BOUNTY_REPO_DENYLIST, DENYLIST_LC;
|
|
524
|
-
var init_bounty_gate = __esm({
|
|
525
|
-
"../../packages/core/src/feeds/bounty-gate.ts"() {
|
|
526
|
-
"use strict";
|
|
527
|
-
BOUNTY_REPO_DENYLIST = [
|
|
528
|
-
"SecureBananaLabs/bug-bounty",
|
|
529
|
-
// Meta-farm: a bounty PLATFORM whose own issues are an assignment-gated
|
|
530
|
-
// contributor queue ("please assign me, my chief") — an unsolicited PR won't
|
|
531
|
-
// merge, so it's not a real claimable bounty. Not structurally derivable from
|
|
532
|
-
// any fetched field, so it's a manual entry (also dropped from the allowlist).
|
|
533
|
-
"boundlessfi/boundless"
|
|
534
|
-
];
|
|
535
|
-
DENYLIST_LC = new Set(BOUNTY_REPO_DENYLIST.map((r) => r.toLowerCase()));
|
|
536
|
-
}
|
|
537
|
-
});
|
|
538
|
-
|
|
539
555
|
// ../../packages/core/src/concurrency.ts
|
|
540
556
|
var init_concurrency = __esm({
|
|
541
557
|
"../../packages/core/src/concurrency.ts"() {
|
|
@@ -3865,6 +3881,21 @@ var init_legible = __esm({
|
|
|
3865
3881
|
}
|
|
3866
3882
|
});
|
|
3867
3883
|
|
|
3884
|
+
// ../../packages/core/src/credential/legible-trajectory.ts
|
|
3885
|
+
var init_legible_trajectory = __esm({
|
|
3886
|
+
"../../packages/core/src/credential/legible-trajectory.ts"() {
|
|
3887
|
+
"use strict";
|
|
3888
|
+
}
|
|
3889
|
+
});
|
|
3890
|
+
|
|
3891
|
+
// ../../packages/core/src/short-token.ts
|
|
3892
|
+
import { createHash as createHash2 } from "crypto";
|
|
3893
|
+
var init_short_token = __esm({
|
|
3894
|
+
"../../packages/core/src/short-token.ts"() {
|
|
3895
|
+
"use strict";
|
|
3896
|
+
}
|
|
3897
|
+
});
|
|
3898
|
+
|
|
3868
3899
|
// ../../packages/core/src/index.ts
|
|
3869
3900
|
var init_src = __esm({
|
|
3870
3901
|
"../../packages/core/src/index.ts"() {
|
|
@@ -3881,6 +3912,8 @@ var init_src = __esm({
|
|
|
3881
3912
|
init_chatCrypto();
|
|
3882
3913
|
init_job_status();
|
|
3883
3914
|
init_legible();
|
|
3915
|
+
init_legible_trajectory();
|
|
3916
|
+
init_short_token();
|
|
3884
3917
|
}
|
|
3885
3918
|
});
|
|
3886
3919
|
|
|
@@ -3892,9 +3925,9 @@ var init_keytar = __esm({
|
|
|
3892
3925
|
}
|
|
3893
3926
|
});
|
|
3894
3927
|
|
|
3895
|
-
// node-file:/Users
|
|
3928
|
+
// node-file:/private/tmp/claude-501/-Users-ericgang-job-placement-inline/3ffac25b-ca95-4a86-9e17-a4cf326551de/scratchpad/rel2/node_modules/keytar/build/Release/keytar.node
|
|
3896
3929
|
var require_keytar = __commonJS({
|
|
3897
|
-
"node-file:/Users
|
|
3930
|
+
"node-file:/private/tmp/claude-501/-Users-ericgang-job-placement-inline/3ffac25b-ca95-4a86-9e17-a4cf326551de/scratchpad/rel2/node_modules/keytar/build/Release/keytar.node"(exports, module) {
|
|
3898
3931
|
"use strict";
|
|
3899
3932
|
init_keytar();
|
|
3900
3933
|
try {
|
|
@@ -4267,7 +4300,7 @@ var init_chat_client = __esm({
|
|
|
4267
4300
|
init_src();
|
|
4268
4301
|
init_chat_keystore();
|
|
4269
4302
|
init_web_session();
|
|
4270
|
-
CHAT_BASE = process.env["TERMINALHIRE_API_URL"] || "https://
|
|
4303
|
+
CHAT_BASE = process.env["TERMINALHIRE_API_URL"] || "https://terminalhire.com";
|
|
4271
4304
|
GH_SESSION_COOKIE = "__jpi_gh_session";
|
|
4272
4305
|
TERMINALHIRE_DIR3 = join5(homedir4(), ".terminalhire");
|
|
4273
4306
|
PEERS_FILE = join5(TERMINALHIRE_DIR3, "chat-peers.json");
|
|
@@ -4485,7 +4518,7 @@ var init_jpi_chat = __esm({
|
|
|
4485
4518
|
init_chat_client();
|
|
4486
4519
|
init_config();
|
|
4487
4520
|
init_web_session();
|
|
4488
|
-
CHAT_BASE2 = process.env["TERMINALHIRE_API_URL"] || "https://
|
|
4521
|
+
CHAT_BASE2 = process.env["TERMINALHIRE_API_URL"] || "https://terminalhire.com";
|
|
4489
4522
|
GH_SESSION_COOKIE2 = "__jpi_gh_session";
|
|
4490
4523
|
ANSI_CSI = /\x1b\[[0-?]*[ -/]*[@-~]/g;
|
|
4491
4524
|
ANSI_OSC = /\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)/g;
|
|
@@ -4873,7 +4906,7 @@ var init_jpi_chat_read = __esm({
|
|
|
4873
4906
|
init_chat_client();
|
|
4874
4907
|
init_web_session();
|
|
4875
4908
|
init_jpi_chat();
|
|
4876
|
-
CHAT_BASE3 = process.env["TERMINALHIRE_API_URL"] || "https://
|
|
4909
|
+
CHAT_BASE3 = process.env["TERMINALHIRE_API_URL"] || "https://terminalhire.com";
|
|
4877
4910
|
GH_SESSION_COOKIE3 = "__jpi_gh_session";
|
|
4878
4911
|
TERMINALHIRE_DIR5 = process.env.TERMINALHIRE_DIR || join8(homedir7(), ".terminalhire");
|
|
4879
4912
|
READS_FILE = join8(TERMINALHIRE_DIR5, "chat-reads.json");
|