terminalhire 0.13.0 → 0.15.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.
@@ -552,6 +552,31 @@ function normalize(tokens) {
552
552
  }
553
553
  return Array.from(result);
554
554
  }
555
+ function getAdjacentTags(tag, hops = 1, graph = GRAPH) {
556
+ const lower = String(tag ?? "").toLowerCase().trim();
557
+ const id = graph.ids.has(lower) ? lower : graph.synonyms.get(lower);
558
+ if (!id) return [];
559
+ const oneHop = (source) => {
560
+ const out = [];
561
+ for (const [to, edge] of graph.closure.get(source) ?? []) {
562
+ if (edge.via === to) out.push([to, edge.w]);
563
+ }
564
+ return out;
565
+ };
566
+ const byWeightThenId = (a, b) => b[1] - a[1] || (a[0] < b[0] ? -1 : 1);
567
+ const ring1 = oneHop(id).sort(byWeightThenId);
568
+ if (hops === 1) return ring1.map(([to]) => to);
569
+ const exclude = /* @__PURE__ */ new Set([id, ...ring1.map(([to]) => to)]);
570
+ const best = /* @__PURE__ */ new Map();
571
+ for (const [n, w1] of ring1) {
572
+ for (const [to, w2] of oneHop(n)) {
573
+ if (exclude.has(to)) continue;
574
+ const w = w1 * w2;
575
+ if (w > (best.get(to) ?? 0)) best.set(to, w);
576
+ }
577
+ }
578
+ return [...best.entries()].sort(byWeightThenId).map(([to]) => to);
579
+ }
555
580
  function expandWeighted(tags, graph = GRAPH) {
556
581
  const out = /* @__PURE__ */ new Map();
557
582
  const put = (tag, weight, via) => {
@@ -2928,11 +2953,14 @@ You control whether this connects \u2014 no contact details are shared unless yo
2928
2953
  return { subject, text };
2929
2954
  }
2930
2955
  function introActorRole(intro, actorLogin) {
2931
- const a = actorLogin.trim().toLowerCase();
2932
- if (a && a === intro.targetLogin.trim().toLowerCase()) return "target";
2933
- if (a && a === intro.requesterLogin.trim().toLowerCase()) return "requester";
2956
+ if (sameLogin(actorLogin, intro.targetLogin)) return "target";
2957
+ if (sameLogin(actorLogin, intro.requesterLogin)) return "requester";
2934
2958
  return "other";
2935
2959
  }
2960
+ function sameLogin(a, b) {
2961
+ const an = a.trim().toLowerCase();
2962
+ return an.length > 0 && an === b.trim().toLowerCase();
2963
+ }
2936
2964
  function authorizeIntroDecision(intro, actorLogin) {
2937
2965
  const role = introActorRole(intro, actorLogin);
2938
2966
  if (role === "target") return { ok: true };
@@ -6346,6 +6374,7 @@ __export(src_exports, {
6346
6374
  flattenTiers: () => flattenTiers,
6347
6375
  funnelCounts: () => funnelCounts,
6348
6376
  generateIdentityKeypair: () => generateIdentityKeypair,
6377
+ getAdjacentTags: () => getAdjacentTags,
6349
6378
  getBuyer: () => getBuyer,
6350
6379
  githubBounties: () => githubBounties,
6351
6380
  githubToFingerprint: () => githubToFingerprint,
@@ -6373,6 +6402,7 @@ __export(src_exports, {
6373
6402
  rejectExtraIntroFields: () => rejectExtraIntroFields,
6374
6403
  revealIntroContacts: () => revealIntroContacts,
6375
6404
  safetyNumber: () => safetyNumber,
6405
+ sameLogin: () => sameLogin,
6376
6406
  setStatus: () => setStatus,
6377
6407
  tokenize: () => tokenize,
6378
6408
  validateGraph: () => validateGraph,
@@ -6644,7 +6674,7 @@ import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSy
6644
6674
  import { join as join3 } from "path";
6645
6675
  import { homedir as homedir2 } from "os";
6646
6676
  import { createInterface } from "readline";
6647
- var TERMINALHIRE_DIR2 = join3(homedir2(), ".terminalhire");
6677
+ var TERMINALHIRE_DIR2 = process.env.TERMINALHIRE_DIR || join3(homedir2(), ".terminalhire");
6648
6678
  var INDEX_CACHE_FILE = join3(TERMINALHIRE_DIR2, "index-cache.json");
6649
6679
  var INDEX_TTL_MS = 15 * 60 * 1e3;
6650
6680
  var API_URL = process.env["TERMINALHIRE_API_URL"] ?? process.env["JPI_API_URL"] ?? "https://terminalhire.com";
@@ -4456,6 +4456,8 @@ function readReadCursors() {
4456
4456
  function writeReadCursor(login, iso, deps = {}) {
4457
4457
  const read = deps.readReadCursors ?? readReadCursors;
4458
4458
  const cursors = read();
4459
+ const prev = cursors[login];
4460
+ if (prev && iso <= prev) return;
4459
4461
  cursors[login] = iso;
4460
4462
  mkdirSync6(TERMINALHIRE_DIR5, { recursive: true });
4461
4463
  writeFileSync6(READS_FILE, JSON.stringify(cursors, null, 2), { mode: 384, encoding: "utf8" });
@@ -4771,7 +4773,7 @@ var init_jpi_chat_read = __esm({
4771
4773
  init_jpi_chat();
4772
4774
  CHAT_BASE3 = process.env["TERMINALHIRE_API_URL"] || "https://www.terminalhire.com";
4773
4775
  GH_SESSION_COOKIE3 = "__jpi_gh_session";
4774
- TERMINALHIRE_DIR5 = join8(homedir7(), ".terminalhire");
4776
+ TERMINALHIRE_DIR5 = process.env.TERMINALHIRE_DIR || join8(homedir7(), ".terminalhire");
4775
4777
  READS_FILE = join8(TERMINALHIRE_DIR5, "chat-reads.json");
4776
4778
  INDEX_CACHE_FILE = join8(TERMINALHIRE_DIR5, "index-cache.json");
4777
4779
  REACHABLE_DISPLAY = { shareActivity: false, optin: false, lastSeen: null };