terminalhire 0.10.7 → 0.10.9
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-chat-read.js +30 -1
- package/dist/bin/jpi-chat.js +30 -1
- package/dist/bin/jpi-dispatch.js +46 -10
- package/dist/bin/jpi-refresh.js +9 -2
- package/dist/bin/jpi.js +17 -3
- package/package.json +1 -1
|
@@ -4269,6 +4269,31 @@ var init_jpi_chat = __esm({
|
|
|
4269
4269
|
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
4270
4270
|
import { homedir as homedir6 } from "os";
|
|
4271
4271
|
import { join as join7 } from "path";
|
|
4272
|
+
async function syncUnreadBadge(deps = {}) {
|
|
4273
|
+
const readCookie = deps.readCookie ?? readWebSessionCookie;
|
|
4274
|
+
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
4275
|
+
const cacheFile = deps.cacheFile ?? INDEX_CACHE_FILE;
|
|
4276
|
+
try {
|
|
4277
|
+
const cookie = readCookie();
|
|
4278
|
+
if (!cookie || !existsSync6(cacheFile)) return;
|
|
4279
|
+
const res = await fetchImpl(`${CHAT_BASE3}/api/chat/inbox`, {
|
|
4280
|
+
method: "GET",
|
|
4281
|
+
headers: { Cookie: `${GH_SESSION_COOKIE3}=${cookie}` },
|
|
4282
|
+
signal: AbortSignal.timeout(2500)
|
|
4283
|
+
});
|
|
4284
|
+
if (!res.ok) return;
|
|
4285
|
+
const body = await res.json();
|
|
4286
|
+
const inbox = Array.isArray(body?.inbox) ? body.inbox : [];
|
|
4287
|
+
const total = inbox.reduce(
|
|
4288
|
+
(sum, it) => sum + (it && typeof it.unreadCount === "number" && it.unreadCount > 0 ? it.unreadCount : 0),
|
|
4289
|
+
0
|
|
4290
|
+
);
|
|
4291
|
+
const entry = JSON.parse(readFileSync7(cacheFile, "utf8"));
|
|
4292
|
+
entry.unreadChat = { count: total };
|
|
4293
|
+
writeFileSync6(cacheFile, JSON.stringify(entry), "utf8");
|
|
4294
|
+
} catch {
|
|
4295
|
+
}
|
|
4296
|
+
}
|
|
4272
4297
|
function readReadCursors() {
|
|
4273
4298
|
try {
|
|
4274
4299
|
if (!existsSync6(READS_FILE)) return {};
|
|
@@ -4486,6 +4511,7 @@ async function runReadThread(opts = {}) {
|
|
|
4486
4511
|
resolveConnection = defaultResolveConnection,
|
|
4487
4512
|
writeCursor = writeReadCursor,
|
|
4488
4513
|
syncCursor = postReadCursor,
|
|
4514
|
+
syncBadge = syncUnreadBadge,
|
|
4489
4515
|
ensureDisclosure = ensureChatDisclosure
|
|
4490
4516
|
} = opts;
|
|
4491
4517
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
@@ -4532,6 +4558,7 @@ async function runReadThread(opts = {}) {
|
|
|
4532
4558
|
} catch {
|
|
4533
4559
|
}
|
|
4534
4560
|
await syncCursor(peerLogin, newest.createdAt);
|
|
4561
|
+
await syncBadge();
|
|
4535
4562
|
}
|
|
4536
4563
|
}
|
|
4537
4564
|
return { ok: true, shown: shownMessages.length, total };
|
|
@@ -4579,7 +4606,7 @@ async function runSend(opts = {}) {
|
|
|
4579
4606
|
);
|
|
4580
4607
|
return { ok: true };
|
|
4581
4608
|
}
|
|
4582
|
-
var CHAT_BASE3, GH_SESSION_COOKIE3, TERMINALHIRE_DIR5, READS_FILE;
|
|
4609
|
+
var CHAT_BASE3, GH_SESSION_COOKIE3, TERMINALHIRE_DIR5, READS_FILE, INDEX_CACHE_FILE;
|
|
4583
4610
|
var init_jpi_chat_read = __esm({
|
|
4584
4611
|
"bin/jpi-chat-read.js"() {
|
|
4585
4612
|
init_chat_client();
|
|
@@ -4589,6 +4616,7 @@ var init_jpi_chat_read = __esm({
|
|
|
4589
4616
|
GH_SESSION_COOKIE3 = "__jpi_gh_session";
|
|
4590
4617
|
TERMINALHIRE_DIR5 = join7(homedir6(), ".terminalhire");
|
|
4591
4618
|
READS_FILE = join7(TERMINALHIRE_DIR5, "chat-reads.json");
|
|
4619
|
+
INDEX_CACHE_FILE = join7(TERMINALHIRE_DIR5, "index-cache.json");
|
|
4592
4620
|
}
|
|
4593
4621
|
});
|
|
4594
4622
|
init_jpi_chat_read();
|
|
@@ -4602,6 +4630,7 @@ export {
|
|
|
4602
4630
|
runInbox,
|
|
4603
4631
|
runReadThread,
|
|
4604
4632
|
runSend,
|
|
4633
|
+
syncUnreadBadge,
|
|
4605
4634
|
writeReadCursor
|
|
4606
4635
|
};
|
|
4607
4636
|
/*! Bundled license information:
|
package/dist/bin/jpi-chat.js
CHANGED
|
@@ -4174,11 +4174,37 @@ __export(jpi_chat_read_exports, {
|
|
|
4174
4174
|
runInbox: () => runInbox,
|
|
4175
4175
|
runReadThread: () => runReadThread,
|
|
4176
4176
|
runSend: () => runSend,
|
|
4177
|
+
syncUnreadBadge: () => syncUnreadBadge,
|
|
4177
4178
|
writeReadCursor: () => writeReadCursor
|
|
4178
4179
|
});
|
|
4179
4180
|
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
4180
4181
|
import { homedir as homedir6 } from "os";
|
|
4181
4182
|
import { join as join7 } from "path";
|
|
4183
|
+
async function syncUnreadBadge(deps = {}) {
|
|
4184
|
+
const readCookie = deps.readCookie ?? readWebSessionCookie;
|
|
4185
|
+
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
4186
|
+
const cacheFile = deps.cacheFile ?? INDEX_CACHE_FILE;
|
|
4187
|
+
try {
|
|
4188
|
+
const cookie = readCookie();
|
|
4189
|
+
if (!cookie || !existsSync6(cacheFile)) return;
|
|
4190
|
+
const res = await fetchImpl(`${CHAT_BASE2}/api/chat/inbox`, {
|
|
4191
|
+
method: "GET",
|
|
4192
|
+
headers: { Cookie: `${GH_SESSION_COOKIE2}=${cookie}` },
|
|
4193
|
+
signal: AbortSignal.timeout(2500)
|
|
4194
|
+
});
|
|
4195
|
+
if (!res.ok) return;
|
|
4196
|
+
const body = await res.json();
|
|
4197
|
+
const inbox = Array.isArray(body?.inbox) ? body.inbox : [];
|
|
4198
|
+
const total = inbox.reduce(
|
|
4199
|
+
(sum, it) => sum + (it && typeof it.unreadCount === "number" && it.unreadCount > 0 ? it.unreadCount : 0),
|
|
4200
|
+
0
|
|
4201
|
+
);
|
|
4202
|
+
const entry = JSON.parse(readFileSync7(cacheFile, "utf8"));
|
|
4203
|
+
entry.unreadChat = { count: total };
|
|
4204
|
+
writeFileSync6(cacheFile, JSON.stringify(entry), "utf8");
|
|
4205
|
+
} catch {
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4182
4208
|
function readReadCursors() {
|
|
4183
4209
|
try {
|
|
4184
4210
|
if (!existsSync6(READS_FILE)) return {};
|
|
@@ -4396,6 +4422,7 @@ async function runReadThread(opts = {}) {
|
|
|
4396
4422
|
resolveConnection = defaultResolveConnection,
|
|
4397
4423
|
writeCursor = writeReadCursor,
|
|
4398
4424
|
syncCursor = postReadCursor,
|
|
4425
|
+
syncBadge = syncUnreadBadge,
|
|
4399
4426
|
ensureDisclosure = ensureChatDisclosure
|
|
4400
4427
|
} = opts;
|
|
4401
4428
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
@@ -4442,6 +4469,7 @@ async function runReadThread(opts = {}) {
|
|
|
4442
4469
|
} catch {
|
|
4443
4470
|
}
|
|
4444
4471
|
await syncCursor(peerLogin, newest.createdAt);
|
|
4472
|
+
await syncBadge();
|
|
4445
4473
|
}
|
|
4446
4474
|
}
|
|
4447
4475
|
return { ok: true, shown: shownMessages.length, total };
|
|
@@ -4489,7 +4517,7 @@ async function runSend(opts = {}) {
|
|
|
4489
4517
|
);
|
|
4490
4518
|
return { ok: true };
|
|
4491
4519
|
}
|
|
4492
|
-
var CHAT_BASE2, GH_SESSION_COOKIE2, TERMINALHIRE_DIR5, READS_FILE;
|
|
4520
|
+
var CHAT_BASE2, GH_SESSION_COOKIE2, TERMINALHIRE_DIR5, READS_FILE, INDEX_CACHE_FILE;
|
|
4493
4521
|
var init_jpi_chat_read = __esm({
|
|
4494
4522
|
"bin/jpi-chat-read.js"() {
|
|
4495
4523
|
"use strict";
|
|
@@ -4500,6 +4528,7 @@ var init_jpi_chat_read = __esm({
|
|
|
4500
4528
|
GH_SESSION_COOKIE2 = "__jpi_gh_session";
|
|
4501
4529
|
TERMINALHIRE_DIR5 = join7(homedir6(), ".terminalhire");
|
|
4502
4530
|
READS_FILE = join7(TERMINALHIRE_DIR5, "chat-reads.json");
|
|
4531
|
+
INDEX_CACHE_FILE = join7(TERMINALHIRE_DIR5, "index-cache.json");
|
|
4503
4532
|
}
|
|
4504
4533
|
});
|
|
4505
4534
|
|
package/dist/bin/jpi-dispatch.js
CHANGED
|
@@ -10296,11 +10296,37 @@ __export(jpi_chat_read_exports, {
|
|
|
10296
10296
|
runInbox: () => runInbox,
|
|
10297
10297
|
runReadThread: () => runReadThread,
|
|
10298
10298
|
runSend: () => runSend,
|
|
10299
|
+
syncUnreadBadge: () => syncUnreadBadge,
|
|
10299
10300
|
writeReadCursor: () => writeReadCursor
|
|
10300
10301
|
});
|
|
10301
10302
|
import { existsSync as existsSync12, mkdirSync as mkdirSync13, readFileSync as readFileSync16, writeFileSync as writeFileSync13 } from "fs";
|
|
10302
10303
|
import { homedir as homedir15 } from "os";
|
|
10303
10304
|
import { join as join16 } from "path";
|
|
10305
|
+
async function syncUnreadBadge(deps = {}) {
|
|
10306
|
+
const readCookie = deps.readCookie ?? readWebSessionCookie;
|
|
10307
|
+
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
10308
|
+
const cacheFile = deps.cacheFile ?? INDEX_CACHE_FILE5;
|
|
10309
|
+
try {
|
|
10310
|
+
const cookie = readCookie();
|
|
10311
|
+
if (!cookie || !existsSync12(cacheFile)) return;
|
|
10312
|
+
const res = await fetchImpl(`${CHAT_BASE2}/api/chat/inbox`, {
|
|
10313
|
+
method: "GET",
|
|
10314
|
+
headers: { Cookie: `${GH_SESSION_COOKIE4}=${cookie}` },
|
|
10315
|
+
signal: AbortSignal.timeout(2500)
|
|
10316
|
+
});
|
|
10317
|
+
if (!res.ok) return;
|
|
10318
|
+
const body = await res.json();
|
|
10319
|
+
const inbox = Array.isArray(body?.inbox) ? body.inbox : [];
|
|
10320
|
+
const total = inbox.reduce(
|
|
10321
|
+
(sum, it) => sum + (it && typeof it.unreadCount === "number" && it.unreadCount > 0 ? it.unreadCount : 0),
|
|
10322
|
+
0
|
|
10323
|
+
);
|
|
10324
|
+
const entry = JSON.parse(readFileSync16(cacheFile, "utf8"));
|
|
10325
|
+
entry.unreadChat = { count: total };
|
|
10326
|
+
writeFileSync13(cacheFile, JSON.stringify(entry), "utf8");
|
|
10327
|
+
} catch {
|
|
10328
|
+
}
|
|
10329
|
+
}
|
|
10304
10330
|
function readReadCursors() {
|
|
10305
10331
|
try {
|
|
10306
10332
|
if (!existsSync12(READS_FILE)) return {};
|
|
@@ -10518,6 +10544,7 @@ async function runReadThread(opts = {}) {
|
|
|
10518
10544
|
resolveConnection = defaultResolveConnection,
|
|
10519
10545
|
writeCursor = writeReadCursor,
|
|
10520
10546
|
syncCursor = postReadCursor,
|
|
10547
|
+
syncBadge = syncUnreadBadge,
|
|
10521
10548
|
ensureDisclosure = ensureChatDisclosure
|
|
10522
10549
|
} = opts;
|
|
10523
10550
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
@@ -10564,6 +10591,7 @@ async function runReadThread(opts = {}) {
|
|
|
10564
10591
|
} catch {
|
|
10565
10592
|
}
|
|
10566
10593
|
await syncCursor(peerLogin, newest.createdAt);
|
|
10594
|
+
await syncBadge();
|
|
10567
10595
|
}
|
|
10568
10596
|
}
|
|
10569
10597
|
return { ok: true, shown: shownMessages.length, total };
|
|
@@ -10611,7 +10639,7 @@ async function runSend(opts = {}) {
|
|
|
10611
10639
|
);
|
|
10612
10640
|
return { ok: true };
|
|
10613
10641
|
}
|
|
10614
|
-
var CHAT_BASE2, GH_SESSION_COOKIE4, TERMINALHIRE_DIR12, READS_FILE;
|
|
10642
|
+
var CHAT_BASE2, GH_SESSION_COOKIE4, TERMINALHIRE_DIR12, READS_FILE, INDEX_CACHE_FILE5;
|
|
10615
10643
|
var init_jpi_chat_read = __esm({
|
|
10616
10644
|
"bin/jpi-chat-read.js"() {
|
|
10617
10645
|
"use strict";
|
|
@@ -10622,6 +10650,7 @@ var init_jpi_chat_read = __esm({
|
|
|
10622
10650
|
GH_SESSION_COOKIE4 = "__jpi_gh_session";
|
|
10623
10651
|
TERMINALHIRE_DIR12 = join16(homedir15(), ".terminalhire");
|
|
10624
10652
|
READS_FILE = join16(TERMINALHIRE_DIR12, "chat-reads.json");
|
|
10653
|
+
INDEX_CACHE_FILE5 = join16(TERMINALHIRE_DIR12, "index-cache.json");
|
|
10625
10654
|
}
|
|
10626
10655
|
});
|
|
10627
10656
|
|
|
@@ -13090,6 +13119,8 @@ async function run18() {
|
|
|
13090
13119
|
} catch {
|
|
13091
13120
|
}
|
|
13092
13121
|
let incomingPending = { count: 0 };
|
|
13122
|
+
let sessionStale = false;
|
|
13123
|
+
const sessionExpired = (res) => res.status === 401;
|
|
13093
13124
|
const sessionCookie = readWebSessionFile();
|
|
13094
13125
|
if (sessionCookie && !isInboundNudgeMuted()) try {
|
|
13095
13126
|
const res = await fetch(`${API_URL6}/api/intro/list`, {
|
|
@@ -13102,6 +13133,8 @@ async function run18() {
|
|
|
13102
13133
|
const intros = Array.isArray(body?.intros) ? body.intros : [];
|
|
13103
13134
|
const incoming = intros.filter((it) => it && it.role === "incoming" && it.status === "pending");
|
|
13104
13135
|
incomingPending = { count: incoming.length };
|
|
13136
|
+
} else if (sessionExpired(res)) {
|
|
13137
|
+
sessionStale = true;
|
|
13105
13138
|
}
|
|
13106
13139
|
} catch {
|
|
13107
13140
|
}
|
|
@@ -13120,6 +13153,8 @@ async function run18() {
|
|
|
13120
13153
|
0
|
|
13121
13154
|
);
|
|
13122
13155
|
unreadChat = { count: total };
|
|
13156
|
+
} else if (sessionExpired(res)) {
|
|
13157
|
+
sessionStale = true;
|
|
13123
13158
|
}
|
|
13124
13159
|
} catch {
|
|
13125
13160
|
}
|
|
@@ -13131,9 +13166,10 @@ async function run18() {
|
|
|
13131
13166
|
topMatches,
|
|
13132
13167
|
topPeers,
|
|
13133
13168
|
incomingPending,
|
|
13134
|
-
unreadChat
|
|
13169
|
+
unreadChat,
|
|
13170
|
+
sessionStale
|
|
13135
13171
|
};
|
|
13136
|
-
writeFileSync17(
|
|
13172
|
+
writeFileSync17(INDEX_CACHE_FILE6, JSON.stringify(cacheEntry), "utf8");
|
|
13137
13173
|
try {
|
|
13138
13174
|
const {
|
|
13139
13175
|
readSpinnerConfig: readSpinnerConfig2,
|
|
@@ -13184,7 +13220,7 @@ async function run18() {
|
|
|
13184
13220
|
process.exit(1);
|
|
13185
13221
|
}
|
|
13186
13222
|
}
|
|
13187
|
-
var GH_SESSION_COOKIE7, __dirname4, TERMINALHIRE_DIR14,
|
|
13223
|
+
var GH_SESSION_COOKIE7, __dirname4, TERMINALHIRE_DIR14, INDEX_CACHE_FILE6, API_URL6;
|
|
13188
13224
|
var init_jpi_refresh = __esm({
|
|
13189
13225
|
"bin/jpi-refresh.js"() {
|
|
13190
13226
|
"use strict";
|
|
@@ -13194,8 +13230,8 @@ var init_jpi_refresh = __esm({
|
|
|
13194
13230
|
GH_SESSION_COOKIE7 = "__jpi_gh_session";
|
|
13195
13231
|
__dirname4 = fileURLToPath5(new URL(".", import.meta.url));
|
|
13196
13232
|
TERMINALHIRE_DIR14 = join23(homedir21(), ".terminalhire");
|
|
13197
|
-
|
|
13198
|
-
API_URL6 = process.env["TERMINALHIRE_API_URL"] ?? process.env["JPI_API_URL"] ?? "https://terminalhire.com";
|
|
13233
|
+
INDEX_CACHE_FILE6 = join23(TERMINALHIRE_DIR14, "index-cache.json");
|
|
13234
|
+
API_URL6 = process.env["TERMINALHIRE_API_URL"] ?? process.env["JPI_API_URL"] ?? "https://www.terminalhire.com";
|
|
13199
13235
|
}
|
|
13200
13236
|
});
|
|
13201
13237
|
|
|
@@ -13210,8 +13246,8 @@ import { homedir as homedir22 } from "os";
|
|
|
13210
13246
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
13211
13247
|
function findJobInCache(jobId) {
|
|
13212
13248
|
try {
|
|
13213
|
-
if (!existsSync18(
|
|
13214
|
-
const raw = readFileSync22(
|
|
13249
|
+
if (!existsSync18(INDEX_CACHE_FILE7)) return null;
|
|
13250
|
+
const raw = readFileSync22(INDEX_CACHE_FILE7, "utf8");
|
|
13215
13251
|
const entry = JSON.parse(raw);
|
|
13216
13252
|
const jobs = entry?.index?.jobs ?? [];
|
|
13217
13253
|
return jobs.find((j) => j.id === jobId) ?? null;
|
|
@@ -13299,13 +13335,13 @@ async function run19() {
|
|
|
13299
13335
|
process.exit(1);
|
|
13300
13336
|
}
|
|
13301
13337
|
}
|
|
13302
|
-
var __dirname5, TERMINALHIRE_DIR15,
|
|
13338
|
+
var __dirname5, TERMINALHIRE_DIR15, INDEX_CACHE_FILE7;
|
|
13303
13339
|
var init_jpi_save = __esm({
|
|
13304
13340
|
"bin/jpi-save.js"() {
|
|
13305
13341
|
"use strict";
|
|
13306
13342
|
__dirname5 = fileURLToPath6(new URL(".", import.meta.url));
|
|
13307
13343
|
TERMINALHIRE_DIR15 = join24(homedir22(), ".terminalhire");
|
|
13308
|
-
|
|
13344
|
+
INDEX_CACHE_FILE7 = join24(TERMINALHIRE_DIR15, "index-cache.json");
|
|
13309
13345
|
}
|
|
13310
13346
|
});
|
|
13311
13347
|
|
package/dist/bin/jpi-refresh.js
CHANGED
|
@@ -6980,7 +6980,7 @@ var GH_SESSION_COOKIE = "__jpi_gh_session";
|
|
|
6980
6980
|
var __dirname2 = fileURLToPath3(new URL(".", import.meta.url));
|
|
6981
6981
|
var TERMINALHIRE_DIR4 = join9(homedir7(), ".terminalhire");
|
|
6982
6982
|
var INDEX_CACHE_FILE2 = join9(TERMINALHIRE_DIR4, "index-cache.json");
|
|
6983
|
-
var API_URL2 = process.env["TERMINALHIRE_API_URL"] ?? process.env["JPI_API_URL"] ?? "https://terminalhire.com";
|
|
6983
|
+
var API_URL2 = process.env["TERMINALHIRE_API_URL"] ?? process.env["JPI_API_URL"] ?? "https://www.terminalhire.com";
|
|
6984
6984
|
async function run() {
|
|
6985
6985
|
try {
|
|
6986
6986
|
let index;
|
|
@@ -7079,6 +7079,8 @@ async function run() {
|
|
|
7079
7079
|
} catch {
|
|
7080
7080
|
}
|
|
7081
7081
|
let incomingPending = { count: 0 };
|
|
7082
|
+
let sessionStale = false;
|
|
7083
|
+
const sessionExpired = (res) => res.status === 401;
|
|
7082
7084
|
const sessionCookie = readWebSessionFile();
|
|
7083
7085
|
if (sessionCookie && !isInboundNudgeMuted()) try {
|
|
7084
7086
|
const res = await fetch(`${API_URL2}/api/intro/list`, {
|
|
@@ -7091,6 +7093,8 @@ async function run() {
|
|
|
7091
7093
|
const intros = Array.isArray(body?.intros) ? body.intros : [];
|
|
7092
7094
|
const incoming = intros.filter((it) => it && it.role === "incoming" && it.status === "pending");
|
|
7093
7095
|
incomingPending = { count: incoming.length };
|
|
7096
|
+
} else if (sessionExpired(res)) {
|
|
7097
|
+
sessionStale = true;
|
|
7094
7098
|
}
|
|
7095
7099
|
} catch {
|
|
7096
7100
|
}
|
|
@@ -7109,6 +7113,8 @@ async function run() {
|
|
|
7109
7113
|
0
|
|
7110
7114
|
);
|
|
7111
7115
|
unreadChat = { count: total };
|
|
7116
|
+
} else if (sessionExpired(res)) {
|
|
7117
|
+
sessionStale = true;
|
|
7112
7118
|
}
|
|
7113
7119
|
} catch {
|
|
7114
7120
|
}
|
|
@@ -7120,7 +7126,8 @@ async function run() {
|
|
|
7120
7126
|
topMatches,
|
|
7121
7127
|
topPeers,
|
|
7122
7128
|
incomingPending,
|
|
7123
|
-
unreadChat
|
|
7129
|
+
unreadChat,
|
|
7130
|
+
sessionStale
|
|
7124
7131
|
};
|
|
7125
7132
|
writeFileSync6(INDEX_CACHE_FILE2, JSON.stringify(cacheEntry), "utf8");
|
|
7126
7133
|
try {
|
package/dist/bin/jpi.js
CHANGED
|
@@ -105,6 +105,16 @@ function getCachedUnreadChatCount() {
|
|
|
105
105
|
return 0;
|
|
106
106
|
}
|
|
107
107
|
}
|
|
108
|
+
function getCachedSessionStale() {
|
|
109
|
+
try {
|
|
110
|
+
const raw = readFileSync(INDEX_CACHE_FILE, "utf8");
|
|
111
|
+
const entry = JSON.parse(raw);
|
|
112
|
+
if (Date.now() - entry.ts > INDEX_CACHE_TTL_MS) return false;
|
|
113
|
+
return entry.sessionStale === true;
|
|
114
|
+
} catch {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
108
118
|
function getNudgeMode() {
|
|
109
119
|
const envVal = process.env["TERMINALHIRE_NUDGE"];
|
|
110
120
|
if (envVal) {
|
|
@@ -178,9 +188,10 @@ try {
|
|
|
178
188
|
const matchCount = getCachedMatchCount();
|
|
179
189
|
const incomingCount = getCachedIncomingCount();
|
|
180
190
|
const unreadChatCount = getCachedUnreadChatCount();
|
|
191
|
+
const sessionStale = getCachedSessionStale() && incomingCount === 0 && unreadChatCount === 0;
|
|
181
192
|
const haveRoles = matchCount !== null && matchCount > 0;
|
|
182
|
-
if (!haveRoles && incomingCount === 0 && unreadChatCount === 0) process.exit(0);
|
|
183
|
-
const hasConnectionSignal = incomingCount > 0 || unreadChatCount > 0;
|
|
193
|
+
if (!haveRoles && incomingCount === 0 && unreadChatCount === 0 && !sessionStale) process.exit(0);
|
|
194
|
+
const hasConnectionSignal = incomingCount > 0 || unreadChatCount > 0 || sessionStale;
|
|
184
195
|
const nudgeMode = getNudgeMode();
|
|
185
196
|
if (!hasConnectionSignal && !shouldNudge(nudgeMode, sessionId)) process.exit(0);
|
|
186
197
|
let line;
|
|
@@ -189,11 +200,14 @@ try {
|
|
|
189
200
|
line = `\u2726 ${matchCount} ${plural} match your current work \u2014 run: terminalhire jobs`;
|
|
190
201
|
if (incomingCount > 0) line += ` \xB7 \u2709 ${incomingCount} waiting to connect`;
|
|
191
202
|
if (unreadChatCount > 0) line += ` \xB7 \u{1F4AC} ${unreadChatCount} unread`;
|
|
203
|
+
if (sessionStale) line += ` \xB7 \u26A0 session expired \u2014 run: terminalhire link`;
|
|
192
204
|
} else if (incomingCount > 0) {
|
|
193
205
|
line = `\u2709 ${incomingCount} waiting to connect \u2014 run: terminalhire intro --list`;
|
|
194
206
|
if (unreadChatCount > 0) line += ` \xB7 \u{1F4AC} ${unreadChatCount} unread`;
|
|
195
|
-
} else {
|
|
207
|
+
} else if (unreadChatCount > 0) {
|
|
196
208
|
line = `\u{1F4AC} ${unreadChatCount} unread \u2014 run: terminalhire chat`;
|
|
209
|
+
} else {
|
|
210
|
+
line = `\u26A0 terminalhire session expired \u2014 run: terminalhire link to restore your connection signals`;
|
|
197
211
|
}
|
|
198
212
|
process.stdout.write(line + "\n");
|
|
199
213
|
if (haveRoles && nudgeMode === "session") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "terminalhire",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.9",
|
|
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",
|