terminalhire 0.10.10 → 0.10.11

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.
@@ -4039,7 +4039,21 @@ function createChatClient(overrides) {
4039
4039
  const data = await res.json();
4040
4040
  const presence = data.presence ?? null;
4041
4041
  if (!presence) return null;
4042
- return { login: presence.login, lastSeen: presence.lastSeen };
4042
+ return {
4043
+ login: presence.login,
4044
+ lastSeen: presence.lastSeen ?? null,
4045
+ optin: presence.optin === true,
4046
+ shareActivity: presence.shareActivity === true
4047
+ };
4048
+ }
4049
+ async function setActivitySharing(share) {
4050
+ const res = await authedFetch("/api/chat/activity", {
4051
+ method: "POST",
4052
+ headers: { "Content-Type": "application/json" },
4053
+ body: JSON.stringify({ share })
4054
+ });
4055
+ if (!res.ok) throw new ChatRequestError("/api/chat/activity", res.status);
4056
+ await res.json();
4043
4057
  }
4044
4058
  async function applyBlock(login, action) {
4045
4059
  const target = login.trim();
@@ -4063,6 +4077,7 @@ function createChatClient(overrides) {
4063
4077
  pollMessages,
4064
4078
  heartbeat,
4065
4079
  getPeerPresence,
4080
+ setActivitySharing,
4066
4081
  blockPeer: (login) => applyBlock(login, "block"),
4067
4082
  unblock: (login) => applyBlock(login, "unblock"),
4068
4083
  getSafetyNumber
@@ -4151,6 +4166,7 @@ var init_config = __esm({
4151
4166
  peerConnectPrompted: false,
4152
4167
  resumePublishPrompted: false,
4153
4168
  chatDisclosureAck: false,
4169
+ chatShareActivity: false,
4154
4170
  inboundNudgeMuted: false,
4155
4171
  inboundNudgeDisclosed: false
4156
4172
  };
@@ -4159,6 +4175,9 @@ var init_config = __esm({
4159
4175
 
4160
4176
  // bin/jpi-chat.js
4161
4177
  import { createInterface } from "readline";
4178
+ import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
4179
+ import { homedir as homedir6 } from "os";
4180
+ import { join as join7 } from "path";
4162
4181
  function sanitizeLine(text) {
4163
4182
  return String(text).replace(ANSI_CSI, "").replace(ANSI_OSC, "").replace(ANSI_OTHER, "").replace(C0_C1_DEL, "");
4164
4183
  }
@@ -4251,7 +4270,7 @@ async function defaultListPendingInvites(deps = {}) {
4251
4270
  const invites = listed.intros.filter((it) => it && it.role === "incoming" && it.status === "pending" && it.counterpartyLogin).map((it) => ({ login: it.counterpartyLogin }));
4252
4271
  return { status: "ok", invites };
4253
4272
  }
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;
4273
+ 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, ACTIVE_WINDOW_MS;
4255
4274
  var init_jpi_chat = __esm({
4256
4275
  "bin/jpi-chat.js"() {
4257
4276
  "use strict";
@@ -4268,20 +4287,21 @@ var init_jpi_chat = __esm({
4268
4287
  CHAT_AT_REST = "Your private key is encrypted against casual access, not full machine compromise.";
4269
4288
  CHAT_CODE_OF_CONDUCT = "Code of conduct: keep it professional \u2014 harassment, spam, or abuse gets you blocked and removed.";
4270
4289
  CHAT_MIN_AGE = "You must be at least 13 years old to use connections chat.";
4290
+ ACTIVE_WINDOW_MS = 2 * 60 * 1e3;
4271
4291
  }
4272
4292
  });
4273
4293
 
4274
4294
  // bin/jpi-chat-read.js
4275
- import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4276
- import { homedir as homedir6 } from "os";
4277
- import { join as join7 } from "path";
4295
+ import { existsSync as existsSync7, mkdirSync as mkdirSync6, readFileSync as readFileSync8, writeFileSync as writeFileSync6 } from "fs";
4296
+ import { homedir as homedir7 } from "os";
4297
+ import { join as join8 } from "path";
4278
4298
  async function syncUnreadBadge(deps = {}) {
4279
4299
  const readCookie = deps.readCookie ?? readWebSessionCookie;
4280
4300
  const fetchImpl = deps.fetchImpl ?? globalThis.fetch;
4281
4301
  const cacheFile = deps.cacheFile ?? INDEX_CACHE_FILE;
4282
4302
  try {
4283
4303
  const cookie = readCookie();
4284
- if (!cookie || !existsSync6(cacheFile)) return;
4304
+ if (!cookie || !existsSync7(cacheFile)) return;
4285
4305
  const res = await fetchImpl(`${CHAT_BASE3}/api/chat/inbox`, {
4286
4306
  method: "GET",
4287
4307
  headers: { Cookie: `${GH_SESSION_COOKIE3}=${cookie}` },
@@ -4294,7 +4314,7 @@ async function syncUnreadBadge(deps = {}) {
4294
4314
  (sum, it) => sum + (it && typeof it.unreadCount === "number" && it.unreadCount > 0 ? it.unreadCount : 0),
4295
4315
  0
4296
4316
  );
4297
- const entry = JSON.parse(readFileSync7(cacheFile, "utf8"));
4317
+ const entry = JSON.parse(readFileSync8(cacheFile, "utf8"));
4298
4318
  entry.unreadChat = { count: total };
4299
4319
  writeFileSync6(cacheFile, JSON.stringify(entry), "utf8");
4300
4320
  } catch {
@@ -4302,8 +4322,8 @@ async function syncUnreadBadge(deps = {}) {
4302
4322
  }
4303
4323
  function readReadCursors() {
4304
4324
  try {
4305
- if (!existsSync6(READS_FILE)) return {};
4306
- const parsed = JSON.parse(readFileSync7(READS_FILE, "utf8"));
4325
+ if (!existsSync7(READS_FILE)) return {};
4326
+ const parsed = JSON.parse(readFileSync8(READS_FILE, "utf8"));
4307
4327
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
4308
4328
  const out = {};
4309
4329
  for (const [login, iso] of Object.entries(parsed)) {
@@ -4593,7 +4613,10 @@ async function runSend(opts = {}) {
4593
4613
  input = process.stdin,
4594
4614
  client = createChatClient(),
4595
4615
  resolveConnection = defaultResolveConnection,
4596
- ensureDisclosure = ensureChatDisclosure
4616
+ ensureDisclosure = ensureChatDisclosure,
4617
+ writeCursor = writeReadCursor,
4618
+ syncCursor = postReadCursor,
4619
+ syncBadge = syncUnreadBadge
4597
4620
  } = opts;
4598
4621
  const target = String(login ?? "").replace(/^@/, "").trim();
4599
4622
  const body = String(text ?? "").trim();
@@ -4619,6 +4642,19 @@ async function runSend(opts = {}) {
4619
4642
  `);
4620
4643
  return { ok: false, reason: "error" };
4621
4644
  }
4645
+ const nowIso = (/* @__PURE__ */ new Date()).toISOString();
4646
+ try {
4647
+ writeCursor(peerLogin, nowIso);
4648
+ } catch {
4649
+ }
4650
+ await syncCursor(peerLogin, nowIso);
4651
+ await syncBadge();
4652
+ if (typeof client.heartbeat === "function") {
4653
+ try {
4654
+ await client.heartbeat(false);
4655
+ } catch {
4656
+ }
4657
+ }
4622
4658
  output.write(
4623
4659
  `
4624
4660
  Sent to @${sanitizeLine(peerLogin)}: ${sanitizeLine(body)}
@@ -4636,9 +4672,9 @@ var init_jpi_chat_read = __esm({
4636
4672
  init_jpi_chat();
4637
4673
  CHAT_BASE3 = process.env["TERMINALHIRE_API_URL"] || "https://www.terminalhire.com";
4638
4674
  GH_SESSION_COOKIE3 = "__jpi_gh_session";
4639
- TERMINALHIRE_DIR5 = join7(homedir6(), ".terminalhire");
4640
- READS_FILE = join7(TERMINALHIRE_DIR5, "chat-reads.json");
4641
- INDEX_CACHE_FILE = join7(TERMINALHIRE_DIR5, "index-cache.json");
4675
+ TERMINALHIRE_DIR5 = join8(homedir7(), ".terminalhire");
4676
+ READS_FILE = join8(TERMINALHIRE_DIR5, "chat-reads.json");
4677
+ INDEX_CACHE_FILE = join8(TERMINALHIRE_DIR5, "index-cache.json");
4642
4678
  }
4643
4679
  });
4644
4680
  init_jpi_chat_read();