terminalhire 0.10.8 → 0.10.10
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 +55 -4
- package/dist/bin/jpi-chat.js +56 -4
- package/dist/bin/jpi-dispatch.js +63 -11
- package/package.json +1 -1
|
@@ -4245,6 +4245,12 @@ async function defaultListConnections(deps = {}) {
|
|
|
4245
4245
|
const connections = listed.intros.filter((it) => it && it.status === "accepted" && it.counterpartyLogin).map((it) => ({ introId: it.id, peerLogin: it.counterpartyLogin }));
|
|
4246
4246
|
return { status: "ok", connections };
|
|
4247
4247
|
}
|
|
4248
|
+
async function defaultListPendingInvites(deps = {}) {
|
|
4249
|
+
const listed = await fetchIntroList(deps);
|
|
4250
|
+
if (listed.status !== "ok") return listed;
|
|
4251
|
+
const invites = listed.intros.filter((it) => it && it.role === "incoming" && it.status === "pending" && it.counterpartyLogin).map((it) => ({ login: it.counterpartyLogin }));
|
|
4252
|
+
return { status: "ok", invites };
|
|
4253
|
+
}
|
|
4248
4254
|
var CHAT_BASE2, GH_SESSION_COOKIE2, ANSI_CSI, ANSI_OSC, ANSI_OTHER, C0_C1_DEL, CHAT_DISCLOSURE, CHAT_AT_REST, CHAT_CODE_OF_CONDUCT, CHAT_MIN_AGE;
|
|
4249
4255
|
var init_jpi_chat = __esm({
|
|
4250
4256
|
"bin/jpi-chat.js"() {
|
|
@@ -4269,6 +4275,31 @@ var init_jpi_chat = __esm({
|
|
|
4269
4275
|
import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
|
|
4270
4276
|
import { homedir as homedir6 } from "os";
|
|
4271
4277
|
import { join as join7 } from "path";
|
|
4278
|
+
async function syncUnreadBadge(deps = {}) {
|
|
4279
|
+
const readCookie = deps.readCookie ?? readWebSessionCookie;
|
|
4280
|
+
const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
|
|
4281
|
+
const cacheFile = deps.cacheFile ?? INDEX_CACHE_FILE;
|
|
4282
|
+
try {
|
|
4283
|
+
const cookie = readCookie();
|
|
4284
|
+
if (!cookie || !existsSync6(cacheFile)) return;
|
|
4285
|
+
const res = await fetchImpl(`${CHAT_BASE3}/api/chat/inbox`, {
|
|
4286
|
+
method: "GET",
|
|
4287
|
+
headers: { Cookie: `${GH_SESSION_COOKIE3}=${cookie}` },
|
|
4288
|
+
signal: AbortSignal.timeout(2500)
|
|
4289
|
+
});
|
|
4290
|
+
if (!res.ok) return;
|
|
4291
|
+
const body = await res.json();
|
|
4292
|
+
const inbox = Array.isArray(body?.inbox) ? body.inbox : [];
|
|
4293
|
+
const total = inbox.reduce(
|
|
4294
|
+
(sum, it) => sum + (it && typeof it.unreadCount === "number" && it.unreadCount > 0 ? it.unreadCount : 0),
|
|
4295
|
+
0
|
|
4296
|
+
);
|
|
4297
|
+
const entry = JSON.parse(readFileSync7(cacheFile, "utf8"));
|
|
4298
|
+
entry.unreadChat = { count: total };
|
|
4299
|
+
writeFileSync6(cacheFile, JSON.stringify(entry), "utf8");
|
|
4300
|
+
} catch {
|
|
4301
|
+
}
|
|
4302
|
+
}
|
|
4272
4303
|
function readReadCursors() {
|
|
4273
4304
|
try {
|
|
4274
4305
|
if (!existsSync6(READS_FILE)) return {};
|
|
@@ -4328,10 +4359,19 @@ function truncate(s, n) {
|
|
|
4328
4359
|
const t = String(s);
|
|
4329
4360
|
return t.length <= n ? t : `${t.slice(0, n - 1)}\u2026`;
|
|
4330
4361
|
}
|
|
4331
|
-
function renderInbox(items) {
|
|
4362
|
+
function renderInbox(items, invites = []) {
|
|
4332
4363
|
const lines = [];
|
|
4333
4364
|
lines.push(" connections \xB7 terminalhire chat");
|
|
4334
4365
|
lines.push(" " + "\u2500".repeat(64));
|
|
4366
|
+
if (invites && invites.length > 0) {
|
|
4367
|
+
lines.push(` PENDING INVITATIONS (${invites.length})`);
|
|
4368
|
+
for (const iv of invites) {
|
|
4369
|
+
const login = sanitizeLine(iv.login);
|
|
4370
|
+
const handle = `@${login}`;
|
|
4371
|
+
lines.push(` \u2198 ${handle.padEnd(18)} wants to connect \xB7 terminalhire intro --accept ${handle}`);
|
|
4372
|
+
}
|
|
4373
|
+
lines.push(" " + "\u2500".repeat(64));
|
|
4374
|
+
}
|
|
4335
4375
|
if (!items || items.length === 0) {
|
|
4336
4376
|
lines.push(" (no accepted connections yet \u2014 request one: terminalhire intro <login>)");
|
|
4337
4377
|
} else {
|
|
@@ -4438,6 +4478,7 @@ async function runInbox(opts = {}) {
|
|
|
4438
4478
|
input = process.stdin,
|
|
4439
4479
|
client = createChatClient(),
|
|
4440
4480
|
listConnections = defaultListConnections,
|
|
4481
|
+
listInvites = defaultListPendingInvites,
|
|
4441
4482
|
readCursors = readReadCursors,
|
|
4442
4483
|
ensureDisclosure = ensureChatDisclosure
|
|
4443
4484
|
} = opts;
|
|
@@ -4448,6 +4489,12 @@ async function runInbox(opts = {}) {
|
|
|
4448
4489
|
if (listed.status !== "ok") {
|
|
4449
4490
|
return { ok: false, reason: writeProblem(output, listed, "") };
|
|
4450
4491
|
}
|
|
4492
|
+
let invites = [];
|
|
4493
|
+
try {
|
|
4494
|
+
const inv = await listInvites();
|
|
4495
|
+
if (inv && inv.status === "ok") invites = inv.invites;
|
|
4496
|
+
} catch {
|
|
4497
|
+
}
|
|
4451
4498
|
const cursors = readCursors();
|
|
4452
4499
|
const items = [];
|
|
4453
4500
|
for (const conn of listed.connections) {
|
|
@@ -4472,8 +4519,8 @@ async function runInbox(opts = {}) {
|
|
|
4472
4519
|
});
|
|
4473
4520
|
}
|
|
4474
4521
|
await clearPresence(client);
|
|
4475
|
-
output.write(renderInbox(items));
|
|
4476
|
-
return { ok: true, count: items.length };
|
|
4522
|
+
output.write(renderInbox(items, invites));
|
|
4523
|
+
return { ok: true, count: items.length, invites: invites.length };
|
|
4477
4524
|
}
|
|
4478
4525
|
async function runReadThread(opts = {}) {
|
|
4479
4526
|
const {
|
|
@@ -4486,6 +4533,7 @@ async function runReadThread(opts = {}) {
|
|
|
4486
4533
|
resolveConnection = defaultResolveConnection,
|
|
4487
4534
|
writeCursor = writeReadCursor,
|
|
4488
4535
|
syncCursor = postReadCursor,
|
|
4536
|
+
syncBadge = syncUnreadBadge,
|
|
4489
4537
|
ensureDisclosure = ensureChatDisclosure
|
|
4490
4538
|
} = opts;
|
|
4491
4539
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
@@ -4532,6 +4580,7 @@ async function runReadThread(opts = {}) {
|
|
|
4532
4580
|
} catch {
|
|
4533
4581
|
}
|
|
4534
4582
|
await syncCursor(peerLogin, newest.createdAt);
|
|
4583
|
+
await syncBadge();
|
|
4535
4584
|
}
|
|
4536
4585
|
}
|
|
4537
4586
|
return { ok: true, shown: shownMessages.length, total };
|
|
@@ -4579,7 +4628,7 @@ async function runSend(opts = {}) {
|
|
|
4579
4628
|
);
|
|
4580
4629
|
return { ok: true };
|
|
4581
4630
|
}
|
|
4582
|
-
var CHAT_BASE3, GH_SESSION_COOKIE3, TERMINALHIRE_DIR5, READS_FILE;
|
|
4631
|
+
var CHAT_BASE3, GH_SESSION_COOKIE3, TERMINALHIRE_DIR5, READS_FILE, INDEX_CACHE_FILE;
|
|
4583
4632
|
var init_jpi_chat_read = __esm({
|
|
4584
4633
|
"bin/jpi-chat-read.js"() {
|
|
4585
4634
|
init_chat_client();
|
|
@@ -4589,6 +4638,7 @@ var init_jpi_chat_read = __esm({
|
|
|
4589
4638
|
GH_SESSION_COOKIE3 = "__jpi_gh_session";
|
|
4590
4639
|
TERMINALHIRE_DIR5 = join7(homedir6(), ".terminalhire");
|
|
4591
4640
|
READS_FILE = join7(TERMINALHIRE_DIR5, "chat-reads.json");
|
|
4641
|
+
INDEX_CACHE_FILE = join7(TERMINALHIRE_DIR5, "index-cache.json");
|
|
4592
4642
|
}
|
|
4593
4643
|
});
|
|
4594
4644
|
init_jpi_chat_read();
|
|
@@ -4602,6 +4652,7 @@ export {
|
|
|
4602
4652
|
runInbox,
|
|
4603
4653
|
runReadThread,
|
|
4604
4654
|
runSend,
|
|
4655
|
+
syncUnreadBadge,
|
|
4605
4656
|
writeReadCursor
|
|
4606
4657
|
};
|
|
4607
4658
|
/*! 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 {};
|
|
@@ -4238,10 +4264,19 @@ function truncate(s, n) {
|
|
|
4238
4264
|
const t = String(s);
|
|
4239
4265
|
return t.length <= n ? t : `${t.slice(0, n - 1)}\u2026`;
|
|
4240
4266
|
}
|
|
4241
|
-
function renderInbox(items) {
|
|
4267
|
+
function renderInbox(items, invites = []) {
|
|
4242
4268
|
const lines = [];
|
|
4243
4269
|
lines.push(" connections \xB7 terminalhire chat");
|
|
4244
4270
|
lines.push(" " + "\u2500".repeat(64));
|
|
4271
|
+
if (invites && invites.length > 0) {
|
|
4272
|
+
lines.push(` PENDING INVITATIONS (${invites.length})`);
|
|
4273
|
+
for (const iv of invites) {
|
|
4274
|
+
const login = sanitizeLine(iv.login);
|
|
4275
|
+
const handle = `@${login}`;
|
|
4276
|
+
lines.push(` \u2198 ${handle.padEnd(18)} wants to connect \xB7 terminalhire intro --accept ${handle}`);
|
|
4277
|
+
}
|
|
4278
|
+
lines.push(" " + "\u2500".repeat(64));
|
|
4279
|
+
}
|
|
4245
4280
|
if (!items || items.length === 0) {
|
|
4246
4281
|
lines.push(" (no accepted connections yet \u2014 request one: terminalhire intro <login>)");
|
|
4247
4282
|
} else {
|
|
@@ -4348,6 +4383,7 @@ async function runInbox(opts = {}) {
|
|
|
4348
4383
|
input = process.stdin,
|
|
4349
4384
|
client = createChatClient(),
|
|
4350
4385
|
listConnections = defaultListConnections,
|
|
4386
|
+
listInvites = defaultListPendingInvites,
|
|
4351
4387
|
readCursors = readReadCursors,
|
|
4352
4388
|
ensureDisclosure = ensureChatDisclosure
|
|
4353
4389
|
} = opts;
|
|
@@ -4358,6 +4394,12 @@ async function runInbox(opts = {}) {
|
|
|
4358
4394
|
if (listed.status !== "ok") {
|
|
4359
4395
|
return { ok: false, reason: writeProblem(output, listed, "") };
|
|
4360
4396
|
}
|
|
4397
|
+
let invites = [];
|
|
4398
|
+
try {
|
|
4399
|
+
const inv = await listInvites();
|
|
4400
|
+
if (inv && inv.status === "ok") invites = inv.invites;
|
|
4401
|
+
} catch {
|
|
4402
|
+
}
|
|
4361
4403
|
const cursors = readCursors();
|
|
4362
4404
|
const items = [];
|
|
4363
4405
|
for (const conn of listed.connections) {
|
|
@@ -4382,8 +4424,8 @@ async function runInbox(opts = {}) {
|
|
|
4382
4424
|
});
|
|
4383
4425
|
}
|
|
4384
4426
|
await clearPresence(client);
|
|
4385
|
-
output.write(renderInbox(items));
|
|
4386
|
-
return { ok: true, count: items.length };
|
|
4427
|
+
output.write(renderInbox(items, invites));
|
|
4428
|
+
return { ok: true, count: items.length, invites: invites.length };
|
|
4387
4429
|
}
|
|
4388
4430
|
async function runReadThread(opts = {}) {
|
|
4389
4431
|
const {
|
|
@@ -4396,6 +4438,7 @@ async function runReadThread(opts = {}) {
|
|
|
4396
4438
|
resolveConnection = defaultResolveConnection,
|
|
4397
4439
|
writeCursor = writeReadCursor,
|
|
4398
4440
|
syncCursor = postReadCursor,
|
|
4441
|
+
syncBadge = syncUnreadBadge,
|
|
4399
4442
|
ensureDisclosure = ensureChatDisclosure
|
|
4400
4443
|
} = opts;
|
|
4401
4444
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
@@ -4442,6 +4485,7 @@ async function runReadThread(opts = {}) {
|
|
|
4442
4485
|
} catch {
|
|
4443
4486
|
}
|
|
4444
4487
|
await syncCursor(peerLogin, newest.createdAt);
|
|
4488
|
+
await syncBadge();
|
|
4445
4489
|
}
|
|
4446
4490
|
}
|
|
4447
4491
|
return { ok: true, shown: shownMessages.length, total };
|
|
@@ -4489,7 +4533,7 @@ async function runSend(opts = {}) {
|
|
|
4489
4533
|
);
|
|
4490
4534
|
return { ok: true };
|
|
4491
4535
|
}
|
|
4492
|
-
var CHAT_BASE2, GH_SESSION_COOKIE2, TERMINALHIRE_DIR5, READS_FILE;
|
|
4536
|
+
var CHAT_BASE2, GH_SESSION_COOKIE2, TERMINALHIRE_DIR5, READS_FILE, INDEX_CACHE_FILE;
|
|
4493
4537
|
var init_jpi_chat_read = __esm({
|
|
4494
4538
|
"bin/jpi-chat-read.js"() {
|
|
4495
4539
|
"use strict";
|
|
@@ -4500,6 +4544,7 @@ var init_jpi_chat_read = __esm({
|
|
|
4500
4544
|
GH_SESSION_COOKIE2 = "__jpi_gh_session";
|
|
4501
4545
|
TERMINALHIRE_DIR5 = join7(homedir6(), ".terminalhire");
|
|
4502
4546
|
READS_FILE = join7(TERMINALHIRE_DIR5, "chat-reads.json");
|
|
4547
|
+
INDEX_CACHE_FILE = join7(TERMINALHIRE_DIR5, "index-cache.json");
|
|
4503
4548
|
}
|
|
4504
4549
|
});
|
|
4505
4550
|
|
|
@@ -4591,6 +4636,12 @@ async function defaultListConnections(deps = {}) {
|
|
|
4591
4636
|
const connections = listed.intros.filter((it) => it && it.status === "accepted" && it.counterpartyLogin).map((it) => ({ introId: it.id, peerLogin: it.counterpartyLogin }));
|
|
4592
4637
|
return { status: "ok", connections };
|
|
4593
4638
|
}
|
|
4639
|
+
async function defaultListPendingInvites(deps = {}) {
|
|
4640
|
+
const listed = await fetchIntroList(deps);
|
|
4641
|
+
if (listed.status !== "ok") return listed;
|
|
4642
|
+
const invites = listed.intros.filter((it) => it && it.role === "incoming" && it.status === "pending" && it.counterpartyLogin).map((it) => ({ login: it.counterpartyLogin }));
|
|
4643
|
+
return { status: "ok", invites };
|
|
4644
|
+
}
|
|
4594
4645
|
function formatThread(state) {
|
|
4595
4646
|
const { peerLogin, online, messages, inputBuffer, banner } = state;
|
|
4596
4647
|
const safePeer = sanitizeLine(peerLogin);
|
|
@@ -5139,6 +5190,7 @@ export {
|
|
|
5139
5190
|
CHAT_DISCLOSURE,
|
|
5140
5191
|
CHAT_MIN_AGE,
|
|
5141
5192
|
defaultListConnections,
|
|
5193
|
+
defaultListPendingInvites,
|
|
5142
5194
|
defaultResolveConnection,
|
|
5143
5195
|
ensureChatDisclosure,
|
|
5144
5196
|
formatThread,
|
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 {};
|
|
@@ -10360,10 +10386,19 @@ function truncate(s, n) {
|
|
|
10360
10386
|
const t = String(s);
|
|
10361
10387
|
return t.length <= n ? t : `${t.slice(0, n - 1)}\u2026`;
|
|
10362
10388
|
}
|
|
10363
|
-
function renderInbox(items) {
|
|
10389
|
+
function renderInbox(items, invites = []) {
|
|
10364
10390
|
const lines = [];
|
|
10365
10391
|
lines.push(" connections \xB7 terminalhire chat");
|
|
10366
10392
|
lines.push(" " + "\u2500".repeat(64));
|
|
10393
|
+
if (invites && invites.length > 0) {
|
|
10394
|
+
lines.push(` PENDING INVITATIONS (${invites.length})`);
|
|
10395
|
+
for (const iv of invites) {
|
|
10396
|
+
const login = sanitizeLine(iv.login);
|
|
10397
|
+
const handle = `@${login}`;
|
|
10398
|
+
lines.push(` \u2198 ${handle.padEnd(18)} wants to connect \xB7 terminalhire intro --accept ${handle}`);
|
|
10399
|
+
}
|
|
10400
|
+
lines.push(" " + "\u2500".repeat(64));
|
|
10401
|
+
}
|
|
10367
10402
|
if (!items || items.length === 0) {
|
|
10368
10403
|
lines.push(" (no accepted connections yet \u2014 request one: terminalhire intro <login>)");
|
|
10369
10404
|
} else {
|
|
@@ -10470,6 +10505,7 @@ async function runInbox(opts = {}) {
|
|
|
10470
10505
|
input = process.stdin,
|
|
10471
10506
|
client = createChatClient(),
|
|
10472
10507
|
listConnections = defaultListConnections,
|
|
10508
|
+
listInvites = defaultListPendingInvites,
|
|
10473
10509
|
readCursors = readReadCursors,
|
|
10474
10510
|
ensureDisclosure = ensureChatDisclosure
|
|
10475
10511
|
} = opts;
|
|
@@ -10480,6 +10516,12 @@ async function runInbox(opts = {}) {
|
|
|
10480
10516
|
if (listed.status !== "ok") {
|
|
10481
10517
|
return { ok: false, reason: writeProblem(output, listed, "") };
|
|
10482
10518
|
}
|
|
10519
|
+
let invites = [];
|
|
10520
|
+
try {
|
|
10521
|
+
const inv = await listInvites();
|
|
10522
|
+
if (inv && inv.status === "ok") invites = inv.invites;
|
|
10523
|
+
} catch {
|
|
10524
|
+
}
|
|
10483
10525
|
const cursors = readCursors();
|
|
10484
10526
|
const items = [];
|
|
10485
10527
|
for (const conn of listed.connections) {
|
|
@@ -10504,8 +10546,8 @@ async function runInbox(opts = {}) {
|
|
|
10504
10546
|
});
|
|
10505
10547
|
}
|
|
10506
10548
|
await clearPresence(client);
|
|
10507
|
-
output.write(renderInbox(items));
|
|
10508
|
-
return { ok: true, count: items.length };
|
|
10549
|
+
output.write(renderInbox(items, invites));
|
|
10550
|
+
return { ok: true, count: items.length, invites: invites.length };
|
|
10509
10551
|
}
|
|
10510
10552
|
async function runReadThread(opts = {}) {
|
|
10511
10553
|
const {
|
|
@@ -10518,6 +10560,7 @@ async function runReadThread(opts = {}) {
|
|
|
10518
10560
|
resolveConnection = defaultResolveConnection,
|
|
10519
10561
|
writeCursor = writeReadCursor,
|
|
10520
10562
|
syncCursor = postReadCursor,
|
|
10563
|
+
syncBadge = syncUnreadBadge,
|
|
10521
10564
|
ensureDisclosure = ensureChatDisclosure
|
|
10522
10565
|
} = opts;
|
|
10523
10566
|
const target = String(login ?? "").replace(/^@/, "").trim();
|
|
@@ -10564,6 +10607,7 @@ async function runReadThread(opts = {}) {
|
|
|
10564
10607
|
} catch {
|
|
10565
10608
|
}
|
|
10566
10609
|
await syncCursor(peerLogin, newest.createdAt);
|
|
10610
|
+
await syncBadge();
|
|
10567
10611
|
}
|
|
10568
10612
|
}
|
|
10569
10613
|
return { ok: true, shown: shownMessages.length, total };
|
|
@@ -10611,7 +10655,7 @@ async function runSend(opts = {}) {
|
|
|
10611
10655
|
);
|
|
10612
10656
|
return { ok: true };
|
|
10613
10657
|
}
|
|
10614
|
-
var CHAT_BASE2, GH_SESSION_COOKIE4, TERMINALHIRE_DIR12, READS_FILE;
|
|
10658
|
+
var CHAT_BASE2, GH_SESSION_COOKIE4, TERMINALHIRE_DIR12, READS_FILE, INDEX_CACHE_FILE5;
|
|
10615
10659
|
var init_jpi_chat_read = __esm({
|
|
10616
10660
|
"bin/jpi-chat-read.js"() {
|
|
10617
10661
|
"use strict";
|
|
@@ -10622,6 +10666,7 @@ var init_jpi_chat_read = __esm({
|
|
|
10622
10666
|
GH_SESSION_COOKIE4 = "__jpi_gh_session";
|
|
10623
10667
|
TERMINALHIRE_DIR12 = join16(homedir15(), ".terminalhire");
|
|
10624
10668
|
READS_FILE = join16(TERMINALHIRE_DIR12, "chat-reads.json");
|
|
10669
|
+
INDEX_CACHE_FILE5 = join16(TERMINALHIRE_DIR12, "index-cache.json");
|
|
10625
10670
|
}
|
|
10626
10671
|
});
|
|
10627
10672
|
|
|
@@ -10633,6 +10678,7 @@ __export(jpi_chat_exports, {
|
|
|
10633
10678
|
CHAT_DISCLOSURE: () => CHAT_DISCLOSURE,
|
|
10634
10679
|
CHAT_MIN_AGE: () => CHAT_MIN_AGE,
|
|
10635
10680
|
defaultListConnections: () => defaultListConnections,
|
|
10681
|
+
defaultListPendingInvites: () => defaultListPendingInvites,
|
|
10636
10682
|
defaultResolveConnection: () => defaultResolveConnection,
|
|
10637
10683
|
ensureChatDisclosure: () => ensureChatDisclosure,
|
|
10638
10684
|
formatThread: () => formatThread,
|
|
@@ -10728,6 +10774,12 @@ async function defaultListConnections(deps = {}) {
|
|
|
10728
10774
|
const connections = listed.intros.filter((it) => it && it.status === "accepted" && it.counterpartyLogin).map((it) => ({ introId: it.id, peerLogin: it.counterpartyLogin }));
|
|
10729
10775
|
return { status: "ok", connections };
|
|
10730
10776
|
}
|
|
10777
|
+
async function defaultListPendingInvites(deps = {}) {
|
|
10778
|
+
const listed = await fetchIntroList(deps);
|
|
10779
|
+
if (listed.status !== "ok") return listed;
|
|
10780
|
+
const invites = listed.intros.filter((it) => it && it.role === "incoming" && it.status === "pending" && it.counterpartyLogin).map((it) => ({ login: it.counterpartyLogin }));
|
|
10781
|
+
return { status: "ok", invites };
|
|
10782
|
+
}
|
|
10731
10783
|
function formatThread(state) {
|
|
10732
10784
|
const { peerLogin, online, messages, inputBuffer, banner } = state;
|
|
10733
10785
|
const safePeer = sanitizeLine(peerLogin);
|
|
@@ -13140,7 +13192,7 @@ async function run18() {
|
|
|
13140
13192
|
unreadChat,
|
|
13141
13193
|
sessionStale
|
|
13142
13194
|
};
|
|
13143
|
-
writeFileSync17(
|
|
13195
|
+
writeFileSync17(INDEX_CACHE_FILE6, JSON.stringify(cacheEntry), "utf8");
|
|
13144
13196
|
try {
|
|
13145
13197
|
const {
|
|
13146
13198
|
readSpinnerConfig: readSpinnerConfig2,
|
|
@@ -13191,7 +13243,7 @@ async function run18() {
|
|
|
13191
13243
|
process.exit(1);
|
|
13192
13244
|
}
|
|
13193
13245
|
}
|
|
13194
|
-
var GH_SESSION_COOKIE7, __dirname4, TERMINALHIRE_DIR14,
|
|
13246
|
+
var GH_SESSION_COOKIE7, __dirname4, TERMINALHIRE_DIR14, INDEX_CACHE_FILE6, API_URL6;
|
|
13195
13247
|
var init_jpi_refresh = __esm({
|
|
13196
13248
|
"bin/jpi-refresh.js"() {
|
|
13197
13249
|
"use strict";
|
|
@@ -13201,7 +13253,7 @@ var init_jpi_refresh = __esm({
|
|
|
13201
13253
|
GH_SESSION_COOKIE7 = "__jpi_gh_session";
|
|
13202
13254
|
__dirname4 = fileURLToPath5(new URL(".", import.meta.url));
|
|
13203
13255
|
TERMINALHIRE_DIR14 = join23(homedir21(), ".terminalhire");
|
|
13204
|
-
|
|
13256
|
+
INDEX_CACHE_FILE6 = join23(TERMINALHIRE_DIR14, "index-cache.json");
|
|
13205
13257
|
API_URL6 = process.env["TERMINALHIRE_API_URL"] ?? process.env["JPI_API_URL"] ?? "https://www.terminalhire.com";
|
|
13206
13258
|
}
|
|
13207
13259
|
});
|
|
@@ -13217,8 +13269,8 @@ import { homedir as homedir22 } from "os";
|
|
|
13217
13269
|
import { fileURLToPath as fileURLToPath6 } from "url";
|
|
13218
13270
|
function findJobInCache(jobId) {
|
|
13219
13271
|
try {
|
|
13220
|
-
if (!existsSync18(
|
|
13221
|
-
const raw = readFileSync22(
|
|
13272
|
+
if (!existsSync18(INDEX_CACHE_FILE7)) return null;
|
|
13273
|
+
const raw = readFileSync22(INDEX_CACHE_FILE7, "utf8");
|
|
13222
13274
|
const entry = JSON.parse(raw);
|
|
13223
13275
|
const jobs = entry?.index?.jobs ?? [];
|
|
13224
13276
|
return jobs.find((j) => j.id === jobId) ?? null;
|
|
@@ -13306,13 +13358,13 @@ async function run19() {
|
|
|
13306
13358
|
process.exit(1);
|
|
13307
13359
|
}
|
|
13308
13360
|
}
|
|
13309
|
-
var __dirname5, TERMINALHIRE_DIR15,
|
|
13361
|
+
var __dirname5, TERMINALHIRE_DIR15, INDEX_CACHE_FILE7;
|
|
13310
13362
|
var init_jpi_save = __esm({
|
|
13311
13363
|
"bin/jpi-save.js"() {
|
|
13312
13364
|
"use strict";
|
|
13313
13365
|
__dirname5 = fileURLToPath6(new URL(".", import.meta.url));
|
|
13314
13366
|
TERMINALHIRE_DIR15 = join24(homedir22(), ".terminalhire");
|
|
13315
|
-
|
|
13367
|
+
INDEX_CACHE_FILE7 = join24(TERMINALHIRE_DIR15, "index-cache.json");
|
|
13316
13368
|
}
|
|
13317
13369
|
});
|
|
13318
13370
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "terminalhire",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.10",
|
|
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",
|