terminalhire 0.9.0 → 0.9.1

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.
@@ -3855,14 +3855,53 @@ var init_chat_keystore = __esm({
3855
3855
  }
3856
3856
  });
3857
3857
 
3858
- // src/chat-client.ts
3859
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
3858
+ // src/web-session.ts
3859
+ import {
3860
+ chmodSync,
3861
+ existsSync as existsSync3,
3862
+ mkdirSync as mkdirSync3,
3863
+ readFileSync as readFileSync4,
3864
+ rmSync as rmSync3,
3865
+ writeFileSync as writeFileSync3
3866
+ } from "fs";
3860
3867
  import { homedir as homedir3 } from "os";
3861
3868
  import { join as join4 } from "path";
3869
+ function terminalhireDir() {
3870
+ return join4(homedir3(), ".terminalhire");
3871
+ }
3872
+ function webSessionFilePath() {
3873
+ return join4(terminalhireDir(), "web-session");
3874
+ }
3875
+ function readWebSessionFile() {
3876
+ try {
3877
+ const path = webSessionFilePath();
3878
+ if (!existsSync3(path)) return null;
3879
+ const v = readFileSync4(path, "utf8").trim();
3880
+ return v.length > 0 ? v : null;
3881
+ } catch {
3882
+ return null;
3883
+ }
3884
+ }
3885
+ function readWebSessionCookie() {
3886
+ const fromFile = readWebSessionFile();
3887
+ if (fromFile) return fromFile;
3888
+ const env = process.env["TERMINALHIRE_WEB_SESSION"];
3889
+ return typeof env === "string" && env.length > 0 ? env : null;
3890
+ }
3891
+ var init_web_session = __esm({
3892
+ "src/web-session.ts"() {
3893
+ "use strict";
3894
+ }
3895
+ });
3896
+
3897
+ // src/chat-client.ts
3898
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
3899
+ import { homedir as homedir4 } from "os";
3900
+ import { join as join5 } from "path";
3862
3901
  function defaultReadPeerPins() {
3863
3902
  try {
3864
- if (!existsSync3(PEERS_FILE)) return {};
3865
- const parsed = JSON.parse(readFileSync4(PEERS_FILE, "utf8"));
3903
+ if (!existsSync4(PEERS_FILE)) return {};
3904
+ const parsed = JSON.parse(readFileSync5(PEERS_FILE, "utf8"));
3866
3905
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
3867
3906
  const out = {};
3868
3907
  for (const [login, key] of Object.entries(parsed)) {
@@ -3874,16 +3913,15 @@ function defaultReadPeerPins() {
3874
3913
  }
3875
3914
  }
3876
3915
  function defaultWritePeerPins(pins) {
3877
- mkdirSync3(TERMINALHIRE_DIR3, { recursive: true });
3878
- writeFileSync3(PEERS_FILE, JSON.stringify(pins, null, 2), { mode: 384, encoding: "utf8" });
3916
+ mkdirSync4(TERMINALHIRE_DIR3, { recursive: true });
3917
+ writeFileSync4(PEERS_FILE, JSON.stringify(pins, null, 2), { mode: 384, encoding: "utf8" });
3879
3918
  }
3880
3919
  function defaultChatClientDeps() {
3881
3920
  return {
3882
3921
  fetchImpl: (...args) => globalThis.fetch(...args),
3883
- sessionCookie: () => {
3884
- const v = process.env["TERMINALHIRE_WEB_SESSION"];
3885
- return typeof v === "string" && v.length > 0 ? v : null;
3886
- },
3922
+ // Session source priority: persisted file (`terminalhire link`) FIRST, then the
3923
+ // legacy TERMINALHIRE_WEB_SESSION env, then none.
3924
+ sessionCookie: () => readWebSessionCookie(),
3887
3925
  loadIdentity: () => loadOrCreateIdentity(),
3888
3926
  readPeerPins: defaultReadPeerPins,
3889
3927
  writePeerPins: defaultWritePeerPins
@@ -4036,15 +4074,16 @@ var init_chat_client = __esm({
4036
4074
  "use strict";
4037
4075
  init_src();
4038
4076
  init_chat_keystore();
4077
+ init_web_session();
4039
4078
  CHAT_BASE = process.env["TERMINALHIRE_API_URL"] || "https://www.terminalhire.com";
4040
4079
  GH_SESSION_COOKIE = "__jpi_gh_session";
4041
- TERMINALHIRE_DIR3 = join4(homedir3(), ".terminalhire");
4042
- PEERS_FILE = join4(TERMINALHIRE_DIR3, "chat-peers.json");
4080
+ TERMINALHIRE_DIR3 = join5(homedir4(), ".terminalhire");
4081
+ PEERS_FILE = join5(TERMINALHIRE_DIR3, "chat-peers.json");
4043
4082
  REQUEST_TIMEOUT_MS = 1e4;
4044
4083
  ChatNotLinkedError = class extends Error {
4045
4084
  constructor() {
4046
4085
  super(
4047
- `No linked web session found on this machine. Sign in at ${CHAT_BASE}/dashboard, then re-run with a bridged session (TERMINALHIRE_WEB_SESSION).`
4086
+ "No linked web session found on this machine. Run `terminalhire link` to connect this terminal to your account, then re-run."
4048
4087
  );
4049
4088
  this.name = "ChatNotLinkedError";
4050
4089
  }
@@ -4052,7 +4091,7 @@ var init_chat_client = __esm({
4052
4091
  ChatSessionExpiredError = class extends Error {
4053
4092
  constructor() {
4054
4093
  super(
4055
- `Your web session expired \u2014 re-link it by signing in again at ${CHAT_BASE}/dashboard and re-bridging TERMINALHIRE_WEB_SESSION, then re-run.`
4094
+ "Your linked web session expired. Run `terminalhire link` to reconnect this terminal, then re-run."
4056
4095
  );
4057
4096
  this.name = "ChatSessionExpiredError";
4058
4097
  }
@@ -4081,13 +4120,13 @@ var init_chat_client = __esm({
4081
4120
  });
4082
4121
 
4083
4122
  // src/config.ts
4084
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync4 } from "fs";
4085
- import { join as join5 } from "path";
4086
- import { homedir as homedir4 } from "os";
4123
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync5 } from "fs";
4124
+ import { join as join6 } from "path";
4125
+ import { homedir as homedir5 } from "os";
4087
4126
  function readConfig() {
4088
4127
  try {
4089
- if (!existsSync4(CONFIG_FILE)) return { ...DEFAULT_CONFIG };
4090
- const raw = readFileSync5(CONFIG_FILE, "utf8");
4128
+ if (!existsSync5(CONFIG_FILE)) return { ...DEFAULT_CONFIG };
4129
+ const raw = readFileSync6(CONFIG_FILE, "utf8");
4091
4130
  const parsed = JSON.parse(raw);
4092
4131
  return { ...DEFAULT_CONFIG, ...parsed };
4093
4132
  } catch {
@@ -4095,17 +4134,17 @@ function readConfig() {
4095
4134
  }
4096
4135
  }
4097
4136
  function writeConfig(config) {
4098
- mkdirSync4(TERMINALHIRE_DIR4, { recursive: true });
4137
+ mkdirSync5(TERMINALHIRE_DIR4, { recursive: true });
4099
4138
  const current = readConfig();
4100
4139
  const merged = { ...current, ...config };
4101
- writeFileSync4(CONFIG_FILE, JSON.stringify(merged, null, 2) + "\n", "utf8");
4140
+ writeFileSync5(CONFIG_FILE, JSON.stringify(merged, null, 2) + "\n", "utf8");
4102
4141
  }
4103
4142
  var TERMINALHIRE_DIR4, CONFIG_FILE, DEFAULT_CONFIG;
4104
4143
  var init_config = __esm({
4105
4144
  "src/config.ts"() {
4106
4145
  "use strict";
4107
- TERMINALHIRE_DIR4 = join5(homedir4(), ".terminalhire");
4108
- CONFIG_FILE = join5(TERMINALHIRE_DIR4, "config.json");
4146
+ TERMINALHIRE_DIR4 = join6(homedir5(), ".terminalhire");
4147
+ CONFIG_FILE = join6(TERMINALHIRE_DIR4, "config.json");
4109
4148
  DEFAULT_CONFIG = {
4110
4149
  nudge: "session",
4111
4150
  peerConnect: false,
@@ -4225,13 +4264,13 @@ var init_jpi_chat = __esm({
4225
4264
  });
4226
4265
 
4227
4266
  // bin/jpi-chat-read.js
4228
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
4229
- import { homedir as homedir5 } from "os";
4230
- import { join as join6 } from "path";
4267
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4268
+ import { homedir as homedir6 } from "os";
4269
+ import { join as join7 } from "path";
4231
4270
  function readReadCursors() {
4232
4271
  try {
4233
- if (!existsSync5(READS_FILE)) return {};
4234
- const parsed = JSON.parse(readFileSync6(READS_FILE, "utf8"));
4272
+ if (!existsSync6(READS_FILE)) return {};
4273
+ const parsed = JSON.parse(readFileSync7(READS_FILE, "utf8"));
4235
4274
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
4236
4275
  const out = {};
4237
4276
  for (const [login, iso] of Object.entries(parsed)) {
@@ -4246,8 +4285,8 @@ function writeReadCursor(login, iso, deps = {}) {
4246
4285
  const read = deps.readReadCursors ?? readReadCursors;
4247
4286
  const cursors = read();
4248
4287
  cursors[login] = iso;
4249
- mkdirSync5(TERMINALHIRE_DIR5, { recursive: true });
4250
- writeFileSync5(READS_FILE, JSON.stringify(cursors, null, 2), { mode: 384, encoding: "utf8" });
4288
+ mkdirSync6(TERMINALHIRE_DIR5, { recursive: true });
4289
+ writeFileSync6(READS_FILE, JSON.stringify(cursors, null, 2), { mode: 384, encoding: "utf8" });
4251
4290
  }
4252
4291
  function formatClock(iso) {
4253
4292
  const d = new Date(iso);
@@ -4530,8 +4569,8 @@ var init_jpi_chat_read = __esm({
4530
4569
  init_chat_client();
4531
4570
  init_jpi_chat();
4532
4571
  CHAT_BASE3 = process.env["TERMINALHIRE_API_URL"] || "https://www.terminalhire.com";
4533
- TERMINALHIRE_DIR5 = join6(homedir5(), ".terminalhire");
4534
- READS_FILE = join6(TERMINALHIRE_DIR5, "chat-reads.json");
4572
+ TERMINALHIRE_DIR5 = join7(homedir6(), ".terminalhire");
4573
+ READS_FILE = join7(TERMINALHIRE_DIR5, "chat-reads.json");
4535
4574
  }
4536
4575
  });
4537
4576
  init_jpi_chat_read();
@@ -3860,14 +3860,53 @@ var init_chat_keystore = __esm({
3860
3860
  }
3861
3861
  });
3862
3862
 
3863
- // src/chat-client.ts
3864
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
3863
+ // src/web-session.ts
3864
+ import {
3865
+ chmodSync,
3866
+ existsSync as existsSync3,
3867
+ mkdirSync as mkdirSync3,
3868
+ readFileSync as readFileSync4,
3869
+ rmSync as rmSync3,
3870
+ writeFileSync as writeFileSync3
3871
+ } from "fs";
3865
3872
  import { homedir as homedir3 } from "os";
3866
3873
  import { join as join4 } from "path";
3874
+ function terminalhireDir() {
3875
+ return join4(homedir3(), ".terminalhire");
3876
+ }
3877
+ function webSessionFilePath() {
3878
+ return join4(terminalhireDir(), "web-session");
3879
+ }
3880
+ function readWebSessionFile() {
3881
+ try {
3882
+ const path = webSessionFilePath();
3883
+ if (!existsSync3(path)) return null;
3884
+ const v = readFileSync4(path, "utf8").trim();
3885
+ return v.length > 0 ? v : null;
3886
+ } catch {
3887
+ return null;
3888
+ }
3889
+ }
3890
+ function readWebSessionCookie() {
3891
+ const fromFile = readWebSessionFile();
3892
+ if (fromFile) return fromFile;
3893
+ const env = process.env["TERMINALHIRE_WEB_SESSION"];
3894
+ return typeof env === "string" && env.length > 0 ? env : null;
3895
+ }
3896
+ var init_web_session = __esm({
3897
+ "src/web-session.ts"() {
3898
+ "use strict";
3899
+ }
3900
+ });
3901
+
3902
+ // src/chat-client.ts
3903
+ import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync4 } from "fs";
3904
+ import { homedir as homedir4 } from "os";
3905
+ import { join as join5 } from "path";
3867
3906
  function defaultReadPeerPins() {
3868
3907
  try {
3869
- if (!existsSync3(PEERS_FILE)) return {};
3870
- const parsed = JSON.parse(readFileSync4(PEERS_FILE, "utf8"));
3908
+ if (!existsSync4(PEERS_FILE)) return {};
3909
+ const parsed = JSON.parse(readFileSync5(PEERS_FILE, "utf8"));
3871
3910
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
3872
3911
  const out = {};
3873
3912
  for (const [login, key] of Object.entries(parsed)) {
@@ -3879,16 +3918,15 @@ function defaultReadPeerPins() {
3879
3918
  }
3880
3919
  }
3881
3920
  function defaultWritePeerPins(pins) {
3882
- mkdirSync3(TERMINALHIRE_DIR3, { recursive: true });
3883
- writeFileSync3(PEERS_FILE, JSON.stringify(pins, null, 2), { mode: 384, encoding: "utf8" });
3921
+ mkdirSync4(TERMINALHIRE_DIR3, { recursive: true });
3922
+ writeFileSync4(PEERS_FILE, JSON.stringify(pins, null, 2), { mode: 384, encoding: "utf8" });
3884
3923
  }
3885
3924
  function defaultChatClientDeps() {
3886
3925
  return {
3887
3926
  fetchImpl: (...args) => globalThis.fetch(...args),
3888
- sessionCookie: () => {
3889
- const v = process.env["TERMINALHIRE_WEB_SESSION"];
3890
- return typeof v === "string" && v.length > 0 ? v : null;
3891
- },
3927
+ // Session source priority: persisted file (`terminalhire link`) FIRST, then the
3928
+ // legacy TERMINALHIRE_WEB_SESSION env, then none.
3929
+ sessionCookie: () => readWebSessionCookie(),
3892
3930
  loadIdentity: () => loadOrCreateIdentity(),
3893
3931
  readPeerPins: defaultReadPeerPins,
3894
3932
  writePeerPins: defaultWritePeerPins
@@ -4041,15 +4079,16 @@ var init_chat_client = __esm({
4041
4079
  "use strict";
4042
4080
  init_src();
4043
4081
  init_chat_keystore();
4082
+ init_web_session();
4044
4083
  CHAT_BASE = process.env["TERMINALHIRE_API_URL"] || "https://www.terminalhire.com";
4045
4084
  GH_SESSION_COOKIE = "__jpi_gh_session";
4046
- TERMINALHIRE_DIR3 = join4(homedir3(), ".terminalhire");
4047
- PEERS_FILE = join4(TERMINALHIRE_DIR3, "chat-peers.json");
4085
+ TERMINALHIRE_DIR3 = join5(homedir4(), ".terminalhire");
4086
+ PEERS_FILE = join5(TERMINALHIRE_DIR3, "chat-peers.json");
4048
4087
  REQUEST_TIMEOUT_MS = 1e4;
4049
4088
  ChatNotLinkedError = class extends Error {
4050
4089
  constructor() {
4051
4090
  super(
4052
- `No linked web session found on this machine. Sign in at ${CHAT_BASE}/dashboard, then re-run with a bridged session (TERMINALHIRE_WEB_SESSION).`
4091
+ "No linked web session found on this machine. Run `terminalhire link` to connect this terminal to your account, then re-run."
4053
4092
  );
4054
4093
  this.name = "ChatNotLinkedError";
4055
4094
  }
@@ -4057,7 +4096,7 @@ var init_chat_client = __esm({
4057
4096
  ChatSessionExpiredError = class extends Error {
4058
4097
  constructor() {
4059
4098
  super(
4060
- `Your web session expired \u2014 re-link it by signing in again at ${CHAT_BASE}/dashboard and re-bridging TERMINALHIRE_WEB_SESSION, then re-run.`
4099
+ "Your linked web session expired. Run `terminalhire link` to reconnect this terminal, then re-run."
4061
4100
  );
4062
4101
  this.name = "ChatSessionExpiredError";
4063
4102
  }
@@ -4086,13 +4125,13 @@ var init_chat_client = __esm({
4086
4125
  });
4087
4126
 
4088
4127
  // src/config.ts
4089
- import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync4 } from "fs";
4090
- import { join as join5 } from "path";
4091
- import { homedir as homedir4 } from "os";
4128
+ import { readFileSync as readFileSync6, writeFileSync as writeFileSync5, mkdirSync as mkdirSync5, existsSync as existsSync5 } from "fs";
4129
+ import { join as join6 } from "path";
4130
+ import { homedir as homedir5 } from "os";
4092
4131
  function readConfig() {
4093
4132
  try {
4094
- if (!existsSync4(CONFIG_FILE)) return { ...DEFAULT_CONFIG };
4095
- const raw = readFileSync5(CONFIG_FILE, "utf8");
4133
+ if (!existsSync5(CONFIG_FILE)) return { ...DEFAULT_CONFIG };
4134
+ const raw = readFileSync6(CONFIG_FILE, "utf8");
4096
4135
  const parsed = JSON.parse(raw);
4097
4136
  return { ...DEFAULT_CONFIG, ...parsed };
4098
4137
  } catch {
@@ -4100,17 +4139,17 @@ function readConfig() {
4100
4139
  }
4101
4140
  }
4102
4141
  function writeConfig(config) {
4103
- mkdirSync4(TERMINALHIRE_DIR4, { recursive: true });
4142
+ mkdirSync5(TERMINALHIRE_DIR4, { recursive: true });
4104
4143
  const current = readConfig();
4105
4144
  const merged = { ...current, ...config };
4106
- writeFileSync4(CONFIG_FILE, JSON.stringify(merged, null, 2) + "\n", "utf8");
4145
+ writeFileSync5(CONFIG_FILE, JSON.stringify(merged, null, 2) + "\n", "utf8");
4107
4146
  }
4108
4147
  var TERMINALHIRE_DIR4, CONFIG_FILE, DEFAULT_CONFIG;
4109
4148
  var init_config = __esm({
4110
4149
  "src/config.ts"() {
4111
4150
  "use strict";
4112
- TERMINALHIRE_DIR4 = join5(homedir4(), ".terminalhire");
4113
- CONFIG_FILE = join5(TERMINALHIRE_DIR4, "config.json");
4151
+ TERMINALHIRE_DIR4 = join6(homedir5(), ".terminalhire");
4152
+ CONFIG_FILE = join6(TERMINALHIRE_DIR4, "config.json");
4114
4153
  DEFAULT_CONFIG = {
4115
4154
  nudge: "session",
4116
4155
  peerConnect: false,
@@ -4134,13 +4173,13 @@ __export(jpi_chat_read_exports, {
4134
4173
  runSend: () => runSend,
4135
4174
  writeReadCursor: () => writeReadCursor
4136
4175
  });
4137
- import { existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync6, writeFileSync as writeFileSync5 } from "fs";
4138
- import { homedir as homedir5 } from "os";
4139
- import { join as join6 } from "path";
4176
+ import { existsSync as existsSync6, mkdirSync as mkdirSync6, readFileSync as readFileSync7, writeFileSync as writeFileSync6 } from "fs";
4177
+ import { homedir as homedir6 } from "os";
4178
+ import { join as join7 } from "path";
4140
4179
  function readReadCursors() {
4141
4180
  try {
4142
- if (!existsSync5(READS_FILE)) return {};
4143
- const parsed = JSON.parse(readFileSync6(READS_FILE, "utf8"));
4181
+ if (!existsSync6(READS_FILE)) return {};
4182
+ const parsed = JSON.parse(readFileSync7(READS_FILE, "utf8"));
4144
4183
  if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) return {};
4145
4184
  const out = {};
4146
4185
  for (const [login, iso] of Object.entries(parsed)) {
@@ -4155,8 +4194,8 @@ function writeReadCursor(login, iso, deps = {}) {
4155
4194
  const read = deps.readReadCursors ?? readReadCursors;
4156
4195
  const cursors = read();
4157
4196
  cursors[login] = iso;
4158
- mkdirSync5(TERMINALHIRE_DIR5, { recursive: true });
4159
- writeFileSync5(READS_FILE, JSON.stringify(cursors, null, 2), { mode: 384, encoding: "utf8" });
4197
+ mkdirSync6(TERMINALHIRE_DIR5, { recursive: true });
4198
+ writeFileSync6(READS_FILE, JSON.stringify(cursors, null, 2), { mode: 384, encoding: "utf8" });
4160
4199
  }
4161
4200
  function formatClock(iso) {
4162
4201
  const d = new Date(iso);
@@ -4440,8 +4479,8 @@ var init_jpi_chat_read = __esm({
4440
4479
  init_chat_client();
4441
4480
  init_jpi_chat();
4442
4481
  CHAT_BASE2 = process.env["TERMINALHIRE_API_URL"] || "https://www.terminalhire.com";
4443
- TERMINALHIRE_DIR5 = join6(homedir5(), ".terminalhire");
4444
- READS_FILE = join6(TERMINALHIRE_DIR5, "chat-reads.json");
4482
+ TERMINALHIRE_DIR5 = join7(homedir6(), ".terminalhire");
4483
+ READS_FILE = join7(TERMINALHIRE_DIR5, "chat-reads.json");
4445
4484
  }
4446
4485
  });
4447
4486